TBlockHeader record size can vary in size.

Started by Skybuck, April 04, 2023, 08:43:08 PM

Previous topic - Next topic

Skybuck

unit UFileStorage contains the following record:

Type
   TBlockHeader = Record
      BlockNumber : Cardinal;
      StreamBlockRelStartPos : Int64;
      BlockSize : Cardinal;
   end; // 16 bytes

The '16 bytes' comment is misleading.

The size of this record depends on the compiler setting: "record field alignment" which is "quad word" for target platform win64.

A quad word contains 64 bits. Each field in the above record is aligned on a 64 bit boundary (8 bytes),  leading to 3 x 8 bytes = 24 bytes.

The current PascalCoin software loads the fields individually and is thus not affected by this change in record size.

Example from UFileStorage.pas:

If Stream.ReadData( BlockHeader.BlockNumber, 'BlockHeader.BlockNumber' ) < sizeof(BlockHeader.BlockNumber) then exit;
If Stream.ReadData( BlockHeader.StreamBlockRelStartPos, 'BlockHeader.StreamBlockRelStartPos' ) < sizeof(BlockHeader.StreamBlockRelStartPos) then exit;
If Stream.ReadData( BlockHeader.BlockSize, 'BlockHeader.BlockSize' ) < sizeof(BlockHeader.BlockSize) then exit;

To read the block header correctly all at once, the packed directive can be added as follows:

Type
   TBlockHeader = packed record
      BlockNumber : Cardinal;
      StreamBlockRelStartPos : Int64;
      BlockSize : Cardinal;
   end; // 16 bytes

Now the record is truely 16 bytes in size.