-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Store Accessor Types #4554
Comments
@mossid thanks for creating this issue as a reference to the existing PR. From what I understand, this exists mainly as an improvement to developer ergonomics -- it doesn't not provide any discrete new functionality. A "nice-to-have" if you will. However, @jackzampolin stated that this is somehow needed for IBC? Can you elaborate on that please? What does this allow you to do that you cannot currently do for IBC? |
Working ADR on #4998 |
Closing this as it was not included on the SDK at the end. A new proposal with a more detailed ADR would be required to include it. |
Store accessor types are the helpers for accessing the underlying
KVStore
. Currently, to get a value from aKVStore
, you first need to:This decreases the readability of the code and harder to review. The types suppress the steps to one. There are several types, mostly parameterized by the type of the stored value, but the generic pattern is shown at
value.go
Base
Base
is a pair of codec, store getter function, and prefix.cdc
is used for marshaling/unmarshaling theinterface{}
s,storefn
is used to get aKVStore
given aContext
,prefix
will be applied as an argument forprefix.NewStore
.Value
The
Value
containscdc
,key
,storefn
in it, so it is preparameterized with the key. It can be considered as a pointer to a specific location in the key-value state. For any operations on it, it will internally get theKVStore
with thestorefn(ctx)
, access theKVStore
with thekey
, and marshal/unmarshal the value using thecdc.Must(Marshal/Unmarshal)BinaryBare
.Value
is the generic type that handles all types, so it takes aninterface{}
as its value argument.Variants of
Value
.type Boolean
: operations takebool
instead ofinterface{}
as its valuetype Enum
: operations takebyte
instead ofinterface{}
as its valuetype Integer
: operations takeuint64
instead ofinterface{}
as its valueThese variants are only differentiated by their type signature; the behaviours must be same with
Value
(all values must be marshaled/unmarshaled with thecdc
).The general pattern of methods:
Get(ctx sdk.Context, ptr interface{})
: unmarshals the stored value to the pointer, noop if nil value, panic if cannot unmarshalGetSafe(ctx sdk.Context, ptr interface{}) error
: same withGet
but returns error instead of panicGetRaw(ctx sdk.Context) []byte
: returns raw byte slice valueSet(ctx sdk.Context, o interface{})
: sets the value into the state, panics if failed to marshalSetRaw(ctx sdk.Context, bz []byte)
: sets the raw byte slice value into the stateExists(ctx sdk.Context) bool
: returns if the value existsDelete(ctx sdk.Context)
: deletes the valueKey(ctx sdk.Context)
: returns the key that the value actually uses to access the KVStoreOnly when the
ctx
is passed as an argument, we have a state access.Mapping
Mapping
can be understood as a mapping from[]byte
toValue
. It has a methodValue(key []byte)
, which returnsNewValue(Mapping.base, key)
. All the other methods have one more parameterkey []byte
, compared toValue
, which is translated intoMapping.Value(key).{OperationName}
.Variants of
Mapping
:type Indexer
: operation takesuint64
instead of[]byte
as its keyThe text was updated successfully, but these errors were encountered: