Skip to content

Commit

Permalink
Correctly implement WasmSnapshotter
Browse files Browse the repository at this point in the history
  • Loading branch information
iKapitonau committed Nov 26, 2024
1 parent 244c929 commit 67c8c57
Showing 1 changed file with 17 additions and 52 deletions.
69 changes: 17 additions & 52 deletions x/compute/internal/keeper/wasm_snapshotter.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,15 @@ import (
storetypes "cosmossdk.io/store/types"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
protoio "github.com/cosmos/gogoproto/io"
"github.com/scrtlabs/SecretNetwork/x/compute/internal/types"
)

/*
API to implement:
// Snapshotter is something that can create and restore snapshots, consisting of streamed binary
// chunks - all of which must be read from the channel and closed. If an unsupported format is
// given, it must return ErrUnknownFormat (possibly wrapped with fmt.Errorf).
type Snapshotter interface {
// Snapshot writes snapshot items into the protobuf writer.
Snapshot(height uint64, protoWriter protoio.Writer) error
// Restore restores a state snapshot from the protobuf items read from the reader.
// If the ready channel is non-nil, it returns a ready signal (by being closed) once the
// restorer is ready to accept chunks.
Restore(height uint64, format uint32, protoReader protoio.Reader) (SnapshotItem, error)
}
// ExtensionSnapshotter is an extension Snapshotter that is appended to the snapshot stream.
// ExtensionSnapshotter has an unique name and manages it's own internal formats.
type ExtensionSnapshotter interface {
Snapshotter
// SnapshotName returns the name of snapshotter, it should be unique in the manager.
SnapshotName() string
Expand All @@ -48,6 +32,13 @@ type ExtensionSnapshotter interface {
// SupportedFormats returns a list of formats it can restore from.
SupportedFormats() []uint32
// SnapshotExtension writes extension payloads into the underlying protobuf stream.
SnapshotExtension(height uint64, payloadWriter ExtensionPayloadWriter) error
// RestoreExtension restores an extension state snapshot,
// the payload reader returns `io.EOF` when reached the extension boundaries.
RestoreExtension(height uint64, format uint32, payloadReader ExtensionPayloadReader) error
}
*/

Expand Down Expand Up @@ -81,7 +72,7 @@ func (ws *WasmSnapshotter) SupportedFormats() []uint32 {
return []uint32{1}
}

func (ws *WasmSnapshotter) Snapshot(height uint64, protoWriter protoio.Writer) error {
func (ws *WasmSnapshotter) SnapshotExtension(height uint64, payloadWriter snapshottypes.ExtensionPayloadWriter) error {
// TODO: This seems more correct (historical info), but kills my tests
// Since codeIDs and wasm are immutible, it is never wrong to return new wasm data than the
// user requests
Expand Down Expand Up @@ -113,7 +104,7 @@ func (ws *WasmSnapshotter) Snapshot(height uint64, protoWriter protoio.Writer) e
return true
}

err = snapshottypes.WriteExtensionPayload(protoWriter, wasmBytes)
err = payloadWriter(wasmBytes)
if err != nil {
rerr = err
return true
Expand All @@ -125,54 +116,28 @@ func (ws *WasmSnapshotter) Snapshot(height uint64, protoWriter protoio.Writer) e
return rerr
}

func (ws *WasmSnapshotter) Restore(
height uint64, format uint32, protoReader protoio.Reader, //nolint:all
) (snapshottypes.SnapshotItem, error) {
func (ws *WasmSnapshotter) RestoreExtension(
height uint64, format uint32, payloadReader snapshottypes.ExtensionPayloadReader, //nolint:all
) error {
if format != 1 {
return snapshottypes.SnapshotItem{}, snapshottypes.ErrUnknownFormat
return snapshottypes.ErrUnknownFormat
}

for {
item := snapshottypes.SnapshotItem{}
err := protoReader.ReadMsg(&item)
wasmBytes, err := payloadReader()
if err == io.EOF {
return snapshottypes.SnapshotItem{}, nil
return nil
} else if err != nil {
return snapshottypes.SnapshotItem{}, errorsmod.Wrap(err, "invalid protobuf message")
}

// if it is not another ExtensionPayload message, then it is not for us.
// we should return it an let the manager handle this one
payload := item.GetExtensionPayload()
if payload == nil {
return item, nil
return errorsmod.Wrap(err, "invalid protobuf message")
}

wasmBytes := payload.Payload

codeHash := sha256.Sum256(wasmBytes)
wasmFileName := hex.EncodeToString(codeHash[:])
wasmFilePath := filepath.Join(ws.wasmDirectory, wasmFileName)

err = os.WriteFile(wasmFilePath, wasmBytes, 0o600 /* -rw------- */)
if err != nil {
return snapshottypes.SnapshotItem{}, errorsmod.Wrapf(err, "failed to write wasm file '%v' to disk", wasmFilePath)
return errorsmod.Wrapf(err, "failed to write wasm file '%v' to disk", wasmFilePath)
}
}
}

func (ws *WasmSnapshotter) PruneSnapshotHeight(_ int64) {
panic("not implemented")
}

func (ws *WasmSnapshotter) SetSnapshotInterval(_ uint64) {
panic("not implemented")
}

func (ws *WasmSnapshotter) RestoreExtension(_ uint64, _ uint32, _ snapshottypes.ExtensionPayloadReader) error {
panic("not implemented")
}

func (ws *WasmSnapshotter) SnapshotExtension(_ uint64, _ snapshottypes.ExtensionPayloadWriter) error {
panic("not implemented")
}

0 comments on commit 67c8c57

Please sign in to comment.