Wie geht der Satoshi-Client mit Endianness um?

Ich sehe mir den Quellcode des Satoshi-Clients an, insbesondere wie Transaktionen serialisiert und über das Netzwerk gesendet oder auf der Festplatte gespeichert werden.

Die CTransactionKlasse hat diesen Block:

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

Wenn ich mich nicht irre, IMPLEMENT_SERIALIZEerweitert sich der Serialisierungsteil von zu:

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))
    }
}                                           

Konzentrieren wir uns nLockTimezunächst darauf, was eine unsigned int. SerReadWriteist definiert als:

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;
}

Die SerializeFunktion für unsigned ints ist definiert als:

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

Was sich erweitert zu:

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

Dies wandelt also die 4-Byte unsigned intin a um char*und schreibt sie dann in den Stream.

Wird dies jedoch auf Big-Endian- und Little-Endian-Maschinen nicht zu unterschiedlichen Ergebnissen führen? Wie geht der Kunde damit um? Oder ist das Protokoll in Little-Endian definiert, und auf den Maschinen, auf denen der Satoshi-Client aufgebaut ist, funktioniert es am Ende einfach?

Für die Zwecke des Speicherns auf der Festplatte sollte dies keine Rolle spielen, da die Festplattendateien wahrscheinlich nicht dazu gedacht sind, portabel zu sein. Sind Sie sicher, dass derselbe Code zum Senden von Daten im Netzwerk verwendet wird? Das Ignorieren der Endianness für Netzwerkdaten wäre eher ein Anfängerfehler.
@NateEldredge: Ja, zum Speichern von Datenträgern sollte es keine Rolle spielen. nTypeist einer von SER_NETWORK, SER_DISK, und SER_GETHASH, also denke ich, dass dieser Code auch dafür verwendet wird. (Es ist der 3. Parameter von Serialize, nicht er wird nicht benannt, weil er nicht verwendet wird). Es scheint ein Anfängerfehler zu sein, weshalb ich frage!
"satoshi client" Meinst du Bitcoin-Qt ?
@PeterMortensen: ja!

Antworten (1)

Das ist richtig. Es gab einige Versuche, dies zu beheben, aber soweit ich weiß, ist es niemandem gelungen. Grund? Es ist furchtbar schwer, echte Hardware zu finden, um dies zu testen, und noch schwieriger, Leute zu finden, die sich wirklich darum kümmern :)
@PieterWuille Möglicherweise kann eine QEMU-VM zum Testen verwendet werden. Das Problem ist also, dass sich niemand darum kümmert.
Alles ist möglich. Der Punkt ist, dass sich so wenige Leute darum kümmern oder tatsächlich davon betroffen sind (fast keine neue Hardware ist heutzutage Big-Endian), dass es nicht viel Sinn macht, dies zu priorisieren. Niemand wird argumentieren, dass Endian-Neutralität eine schlechte Sache wäre, aber jemand muss es trotzdem tun.
@abacabadabacaba Ich habe mich gefragt, warum es in Endianess Inkonsistenzen bei Transaktionen und Mining-Protokollen gibt. Ich verstehe gerade erst das Konzept von Endianess (für mich macht es keinen Sinn , Bytes von rechts nach links zu schreiben). Warum in aller Welt gibt es keine Konsistenz (ELI5, wenn möglich!)