-
Notifications
You must be signed in to change notification settings - Fork 6
feat: custom indexer module (single index) #443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
ef55c74
feat: custom indexer module with example index (WIP)
whankinsiv f50f6fd
merge origin/main
whankinsiv f930b90
feat: Fjall backed indexer example and cursor store
whankinsiv 55ec7d5
fix: cleanup
whankinsiv bf39333
fix: cargo shear
whankinsiv d6e56fc
fix: use pool_id instead of duplicating conversion from key hash
whankinsiv f791bf4
merge origin/main
whankinsiv File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # The topic to publish sync commands on | ||
| sync-command-publisher-topic = "cardano.sync.command" | ||
| # The topic to receive txs on | ||
| txs-subscribe-topic = "cardano.txs" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| use acropolis_common::{BlockInfo, Point}; | ||
| use anyhow::Result; | ||
| use caryatid_sdk::async_trait; | ||
| use pallas::ledger::traverse::MultiEraTx; | ||
|
|
||
| #[async_trait] | ||
| pub trait ChainIndex: Send + Sync + 'static { | ||
| fn name(&self) -> String; | ||
|
|
||
| async fn handle_onchain_tx(&mut self, info: &BlockInfo, tx: &MultiEraTx<'_>) -> Result<()> { | ||
| let _ = (info, tx); | ||
| Ok(()) | ||
| } | ||
|
|
||
| async fn handle_rollback(&mut self, point: &Point) -> Result<()> { | ||
| let _ = point; | ||
| Ok(()) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| use std::{future::Future, path::Path, sync::Mutex}; | ||
|
|
||
| use acropolis_common::Point; | ||
| use anyhow::Result; | ||
| use fjall::{Config, Keyspace, Partition, PartitionCreateOptions}; | ||
|
|
||
| pub trait CursorStore: Send + Sync + 'static { | ||
| fn load(&self) -> impl Future<Output = Result<Option<Point>>> + Send; | ||
| fn save(&self, point: &Point) -> impl Future<Output = Result<()>> + Send; | ||
| } | ||
|
|
||
| // In memory cursor store (Not persisted across runs) | ||
| pub struct InMemoryCursorStore { | ||
| cursor: Mutex<Option<Point>>, | ||
| } | ||
| impl InMemoryCursorStore { | ||
| pub fn new(point: Point) -> Self { | ||
| Self { | ||
| cursor: Mutex::new(Some(point)), | ||
| } | ||
| } | ||
| } | ||
| impl CursorStore for InMemoryCursorStore { | ||
| async fn load(&self) -> Result<Option<Point>> { | ||
| let guard = self.cursor.lock().map_err(|_| anyhow::anyhow!("cursor mutex poisoned"))?; | ||
| Ok(guard.as_ref().cloned()) | ||
| } | ||
|
|
||
| async fn save(&self, point: &Point) -> Result<()> { | ||
| let mut guard = self.cursor.lock().map_err(|_| anyhow::anyhow!("cursor mutex poisoned"))?; | ||
| *guard = Some(point.clone()); | ||
| Ok(()) | ||
| } | ||
| } | ||
|
|
||
| // Fjall backed cursor store (Retains last stored point) | ||
| pub struct FjallCursorStore { | ||
| cursor: Partition, | ||
| } | ||
|
|
||
| impl FjallCursorStore { | ||
| pub fn new(path: impl AsRef<Path>, point: Point) -> Result<Self> { | ||
| let cfg = Config::new(path); | ||
| let keyspace = Keyspace::open(cfg)?; | ||
| let partition = keyspace.open_partition("cursor", PartitionCreateOptions::default())?; | ||
|
|
||
| // Use stored point if exists or initialize with provided point | ||
| match partition.get("cursor")? { | ||
| Some(_) => Ok(Self { cursor: partition }), | ||
| None => { | ||
| let raw = bincode::serialize(&point)?; | ||
| partition.insert("cursor", raw)?; | ||
| Ok(Self { cursor: partition }) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl CursorStore for FjallCursorStore { | ||
| async fn load(&self) -> Result<Option<Point>> { | ||
| let raw = self.cursor.get("cursor")?; | ||
|
|
||
| let Some(bytes) = raw else { | ||
| return Ok(None); | ||
| }; | ||
|
|
||
| let point: Point = bincode::deserialize(&bytes)?; | ||
|
|
||
| Ok(Some(point)) | ||
| } | ||
|
|
||
| async fn save(&self, point: &Point) -> Result<()> { | ||
| let raw = bincode::serialize(point)?; | ||
|
|
||
| self.cursor.insert("cursor", raw)?; | ||
|
|
||
| Ok(()) | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not likely to be a problem here as I would expect the structure of
Pointto be stable (it's a simple two-variant enum), however for less stable types that you're encoding/decoding, I like to include a version prefix constant to ensure compatibility with previous versions of a struct's encoding/decoding. This is particularly relevant with bincode since it's a non-self-describing format—it doesn't store field names or type information, so changes to field order or structure can cause silent deserialization failures.Something like the following:
Again, this is more pertinent to data that could be subject to change in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could totally change in the future. A Point is just two fields, but as we index more forms of data we may need more info in these cursors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense 👍🏼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this'll be handed in a followup