Skip to content

Commit 1ce6943

Browse files
authored
Change account layout (#451)
Modify account layout in accounts database: 1. reuse slack space which is available in block allocation if possible, this avoids reallocation of accounts if the data field grows insignificantly. 2. track account owner change to avoid index checks in happy path depends on #419 closes #443 closes #441 <!-- greptile_comment --> ## Greptile Summary Major refactoring of AccountsDB storage and indexing system to optimize account data storage and improve performance through block space reuse and owner tracking. - Consolidated multiple LMDB environments into a single environment and introduced new `Table` abstraction in `magicblock-accounts-db/src/index/table.rs` for better database operation encapsulation - Modified account serialization in `magicblock-accounts-db/src/lib.rs` to reuse slack space in block allocations, reducing unnecessary reallocations for small data growth - Added owner change tracking to optimize index checks by skipping them in the happy path when owner hasn't changed - Improved LMDB iteration safety and efficiency in `magicblock-accounts-db/src/index/iterator.rs` by removing manual cursor management - Changed program account iteration behavior to return empty iterators instead of NotFound errors for better API consistency <!-- /greptile_comment -->
1 parent b2882c3 commit 1ce6943

File tree

6 files changed

+20
-15
lines changed

6 files changed

+20
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ serde = "1.0.217"
142142
serde_derive = "1.0"
143143
serde_json = "1.0"
144144
sha3 = "0.10.8"
145-
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "7bdfefc" }
145+
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "5b50fad" }
146146
solana-accounts-db = { version = "2.2" }
147147
solana-account-decoder = { version = "2.2" }
148148
solana-address-lookup-table-program = { version = "2.2" }
@@ -203,6 +203,6 @@ vergen = "8.3.1"
203203
# some solana dependencies have solana-storage-proto as dependency
204204
# we need to patch them with our version, because they use protobuf-src v1.1.0
205205
# and we use protobuf-src v2.1.1. Otherwise compilation fails
206-
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "7bdfefc" }
206+
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "5b50fad" }
207207
solana-storage-proto = { path = "./storage-proto" }
208208
solana-svm = { git = "https://github.com/magicblock-labs/magicblock-svm.git" }

magicblock-accounts-db/src/lib.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ impl AccountsDb {
106106
// For borrowed variants everything is already written and we just increment the
107107
// atomic counter. New readers will see the latest update.
108108
acc.commit();
109+
// check whether the account's owner has changed
110+
if !acc.owner_changed {
111+
return;
112+
}
109113
// and perform some index bookkeeping to ensure correct owner
110114
let _ = self
111115
.index
@@ -116,11 +120,11 @@ impl AccountsDb {
116120
));
117121
}
118122
AccountSharedData::Owned(acc) => {
119-
let datalen = account.data().len();
120-
// we multiply by 2 for shadow buffer and add extra space for metadata
121-
let size = AccountSharedData::serialized_size_aligned(datalen)
122-
* 2
123-
+ AccountSharedData::SERIALIZED_META_SIZE;
123+
let datalen = account.data().len() as u32;
124+
let block_size = self.storage.block_size() as u32;
125+
let size = AccountSharedData::serialized_size_aligned(
126+
datalen, block_size,
127+
) as usize;
124128

125129
let blocks = self.storage.get_block_count(size);
126130
// TODO(bmuddha) perf optimization: use reallocs sparringly
@@ -143,13 +147,14 @@ impl AccountsDb {
143147
};
144148

145149
// SAFETY:
146-
// Allocation object is obtained by obtaining valid offset from storage, which
150+
// Allocation object is constructed by obtaining a valid offset from storage, which
147151
// is unoccupied by other accounts, points to valid memory within mmap and is
148152
// properly aligned to 8 bytes, so the contract of serialize_to_mmap is satisfied
149153
unsafe {
150154
AccountSharedData::serialize_to_mmap(
151155
acc,
152156
allocation.storage.as_ptr(),
157+
block_size * allocation.blocks,
153158
)
154159
};
155160
// update accounts index

magicblock-accounts-db/src/storage.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ impl AccountsStorage {
273273
+ METADATA_STORAGE_SIZE as u64
274274
}
275275

276-
fn block_size(&self) -> usize {
276+
pub(crate) fn block_size(&self) -> usize {
277277
self.meta.block_size as usize
278278
}
279279

magicblock-accounts-db/src/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fn test_modify_account() {
7676
#[test]
7777
fn test_account_resize() {
7878
let tenv = init_test_env();
79-
let huge_data = [42; SPACE * 2];
79+
let huge_data = [42; SPACE * 4];
8080
let AccountWithPubkey {
8181
pubkey,
8282
account: mut uncommitted,
@@ -89,7 +89,7 @@ fn test_account_resize() {
8989
);
9090
assert_eq!(
9191
uncommitted.data().len(),
92-
SPACE * 2,
92+
SPACE * 4,
9393
"account should have been resized to double of SPACE"
9494
);
9595

@@ -123,7 +123,7 @@ fn test_alloc_reuse() {
123123
pubkey,
124124
account: mut acc1,
125125
} = tenv.account();
126-
let huge_data = [42; SPACE * 2];
126+
let huge_data = [42; SPACE * 4];
127127

128128
let old_addr = acc1.data().as_ptr();
129129

test-integration/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ program-schedulecommit-security = { path = "programs/schedulecommit-security" }
5151
rayon = "1.10.0"
5252
schedulecommit-client = { path = "schedulecommit/client" }
5353
serde = "1.0.217"
54-
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "7bdfefc" }
54+
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "5b50fad" }
5555
solana-program = "2.2"
5656
solana-program-test = "2.2"
5757
solana-pubkey = { version = "2.2" }
@@ -73,4 +73,4 @@ tokio = "1.0"
7373
# and we use protobuf-src v2.1.1. Otherwise compilation fails
7474
solana-storage-proto = { path = "../storage-proto" }
7575
# same reason as above
76-
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "7bdfefc" }
76+
solana-account = { git = "https://github.com/magicblock-labs/solana-account.git", rev = "5b50fad" }

0 commit comments

Comments
 (0)