Skip to content

Commit

Permalink
Serialize lamports per signature (#25364)
Browse files Browse the repository at this point in the history
* Serialize lamports per signature

* Add full snapshot archive test, enable features in previous tests
  • Loading branch information
AshwinSekar authored Jun 6, 2022
1 parent ec64d52 commit 8caced6
Show file tree
Hide file tree
Showing 6 changed files with 320 additions and 14 deletions.
4 changes: 2 additions & 2 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1282,10 +1282,10 @@ pub struct Bank {

/// Deprecated, do not use
/// Latest transaction fees for transactions processed by this bank
fee_calculator: FeeCalculator,
pub(crate) fee_calculator: FeeCalculator,

/// Track cluster signature throughput and adjust fee rate
fee_rate_governor: FeeRateGovernor,
pub(crate) fee_rate_governor: FeeRateGovernor,

/// Rent that has been collected
collected_rent: AtomicU64,
Expand Down
22 changes: 13 additions & 9 deletions runtime/src/genesis_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,18 +196,22 @@ pub fn create_genesis_config_with_leader(
pub fn activate_all_features(genesis_config: &mut GenesisConfig) {
// Activate all features at genesis in development mode
for feature_id in FeatureSet::default().inactive {
genesis_config.accounts.insert(
feature_id,
Account::from(feature::create_account(
&Feature {
activated_at: Some(0),
},
std::cmp::max(genesis_config.rent.minimum_balance(Feature::size_of()), 1),
)),
);
activate_feature(genesis_config, feature_id);
}
}

pub fn activate_feature(genesis_config: &mut GenesisConfig, feature_id: Pubkey) {
genesis_config.accounts.insert(
feature_id,
Account::from(feature::create_account(
&Feature {
activated_at: Some(0),
},
std::cmp::max(genesis_config.rent.minimum_balance(Feature::size_of()), 1),
)),
);
}

#[allow(clippy::too_many_arguments)]
pub fn create_genesis_config_with_leader_ex(
mint_lamports: u64,
Expand Down
72 changes: 72 additions & 0 deletions runtime/src/serde_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ trait TypeContext<'a>: PartialEq {
where
Self: std::marker::Sized;

#[cfg(test)]
fn serialize_bank_and_storage_without_extra_fields<S: serde::ser::Serializer>(
serializer: S,
serializable_bank: &SerializableBankAndStorageNoExtra<'a, Self>,
) -> std::result::Result<S::Ok, S::Error>
where
Self: std::marker::Sized;

fn serialize_accounts_db_fields<S: serde::ser::Serializer>(
serializer: S,
serializable_db: &SerializableAccountsDb<'a, Self>,
Expand Down Expand Up @@ -315,6 +323,37 @@ where
})
}

#[cfg(test)]
pub(crate) fn bank_to_stream_no_extra_fields<W>(
serde_style: SerdeStyle,
stream: &mut BufWriter<W>,
bank: &Bank,
snapshot_storages: &[SnapshotStorage],
) -> Result<(), Error>
where
W: Write,
{
macro_rules! INTO {
($style:ident) => {
bincode::serialize_into(
stream,
&SerializableBankAndStorageNoExtra::<$style::Context> {
bank,
snapshot_storages,
phantom: std::marker::PhantomData::default(),
},
)
};
}
match serde_style {
SerdeStyle::Newer => INTO!(newer),
}
.map_err(|err| {
warn!("bankrc_to_stream error: {:?}", err);
err
})
}

/// deserialize the bank from 'stream_reader'
/// modify the accounts_hash
/// reserialize the bank to 'stream_writer'
Expand Down Expand Up @@ -381,6 +420,39 @@ impl<'a, C: TypeContext<'a>> Serialize for SerializableBankAndStorage<'a, C> {
}
}

#[cfg(test)]
struct SerializableBankAndStorageNoExtra<'a, C> {
bank: &'a Bank,
snapshot_storages: &'a [SnapshotStorage],
phantom: std::marker::PhantomData<C>,
}

#[cfg(test)]
impl<'a, C: TypeContext<'a>> Serialize for SerializableBankAndStorageNoExtra<'a, C> {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
C::serialize_bank_and_storage_without_extra_fields(serializer, self)
}
}

#[cfg(test)]
impl<'a, C> From<SerializableBankAndStorageNoExtra<'a, C>> for SerializableBankAndStorage<'a, C> {
fn from(s: SerializableBankAndStorageNoExtra<'a, C>) -> SerializableBankAndStorage<'a, C> {
let SerializableBankAndStorageNoExtra {
bank,
snapshot_storages,
phantom,
} = s;
SerializableBankAndStorage {
bank,
snapshot_storages,
phantom,
}
}
}

struct SerializableAccountsDb<'a, C> {
accounts_db: &'a AccountsDb,
slot: Slot,
Expand Down
45 changes: 43 additions & 2 deletions runtime/src/serde_snapshot/newer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,33 @@ impl<'a> TypeContext<'a> for Context {
serializer: S,
serializable_bank: &SerializableBankAndStorage<'a, Self>,
) -> std::result::Result<S::Ok, S::Error>
where
Self: std::marker::Sized,
{
let ancestors = HashMap::from(&serializable_bank.bank.ancestors);
let fields = serializable_bank.bank.get_fields_to_serialize(&ancestors);
let lamports_per_signature = fields.fee_rate_governor.lamports_per_signature;
(
SerializableVersionedBank::from(fields),
SerializableAccountsDb::<'a, Self> {
accounts_db: &*serializable_bank.bank.rc.accounts.accounts_db,
slot: serializable_bank.bank.rc.slot,
account_storage_entries: serializable_bank.snapshot_storages,
phantom: std::marker::PhantomData::default(),
},
// Additional fields, we manually store the lamps per signature here so that
// we can grab it on restart.
// TODO: if we do a snapshot version bump, consider moving this out.
lamports_per_signature,
)
.serialize(serializer)
}

#[cfg(test)]
fn serialize_bank_and_storage_without_extra_fields<S: serde::ser::Serializer>(
serializer: S,
serializable_bank: &SerializableBankAndStorageNoExtra<'a, Self>,
) -> std::result::Result<S::Ok, S::Error>
where
Self: std::marker::Sized,
{
Expand Down Expand Up @@ -279,8 +306,18 @@ impl<'a> TypeContext<'a> for Context {
where
R: Read,
{
let bank_fields = deserialize_from::<_, DeserializableVersionedBank>(&mut stream)?.into();
let mut bank_fields: BankFieldsToDeserialize =
deserialize_from::<_, DeserializableVersionedBank>(&mut stream)?.into();
let accounts_db_fields = Self::deserialize_accounts_db_fields(stream)?;
// Process extra fields
let lamports_per_signature: u64 = match deserialize_from(stream) {
Err(err) if err.to_string() == "io error: unexpected end of file" => Ok(0),
Err(err) if err.to_string() == "io error: failed to fill whole buffer" => Ok(0),
result => result,
}?;
bank_fields.fee_rate_governor = bank_fields
.fee_rate_governor
.clone_with_lamports_per_signature(lamports_per_signature);
Ok((bank_fields, accounts_db_fields))
}

Expand Down Expand Up @@ -311,6 +348,7 @@ impl<'a> TypeContext<'a> for Context {
let rhs = bank_fields;
let blockhash_queue = RwLock::new(rhs.blockhash_queue.clone());
let hard_forks = RwLock::new(rhs.hard_forks.clone());
let lamports_per_signature = rhs.fee_rate_governor.lamports_per_signature;
let bank = SerializableVersionedBank {
blockhash_queue: &blockhash_queue,
ancestors: &rhs.ancestors,
Expand Down Expand Up @@ -346,6 +384,9 @@ impl<'a> TypeContext<'a> for Context {
is_delta: rhs.is_delta,
};

bincode::serialize_into(stream_writer, &(bank, accounts_db_fields))
bincode::serialize_into(
stream_writer,
&(bank, accounts_db_fields, lamports_per_signature),
)
}
}
Loading

0 comments on commit 8caced6

Please sign in to comment.