diff --git a/Cargo.lock b/Cargo.lock index f252db71e025b5..3055831aaf7cf4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7662,6 +7662,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "serde_with", "solana-accounts-db", "solana-address-lookup-table-program", "solana-bpf-loader-program", @@ -7675,6 +7676,7 @@ dependencies = [ "solana-frozen-abi", "solana-frozen-abi-macro", "solana-inline-spl", + "solana-lattice-hash", "solana-loader-v4-program", "solana-logger", "solana-measure", diff --git a/accounts-db/src/accounts_hash.rs b/accounts-db/src/accounts_hash.rs index 4dddbded4d219e..3e70f3d1fa0edb 100644 --- a/accounts-db/src/accounts_hash.rs +++ b/accounts-db/src/accounts_hash.rs @@ -1265,6 +1265,10 @@ pub struct AccountLtHash(pub LtHash); pub const ZERO_LAMPORT_ACCOUNT_LT_HASH: AccountLtHash = AccountLtHash(LtHash([0; LtHash::NUM_ELEMENTS])); +/// Lattice hash of all accounts +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct AccountsLtHash(pub LtHash); + /// Hash of accounts #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum AccountsHashKind { diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index c78af59223b460..626f2624711289 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -5998,6 +5998,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "serde_with", "solana-accounts-db", "solana-address-lookup-table-program", "solana-bpf-loader-program", @@ -6009,6 +6010,7 @@ dependencies = [ "solana-feature-set", "solana-fee", "solana-inline-spl", + "solana-lattice-hash", "solana-loader-v4-program", "solana-measure", "solana-metrics", diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 849d583b01aa3c..014995d592b612 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -46,6 +46,7 @@ regex = { workspace = true } serde = { workspace = true, features = ["rc"] } serde_derive = { workspace = true } serde_json = { workspace = true } +serde_with = { workspace = true } solana-accounts-db = { workspace = true } solana-address-lookup-table-program = { workspace = true } solana-bpf-loader-program = { workspace = true } @@ -63,6 +64,7 @@ solana-frozen-abi-macro = { workspace = true, optional = true, features = [ "frozen-abi", ] } solana-inline-spl = { workspace = true } +solana-lattice-hash = { workspace = true } solana-loader-v4-program = { workspace = true } solana-measure = { workspace = true } solana-metrics = { workspace = true } diff --git a/runtime/src/serde_snapshot.rs b/runtime/src/serde_snapshot.rs index 7dd6e7bf7f21e8..1494413bcfb02e 100644 --- a/runtime/src/serde_snapshot.rs +++ b/runtime/src/serde_snapshot.rs @@ -57,10 +57,12 @@ use { thread::Builder, }, storage::SerializableStorage, + types::SerdeAccountsLtHash, }; mod storage; mod tests; +mod types; mod utils; pub(crate) use { @@ -400,6 +402,9 @@ struct ExtraFieldsToDeserialize { epoch_accounts_hash: Option, #[serde(deserialize_with = "default_on_eof")] versioned_epoch_stakes: HashMap, + #[serde(deserialize_with = "default_on_eof")] + #[allow(dead_code)] + accounts_lt_hash: Option, } /// Extra fields that are serialized at the end of snapshots. @@ -441,6 +446,7 @@ where incremental_snapshot_persistence, epoch_accounts_hash, versioned_epoch_stakes, + accounts_lt_hash: _, } = extra_fields; bank_fields.fee_rate_governor = bank_fields diff --git a/runtime/src/serde_snapshot/types.rs b/runtime/src/serde_snapshot/types.rs new file mode 100644 index 00000000000000..6dd9ef099cabaf --- /dev/null +++ b/runtime/src/serde_snapshot/types.rs @@ -0,0 +1,22 @@ +use {solana_accounts_db::accounts_hash::AccountsLtHash, solana_lattice_hash::lt_hash::LtHash}; + +/// Snapshot serde-safe AccountsLtHash +#[cfg_attr(feature = "frozen-abi", derive(AbiExample))] +#[serde_with::serde_as] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +pub struct SerdeAccountsLtHash( + // serde only has array support up to 32 elements; anything larger needs to be handled manually + // see https://github.com/serde-rs/serde/issues/1937 for more information + #[serde_as(as = "[_; LtHash::NUM_ELEMENTS]")] pub [u16; LtHash::NUM_ELEMENTS], +); + +impl From for AccountsLtHash { + fn from(accounts_lt_hash: SerdeAccountsLtHash) -> Self { + Self(LtHash(accounts_lt_hash.0)) + } +} +impl From for SerdeAccountsLtHash { + fn from(accounts_lt_hash: AccountsLtHash) -> Self { + Self(accounts_lt_hash.0 .0) + } +}