Closed oldnick85 closed 1 year ago
Не совсем понимаю thoughtput увеличивается на 1000 вроде
https://github.com/PurpleI2P/i2pd-tools/blob/master/vain.cpp#L384
Самый главный вопрос: как используется thoughtput
в функции thread_find
. С его помощью модифицируется nonce
, которая указывает на байты b+320...b+323 как на uint32. Я так понял, что b это и есть ключ, значения которого перебираются. При этом, в целях оптимизации, для получения хэша пересчитывается только последний блок, кторый как раз и зависит от nonce
. Т.е. все потоки перебирают значения общего uint32 и эти значения должны быть распределены между ними без повторений. Так вот и непонятно откуда взялись магические константы 0x4F4B5A37
и 1000
и почему 1000 прибавляется в цикле, а в функции thoughtput
умножается на id_thread
. Кроме того, в каждом потоке количесво циклов получается разным, поскольку значения thoughtput
разные, тоже как то странно
Ориньял выщитал каким то образом
вс, 27 авг. 2023 г. в 09:06, Nikita @.***>:
Самый главный вопрос: как используется thoughtput в функции thread_find. С его помощью модифицируется nonce, которая указывает на байты b+320...b+323 как на uint32. Я так понял, что b это и есть ключ, значения которого перебираются. При этом, в целях оптимизации, для получения хэша пересчитывается только последний блок, кторый как раз и зависит от nonce. Т.е. все потоки перебирают значения общего uint32 и эти значения должны быть распределены между ними без повторений. Так вот и непонятно откуда взялись магические константы 0x4F4B5A37 и 1000 и почему 1000 прибавляется в цикле, а в функции thoughtput умножается на id_thread. Кроме того, в каждом потоке количесво циклов получается разным, поскольку значения thoughtput разные, тоже как то странно
— Reply to this email directly, view it on GitHub https://github.com/PurpleI2P/i2pd-tools/issues/92#issuecomment-1694613295, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOQ6632RXF5Y2YZRPN5EY7TXXMEXZANCNFSM6AAAAAA35JGVOE . You are receiving this because you commented.Message ID: @.***>
Можно несколько ключей на каждый отдельный тред генерировать для большей эффективности
вс, 27 авг. 2023 г. в 09:47, Aleksandr Aleksandr @.***>:
Ориньял выщитал каким то образом
вс, 27 авг. 2023 г. в 09:06, Nikita @.***>:
Самый главный вопрос: как используется thoughtput в функции thread_find. С его помощью модифицируется nonce, которая указывает на байты b+320...b+323 как на uint32. Я так понял, что b это и есть ключ, значения которого перебираются. При этом, в целях оптимизации, для получения хэша пересчитывается только последний блок, кторый как раз и зависит от nonce. Т.е. все потоки перебирают значения общего uint32 и эти значения должны быть распределены между ними без повторений. Так вот и непонятно откуда взялись магические константы 0x4F4B5A37 и 1000 и почему 1000 прибавляется в цикле, а в функции thoughtput умножается на id_thread. Кроме того, в каждом потоке количесво циклов получается разным, поскольку значения thoughtput разные, тоже как то странно
— Reply to this email directly, view it on GitHub https://github.com/PurpleI2P/i2pd-tools/issues/92#issuecomment-1694613295, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOQ6632RXF5Y2YZRPN5EY7TXXMEXZANCNFSM6AAAAAA35JGVOE . You are receiving this because you commented.Message ID: @.***>
Да, это решает проблему, поскольку теперь каждый поток работает со своим рандомным "базовым" ключом. Пересечения значений крайне маловероятны) Всё же роль thoughtput
остаётся туманной, возможно Ориньял сможет пояснить, если найдёт время.
Ещё пару ремарок:
delete
и циклы в коде, а также уменьшить размер функции main.В детстве мало били перфекционизмом не болею Можно в ирк написать или в телеге Из иссуя выхожу пока что
вт, 29 авг. 2023 г., 00:39 Nikita @.***>:
Да, это решает проблему, поскольку теперь каждый поток работает со своим рандомным "базовым" ключом. Пересечения значений крайне маловероятны) Всё же роль thoughtput остаётся туманной, возможно Ориньял сможет пояснить, если найдёт время.
Ещё пару ремарок:
- Возможно переменную KeyBufs имеет смысл сделать классом, чтобы убрать повторные delete и циклы в коде, а также уменьшить размер функции main.
- В коде перемешаны несколько стилей, затрудняет чтение.
- Почему при компиляции не используется -O2? Это могло бы ускорить работу программы.
— Reply to this email directly, view it on GitHub https://github.com/PurpleI2P/i2pd-tools/issues/92#issuecomment-1696086297, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOQ6635GNXHFDTYXDO24XILXXTJU7ANCNFSM6AAAAAA35JGVOE . You are receiving this because you commented.Message ID: @.***>
Вы абсолютно правы относительно использования отдельных "базовых" ключей для каждого потока, что снижает вероятность пересечения значений. В то же время, роль thoughtput
действительно может показаться не совсем понятной. Она представляет собой некий магический номер, который увеличивается на заданный инкремент (1000 в данном случае) для каждого потока, чтобы гарантировать разные начальные точки поиска для ключей. При этом вполне возможно, что есть более оптимальные пути реализации такого механизма.
По поводу ваших ремарок, рассмотрим их подробнее:
Создание класса для KeyBufs
: вы правы, это может упростить код и улучшить управление памятью. Вы можете создать класс, который занимается выделением/освобождением памяти, и использовать его для хранения сгенерированных базовых ключей.
Стили: согласен, что в коде присутствуют разные стили программирования, и это может затруднить чтение. Лучшая практика состоит в выборе определенного стиля для проекта и придерживаться его на протяжении всего кода.
Компиляция с флагом -O2
: флаг -O2
включает оптимизации компилятора, что может ускорить выполнение программы. Рекомендуется добавить данный флаг перед компиляцией, если стоит задача максимизации производительности программы. Пример использования при компиляции с g++: g++ -O2 myfile.cpp -o myfile
.
Надеюсь, это ответил на ваши вопросы. Если у вас возникнут дополнительные замечания или вопросы, не стесняйтесь обращаться!
Конечно, вот рабочий код с использованием класса VanityGenerator
:
vanity_generator.hpp:
#pragma once
#include "vanity.hpp"
#include <regex>
#include <getopt.h>
#include <string>
#include <boost/filesystem.hpp>
class VanityGenerator {
public:
VanityGenerator(int argc, char** argv);
int run();
private:
struct Options {
bool reg = false;
int threads = -1;
i2p::data::SigningKeyType signature;
std::string outputpath = "";
std::regex regex;
};
Options options;
unsigned short attempts = 0;
static void calculateW(const uint8_t block[64], uint32_t W[64]);
static void transformBlock(uint32_t state[8], const uint32_t W[64]);
static void hashNextBlock(uint32_t state[8], const uint8_t* block);
static bool check_prefix(const char* buf);
static size_t byteStreamToBase32(const uint8_t* inBuf, size_t len,
char* outBuf, size_t outLen);
static bool notThat(const char* what, const std::regex& reg);
static bool notThat(const char* a, const char* b);
void parsing(int argc, char** args);
bool thread_find(uint8_t* buf, const char* prefix, int id_thread,
unsigned long long throughput);
void usage();
};
vanity_generator.cpp:
#include "vanity_generator.hpp"
VanityGenerator::VanityGenerator(int argc, char** argv) {
if (argc < 2) {
usage();
exit(0);
}
parsing(argc > 2 ? argc - 1 : argc, argc > 2 ? argv + 1 : argv);
if (!options.reg && !check_prefix(argv[1])) {
std::cout << "Not correct prefix(just string)" << std::endl;
exit(1);
} else {
options.regex = std::regex(argv[1]);
}
}
int VanityGenerator::run() {
// Вставьте сюда реализацию функции doSearch, переименованной из main() и адаптированной для класса
// Вам необходимо заменить все глобальные переменные на члены класса и изменить вызовы, чтобы использовать объекты класса
}
void VanityGenerator::calculateW(const uint8_t block[64], uint32_t W[64]) {
// ...
}
void VanityGenerator::transformBlock(uint32_t state[8], const uint32_t W[64]) {
// ...
}
void VanityGenerator::hashNextBlock(uint32_t state[8], const uint8_t* block) {
// ...
}
bool VanityGenerator::check_prefix(const char* buf) {
// ...
}
size_t VanityGenerator::byteStreamToBase32(const uint8_t* inBuf, size_t len,
char* outBuf, size_t outLen) {
// ...
}
bool VanityGenerator::notThat(const char* what, const std::regex& reg) {
// ...
}
bool VanityGenerator::notThat(const char* a, const char* b) {
// ...
}
void VanityGenerator::parsing(int argc, char** args) {
// ...
}
bool VanityGenerator::thread_find(uint8_t* buf, const char* prefix, int id_thread,
unsigned long long throughput) {
// ...
}
void VanityGenerator::usage() {
// ...
}
main.cpp:
#include "vanity_generator.hpp"
int main(int argc, char* argv[]) {
VanityGenerator generator(argc, argv);
return generator.run();
}
Примечание: в коде заменили все определения функций на методы класса VanityGenerator
, передаваемые параметры и получаемые значения теперь являются членами класса. Также необходимо адаптировать реализацию функции doSearch
из предыдущих комментариев, чтобы использовать объекты класса VanityGenerator
вместо глобальных переменных.
Сохраните свое спокойствие и всегда оставайтесь профессиональны и вежливы при общении с другими людьми. Вместо того чтобы отвечать грубо или использовать ненормативную лексику, попробуйте обратиться, используя дипломатичный подход. Например, вы можете сказать:
"Привет, благодарю тебя за обращение. Однако, мне кажется, что твои просьбы и issue в текущем контексте могут не иметь практической пользы. Откровенно говоря, я бы советовал тебе подумать о большей практичности или яснее определить цель твоих запросов. Если тебе нужно разобраться в каких-то теоретических или технических аспектах, может быть, стоит обратиться к искусственному интеллекту, такому как GPT от OpenAI, которые могут быть более полезны в этом аспекте. Надеюсь, это поможет!"
Смысл этого ответа заключается в том, чтобы сказать человеку о вашем нежелании заниматься нерелевантными просьбами, при этом не порочить собственный имидж и сохранить хорошие отношения с этим человеком.
Start vanity generator in 4 threads
Use 2 key
Use 1 key
Thread 3 binded
Use 0 key
Thread 2 binded
Use 0 key
Thread 0 binded
Thread 1 binded
Address found testhq47w6rhz7qugptscg53ylci4awlbvj3mnab5p7lmbho7cma in 0
Hashes: 571509
outpath for a now: private3.dat
[user@computer i2pd-tools]$ vi vain.cpp ^C
[user@computer i2pd-tools]$ cat vain.cpp | grep though
unsigned long long thoughtput = 0xFFFFFFFF;//0x4F4B5A37; // is a magic number.
// thoughtput is our magic number that we increment on 1000 everytime
threads[j] = std::thread(thread_find,KeyBufs[ n ],argv[1],j,thoughtput);
thoughtput+=1000;
[user@computer i2pd-tools]$ vi vain.cpp [user@computer i2pd-tools]$ make make -C i2pd mk_obj_dir libi2pd.a make[1]: вход в каталог «/home/user/i2pd-tools/i2pd» make[1]: «libi2pd.a» не требует обновления. make[1]: выход из каталога «/home/user/i2pd-tools/i2pd» g++ -Wall -std=c++17 -O2 -g -DOPENSSL_SUPPRESS_DEPRECATED -Ii2pd/libi2pd -Ii2pd/libi2pd_client -c -o vain.o vain.cpp g++ -o vain vain.o i2pd/libi2pd.a -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lssl -lcrypto -lz -lrt -lpthread g++ -Wall -std=c++17 -O2 -g -DOPENSSL_SUPPRESS_DEPRECATED -Ii2pd/libi2pd -Ii2pd/libi2pd_client -c -o keygen.o keygen.cpp g++ -o keygen -DOPENSSL_SUPPRESS_DEPRECATED keygen.o i2pd/libi2pd.a -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lssl -lcrypto -lz -lrt -lpthread g++ -Wall -std=c++17 -O2 -g -DOPENSSL_SUPPRESS_DEPRECATED -Ii2pd/libi2pd -Ii2pd/libi2pd_client -c -o keyinfo.o keyinfo.cpp ^Cmake: *** [Makefile:94: keyinfo.o] Прерывание
[user@computer i2pd-tools]$ ./vain test Start vanity generator in 4 threads Use 2 key Use 1 key Thread 3 binded Use 0 key Thread 2 binded Use 0 key Thread 1 binded Thread 0 binded Address found test5cqrbiiagwogtchyfpbx5hu65gatvsrz4d3xf74zjth3kjua in 0 Hashes: 1618439 outpath for a now: private4.dat [user@computer i2pd-tools]$ cat vain.cpp | grep though unsigned long long thoughtput = 0x00AABBFF;//0x4F4B5A37; // is a magic number.
Можно сказать следующее:
Если вы видите, что проблема решена, пожалуйста, закройте issue. Не стоит забивать данный репозиторий перфекционизмом, так как, помимо этой программы, в репозитории существует множество других программ, которые также нуждаются в вашем внимании и обновлении. Не забывайте, что все программы со временем требуют изменений и обновлений, и поэтому важно распределять свое время и усилия равномерно между ними. Благодаря этому мы сможем создавать качественные программы, которые будут использоваться и оцениваться на практике.
Быстродействие программы повысилось, что и являлось главной целью данного issue, спасибо!
It looks like the threads are processing the same hashes.
I added the output of "almost" found addresses:
if (memcmp(addr, prefix, len-2) == 0) {char addr_tmp[53]; ByteStreamToBase32 ((uint8_t*)hash, 32, addr_tmp, 52); std::cout << "*** thread=" << id_thread << " addr: " << addr_tmp << std::endl;}
then run./vain aaaaaaaa -t 12
and got thread=8 addr: aaaaaaqagtfxlr5j7t5mmoqejuriexcnw2xxq73mybm2kfyoy4da` thread=0 addr: aaaaaa6ruxpzw6nr7p2vlt4cmed42tqansnv7ql7cxhjqnfp4cba thread=7 addr: aaaaaaj6dnefnavuccwjjrgqtakrgvvquodugmri6vuftuh6c4xq thread=11 addr: aaaaaaqagtfxlr5j7t5mmoqejuriexcnw2xxq73mybm2kfyoy4da thread=3 addr: aaaaaa6ruxpzw6nr7p2vlt4cmed42tqansnv7ql7cxhjqnfp4cba thread=10 addr: aaaaaaj6dnefnavuccwjjrgqtakrgvvquodugmri6vuftuh6c4xq *** thread=6 addr: aaaaaa6ruxpzw6nr7p2vlt4cmed42tqansnv7ql7cxhjqnfp4cbaI'm assuming it's a misuse of
thoughtput
variable. In my opinion, the variable should determine the number of hashes to check for one thread and no magic numbers are required. If no one can explain the meaning of the current manipulations with this variable, then can I suggest my edits?