Skip to content

Commit 08936c4

Browse files
committed
use decorators instead of macro, more compile-time checks
1 parent 2d0d5e6 commit 08936c4

File tree

6 files changed

+78
-79
lines changed

6 files changed

+78
-79
lines changed

sysvar/src/clock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ mod tests {
143143
#[test]
144144
fn test_clock_size_matches_bincode() {
145145
// Prove that Clock's in-memory layout matches its bincode serialization,
146-
// so we do not need to use define_sysvar_wire.
146+
// so we do not need to use sysvar_packed_struct.
147147
let clock = Clock::default();
148148
let in_memory_size = core::mem::size_of::<Clock>();
149149

sysvar/src/epoch_rewards.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -156,34 +156,47 @@
156156
157157
#[cfg(feature = "bincode")]
158158
use crate::SysvarSerialize;
159-
use crate::{get_sysvar_via_packed, sysvar_packed_struct, Sysvar};
159+
use crate::{get_sysvar_via_packed, Sysvar};
160160
pub use {
161161
solana_epoch_rewards::EpochRewards,
162162
solana_sdk_ids::sysvar::epoch_rewards::{check_id, id, ID},
163163
};
164164

165-
sysvar_packed_struct! {
166-
struct EpochRewardsPacked(81) {
167-
distribution_starting_block_height: u64,
168-
num_partitions: u64,
169-
parent_blockhash: [u8; 32],
170-
total_points: u128,
171-
total_rewards: u64,
172-
distributed_rewards: u64,
173-
active: u8, // bool as u8
174-
}
165+
#[repr(C, packed)]
166+
#[derive(Clone, Copy)]
167+
struct EpochRewardsPacked {
168+
distribution_starting_block_height: u64,
169+
num_partitions: u64,
170+
parent_blockhash: [u8; 32],
171+
total_points: u128,
172+
total_rewards: u64,
173+
distributed_rewards: u64,
174+
active: u8, // bool as u8
175175
}
176176

177+
const _: () = assert!(core::mem::size_of::<EpochRewardsPacked>() == 81);
178+
177179
impl From<EpochRewardsPacked> for EpochRewards {
178180
fn from(p: EpochRewardsPacked) -> Self {
181+
// Ensure field parity at compile time
182+
let EpochRewardsPacked {
183+
distribution_starting_block_height,
184+
num_partitions,
185+
parent_blockhash,
186+
total_points,
187+
total_rewards,
188+
distributed_rewards,
189+
active,
190+
} = p;
191+
179192
Self {
180-
distribution_starting_block_height: p.distribution_starting_block_height,
181-
num_partitions: p.num_partitions,
182-
parent_blockhash: solana_hash::Hash::new_from_array(p.parent_blockhash),
183-
total_points: p.total_points,
184-
total_rewards: p.total_rewards,
185-
distributed_rewards: p.distributed_rewards,
186-
active: p.active != 0,
193+
distribution_starting_block_height,
194+
num_partitions,
195+
parent_blockhash: solana_hash::Hash::new_from_array(parent_blockhash),
196+
total_points,
197+
total_rewards,
198+
distributed_rewards,
199+
active: active != 0,
187200
}
188201
}
189202
}

sysvar/src/epoch_schedule.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -121,30 +121,41 @@
121121
//! ```
122122
#[cfg(feature = "bincode")]
123123
use crate::SysvarSerialize;
124-
use crate::{get_sysvar_via_packed, sysvar_packed_struct, Sysvar};
124+
use crate::{get_sysvar_via_packed, Sysvar};
125125
pub use {
126126
solana_epoch_schedule::EpochSchedule,
127127
solana_sdk_ids::sysvar::epoch_schedule::{check_id, id, ID},
128128
};
129129

130-
sysvar_packed_struct! {
131-
struct EpochSchedulePacked(33) {
132-
slots_per_epoch: u64,
133-
leader_schedule_slot_offset: u64,
134-
warmup: u8, // bool as u8
135-
first_normal_epoch: u64,
136-
first_normal_slot: u64,
137-
}
130+
#[repr(C, packed)]
131+
#[derive(Clone, Copy)]
132+
struct EpochSchedulePacked {
133+
slots_per_epoch: u64,
134+
leader_schedule_slot_offset: u64,
135+
warmup: u8, // bool as u8
136+
first_normal_epoch: u64,
137+
first_normal_slot: u64,
138138
}
139139

140+
const _: () = assert!(core::mem::size_of::<EpochSchedulePacked>() == 33);
141+
140142
impl From<EpochSchedulePacked> for EpochSchedule {
141143
fn from(p: EpochSchedulePacked) -> Self {
144+
// Ensure field parity at compile time
145+
let EpochSchedulePacked {
146+
slots_per_epoch,
147+
leader_schedule_slot_offset,
148+
warmup,
149+
first_normal_epoch,
150+
first_normal_slot,
151+
} = p;
152+
142153
Self {
143-
slots_per_epoch: p.slots_per_epoch,
144-
leader_schedule_slot_offset: p.leader_schedule_slot_offset,
145-
warmup: p.warmup != 0,
146-
first_normal_epoch: p.first_normal_epoch,
147-
first_normal_slot: p.first_normal_slot,
154+
slots_per_epoch,
155+
leader_schedule_slot_offset,
156+
warmup: warmup != 0,
157+
first_normal_epoch,
158+
first_normal_slot,
148159
}
149160
}
150161
}

sysvar/src/last_restart_slot.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ mod tests {
5757

5858
#[test]
5959
fn test_last_restart_slot_size_matches_bincode() {
60-
// Prove that Clock's in-memory layout matches its bincode serialization,
61-
// so we do not need to use define_sysvar_wire.
60+
// Prove that LastRestartSlot's in-memory layout matches its bincode serialization,
61+
// so we do not need to use sysvar_packed_struct.
6262
let slot = LastRestartSlot::default();
6363
let in_memory_size = core::mem::size_of::<LastRestartSlot>();
6464

sysvar/src/lib.rs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -202,40 +202,6 @@ macro_rules! impl_sysvar_get {
202202
};
203203
}
204204

205-
/// Defines a `#[repr(C, packed)]` struct with compile-time size and alignment checking.
206-
///
207-
/// Used for sysvars whose canonical `#[repr(C)]` layout contains padding
208-
/// that doesn't match the runtime's compact serialization format.
209-
///
210-
/// # Example
211-
///
212-
/// ```ignore
213-
/// sysvar_packed_struct! {
214-
/// struct RentPacked(17) {
215-
/// lamports_per_byte_year: u64,
216-
/// exemption_threshold: [u8; 8],
217-
/// burn_percent: u8,
218-
/// }
219-
/// }
220-
/// ```
221-
#[macro_export]
222-
macro_rules! sysvar_packed_struct {
223-
(
224-
struct $name:ident($size:expr) {
225-
$( $field:ident : $fty:ty ),* $(,)?
226-
}
227-
) => {
228-
#[repr(C, packed)]
229-
#[derive(Clone, Copy)]
230-
struct $name {
231-
$( $field: $fty ),*
232-
}
233-
234-
const _: () = assert!(core::mem::size_of::<$name>() == $size);
235-
const _: () = assert!(core::mem::align_of::<$name>() == 1);
236-
};
237-
}
238-
239205
/// Generic helper to load a sysvar via a packed representation.
240206
///
241207
/// 1. Allocates uninitialized memory for the packed struct

sysvar/src/rent.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,26 +123,35 @@
123123
//! ```
124124
#[cfg(feature = "bincode")]
125125
use crate::SysvarSerialize;
126-
use crate::{get_sysvar_via_packed, sysvar_packed_struct, Sysvar};
126+
use crate::{get_sysvar_via_packed, Sysvar};
127127
pub use {
128128
solana_rent::Rent,
129129
solana_sdk_ids::sysvar::rent::{check_id, id, ID},
130130
};
131131

132-
sysvar_packed_struct! {
133-
struct RentPacked(17) {
134-
lamports_per_byte_year: u64,
135-
exemption_threshold: [u8; 8], // f64 as little-endian bytes
136-
burn_percent: u8,
137-
}
132+
#[repr(C, packed)]
133+
#[derive(Clone, Copy)]
134+
struct RentPacked {
135+
lamports_per_byte_year: u64,
136+
exemption_threshold: [u8; 8], // f64 as little-endian bytes
137+
burn_percent: u8,
138138
}
139139

140+
const _: () = assert!(core::mem::size_of::<RentPacked>() == 17);
141+
140142
impl From<RentPacked> for Rent {
141143
fn from(p: RentPacked) -> Self {
144+
// Ensure field parity at compile time
145+
let RentPacked {
146+
lamports_per_byte_year,
147+
exemption_threshold,
148+
burn_percent,
149+
} = p;
150+
142151
Self {
143-
lamports_per_byte_year: p.lamports_per_byte_year,
144-
exemption_threshold: f64::from_le_bytes(p.exemption_threshold),
145-
burn_percent: p.burn_percent,
152+
lamports_per_byte_year,
153+
exemption_threshold: f64::from_le_bytes(exemption_threshold),
154+
burn_percent,
146155
}
147156
}
148157
}

0 commit comments

Comments
 (0)