Как клиент сатоши обрабатывает порядок следования байтов?

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

В CTransactionклассе есть этот блок:

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

Если я не ошибаюсь, часть сериализации IMPLEMENT_SERIALIZEрасширяется до:

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

Давайте nLockTimeпока сосредоточимся на том, что представляет собой файл unsigned int. SerReadWriteопределяется как:

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

Функция Serializeдля unsigned ints определяется как:

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

Что расширяется до:

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

Итак, это преобразует 4 байта unsigned intв a, char*а затем записывает его в поток.

Однако не будет ли это иметь другой результат на машинах с обратным порядком байтов по сравнению с машинами с прямым порядком байтов? Как к этому относится клиент? Или протокол определен в терминах прямого порядка байтов, и на машинах, на которых построен клиент сатоши, он просто работает?

Для хранения на диске это не имеет значения, потому что файлы на диске, вероятно, не предназначены для переноса. Вы уверены, что этот же код используется для отправки данных по сети? Игнорирование порядка следования байтов для сетевых данных было бы скорее ошибкой новичка.
@NateEldredge: да, для хранения диска это не имеет значения. nTypeявляется одним из SER_NETWORK, SER_DISKи SER_GETHASH, поэтому я думаю, что этот код также используется для этого. (это третий параметр для Serialize, а не безымянный, потому что он не используется). Это похоже на ошибку новичка, поэтому я и спрашиваю!
«клиент сатоши» Вы имеете в виду Bitcoin-Qt ?
@PeterMortensen: да!

Ответы (1)

Это правильно. Было несколько попыток, когда люди хотели это исправить, но, насколько я знаю, никому это не удалось. Причина? Ужасно сложно найти реальное оборудование, чтобы протестировать это, и еще труднее найти людей, которым это действительно небезразлично :)
@PieterWuille Возможно, для тестирования можно использовать виртуальную машину QEMU, поэтому проблема в том, что никому нет дела.
Все возможно. Дело в том, что так мало людей заботятся об этом или на самом деле затронуты этим (в наши дни почти нет нового оборудования с обратным порядком байтов), что не имеет особого смысла расставлять приоритеты в этом. Никто не будет спорить, что быть нейтральным к порядку байтов было бы плохо, но кто-то все равно должен это делать.
@abacabadabacaba Мне было интересно, почему существуют несоответствия в Endianess в транзакциях и протоколе майнинга. Я только начинаю осваивать концепцию Endianess (для меня нет смысла писать байты справа налево). Почему на Земле нет согласованности (если возможно, ELI5!)