L2-Technology / sensei

A lightning node implementation for everyone
https://l2.technology/sensei
Other
198 stars 39 forks source link

Add data layer in front of database and storage abstraction #25

Closed johncantrell97 closed 2 years ago

johncantrell97 commented 2 years ago

As a first step towards #18 and potentially any backend for sensei data we should create a thin layer of abstraction. Basically all of the application code should interact with models that represent the data and shouldn't care how it's stored.

So we'd have structs like Node, Payment, AccessToken etc and all the database adapters would be responsible for saving and hydrating these objects however they want. We sort of have this already but not quite as clean as it should be.

I guess it also means there should be an interface that the db adaptors implement so the service(s) don't care which database is being used.

Something like this:

trait Database {
   fn create_node(&mut self, node: Node) -> Result<Uuid, Error>;
   fn delete_node(&mut self, id: Uuid) -> Result<(), Error>;
   fn list_nodes(&mut self) -> Result<Vec<Node>, Error>;
   fn update_node(&mut self, node: Node) -> Result<(), Error>;
}

impl Database for SqliteDatabase {
   ...
}

impl Database for PostgresDatabase {
  ...
}

and then AdminService and NodeService would store a reference to an object that implements Database trait -- this object will be defined at runtime based on configuration.

Thoughts?

w3irdrobot commented 2 years ago

@johncantrell97 i have started working on #18 and this path is the one i'm going down. :+1:

johncantrell97 commented 2 years ago

awesome, I'll let you do tackle this as part of #18 then! Feel free to discuss in discord if things come up as you work on it. I'd also recommend forking off from rewire-auth branch as it includes the bitcoind and token auth refactors. Both are fairly large changes but I guess should mostly be independent from this.

johncantrell97 commented 2 years ago

hey @searsaw any update on this? happy to take it over if you don't have the time at the moment. once the generic persistence layer work lands I plan on working on this

w3irdrobot commented 2 years ago

@johncantrell97 still working on it. Had some issues I ran into with it as I was going through. Changed directions a few times. Planning on working on it more over the next few days. Hope to have it done soon. Sorry about the delay.

johncantrell97 commented 2 years ago

Ok cool, been thinking more about this as well. After working on the generic key-value store / persistence layer for Sensei I'm wondering if these should follow the same structure here.

With the persistence work I created a SenseiPersister struct that takes in its constructor an object that implements a key-value store. This means sensei code base only interfaces with the SenseiPersister but it's using whatever persistence store you gave it when you created it.

I think this same pattern makes sense here and I'm curious where you landed.

We could have a separate SenseiDatabase struct that takes in its constructor some object that implements the database store interface. This object would be an enum like AnyDatabase in bdk project so we can swap it out at runtime based on the user config. The entire codebase interfaces with SenseiDatabase and doesn't care how the data is stored.