Author

Topic: diff_to_bits (Read 360 times)

legendary
Activity: 2674
Merit: 2334
April 17, 2021, 11:41:39 AM
#9
Что бы что-то менять, нужно понимать как это всё работает, я считаю. Был бы кто-то, кто бы мне всё по полочкам разложил, когда я только начинал изучение этих алгоритмов.

Мне тоже раньше был непонятен этот момент, зачем в блоках Bitcoin нужно использовать именно 4-байтное число для записи таргетированной сложности, хотя для записи 256 нулевых битов можно было обойтись лишь 1 байтом. Да, это нужно для более точного и плавного задания 256-битного числа для поиска майнерами подходящего хеша.

Вот хорошая статья о Target и Difficulty на английском языке:
https://medium.com/@dongha.sohn/bitcoin-6-target-and-difficulty-ee3bc9cc5962

Следует отметить, что при повышении мантиссы на 1, диапазон чисел каждого деления основания увеличивается в 2 раза, то есть при очень высоком значении мантиссы будет сложнее задавать точное значение для таргетированной сложности майнинга.


Кстати говоря, мне кажется более человекочитаем формат сложности именно по степени необходимого хеша, но тогда тяжелее строить графики и отслеживать статистику. А математика сложности более интересна (на мой взгляд) и элегантна у monero (работа с переполнениями).

Не знаю, как устроена математика сложности майнинга у этой анонимной криптовалюты, но мне нравится подход, применённый в Bitcoin Cash, когда таргетированная сложность перезадаётся после каждого нового блока, а медианное время вычисляется из таймстампов за 144 последних блока (то есть за прошедшие сутки).
copper member
Activity: 36
Merit: 11
October 23, 2020, 05:32:41 PM
#8
Помогите пожалуйста.

Как преобразовать этот код  для лайткоинa?

Для биткоина это выглядит так:

static uint8_t diff_to_bits(double diff)
{
   uint64_t diff64;
   uint8_t i;

   diff /= 0.9999847412109375;
   diff *= (double)2147483648.0;
   if (diff > 0x8000000000000000ULL)
      diff = 0x8000000000000000ULL;
   /* Convert it to an integer */
   diff64 = diff;
   for (i = 0; diff64; i++, diff64 >>= 1);

   return i;
}

static double bits_to_diff(uint8_t bits)
{
   double ret = 1.0;

   if (likely(bits > 32))
      ret *= 1ull << (bits - 32);
   else if (unlikely(bits < 32))
      ret /= 1ull << (32 - bits);
       applog(LOG_INFO, "ret=\n",ret);

   return ret;
}

Спасибо!



Что бы что-то менять, нужно понимать как это всё работает, я считаю. Был бы кто-то, кто бы мне всё по полочкам разложил, когда я только начинал изучение этих алгоритмов.

В общем в биткоине кроме bits и difficulty имеет значение еще параметр target. Все эти параметры жестко завязаны между собой на математике. bits нужен для компактной записи больного числа, и данный формат так и называется compact. Target необходим для операции сравнения с хешем, т.е. для самого майнинга, а difficulty просто для человекочитаемости, как разница между максимальным target и текущим.

Начну издалека. В конфиге битка maxtarget указан как 0x1d00ffff, и этот параметр учитывается при расчете difficulty. Проще всего посчитать difficulty можно через связку bits -> target -> difficulty и сейчас объясню почему.

Bits и target это по сути одно и тоже число+-, просто в разных форматах. Для примера есть научный формат записи 3 * 10 ^ 15. Вот именно этот формат с мантиссой (3) и экспонентой (15) используется в ЯП для хранения чисел с плавающей точкой.

Для того, чтобы получить из bits - target, необходимо разделить наш bits на мантиссу и экспоненту. Первый байт bits - экспонента, остальное- мантисса. Для примера 0x1d00ffff - экспонента 0x1d, мантисса 0x00ffff. Далее произведя нехитрую операцию
0x00ffff* 2**(8*(0x1d - 3))  получаем значение 0xffff0000000000000000000000000000000000000000000000000000, которое и используется для сравнения с хешем при майнинге блока, необходимо чтобы хеш был меньше этого числа, общего для всех майнеров.

Кстати, если мы внезапно возьмем log2(0xffff0000000000000000000000000000000000000000000000000000) = 224, то мы получим степень, ниже которой должен быть искомый хеш при майнинге. С увеличением сложности эта степень уменьшается, тем самым включается теория вероятности и закон больших чисел.

Теперь, чтобы получить difficulty - осталось немного, просто посчитать разницу между нашим target и эталонным. Как я писал выше, эталонный target это 0xffff0000000000000000000000000000000000000000000000000000, т.е. в текущем примере разница будет 1.

Если брать другие хеши, например недавний блок 0000000000000000000b518f692832004576bd42162f464fa0151b11e72d8b53. У него bits = 0x170e134e, target = e134e0000000000000000000000000000000000000000, а степень = 180, соответственно difficulty = ffff0000000000000000000000000000000000000000000000000000/e134e0000000000000000000000000000000000000000 = 19997335994446

А для того, чтобы из target получить bits необходимо посчитать у target недостающие нули до формата uint256, посчитать их количество - это и будет экспонентой будущего bits (там есть несколько тонких моментов, но в общем и целом - так). Мантисса же, это первые 3 байта числа (без нулей). Для нашего примера - если добавить лидирующий байт к target = 0x00ffff0000000000000000000000000000000000000000000000000000 - мы получим 29 байт или 0x1d, мантисса же в этом случае будет 0x00ffff. Что и приводит нас обратно к bits 0x1d00ffff.

В вашем же случае вычисления сделаны более замудренными для максимальной эффективности майнинга и увеличения скорости, но суть сводится к тому же, пропуская момент с target. В случае же с litecoin (как и с любым форком биткоина, в основном) - вам достаточно найти параметр maxtarget в коде лайткоина и с помощью него высчитать тоже самое.


Кстати говоря, мне кажется более человекочитаем формат сложности именно по степени необходимого хеша, но тогда тяжелее строить графики и отслеживать статистику. А математика сложности более интересна (на мой взгляд) и элегантна у monero (работа с переполнениями).

 
copper member
Activity: 1554
Merit: 489
Stop the war!
September 25, 2020, 08:54:21 AM
#7
Но ведь в лайте сложность считается по другому. в цгмайнере ведь:

   d64 = truediffone;
   if (opt_scrypt)
      d64 *= (double)65536;
   d64 /= diff;

Если сделать так, будет работать?

static uint8_t diff_to_bits(double diff)
{
//   uint64_t diff64;
        uint64_t diff64 = 0x0000ffff00000000ULL;  //Для BTC:  0x00000000ffff00000000ULL
   uint8_t i;

   diff /= 0.9999847412109375;
   diff *= (double)2147483648.0;
   if (diff > 0x8000000000000000ULL)
      diff = 0x8000000000000000ULL;
   /* Convert it to an integer */
   diff64 = diff;
   for (i = 0; diff64; i++, diff64 >>= 1);

   return i;
}



Одинаково сложность считается.
Просто в лайте сложность искусственно занижается чтобы майнить легче было.

Вобщем диф это целое число. Чем число меньше тем майнить (находить блок для дифа) - сложнее. Чем диф больше - тем майнить легче. В битке как видишь максимальный диф ограничен числом 0x8000000000000000ULL. Это чтобы совсем уж халявные блоки майнерам не доставались ни при каких условиях.
Ну попробуй закомментарить это условие и домножить диф на 65536 или еще на что-нибудь побольше. Это будет означать только то, что ты разрешишь в своем майнере искать более простые блоки.
jr. member
Activity: 45
Merit: 1
September 25, 2020, 04:26:12 AM
#6
Но ведь в лайте сложность считается по другому. в цгмайнере ведь:

   d64 = truediffone;
   if (opt_scrypt)
      d64 *= (double)65536;
   d64 /= diff;

Если сделать так, будет работать?

static uint8_t diff_to_bits(double diff)
{
//   uint64_t diff64;
        uint64_t diff64 = 0x0000ffff00000000ULL;  //Для BTC:  0x00000000ffff00000000ULL
   uint8_t i;

   diff /= 0.9999847412109375;
   diff *= (double)2147483648.0;
   if (diff > 0x8000000000000000ULL)
      diff = 0x8000000000000000ULL;
   /* Convert it to an integer */
   diff64 = diff;
   for (i = 0; diff64; i++, diff64 >>= 1);

   return i;
}

copper member
Activity: 1554
Merit: 489
Stop the war!
September 25, 2020, 03:14:33 AM
#5
Не знаю, могу ли чем-то помочь. Есть только общие соображения: лайт от битка отличается только алгоритмом хэширования, а указанные функции к хэшированию не имеют никакого отношения. Это просто вспомогательные конвертеры диф в битс и обратно. Они должны быть одинаковые для битка и лайта.
В логах ругается на нонс, но это же просто рандомное число которое никак с дифом не связано. Инвалидный нонс, ну чисто по логике, это наверное когда несколько потоков получили одно и то же число нонс и значит будут делать одну и ту же работу. То есть ошибка в диспетчере потоков где-то.
С чего бы я начал, дак это с поиска в коде строки "invalid nonce". Где эта строка пишется в лог? От туда и танцевать надо. Добавить своих логов для каждй функции которая может вызвать этот лог.
jr. member
Activity: 45
Merit: 1
September 24, 2020, 05:50:10 PM
#4
Для лайта d64 *= (double)65536;

Никак не пойму, как пересчитать.

Помогите с кодом. Хотел послать Bам мессичж, но не получается.


[2020-09-24 14:46:06] Selecting pool 0 for work
 [2020-09-24 14:46:06] Generated stratum merkle e24c2e8aaf286268c10ab2ab2c665c8e608d4540a1f6ddd5c4b3a1b19db0edd8
 [2020-09-24 14:46:06] Generated stratum header 2000000082d707057d13915213d93665a76946b6f0d3015d535f440afb8a83eacc620f61e24c2e8aaf286268c10ab2ab2c665c8e608d4540a1f6ddd5c4b3a1b19db0edd85f6c86eb1a01b1980000 00000000008000000000000000000000000000000000000000000000000000000000
 [2020-09-24 14:46:06] Work job_id L9DEwtsDy nonce2 39 ntime 5f6c86eb
 [2020-09-24 14:46:06] Generated target 0000000000000000000000000000000000000000000000000080ff7f00000000
 [2020-09-24 14:46:06] Generated stratum work
 [2020-09-24 14:46:06] Pushing work from pool 0 to hash queue
 [2020-09-24 14:46:06] CTA0: CTARead (amt=128 err=-7 ern=110)
 [2020-09-24 14:46:06] USB: CTA0 read1 buffering 64 extra bytes
 [2020-09-24 14:46:06] CTA0: invalid nonce
jr. member
Activity: 45
Merit: 1
September 24, 2020, 05:21:33 PM
#3
Да, всё кроме этого,поменял, но неправильно считает нонс,98% reject Sad
copper member
Activity: 1554
Merit: 489
Stop the war!
September 24, 2020, 04:31:43 PM
#2
Что за манера копипастить сюда код с гитхаба? Дал бы сразу ссылку, там и форматирование лучше и контекст понятен
https://github.com/ckolivas/cgminer/blob/master/driver-cointerra.c#L26

С чего ты взял, что для лайта именно эту часть кода поменять надо? Или просто все остальное уже поменял, осталось только это?
jr. member
Activity: 45
Merit: 1
September 24, 2020, 03:35:36 PM
#1
Помогите пожалуйста.

Как преобразовать этот код  для лайткоинa?

Для биткоина это выглядит так:

static uint8_t diff_to_bits(double diff)
{
   uint64_t diff64;
   uint8_t i;

   diff /= 0.9999847412109375;
   diff *= (double)2147483648.0;
   if (diff > 0x8000000000000000ULL)
      diff = 0x8000000000000000ULL;
   /* Convert it to an integer */
   diff64 = diff;
   for (i = 0; diff64; i++, diff64 >>= 1);

   return i;
}

static double bits_to_diff(uint8_t bits)
{
   double ret = 1.0;

   if (likely(bits > 32))
      ret *= 1ull << (bits - 32);
   else if (unlikely(bits < 32))
      ret /= 1ull << (32 - bits);
       applog(LOG_INFO, "ret=\n",ret);

   return ret;
}

Спасибо!
Jump to: