Объясните этот комментарий к nNonce из источника bitcoin miner.cpp?

Этот комментарий находится в источнике биткойнов 0.9.3 miner.cpp, прямо над ScanHash_CryptoPPопределением.

//
// ScanHash сканирует nonce в поисках хэша хотя бы с несколькими нулевыми битами.
// Работает с данными с обратным порядком байтов. Вызывающий выполняет реверсирование байтов.
// Все входные буферы выровнены по 16 байтам. nNonce обычно сохраняется
// между вызовами, но периодически или если nNonce равен 0xffff0000 или выше,
// блок перестраивается и nNonce начинается с нуля.
//
беззнаковое целое статическое ScanHash_CryptoPP...
  1. Что означает, что входные буферы выровнены по 16 байтам? Это важно для вычисления хеша?

Я заметил, что некоторые параметры этого метода определены следующим образом:

char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf);
char pdatabuf[128+16];    char* pdata     = alignup<16>(pdatabuf);
char phash1buf[64+16];    char* phash1    = alignup<16>(phash1buf);

Все массивы уже имеют длину, кратную 16, зачем нужны дополнительные 16 символов?

  1. И зачем пробовать только одноразовые номера 0xffff? Это просто искусственное ограничение, чтобы хеширование не длилось вечно?

Ответы (1)

  1. Что означает, что входные буферы выровнены по 16 байтам? Это важно для вычисления хеша?

    Это означает, что младшие четыре бита начального адреса всегда равны нулю. Я предполагаю, что это было сделано из соображений скорости. Существуют инструкции, которые не будут работать с адресами, не выровненными по 16 байтам. Кроме того, некоторые кеши ЦП могут предпочесть это. Я не знаю.

    Однако это не влияет на то, как выполняется майнинг.

  2. Все массивы уже имеют длину, кратную 16, зачем нужны дополнительные 16 символов?

    Не совсем. Обратите внимание, как он получает эти адреса. Он объявляет массив, а затем манипулирует указателем на этот массив. Не существует независимого от платформы способа запросить у ОС выровненный раздел памяти. Вместо этого вы должны запросить что-то немного большее, чем то, что вы хотите, и увеличивать указатель, пока он не остановится на нужной границе.

    Боковое примечание: это ошибка один за другим. На самом деле массив должен быть всего на 15 байт больше, чем обычно. Наверное, не стоит исправлять.

  3. И зачем пробовать только одноразовые номера 0xffff? Это просто искусственное ограничение, чтобы хеширование не длилось вечно?

    Он пытается использовать все значения nonce. Однако он возвращается из функции каждые 65536 итераций, поэтому родительская функция может проверить

    • что он все еще занимается добычей на вершине цепочки,
    • что он все еще подключен к сети,
    • что транзакции не устарели, и
    • что одноразовый номер не собирается обертываться.

    По сути, вся сложная логика реализована в вызывающем объекте BitcoinMiner.

    PS: этот комментарий неверен. Кажется, что он описывает ScanHash, но на самом деле он говорит об этом разделе кода внутри BitcoinMiner:

        // Check for stop or if block needs to be rebuilt
        boost::this_thread::interruption_point();
        if (vNodes.empty() && Params().NetworkID() != CChainParams::REGTEST)
            break;
        if (nBlockNonce >= 0xffff0000)
            break;
        if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
            break;
        if (pindexPrev != chainActive.Tip())
            break;
    

    Кто-то, вероятно, должен переместить комментарий.