¿Cómo maneja el cliente satoshi el endianismo?

Estoy revisando el código fuente del cliente satoshi, particularmente cómo se serializan y envían las transacciones a través de la red o se almacenan en el disco.

La CTransactionclase tiene este bloque:

IMPLEMENT_SERIALIZE
(
    READWRITE(this->nVersion);
    nVersion = this->nVersion;
    READWRITE(vin);
    READWRITE(vout);
    READWRITE(nLockTime);
)

Si no me equivoco, la parte serializada de IMPLEMENT_SERIALIZEse expande a:

template<typename Stream>                   
void Serialize(Stream& s, int nType, int nVersion) const  
{                                           
    CSerActionSerialize ser_action;         
    const bool fGetSize = false;            
    const bool fWrite = true;               
    const bool fRead = false;               
    unsigned int nSerSize = 0;              
    assert(fGetSize||fWrite||fRead); /* suppress warning */
    {
        (nSerSize += ::SerReadWrite(s, (this->nVersion), nType, nVersion, ser_action))
        nVersion = this->nVersion;
        (nSerSize += ::SerReadWrite(s, (vin), nType, nVersion, ser_action))
        (nSerSize += ::SerReadWrite(s, (vout), nType, nVersion, ser_action))
        (nSerSize += ::SerReadWrite(s, (nLockTime), nType, nVersion, ser_action))
    }
}                                           

Centrémonos nLockTimepor ahora, que es un unsigned int. SerReadWriteSe define como:

template<typename Stream, typename T>
inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
{
    ::Serialize(s, obj, nType, nVersion);
    return 0;
}

La Serializefunción, para unsigned ints se define como:

template<typename Stream> 
inline void Serialize(Stream& s, unsigned int a, int, int=0) { 
    WRITEDATA(s, a); 
}

Que se expande a:

template<typename Stream> 
inline void Serialize(Stream& s, unsigned int a, int, int=0) { 
    s.write((char*)&(a), sizeof(a))
}

Entonces, esto convierte los 4 bytes unsigned inten a char*y luego los escribe en la secuencia.

Sin embargo, ¿no tendrá esto un resultado diferente en las máquinas big-endian frente a las máquinas little-endian? ¿Cómo maneja esto el cliente? ¿O el protocolo está definido en términos de little-endian, y en las máquinas en las que se basa el cliente satoshi, termina funcionando?

Para fines de almacenamiento en disco, no debería importar porque los archivos de disco probablemente no estén destinados a ser portátiles. ¿Estás seguro de que este mismo código se usa para enviar datos en la red? Ignorar la endianidad de los datos de red sería un error de novato.
@NateEldredge: sí, para almacenar discos, no debería importar. nTypees uno de SER_NETWORK, SER_DISKy SER_GETHASH, así que creo que este código también se usa para eso. (es el tercer parámetro de Serialize, no se nombra porque no se usa). Parece un error de novato, ¡por eso pregunto!
"cliente satoshi" ¿Te refieres a Bitcoin-Qt ?
@PeterMortensen: ¡sí!

Respuestas (1)

Esto es correcto. Ha habido algunos intentos en los que la gente quería arreglar esto, pero que yo sepa, nadie tuvo éxito. ¿Razón? Es terriblemente difícil encontrar hardware real para probar esto, y aún más difícil encontrar personas a las que realmente les importe :)
@PieterWuille Es posible usar una máquina virtual QEMU para realizar pruebas, por lo que el problema es que a nadie le importa.
Todo es posible. El punto es que tan pocas personas se preocupan o se ven realmente afectadas por esto (casi ningún hardware nuevo es big-endian en estos días), que no tiene mucho sentido priorizar esto. Nadie argumentará que ser endian-neutral sería algo malo, pero alguien aún tiene que hacerlo.
@abacabadabacaba Me he estado preguntando por qué hay inconsistencias en Endianess en las transacciones y el protocolo de minería. Apenas estoy aprendiendo el concepto de Endianess (para mí no tiene sentido escribir bytes de derecha a izquierda). ¿Por qué diablos no hay consistencia (ELI5 si es posible!)