-
Notifications
You must be signed in to change notification settings - Fork 13
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
Add basic Get and Put Api signatures along with protobuf setup #1
Conversation
src/main/proto/ess.proto
Outdated
} | ||
message GetResponse { | ||
bool success = 1; | ||
KeyValue value = 2; |
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.
is it useful to return just one value, or does it make more sense to return everything with a certain key prefix? for VLS at least we always want to get a complete snapshot of the storage for a node when we do perform a get
. does LDK intend to make single item retrievals?
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.
regarding "return everything with a certain key prefix" => i thought about it but this makes for an unbounded query on server-side hence we should be avoiding it
single get does mean some additional work for client.
Regarding "list by key prefix" => this in intended to be solved by listKeys api which will be a paginated api. For LDK as well, we have use-case of reloading parts of snapshot. (This will be done after computing version difference of keys b/w client and server-side)
I had added "Batch" operation support as "future item" in doc, but that also won't solve this problem because there will still be some batch limit. Client needs to use versioning to ensure consistent state instead of relying on getting everything at once in consistent fashion.
Another reason, I was being bit conservative about batch operations is because we intend to support storing values upto ~5MB, even a 10 item get might mean 50MB response depending on client-application.
Let me know if that works.
Side note: Currently this api can be used with any of the approach mentioned in doc, that is "Independent State Updates", "Global State Counter" or "Incremental State Updates". LDK will be using "Global State Counter"
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.
I don't see "Independent State Updates" in the doc. However, that sounds like the approach that VLS would use. But would be interested in hearing more.
So I think the plan with listKeys
would work, but we will need this sooner rather than later, since otherwise there is no way to discover what is in the store.
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.
Yes, LDK needs listKeys and getKeysSummary immediately as well.
Just didn't include it in this commit. Wanted close on basic get and put first.
Heading was named slightly different. Added "Independent State Update" to that heading.
src/main/proto/ess.proto
Outdated
string key = 1; | ||
|
||
// Write will only succeed if current DB version against key is same as in request. | ||
int64 version = 2; |
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.
should document here what is the starting version number - i.e. when a key does not exist, should the version specified here be -1
or 0
?
also, it may make more intuitive sense to provide current_version + 1
(i.e. the new version) here instead of current_version
, but this is a matter of taste
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.
I think from client perspective they will have to maintain a current version of object that they have in-memory or secondary store.
It could be more intuitive to start with 0 as first version as it will be same for client and they just call with their current version at-hand instead of any special handling.
Will add it to docs.
I think we should never check in binaries to our repos, including |
src/main/proto/ess.proto
Outdated
service EncryptedStorageService { | ||
rpc get(GetRequest) returns (GetResponse); | ||
rpc put(PutRequest) returns (PutResponse); | ||
//TODO: Add getKeysSummary (Gives version numbers for all keys in a store) and list by prefix API's | ||
} |
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.
What is being "get" or "put"? I'd recommend following these naming conventions for both method and type names:
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.
Good point, changed it to GetObjectRequest and PutObjectRequest
src/main/proto/ess.proto
Outdated
string key = 1; | ||
|
||
// Write will only succeed if current DB version against key is same as in request. | ||
int64 version = 2; |
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.
Do all KeyValue
s in a PutRequest
need to have the same version or can they differ?
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.
Every key will have its own version. so they can differ.
src/main/proto/ess.proto
Outdated
/* | ||
If present, write will only succeed if current DB globalVersion against a storeId is | ||
same as in request. | ||
*/ | ||
optional int64 globalVersion = 2; |
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.
Could you flesh out all the docs in this file? At a high-level, the versioning scheme should be defined.
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.
Sounds good, i will write a basic explanation in docs.
Hoping to write a much more detailed api doc after impl though.
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.
Can you provide more justification for why there's protobufs to talk to the server? Why is it insufficient to do a simple HTTP(S) GET/PUT RESTful API? It seems this will run over HTTP(S) anyway, so that seems strictly simpler for both client and server? Am I missing something?
I think the request/response bodies may be complex enough that protobufs and strongly-typed bindings to them would be an improvement over JSON. Also, more compact / performant. |
src/main/proto/ess.proto
Outdated
Ref: https://en.wikipedia.org/wiki/Keyspace_(distributed_data_store) | ||
It is up to clients to use single or multiple store's for their usage. | ||
*/ | ||
string storeId = 1; |
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.
I don't understand why we want this?
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.
Its for key grouping,
If service owner wants to implement following:
- client-isolation/rate-limiting/throttling
- authorization
- billing etc.
- Also I could delete a store which is no longer being used.
They can do this based on this identifier.
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.
The service owner definitely wants to implement client isolation, I think that's required for this API fundamentally. My question is why we need this on top of that. Given that clients can only store some limit amount and the clients are all isolated, I don't understand why we need clients to support different storage sections. Can that not also be implemented as just having different "clients"? We're not building an enterprise-scale storage platform for a user, we're building an enterprise-scale storage platform to store data for a lot of small users, I think.
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.
It is exactly that, building "enterprise-scale storage platform to store data for many users".
storeId is an abstraction for clientId.
A client can have multiple stores if they choose to but most might just use single store, its up to them.
Its just like we can create multiple EBS instances and its not assumed that we will only use one.
storeId is client isolation at storage layer, can think of it as userId.
src/main/proto/ess.proto
Outdated
message KeyValue { | ||
string key = 1; | ||
|
||
int64 version = 2; |
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.
Hmm, isn't it kinda awkward on the server to have both a global-version and versions on all the KV entries? Does it make sense to have it in the API explicitly when it will ultimately be implemented by having a dummy "globalVersion" key that could just be a separate KeyValue done on the client side?
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.
Internally it is implemented like just another KV entry only.
We can consider it but i preferred this minor implementation complexity on server side than on client side.
We don't want to explain to clients every time that this is how you should be using this if you want global consistent writes. From multiple discussions i have had on versioning of state, it looks like devs could miss this detail if api is not explicit about it.
By doing so, we can give clients guidance on two popular options for using versioning. And they can simply choose based on their requirements.
(Using GlobalVersioning is optional for clients, for LDK it is required, VLS might not need it.
For single-device access globalVersion is not required.)
Provides a simpler interface for clients using single-item writes who don't care about multi-item transactions.
Using transactions for doing global consistent write is more of an implementation detail.
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.
I guess my question is more if we're controlling the client code or not. I understood that, generally, users wouldn't be exposed to the protobufs here, they'd use some libvss-{rust,java,etc}-client
library. Including the globalversion K-V can then be done at the client level without users being exposed to it.
I'm not sure why they would be? I agree let's avoid JSON, but there's not that many fields here, PUT is the only complicated one, and its really just a set of K-Version-V tuples. That could be sent in a format way simpler than protobufs? |
What did you have in mind? (It's probably best to have a format that is commonly used in web API client code for various languages.) |
I mean pick a simple format. bencoding or something equally simple makes sense to me. binary packing works fine to me, or hex encode it, csv it, i dunno, doesn't matter. Protobufs are a lot of complexity and language support is generally good, but not always great. Something that you can hand-write in any language seems like it would be better than protobufs. |
It sounds like you'd end up supporting client libraries for different languages, people writing sub-standard encoders/decoders, etc. |
Right, sub-standard encoders for Protobufs is an issue ;). If the encoding were simpler sub-standard encoders should be only a performance issue. |
protobuf/grpc is industry standard and is simple.
There is no way, we should be writing custom encoding/format for this. (i thought @devrandom concern about sub-standard serde was on this.) The request/response objects are complex enough, there are two more api's yet to be added, we will be adding more fields and metadata to schema as server matures. Also, i thought we had decided on it in Meeting Notes Oct 5th: "Will use java and grpc to build backend" |
Sorry wasn't in the meeting. Curious though what were the reasons java was chosen? |
@Jasonvdb |
I get the sense grpc support across different languages is more mixed than protobuf. For example going grpc will mean that you cannot talk to a VSS server from entirely within a javascript context, which I think is a no-starter. I think we kinda have to go the HTTPS route for the actual talking, even if we use protobufs for the contents.
This depends on the specific language we're talking about? But, yes, most languages have at least a reasonably good protobuf library.
If we go the grpc route I agree with you, but I don't think we can. With HTTPS we get this for free - /v1, /v2, etc :)
Right, see my above list of suggested alternatives, this is pretty easy to match :).
I don't really understand peoples' hesitance to do this - if we're concerned about adding fields and backwards compat and all that good stuff I may agree, but I don't think that's a concern - and for a three-tuple (where one element is fixed-length) almost anything is reasonable :)
Ah, I recall the java conclusion, I may have missed the grpc note, sorry about that. |
Not sure if I have all the nuances of the conversations, but I believe gRPC exposes an HTTP interface with /v1, /v2, etc. style versioning. Resources: |
Right, so let's just stick with an HTTP interface :). I'm not sure I understand what the specific value of grpc is on top of a simple HTTP interface if we have to support at least HTTP anyway? |
I haven't convinced myself yet that the API will remain simple. |
Right, I think my point here was that the API today is super duper trivially simple, and if we ever need to change that we can switch to protobuf in a /v2/ API. |
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.
In general, I think we should flesh out all the documentation and have some top-level or message-level docs explaining the versioning scheme. See comments for some details.
string key = 2; | ||
} | ||
message GetObjectResponse { | ||
KeyValue value = 2; |
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.
Do we need to return the key?
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.
Yes, its generally a good practice to return key as well.
This is helpful if and when we want to have batch api in future. Makes for a consistent code.
Also slightly easier to implement client side parallel batch calls.
app/src/main/proto/vss.proto
Outdated
/* | ||
If present, write will only succeed if current DB globalVersion against a storeId is | ||
same as in request. | ||
Client is expected to send their current global version at hand. |
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.
How does the client track the global version and when may it be different from the server?
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.
Client side and server side global version only diverge in case of multiple devices.
I.e. multiple client-side updating same state.
Just like they keep track of current value/version against a key, they will need to store global version(either in-memory or disk)
We will provide a vss-client which will do all of this for them.
app/src/main/proto/vss.proto
Outdated
For first write of store, version should be '0'. If write succeeds, clients must increment | ||
their global version(on device) by 1. | ||
|
||
Requests with conflicting version will fail with [`ConflictException`] as ErrorCode. |
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.
Will this return the actual global version on failure? Or does the client need to do something to get in sync?
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.
No, it does not. Returning it from here doesn't add much value and keeps api simpler (and can have some race-conditions if used without considering some edge cases.)
ConflictException indicates that their view of store is out-of-sync. And they need to re-sync their view by fetching all key-versions and global version from server.
And for the keys having different version on server, client will need to update their view(can be done lazy).
(This is will also be provided as implemented method in vss-client)
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.
Is there a method for fetching everything? A client may not have all keys if another client wrote a new key.
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.
Yes it will be in subsequent PR once we have get and put.
app/src/main/proto/vss.proto
Outdated
/* | ||
If present, write will only succeed if current DB globalVersion against a storeId is | ||
same as in request. | ||
Client is expected to send their current global version at hand. |
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.
"at hand" is a little vague. We should spell out what this means.
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.
"Clients are expected to store version against every key locally.
When initiating a PutRequest, request should contain current version for that key."
Let me know if this sounds better or we need to add more context.
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 sure I follow what is meant by "store version against every key locally". This comment is on globalVersion
, and my understanding is there is one global version for a store.
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.
Could you go ahead and push any updated docs? Would be easier to read with new commits rather than looking at comments.
app/src/main/proto/vss.proto
Outdated
/* | ||
If present, write will only succeed if current DB globalVersion against a storeId is | ||
same as in request. | ||
Client is expected to send their current global version at hand. |
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 sure I follow what is meant by "store version against every key locally". This comment is on globalVersion
, and my understanding is there is one global version for a store.
app/src/main/proto/vss.proto
Outdated
For first write of store, version should be '0'. If write succeeds, clients must increment | ||
their global version(on device) by 1. |
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.
Should make it clear the version is incremented on the next put request?
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.
Added clarification
app/src/main/proto/vss.proto
Outdated
For first write of store, version should be '0'. If write succeeds, clients must increment | ||
their global version(on device) by 1. | ||
|
||
Requests with conflicting version will fail with [`ConflictException`] as ErrorCode. |
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.
Is there a method for fetching everything? A client may not have all keys if another client wrote a new key.
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.
I assume authentication is handled at the HTTP layer?
app/src/main/proto/vss.proto
Outdated
their corresponding key versions(client-side) by 1. These updated key versions should be used in | ||
subsequent PutRequests for the keys. | ||
|
||
Requests with conflicting version will fail with [`ConflictException`] as ErrorCode. |
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.
Should we include which version value was wrong in the error result? That way clients know what to download?
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.
Clients might need to sync their whole view depending on conflict and their usage.
Conflict could be either due to key versions or global version.
ErrorResponse should be simple and adding all this info could complicate it. Instead it is easier to re-use existing api's for the functionality.
option java_multiple_files = true; | ||
package org.vss; | ||
|
||
message GetObjectRequest { |
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.
Don't we need an API to fetch the list of keys stored (and maybe the versions of them)?
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.
yes, its part of separate api, will add it in following PR's
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.
Could you add documentation to all messages and fields? The message docs can go into detail about the usage scenario. And fields can explain anything that should be considered when setting them.
app/src/main/proto/vss.proto
Outdated
/* | ||
If present, write will only succeed if current DB globalVersion against a storeId is | ||
same as in request. | ||
Client is expected to global version against store. And PutRequest should contain |
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.
Looks like there's a word missing in the sentence.
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.
Done, 👍
Regarding "The message docs can go into detail about the usage scenario. And fields can explain anything that should be considered when setting them."
I created an issue and we will add these details once we have an implementation.
#3
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.
Could we do this now? Doing it in a follow-up just adds extra review burden.
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.
I have added lot more docs now for every field. But there are still many things which we could cover in here.
I didn't want to stall this PR for docs changes and want to close on interface.
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.
I didn't comment exhaustively on it, but note my comment on using the definite article "the" where appropriate. We'll want to me a little more formal in the language used in docs than everyday informal speech.
app/src/main/proto/vss.proto
Outdated
their global version(client-side) by 1. This updated global version should be used in subsequent | ||
PutObjectRequests for the store. | ||
|
||
Requests with conflicting version will fail with [`ConflictException`] as ErrorCode. |
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.
The []
notation is used in rustdocs for linking. Does proto doc generation have a similar feature?
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.
no, there is no such feature afaik.
Here, i was just using it to quote specific object-field, replaced it with just ` quotes
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.
Largely looks good modulo commented on grammar and nits.
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.
Looks good. Just a few minor comments.
app/src/main/proto/vss.proto
Outdated
|
||
message GetObjectRequest { | ||
|
||
// StoreId: All APIs operate within a single storeId. |
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.
Only use one space between //
and text throughout.
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.
@devrandom Could you take another pass?
app/src/main/proto/vss.proto
Outdated
It is meant to be read and understood programmatically by code that detects/handles errors by | ||
type. | ||
*/ | ||
ErrorCode errorCode = 1; |
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.
I would not have ErrorCode
track the HTTP error codes in any way, to prevent the user from making assumptions about any correlation between the two. in general, we may have error conditions in the future that don't fit any HTTP error code.
message PutObjectResponse { | ||
} | ||
|
||
// When HttpStatusCode is not ok (200), the response `content` contains a serialized ErrorResponse |
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.
unfortunately, I don't think all gRPC client libraries let you access the HTTP error code, or parse the body if the HTTP code is 4xx.
I recommend looking into the tonic
Rust crate to see what is available at least in the Rust case. in particular see the Status
struct, which is returned in the failure case.
and lastly, I think all bets are off if the HTTP code is 5xx, because that could be caused by an intermediate proxy and might not reach the gRPC server at all.
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.
also, consider the gRPC native error codes - https://grpc.github.io/grpc/core/md_doc_statuscodes.html
for example, the FAILED_PRECONDITION
code might be a good match for an incompatible version in a Put.
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.
since it is not a grpc service,
we cannot use status struct acc. to grpc protocol (it uses http/2 trailing headers)
and we don't need to follow grpc status codes.
In case someone wants to create a grpc service, they could use status struct and serialize this errorResponse message inside status.
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.
I somehow missed that the current PR is not for gRPC anymore. is there more information about the underlying protocol - I don't immediately see it in the PR?
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.
Since we didn't define the "service" proto, its not going to generate any grpc service stubs.
Here protobuf is only being used as a binary serialization format for request and response objects.(instead of writing custom binary serialization or json). This helps both client and server to create requests/response like class instances with ease.
This payload will be used as binary body in http-rest post requests. I think we will need to add this detail on overall project readme for vss-server as well as some client with examples.
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.
OK, sounds good
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.
FWIW, the Status
error codes are meant to be protocol-agnostic.
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.
Whether we use HttpStatus codes or protobuf status codes,
the same concern remains that in future we might want to introduce error conditions which donot map directly or have one to many mapping.
Removed this association as part of another comment
Changed to underscore_separated_names for field names and kept camel case for structs. (acc. to protobuf generation guideline). |
Add Basic api signatures
Main file to review : src/main/proto/ess.proto
This will auto-generate required request/response objects.
Note: Since we didn't define the "service" proto, its not going to generate any grpc service stubs.
Here protobuf is only being used as a binary serialization format for request and response objects.(instead of writing custom binary serialization or json). This helps both client and server to create requests/response like class instances with ease.
This payload will be used as binary body in http-rest post requests.
Apart from that it is mostly auto-generated setup for gradle project.
Things like Auth will be added once we add API for creating a "store".
Currently this api can be used with any of the approach mentioned in doc, that is "Independent State Updates", "Global State Counter", "Incremental State Updates".
LDK will be using "Global State Counter", different applications might choose different approaches based on their needs.
Doc: https://docs.google.com/document/d/1mhTAnkXAtxPQRsn17gbEPIN5G8OW2h619f_yk8CXJTE/edit?usp=sharing