Skip to content

Commit

Permalink
mmx_postool + Prover work
Browse files Browse the repository at this point in the history
  • Loading branch information
madMAx43v3r committed Apr 6, 2024
1 parent 5c6b3a6 commit b291453
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 18 deletions.
11 changes: 8 additions & 3 deletions include/mmx/pos/Prover.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@
namespace mmx {
namespace pos {

struct proof_data_t {
hash_t hash; // quality hash
struct proof_data_t
{
hash_t quality; // quality hash
uint64_t index = 0; // final entry index
std::vector<uint32_t> proof; // SSD plots will return full proof as well
};

class Prover {
public:
bool debug = false;
int32_t initial_park_index_shift = 2;
int32_t initial_y_shift = -256;

Prover(const std::string& file_path);

Expand All @@ -40,6 +41,10 @@ class Prover {
return header->plot_id;
}

int get_clevel() const {
return header->ksize - header->xbits;
}

private:
const std::string file_path;

Expand Down
56 changes: 41 additions & 15 deletions src/pos/Prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace pos {
Prover::Prover(const std::string& file_path)
: file_path(file_path)
{
if(!vnx::File(file_path).exists()) {
throw std::logic_error("no such file");
}
header = vnx::read_from_file<const PlotHeader>(file_path);
if(!header) {
throw std::logic_error("invalid plot header");
Expand All @@ -41,35 +44,42 @@ std::vector<proof_data_t> Prover::get_qualities(const hash_t& challenge, const i
}
std::vector<uint64_t> final_entries;
{
int32_t park_index = ((uint64_t(Y_begin >> 1) * header->num_entries_y) >> 31) / header->park_size_y;
const int32_t num_parks_y = cdiv<uint64_t>(header->num_entries_y, header->park_size_y);

park_index = std::max<int32_t>(park_index - initial_park_index_shift, 0);
const uint32_t Y_try_first = std::max<int64_t>(int64_t(Y_begin) + initial_y_shift, 0);
int32_t park_index = ((uint64_t(Y_try_first >> 1) * header->num_entries_y) >> (header->ksize - 1)) / header->park_size_y;

std::vector<uint64_t> bit_stream(cdiv(header->park_bytes_y - 4, 8));
park_index = std::min<int32_t>(park_index, num_parks_y - 1);

const int32_t num_parks_y = cdiv<uint64_t>(header->num_entries_y, header->park_size_y);
std::vector<uint64_t> bit_stream(cdiv(header->park_bytes_y - 4, 8));

bool have_begin = false;
for(size_t i = 0; park_index >= 0 && park_index < num_parks_y; i++)
{
if(i > 100) {
throw std::runtime_error("failed to find Y park");
}
if(debug) {
std::cout << "park_index = " << park_index << std::endl;
}
file.seekg(header->table_offset_y + uint64_t(park_index) * header->park_bytes_y);

uint32_t Y_i = 0;
{
uint64_t tmp = 0;
file.read((char*)tmp, 4);
file.read((char*)&tmp, 4);
Y_i = read_bits(&tmp, 0, header->ksize);
}
if(!file.good()) {
throw std::runtime_error("failed to read Y park header " + std::to_string(park_index));
}
if(debug) {
std::cout << "park_index = " << park_index << ", Y = " << Y_i << std::endl;
}
if(Y_i >= Y_end) {
if(have_begin || park_index == 0) {
break;
}
if(debug) {
std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
}
park_index = std::max<int32_t>(park_index - cdiv(Y_i - Y_begin, header->park_size_y) - 1, 0);
continue;
}
Expand Down Expand Up @@ -137,7 +147,8 @@ std::vector<proof_data_t> Prover::get_qualities(const hash_t& challenge, const i
for(int i = 0; i < N_META_OUT; ++i) {
meta[i] = read_bits(meta_park.data(), (park_offset * N_META_OUT + i) * header->ksize, header->ksize);
}
out.hash = calc_quality(challenge, bytes_t<META_BYTES_OUT>(meta, META_BYTES_OUT));
out.index = final_index;
out.quality = calc_quality(challenge, bytes_t<META_BYTES_OUT>(meta, META_BYTES_OUT));
} else {
out = get_full_proof(challenge, final_index);
}
Expand All @@ -149,9 +160,9 @@ std::vector<proof_data_t> Prover::get_qualities(const hash_t& challenge, const i
proof_data_t Prover::get_full_proof(const hash_t& challenge, const uint64_t final_index) const
{
std::ifstream file(file_path, std::ios_base::binary);
if(!file.good()) {
throw std::runtime_error("failed to open file");
}
if(!file.good()) {
throw std::runtime_error("failed to open file");
}
std::vector<uint32_t> X_values;
std::vector<uint64_t> pointers;
pointers.push_back(final_index);
Expand All @@ -177,10 +188,18 @@ proof_data_t Prover::get_full_proof(const hash_t& challenge, const uint64_t fina
const auto offsets = decode(pd_park, park_offset + 1, header->park_size_pd * header->ksize);
new_pointers.push_back(position + offsets.back());
}
if(debug) {
std::cout << "T" << (table - 1) << " pointers: ";
for(auto ptr : new_pointers) {
std::cout << ptr << " ";
}
std::cout << std::endl;
}
pointers = new_pointers;
table--;
}
proof_data_t out;
out.index = final_index;

std::vector<uint64_t> x_park(cdiv(header->park_bytes_x, 8));

Expand All @@ -191,8 +210,8 @@ proof_data_t Prover::get_full_proof(const hash_t& challenge, const uint64_t fina
file.seekg(header->table_offset_x + park_index * header->park_bytes_x);
file.read((char*)x_park.data(), header->park_bytes_x);
if(!file.good()) {
throw std::runtime_error("failed to read X park " + std::to_string(park_index));
}
throw std::runtime_error("failed to read X park " + std::to_string(park_index));
}
const uint64_t line_point = read_bits(x_park.data(), park_offset * header->entry_bits_x, header->entry_bits_x);

if(table == 2) {
Expand All @@ -204,6 +223,13 @@ proof_data_t Prover::get_full_proof(const hash_t& challenge, const uint64_t fina
}
}

if(debug) {
std::cout << "X_values = ";
for(auto X : X_values) {
std::cout << X << " ";
}
std::cout << std::endl;
}
std::vector<uint32_t> X_out;
const auto res = compute(X_values, &X_out, header->plot_id, header->ksize, header->ksize - header->xbits);
if(res.empty()) {
Expand All @@ -213,7 +239,7 @@ proof_data_t Prover::get_full_proof(const hash_t& challenge, const uint64_t fina
throw std::logic_error("got more than one proof");
}
out.proof = X_out;
out.hash = calc_quality(challenge, res[0].second);
out.quality = calc_quality(challenge, res[0].second);
return out;
}

Expand Down
2 changes: 2 additions & 0 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@

add_executable(tx_bench tx_bench.cpp)
add_executable(mmx_compile mmx_compile.cpp)
add_executable(mmx_postool mmx_postool.cpp)
add_executable(dump_table dump_table.cpp)
add_executable(dump_binary dump_binary.cpp)
add_executable(generate_passwd generate_passwd.cpp)
add_executable(calc_test_rewards calc_test_rewards.cpp)

target_link_libraries(tx_bench mmx_iface)
target_link_libraries(mmx_compile mmx_iface mmx_vm)
target_link_libraries(mmx_postool mmx_iface mmx_pos)
target_link_libraries(dump_table mmx_iface mmx_db)
target_link_libraries(dump_binary mmx_iface mmx_vm)
target_link_libraries(generate_passwd mmx_iface)
Expand Down
143 changes: 143 additions & 0 deletions tools/mmx_postool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* mmx_postool.cpp
*
* Created on: Apr 5, 2024
* Author: mad
*/

#include <mmx/pos/Prover.h>
#include <mmx/pos/verify.h>

#include <vnx/vnx.h>
#include <cmath>

using namespace mmx;


int main(int argc, char** argv)
{
mmx::secp256k1_init();

std::map<std::string, std::string> options;
options["f"] = "file";
options["n"] = "iter";
options["r"] = "threads";
options["v"] = "verbose";
options["file"] = "plot files";
options["iter"] = "number of iterations";
options["threads"] = "number of threads";

vnx::write_config("log_level", 2);

vnx::init("mmx_postool", argc, argv, options);

bool verbose = false;
int num_iter = 100;
int num_threads = 16;
int plot_filter = 4;
std::vector<std::string> file_names;

vnx::read_config("verbose", verbose);
vnx::read_config("file", file_names);
vnx::read_config("iter", num_iter);
vnx::read_config("threads", num_threads);

if(verbose) {
std::cout << "Threads: " << num_threads << std::endl;
std::cout << "Iterations: " << num_iter << std::endl;
}

struct summary_t {
std::string file;
bool valid = false;
std::atomic<uint32_t> num_pass {0};
std::atomic<uint32_t> num_fail {0};
};

std::mutex mutex;
std::vector<std::shared_ptr<summary_t>> result;

for(const auto& file_name : file_names)
{
auto out = std::make_shared<summary_t>();
out->file = file_name;
try {
auto prover = std::make_shared<pos::Prover>(file_name);
prover->debug = true;
auto header = prover->get_header();
if(verbose) {
std::cout << "[" << file_name << "]" << std::endl;
std::cout << "Size: " << (header->has_meta ? "HDD" : "SSD") << " K" << header->ksize << " C" << prover->get_clevel()
<< " (" << header->plot_size / pow(1024, 3) << " GiB)" << std::endl;
std::cout << "Plot ID: " << prover->get_plot_id().to_string() << std::endl;
std::cout << "Contract: " << (header->contract ? header->contract->to_string() : std::string("N/A")) << std::endl;
}
out->valid = true;

for(int iter = 0; iter < num_iter && vnx::do_run(); ++iter)
{
const hash_t challenge(std::to_string(iter));
try {
const auto qualities = prover->get_qualities(challenge, plot_filter);

for(const auto& entry : qualities)
{
if(verbose) {
std::lock_guard<std::mutex> lock(mutex);
std::cout << "[" << iter << "] index = " << entry.index << ", quality = " << entry.quality.to_string() << std::endl;
}
std::vector<uint32_t> proof;
if(entry.proof.size()) {
proof = entry.proof;
} else {
proof = prover->get_full_proof(challenge, entry.index).proof;
}
try {
const auto quality = pos::verify(proof, challenge, header->plot_id, plot_filter, header->ksize);
if(quality != entry.quality) {
throw std::logic_error("invalid quality");
}
if(verbose) {
std::lock_guard<std::mutex> lock(mutex);
std::cout << "Proof " << entry.index << " passed: ";
for(const auto X : proof) {
std::cout << X << " ";
}
std::cout << std::endl;
}
out->num_pass++;
}
catch(const std::exception& ex) {
std::lock_guard<std::mutex> lock(mutex);
std::cerr << "Threw: " << ex.what() << std::endl;
out->num_fail++;
}
}
}
catch(const std::exception& ex) {
std::lock_guard<std::mutex> lock(mutex);
std::cerr << "Threw: " << ex.what() << std::endl;
out->num_fail++;
}
}
}
catch(const std::exception& ex) {
std::cerr << "Failed to open plot " << file_name << ": " << ex.what() << std::endl;
}
result.push_back(out);
}

for(auto entry : result)
{
std::cout << "[" << entry->file << "]" << std::endl;
const auto expected = uint64_t(num_iter) << plot_filter;
std::cout << "Pass: " << entry->num_pass << " / " << expected << std::endl;
std::cout << "Fail: " << entry->num_fail << " / " << expected << std::endl;
}
vnx::close();

mmx::secp256k1_free();
return 0;
}


0 comments on commit b291453

Please sign in to comment.