Skip to content

Commit

Permalink
Merge branch 'wfr-ph' of https://github.com/stotiks/chia-plotter into…
Browse files Browse the repository at this point in the history
… windows-fury-road
  • Loading branch information
stotiks committed Jul 4, 2021
2 parents a53cf8e + 9e7b4c3 commit 82f92a9
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 22 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Expand Up @@ -4,3 +4,6 @@
[submodule "lib/BLAKE3"]
path = lib/BLAKE3
url = https://github.com/BLAKE3-team/BLAKE3.git
[submodule "lib/libbech32"]
path = lib/libbech32
url = https://github.com/dcdpr/libbech32.git
6 changes: 4 additions & 2 deletions CMakeLists.txt
Expand Up @@ -46,6 +46,7 @@ endif()

add_subdirectory(lib/bls-signatures)

add_subdirectory(lib/libbech32)

set(BLAKE3_PATH lib/BLAKE3/c)
set(FSE_PATH lib/FSE/lib)
Expand All @@ -54,6 +55,7 @@ include_directories(
lib
include
lib/bls-signatures/src
lib/libbech32/include/libbech32
${BLAKE3_PATH}
${CMAKE_BINARY_DIR}/_deps/relic-src/include
${CMAKE_BINARY_DIR}/_deps/relic-build/include
Expand Down Expand Up @@ -110,9 +112,9 @@ add_library(chia_plotter STATIC
)

if (MSVC)
target_link_libraries(chia_plotter blake3 fse)
target_link_libraries(chia_plotter blake3 fse bech32)
else()
target_link_libraries(chia_plotter blake3 fse Threads::Threads)
target_link_libraries(chia_plotter blake3 fse bech32 Threads::Threads)
endif()

if(CHIA_PLOT_BUILD_TESTS)
Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -29,6 +29,7 @@ Usage:
-d, --finaldir arg Final directory (default = <tmpdir>)
-w, --waitforcopy Wait for copy to start next plot
-p, --poolkey arg Pool Public Key (48 bytes)
-c, --contract arg Pool Contract Address (64 chars)
-f, --farmerkey arg Farmer Public Key (48 bytes)
-G, --tmptoggle Alternate tmpdir/tmpdir2 (default = false)
--help Print help
Expand Down
1 change: 1 addition & 0 deletions lib/libbech32
Submodule libbech32 added at 954b14
122 changes: 102 additions & 20 deletions src/chia_plot.cpp
Expand Up @@ -15,6 +15,7 @@
#include <bls.hpp>
#include <sodium.h>
#include <cxxopts.hpp>
#include <libbech32.h>

#include <string>
#include <csignal>
Expand Down Expand Up @@ -54,17 +55,44 @@ static void interrupt_handler(int sig)
}
}

std::vector<uint8_t> bech32_address_decode(const std::string& addr)
{
const auto res = bech32::decode(addr);
if(res.encoding != bech32::Bech32m) {
throw std::logic_error("invalid contract address (!Bech32m): " + addr);
}
if(res.hrp != "xch" && res.hrp != "txch") {
throw std::logic_error("invalid contract address (" + res.hrp + " != xch): " + addr);
}
if(res.dp.size() != 52) {
throw std::logic_error("invalid contract address (size != 52): " + addr);
}
Bits bits;
for(int i = 0; i < 51; ++i) {
bits.AppendValue(res.dp[i], 5);
}
bits.AppendValue(res.dp[51] >> 4, 1);
if(bits.GetSize() != 32 * 8) {
throw std::logic_error("invalid contract address (bits != 256): " + addr);
}
std::vector<uint8_t> hash(32);
bits.ToBytes(hash.data());
return hash;
}

inline
phase4::output_t create_plot( const int num_threads,
const int log_num_buckets,
const int log_num_buckets_3,
const vector<uint8_t>& pool_key_bytes,
const vector<uint8_t>& puzzle_hash_bytes,
const vector<uint8_t>& farmer_key_bytes,
const std::string& tmp_dir,
const std::string& tmp_dir_2)
{
const auto total_begin = get_wall_time_micros();

const bool have_puzzle = !puzzle_hash_bytes.empty();

std::cout << "Process ID: " << GETPID() << std::endl;
std::cout << "Number of Threads: " << num_threads << std::endl;
std::cout << "Number of Buckets P1: 2^" << log_num_buckets
Expand All @@ -74,19 +102,25 @@ phase4::output_t create_plot( const int num_threads,

bls::G1Element pool_key;
bls::G1Element farmer_key;
try {
pool_key = bls::G1Element::FromByteVector(pool_key_bytes);
} catch(std::exception& ex) {
std::cout << "Invalid poolkey: " << bls::Util::HexStr(pool_key_bytes) << std::endl;
throw;
if(!have_puzzle) {
try {
pool_key = bls::G1Element::FromByteVector(pool_key_bytes);
} catch(std::exception& ex) {
std::cout << "Invalid poolkey: " << bls::Util::HexStr(pool_key_bytes) << std::endl;
throw;
}
}
try {
farmer_key = bls::G1Element::FromByteVector(farmer_key_bytes);
} catch(std::exception& ex) {
std::cout << "Invalid farmerkey: " << bls::Util::HexStr(farmer_key_bytes) << std::endl;
throw;
}
std::cout << "Pool Public Key: " << bls::Util::HexStr(pool_key.Serialize()) << std::endl;
if(have_puzzle) {
std::cout << "Pool Puzzle Hash: " << bls::Util::HexStr(puzzle_hash_bytes) << std::endl;
} else {
std::cout << "Pool Public Key: " << bls::Util::HexStr(pool_key.Serialize()) << std::endl;
}
std::cout << "Farmer Public Key: " << bls::Util::HexStr(farmer_key.Serialize()) << std::endl;

vector<uint8_t> seed(32);
Expand All @@ -100,11 +134,31 @@ phase4::output_t create_plot( const int num_threads,
local_sk = MPL.DeriveChildSk(local_sk, i);
}
const bls::G1Element local_key = local_sk.GetG1Element();
const bls::G1Element plot_key = local_key + farmer_key;

bls::G1Element plot_key;
if(have_puzzle) {
vector<uint8_t> bytes = (local_key + farmer_key).Serialize();
{
const auto more_bytes = local_key.Serialize();
bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end());
}
{
const auto more_bytes = farmer_key.Serialize();
bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end());
}
std::vector<uint8_t> hash(32);
bls::Util::Hash256(hash.data(), bytes.data(), bytes.size());

const auto taproot_sk = MPL.KeyGen(hash);
plot_key = local_key + farmer_key + taproot_sk.GetG1Element();
}
else {
plot_key = local_key + farmer_key;
}

phase1::input_t params;
{
vector<uint8_t> bytes = pool_key.Serialize();
vector<uint8_t> bytes = have_puzzle ? puzzle_hash_bytes : pool_key.Serialize();
{
const auto plot_bytes = plot_key.Serialize();
bytes.insert(bytes.end(), plot_bytes.begin(), plot_bytes.end());
Expand All @@ -118,8 +172,11 @@ phase4::output_t create_plot( const int num_threads,
std::cout << "Working Directory 2: " << (tmp_dir_2.empty() ? "$PWD" : tmp_dir_2) << std::endl;
std::cout << "Plot Name: " << plot_name << std::endl;

// memo = bytes(pool_public_key) + bytes(farmer_public_key) + bytes(local_master_sk)
params.memo.insert(params.memo.end(), pool_key_bytes.begin(), pool_key_bytes.end());
if(have_puzzle) {
params.memo.insert(params.memo.end(), puzzle_hash_bytes.begin(), puzzle_hash_bytes.end());
} else {
params.memo.insert(params.memo.end(), pool_key_bytes.begin(), pool_key_bytes.end());
}
params.memo.insert(params.memo.end(), farmer_key_bytes.begin(), farmer_key_bytes.end());
{
const auto bytes = master_sk.Serialize();
Expand Down Expand Up @@ -160,6 +217,7 @@ int _main(int argc, char** argv)

cxxopts::Options options("chia_plot",
"For <poolkey> and <farmerkey> see output of `chia keys show`.\n"
"To plot for pools, specify <contract> address instead of <poolkey>, see `chia plotnft show`.\n"
"<tmpdir> needs about 220 GiB space, it will handle about 25% of all writes. (Examples: './', '/mnt/tmp/')\n"
"<tmpdir2> needs about 110 GiB space and ideally is a RAM drive, it will handle about 75% of all writes.\n"
"Combined (tmpdir + tmpdir2) peak disk usage is less than 256 GiB.\n"
Expand All @@ -168,6 +226,7 @@ int _main(int argc, char** argv)
);

std::string pool_key_str;
std::string contract_addr_str;
std::string farmer_key_str;
std::string tmp_dir;
std::string tmp_dir2;
Expand All @@ -189,6 +248,7 @@ int _main(int argc, char** argv)
"d, finaldir", "Final directory (default = <tmpdir>)", cxxopts::value<std::string>(final_dir))(
"w, waitforcopy", "Wait for copy to start next plot", cxxopts::value<bool>(waitforcopy))(
"p, poolkey", "Pool Public Key (48 bytes)", cxxopts::value<std::string>(pool_key_str))(
"c, contract", "Pool Contract Address (64 chars)", cxxopts::value<std::string>(contract_addr_str))(
"f, farmerkey", "Farmer Public Key (48 bytes)", cxxopts::value<std::string>(farmer_key_str))(
"G, tmptoggle", "Alternate tmpdir/tmpdir2", cxxopts::value<bool>(tmptoggle))(
"help", "Print help");
Expand All @@ -203,12 +263,16 @@ int _main(int argc, char** argv)
std::cout << options.help({""}) << std::endl;
return 0;
}
if(pool_key_str.empty()) {
std::cout << "Pool Public Key (48 bytes) needs to be specified via -p <hex>, see `chia keys show`." << std::endl;
if(contract_addr_str.empty() && pool_key_str.empty()) {
std::cout << "Pool Public Key (for solo farming) or Pool Contract Address (for pool farming) needs to be specified via -p or -c, see `chia_plot --help`." << std::endl;
return -2;
}
if(!contract_addr_str.empty() && !pool_key_str.empty()) {
std::cout << "Choose either Pool Public Key (for solo farming) or Pool Contract Address (for pool farming), see `chia_plot --help`." << std::endl;
return -2;
}
if(farmer_key_str.empty()) {
std::cout << "Farmer Public Key (48 bytes) needs to be specified via -f <hex>, see `chia keys show`." << std::endl;
std::cout << "Farmer Public Key (48 bytes) needs to be specified via -f, see `chia keys show`." << std::endl;
return -2;
}
if(tmp_dir.empty()) {
Expand All @@ -224,15 +288,33 @@ int _main(int argc, char** argv)
if(num_buckets_3 <= 0) {
num_buckets_3 = num_buckets;
}
const auto pool_key = hex_to_bytes(pool_key_str);
std::vector<uint8_t> pool_key;
std::vector<uint8_t> puzzle_hash;
const auto farmer_key = hex_to_bytes(farmer_key_str);
const int log_num_buckets = num_buckets >= 16 ? int(log2(num_buckets)) : num_buckets;
const int log_num_buckets_3 = num_buckets_3 >= 16 ? int(log2(num_buckets_3)) : num_buckets_3;

if(pool_key.size() != bls::G1Element::SIZE) {
std::cout << "Invalid poolkey: " << bls::Util::HexStr(pool_key) << ", '" << pool_key_str
<< "' (needs to be " << bls::G1Element::SIZE << " bytes, see `chia keys show`)" << std::endl;
return -2;
if(contract_addr_str.empty()) {
pool_key = hex_to_bytes(pool_key_str);
if(pool_key.size() != bls::G1Element::SIZE) {
std::cout << "Invalid poolkey: " << bls::Util::HexStr(pool_key) << ", '" << pool_key_str
<< "' (needs to be " << bls::G1Element::SIZE << " bytes, see `chia keys show`)" << std::endl;
return -2;
}
}
else {
try {
puzzle_hash = bech32_address_decode(contract_addr_str);
if(puzzle_hash.size() != 32) {
throw std::logic_error("pool puzzle hash needs to be 32 bytes");
}
}
catch(std::exception& ex) {
std::cout << "Invalid contract (address): 0x"
<< bls::Util::HexStr(puzzle_hash) << ", '" << contract_addr_str
<< "' (" << ex.what() << ", see `chia plotnft show`)" << std::endl;
return -2;
}
}
if(farmer_key.size() != bls::G1Element::SIZE) {
std::cout << "Invalid farmerkey: " << bls::Util::HexStr(farmer_key) << ", '" << farmer_key_str
Expand Down Expand Up @@ -372,7 +454,7 @@ int _main(int argc, char** argv)
std::cout << "Crafting plot " << i+1 << " out of " << num_plots << std::endl;
const auto out = create_plot(
num_threads, log_num_buckets, log_num_buckets_3,
pool_key, farmer_key, tmp_dir, tmp_dir2);
pool_key, puzzle_hash, farmer_key, tmp_dir, tmp_dir2);

if(final_dir != tmp_dir)
{
Expand Down

0 comments on commit 82f92a9

Please sign in to comment.