Este comentario está en la fuente de bitcoin 0.9.3 miner.cpp, justo encima de la ScanHash_CryptoPP
definición.
// // ScanHash escanea nonces buscando un hash con al menos algunos bits cero. // Opera en datos big endian. La persona que llama hace la inversión de bytes. // Todos los búferes de entrada están alineados en 16 bytes. nNonce generalmente se conserva // entre llamadas, pero periódicamente o si nNonce es 0xffff0000 o superior, // el bloque se reconstruye y nNonce vuelve a empezar desde cero. // sin firmar int estático ScanHash_CryptoPP...
Me doy cuenta de que algunos de los parámetros de este método se definen de la siguiente manera:
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);
Todas las matrices ya tienen una longitud que es divisible por 16, ¿cuál es la necesidad de los 16 caracteres adicionales?
¿Qué significa que los búferes de entrada están alineados en 16 bytes? ¿Es eso importante para calcular el hash?
Significa que los cuatro bits inferiores de la dirección inicial son siempre cero. Supongo que esto se hizo por razones de velocidad. Hay instrucciones que no funcionarán en direcciones alineadas que no sean de 16 bytes. Además, algunos cachés de CPU podrían preferirlo. No sé.
Sin embargo, no afecta la forma en que se realiza la minería.
Todas las matrices ya tienen una longitud que es divisible por 16, ¿cuál es la necesidad de los 16 caracteres adicionales?
No exactamente. Observe cómo obtiene esas direcciones. Declara una matriz, luego manipula el puntero a esa matriz. No existe una forma independiente de la plataforma para solicitar al sistema operativo una sección de memoria alineada. En su lugar, debe solicitar algo un poco más grande de lo que desea e incrementar el puntero hasta que se ubique en el límite que desea.
Nota al margen: Este es un error de uno por uno. Realmente, la matriz solo necesita ser 15 bytes más grande de lo normal. Probablemente no valga la pena arreglarlo.
¿Y por qué solo probar 0xffff nonces? ¿Es esto solo un límite artificial puesto para que el hashing no tarde una eternidad?
Intenta todos los valores nonce. Sin embargo, regresa de la función cada 65536 iteraciones, por lo que la función principal puede verificar
Básicamente, toda la lógica complicada se implementa en su llamador, BitcoinMiner
.
PD: Ese comentario está mal. Parece describir ScanHash, pero en realidad está hablando de esta sección de código dentro de 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;
Alguien probablemente debería mover el comentario.