Add #[repr(C)] for more future-proof byte mangling (#33085)
* Add #[repr(C)] for more future-proof byte manglng * Improve comments after code-review
This commit is contained in:
parent
025651e0d4
commit
92a0b310c1
|
@ -12561,13 +12561,16 @@ pub mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hash_stored_account() {
|
fn test_hash_stored_account() {
|
||||||
// This test uses some UNSAFE tricks to detect most of account's field
|
// This test uses some UNSAFE tricks to detect most of hashing code changes, resulting from
|
||||||
// addition and deletion without changing the hash code
|
// account's field additions and deletions of StoredAccountMeta and AccountSharedData and
|
||||||
|
// hashing-order changes.
|
||||||
|
|
||||||
const ACCOUNT_DATA_LEN: usize = 3;
|
const ACCOUNT_DATA_LEN: usize = 3;
|
||||||
// the type of InputTuple elements must not contain references;
|
// the type of InputFields elements must not contain references;
|
||||||
// they should be simple scalars or data blobs
|
// they should be simple scalars or data blobs
|
||||||
type InputTuple = (
|
// repr(C) is needed for abi-stability in the dirtiest variant of std::mem::transmute().
|
||||||
|
#[repr(C)]
|
||||||
|
struct InputFields(
|
||||||
Slot,
|
Slot,
|
||||||
StoredMeta,
|
StoredMeta,
|
||||||
AccountMeta,
|
AccountMeta,
|
||||||
|
@ -12575,19 +12578,23 @@ pub mod tests {
|
||||||
usize, // for StoredAccountMeta::offset
|
usize, // for StoredAccountMeta::offset
|
||||||
Hash,
|
Hash,
|
||||||
);
|
);
|
||||||
const INPUT_LEN: usize = std::mem::size_of::<InputTuple>();
|
const INPUT_LEN: usize = std::mem::size_of::<InputFields>();
|
||||||
type InputBlob = [u8; INPUT_LEN];
|
type InputBlob = [u8; INPUT_LEN];
|
||||||
let mut blob: InputBlob = [0u8; INPUT_LEN];
|
let mut blob: InputBlob = [0u8; INPUT_LEN];
|
||||||
|
|
||||||
// spray memory with decreasing counts so that, data layout can be detected.
|
// spray memory with decreasing integers so that, data layout change and/or hashing
|
||||||
|
// reordering can be detected. note that just zeroed blob can't detect field reordering.
|
||||||
for (i, byte) in blob.iter_mut().enumerate() {
|
for (i, byte) in blob.iter_mut().enumerate() {
|
||||||
*byte = (INPUT_LEN - i) as u8;
|
*byte = (INPUT_LEN - i) as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
//UNSAFE: forcibly cast the special byte pattern to actual account fields.
|
//UNSAFE: forcibly cast the special byte pattern to actual account fields.
|
||||||
let (slot, meta, account_meta, data, offset, hash): InputTuple =
|
let InputFields(slot, meta, account_meta, data, offset, hash) =
|
||||||
unsafe { std::mem::transmute::<InputBlob, InputTuple>(blob) };
|
unsafe { std::mem::transmute::<InputBlob, InputFields>(blob) };
|
||||||
|
|
||||||
|
// When adding a field to the following constructor, make sure this is sourced from
|
||||||
|
// InputFields as well after adding new corresponding one to it. Needless to say, but note
|
||||||
|
// that the hashing code itself must be adjusted
|
||||||
let stored_account = StoredAccountMeta::AppendVec(AppendVecStoredAccountMeta {
|
let stored_account = StoredAccountMeta::AppendVec(AppendVecStoredAccountMeta {
|
||||||
meta: &meta,
|
meta: &meta,
|
||||||
account_meta: &account_meta,
|
account_meta: &account_meta,
|
||||||
|
@ -12599,9 +12606,9 @@ pub mod tests {
|
||||||
let account = stored_account.to_account_shared_data();
|
let account = stored_account.to_account_shared_data();
|
||||||
|
|
||||||
let expected_account_hash = if cfg!(debug_assertions) {
|
let expected_account_hash = if cfg!(debug_assertions) {
|
||||||
Hash::from_str("6qtBXmRrLdTdAV5bK6bZZJxQA4fPSUBxzQGq2BQSat25").unwrap()
|
Hash::from_str("8GiQSN2VvWASKPUuZgFkH4v66ihEanrDVXAkMFvLwEa8").unwrap()
|
||||||
} else {
|
} else {
|
||||||
Hash::from_str("5HL9MtsQmxZQ8XSgcAhSkqnrayQFXUY8FT1JsHjDNKbi").unwrap()
|
Hash::from_str("9MYASra3mm8oXzMapYUonB6TcRsKFPtjhNXVgY3MPPUX").unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
Loading…
Reference in New Issue