Skip to content

Conversation

@Harshdev098
Copy link

Have added in_memory store for testing purpose.
We can edit config file to use specific store either postgresql or memory

@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Oct 12, 2025

👋 Thanks for assigning @tankyleo as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@Harshdev098
Copy link
Author

Harshdev098 commented Oct 12, 2025

Hey @tnull @tankyleo Can you please review it

@tnull tnull self-requested a review October 13, 2025 07:10
Copy link
Contributor

@tnull tnull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this!

Generally goes into the right direction, but we def. need to avoid re-allocating everything on every operation.

@Harshdev098 Harshdev098 force-pushed the memory_store branch 2 times, most recently from 4980a75 to 25d57e3 Compare October 14, 2025 06:16
@Harshdev098 Harshdev098 requested a review from tnull October 14, 2025 06:17
@Harshdev098
Copy link
Author

@tnull Have done the required changes

Copy link
Contributor

@tnull tnull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks much better, but I think we still need to handle global_version properly, even if we're currently not using it client-side.

}
}

async fn put(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems we'll also need to track a global_version and set it if it's set in the request?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tnull I've added handling for global_version in put and delete:

  • In put:
    • If request.global_version is set, check it against the current global version
    • After successful transaction, increment the global version and store it.
  • In delete:
    • Increment the global version after a successful delete

@ldk-reviews-bot
Copy link

🔔 1st Reminder

Hey @tankyleo! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link

🔔 2nd Reminder

Hey @tnull @tankyleo! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link

🔔 1st Reminder

Hey @tnull @tankyleo! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

Copy link
Contributor

@tnull tnull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment, will take another look once @tankyleo also had a chance to do a review round here.

created_at: now,
last_updated_at: now,
};
guard.insert(global_key, record);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we only update the entry if it's already existing, so that we don't always override created_at? Maybe rather use guard.entry().or_insert_with(..) (here and elsewhere)?

@Harshdev098
Copy link
Author

@tankyleo Can you please review it!

@ldk-reviews-bot
Copy link

🔔 3rd Reminder

Hey @tankyleo! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link

🔔 4th Reminder

Hey @tankyleo! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link

🔔 5th Reminder

Hey @tankyleo! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

Copy link
Contributor

@tankyleo tankyleo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay !

Self { store: Arc::new(Mutex::new(HashMap::new())) }
}

fn build_vss_record(&self, user_token: String, store_id: String, kv: KeyValue) -> VssDbRecord {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this into a helper function, as it does not need &self and does not return Self

}
}

fn build_key(user_token: &str, store_id: &str, key: &str) -> String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here pull this out into a helper function in this file

match entry {
std::collections::hash_map::Entry::Occupied(mut occ) => {
let existing = occ.get_mut();
if existing.version >= record.version {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For already existing records, a conflict error should be returned anytime the versions don't match, unless record.version has been set to -1 (meaning non-conditional update).

Comment on lines 115 to 117
if existing.version != record.version {
return Ok(());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If record.version is -1, this should be skipped and we should do a non-conditional delete.

version: record.version,
}),
})
} else if request.key == GLOBAL_VERSION_KEY {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like by the time we are here, we know the GLOBAL_VERSION_KEY does not have a value, otherwise guard.get would have returned Some previously. We can just return the GetObjectResponse below directly with version: 0.

for kv in &request.transaction_items {
let key = Self::build_key(&user_token, &store_id, &kv.key);
if let Some(existing) = guard.get(&key) {
if existing.version >= kv.version {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the above comment, shouldn't this just make sure that the existing.version == kv.version, otherwise throw a conflict ? Unless the kv.version is -1.

let key = Self::build_key(&user_token, &store_id, &kv.key);
if let Some(existing) = guard.get(&key) {
if existing.version >= kv.version {
return Err(VssError::ConflictError(format!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's pick a single spot to return ConflictError here similar to how things are done in postgres_store. As much as possible we should be checking for conflicts in a single spot.

use api::kv_store::INITIAL_RECORD_VERSION;
use bytes::Bytes;
use tokio::test;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like we have in postgres_store, let's add a line similar to below here and make sure the tests pass

define_kv_store_tests!(InMemoryKvStoreTest, InMemoryBackendImpl, InMemoryBackendImpl::new());

pub(crate) const INIT_DB_CMD: &str = "CREATE DATABASE";
#[cfg(test)]
const DROP_DB_CMD: &str = "DROP DATABASE";
pub(crate) const DROP_DB_CMD: &str = "DROP DATABASE";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks ! let's pull the formatting changes in postgres_store + pub(crate) changes into a separate commit, and keep the in_memory_store changes to a single commit

@Harshdev098
Copy link
Author

@tankyleo Have done with the required changes! Can you please review it

@Harshdev098 Harshdev098 requested a review from tankyleo October 26, 2025 01:53
Copy link
Contributor

@tnull tnull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing integration with LDK Node locally I found that the tests are currently failing. I now opened #62 to add LDK Node integration tests to our CI here. It would be great if that could land first, and we could also add a CI job for the in-memory store as part of this PR then, ensuring the implementation actually works as expected.

@ldk-reviews-bot
Copy link

🔔 1st Reminder

Hey @tankyleo! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants