-
Notifications
You must be signed in to change notification settings - Fork 206
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
Cosmos x/vstream
implementation
#5466
Conversation
27e7cc4
to
1f47045
Compare
d82718e
to
3ad5774
Compare
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.
Preview of comments. More to come, hopefully this weekend.
]; | ||
|
||
// The subkey under which the cell is stored. | ||
bytes store_subkey = 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.
This is the subkey/child key for vstorage? Make that explicit, and be consistent with the choice of "sub" vs "child" made for vstorage.
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, this is at a lower level than vstorage: the Cosmos SDK multistore. I've noted as such.
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, "subkey" doesn't appear to be standard cosmos terminology - the APIs just use "key".
(gogoproto.moretags) = "yaml:\"end_state\"" | ||
]; | ||
|
||
// The prior position in the stream. |
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.
Add If this is the first cell in the stream, this will be the default value. All other cells will have a reference with a nonzero block height.
]; | ||
|
||
// The sequence number of the value at this position. | ||
uint64 sequence_number = 4 [ |
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 first thought this was redundant with firstSequenceNumber
in StreamCell
, but now I see this is necessary for a reference to a fork point within a cell.
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 see you've removed firstSequenceNumber
from StreamCell
. I guess it's redundant as long as you're always accessing a cell via a StreamPosition
, but it seems a little too bold to leave this essential information only extrinsic. Consider restoring the field.
golang/cosmos/types/stream/cell.go
Outdated
agoric "github.com/Agoric/agoric-sdk/golang/cosmos/types" | ||
) | ||
|
||
func NewStreamCell(blockHeight int64, seq uint64) StreamCell { |
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.
Document that seq
is the first sequence number to use in the cell.
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 changed this to take a prior
position. It's better not to leak the sequence number abstraction.
]; | ||
} | ||
|
||
// StreamPosition is data that refers to a particular stream cell value. |
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.
Add The default value of this message is the equivalent of a null pointer.
golang/cosmos/types/stream/cell.go
Outdated
priorCell.UpdatedBlockHeight, | ||
state.StoreName(), | ||
state.StoreSubkey(), | ||
uint64(len(priorCell.Values)), |
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 you need to add priorCell.FirstSequenceNumber
? Add a test which would have caught 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.
Turns out that was redundant information that I've removed.
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 fixed yet.
golang/cosmos/types/stream/cell.go
Outdated
|
||
func GetLatestPosition(ctx sdk.Context, state agoric.StateRef) (*StreamPosition, error) { | ||
var priorCell StreamCell | ||
if state.Exists(ctx) { |
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.
Consider testing for !state.Exists(ctx)
and returning NewZeroStreamPosition()
. It looks like a non-existing cell results in the return of a zero stream position, but I think it's safer to make this explicit rather than relying on undocumented, implicit behavior.
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
// An interface to allow updating KVStore-backed state and extracting proof |
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.
An interface ... to a stored StreamCell.
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's not StreamCell specific.
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.
Okay, but see below for comments that make it explicit when we are expecting it to reference a StreamCell. When do you think the SDK might start using generics?
type StateRef[T Jsoner] interface {
Read(ctx sdk.Context) (T, error)
Write(ctx sdkContext, value T) error
...
}
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.
Here's my final comments on the code. I'll address the spec documents in another PR - probably after I've seen more of how this all will be used.
// If state=END_STATE_FAILURE, the last value is the serialised error. | ||
repeated bytes values = 1; | ||
|
||
// The block height in which this cell was last updated. |
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. In the comment at least, instead of "was last updated", try "was produced", and see if that inspires a different name.
]; | ||
|
||
// The subkey under which the cell is stored. | ||
bytes store_subkey = 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.
Hmm, "subkey" doesn't appear to be standard cosmos terminology - the APIs just use "key".
]; | ||
|
||
// The sequence number of the value at this position. | ||
uint64 sequence_number = 4 [ |
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 see you've removed firstSequenceNumber
from StreamCell
. I guess it's redundant as long as you're always accessing a cell via a StreamPosition
, but it seems a little too bold to leave this essential information only extrinsic. Consider restoring the field.
) | ||
|
||
// NewStreamCell creates a new StreamCell at blockHeight with the specified | ||
// prior position. |
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.
Use a zero stream position if this is the first cell in the stream.
} | ||
|
||
// GetLatestPosition returns the position of the last value in the cell, or a | ||
// zero stream position if the referenced cell does not exist. |
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 a StateRef could reference anything, document that it is expected to reference a StreamCell.
Add a note that it will unconditionally return the position of the last value in the cell regardless of the cell's end state. The cell end state should be checked to ensure the position is meaningful, e.g. not END_STATE_FAILURE
.
|
||
option go_package = "github.com/Agoric/agoric-sdk/golang/cosmos/types/stream"; | ||
|
||
// StreamCell represents one publish state in a vstream stream. |
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.
"published". Consider instead "StreamCell contains the stream values that are published during the execution of a single block. Each StreamCell contains a reference to the prior cell in the stream.
import "gogoproto/gogo.proto"; | ||
|
||
option go_package = "github.com/Agoric/agoric-sdk/golang/cosmos/types/stream"; | ||
|
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.
Introductory comment: "A stream is a sequence of arbitrary bytes values used by publishers to communicate with consumers. Values in a stream are indexed by 1-based contiguous sequence numbers. A stream is stored as a sequence of StreamCells. StreamCells are typically written to the same key in a KVStore, relying on reading at old block heights to see older values."
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
// An interface to allow updating KVStore-backed state and extracting proof |
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.
Okay, but see below for comments that make it explicit when we are expecting it to reference a StreamCell. When do you think the SDK might start using generics?
type StateRef[T Jsoner] interface {
Read(ctx sdk.Context) (T, error)
Write(ctx sdkContext, value T) error
...
}
|
||
var _ StateRef = KVStoreStateRef{} | ||
|
||
func NewKVStoreStateRef(storeKey sdk.StoreKey, subkey []byte) *KVStoreStateRef { |
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.
Consider not pointer-izing.
var _, _ StreamCellUpdater = AppendStreamCellUpdater{}, FailStreamCellUpdater{} | ||
|
||
type StreamOperation struct { | ||
state agoric.StateRef |
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.
Document that state
is expected to reference a StreamCell
.
@gibson042 did a great job of implementing this feature mostly in JS with a light touch in Go, so this PR is superseded. Closing. |
refs: #5487
Description
On-chain stream publishing for the client described in
@agoric/streams
. See thex/vstream
specSecurity Considerations
Documentation Considerations
Testing Considerations