-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
269 additions
and
270 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,153 +1,153 @@ | ||
package keeper | ||
|
||
import ( | ||
"encoding/hex" | ||
"io" | ||
|
||
snapshot "github.com/cosmos/cosmos-sdk/snapshots/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | ||
protoio "github.com/gogo/protobuf/io" | ||
"github.com/tendermint/tendermint/libs/log" | ||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types" | ||
|
||
"github.com/CosmWasm/wasmd/x/wasm/ioutils" | ||
"github.com/CosmWasm/wasmd/x/wasm/types" | ||
) | ||
|
||
var _ snapshot.ExtensionSnapshotter = &WasmSnapshotter{} | ||
|
||
// SnapshotFormat format 1 is just gzipped wasm byte code for each item payload. No protobuf envelope, no metadata. | ||
const SnapshotFormat = 1 | ||
|
||
type WasmSnapshotter struct { | ||
wasm *Keeper | ||
cms sdk.MultiStore | ||
} | ||
|
||
func NewWasmSnapshotter(cms sdk.MultiStore, wasm *Keeper) *WasmSnapshotter { | ||
return &WasmSnapshotter{ | ||
wasm: wasm, | ||
cms: cms, | ||
} | ||
} | ||
|
||
func (ws *WasmSnapshotter) SnapshotName() string { | ||
return types.ModuleName | ||
} | ||
|
||
func (ws *WasmSnapshotter) SnapshotFormat() uint32 { | ||
return SnapshotFormat | ||
} | ||
|
||
func (ws *WasmSnapshotter) SupportedFormats() []uint32 { | ||
// If we support older formats, add them here and handle them in Restore | ||
return []uint32{SnapshotFormat} | ||
} | ||
|
||
func (ws *WasmSnapshotter) Snapshot(height uint64, protoWriter protoio.Writer) error { | ||
cacheMS, err := ws.cms.CacheMultiStoreWithVersion(int64(height)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ctx := sdk.NewContext(cacheMS, tmproto.Header{}, false, log.NewNopLogger()) | ||
seenBefore := make(map[string]bool) | ||
var rerr error | ||
|
||
ws.wasm.IterateCodeInfos(ctx, func(id uint64, info types.CodeInfo) bool { | ||
// Many code ids may point to the same code hash... only sync it once | ||
hexHash := hex.EncodeToString(info.CodeHash) | ||
// if seenBefore, just skip this one and move to the next | ||
if seenBefore[hexHash] { | ||
return false | ||
} | ||
seenBefore[hexHash] = true | ||
|
||
// load code and abort on error | ||
wasmBytes, err := ws.wasm.GetByteCode(ctx, id) | ||
if err != nil { | ||
rerr = err | ||
return true | ||
} | ||
|
||
compressedWasm, err := ioutils.GzipIt(wasmBytes) | ||
if err != nil { | ||
rerr = err | ||
return true | ||
} | ||
|
||
err = snapshot.WriteExtensionItem(protoWriter, compressedWasm) | ||
if err != nil { | ||
rerr = err | ||
return true | ||
} | ||
|
||
return false | ||
}) | ||
|
||
return rerr | ||
} | ||
|
||
func (ws *WasmSnapshotter) Restore( | ||
height uint64, format uint32, protoReader protoio.Reader, | ||
) (snapshot.SnapshotItem, error) { | ||
if format == SnapshotFormat { | ||
return ws.processAllItems(height, protoReader, restoreV1, finalizeV1) | ||
} | ||
return snapshot.SnapshotItem{}, snapshot.ErrUnknownFormat | ||
} | ||
|
||
func restoreV1(ctx sdk.Context, k *Keeper, compressedCode []byte) error { | ||
wasmCode, err := ioutils.Uncompress(compressedCode, k.GetMaxWasmCodeSize(ctx)) | ||
if err != nil { | ||
return sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) | ||
} | ||
|
||
// FIXME: check which codeIDs the checksum matches?? | ||
_, err = k.wasmVM.Create(wasmCode) | ||
if err != nil { | ||
return sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) | ||
} | ||
return nil | ||
} | ||
|
||
func finalizeV1(ctx sdk.Context, k *Keeper) error { | ||
// FIXME: ensure all codes have been uploaded? | ||
return k.InitializePinnedCodes(ctx) | ||
} | ||
|
||
func (ws *WasmSnapshotter) processAllItems( | ||
height uint64, | ||
protoReader protoio.Reader, | ||
cb func(sdk.Context, *Keeper, []byte) error, | ||
finalize func(sdk.Context, *Keeper) error, | ||
) (snapshot.SnapshotItem, error) { | ||
ctx := sdk.NewContext(ws.cms, tmproto.Header{Height: int64(height)}, false, log.NewNopLogger()) | ||
|
||
// keep the last item here... if we break, it will either be empty (if we hit io.EOF) | ||
// or contain the last item (if we hit payload == nil) | ||
var item snapshot.SnapshotItem | ||
for { | ||
item = snapshot.SnapshotItem{} | ||
err := protoReader.ReadMsg(&item) | ||
if err == io.EOF { | ||
break | ||
} else if err != nil { | ||
return snapshot.SnapshotItem{}, sdkerrors.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 { | ||
break | ||
} | ||
|
||
if err := cb(ctx, ws.wasm, payload.Payload); err != nil { | ||
return snapshot.SnapshotItem{}, sdkerrors.Wrap(err, "processing snapshot item") | ||
} | ||
} | ||
|
||
return item, finalize(ctx, ws.wasm) | ||
} | ||
// import ( | ||
// "encoding/hex" | ||
// "io" | ||
|
||
// snapshot "github.com/cosmos/cosmos-sdk/snapshots/types" | ||
// sdk "github.com/cosmos/cosmos-sdk/types" | ||
// sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | ||
// protoio "github.com/gogo/protobuf/io" | ||
// "github.com/tendermint/tendermint/libs/log" | ||
// tmproto "github.com/tendermint/tendermint/proto/tendermint/types" | ||
|
||
// "github.com/CosmWasm/wasmd/x/wasm/ioutils" | ||
// "github.com/CosmWasm/wasmd/x/wasm/types" | ||
// ) | ||
|
||
// var _ snapshot.ExtensionSnapshotter = &WasmSnapshotter{} | ||
|
||
// // SnapshotFormat format 1 is just gzipped wasm byte code for each item payload. No protobuf envelope, no metadata. | ||
// const SnapshotFormat = 1 | ||
|
||
// type WasmSnapshotter struct { | ||
// wasm *Keeper | ||
// cms sdk.MultiStore | ||
// } | ||
|
||
// func NewWasmSnapshotter(cms sdk.MultiStore, wasm *Keeper) *WasmSnapshotter { | ||
// return &WasmSnapshotter{ | ||
// wasm: wasm, | ||
// cms: cms, | ||
// } | ||
// } | ||
|
||
// func (ws *WasmSnapshotter) SnapshotName() string { | ||
// return types.ModuleName | ||
// } | ||
|
||
// func (ws *WasmSnapshotter) SnapshotFormat() uint32 { | ||
// return SnapshotFormat | ||
// } | ||
|
||
// func (ws *WasmSnapshotter) SupportedFormats() []uint32 { | ||
// // If we support older formats, add them here and handle them in Restore | ||
// return []uint32{SnapshotFormat} | ||
// } | ||
|
||
// func (ws *WasmSnapshotter) Snapshot(height uint64, protoWriter protoio.Writer) error { | ||
// cacheMS, err := ws.cms.CacheMultiStoreWithVersion(int64(height)) | ||
// if err != nil { | ||
// return err | ||
// } | ||
|
||
// ctx := sdk.NewContext(cacheMS, tmproto.Header{}, false, log.NewNopLogger()) | ||
// seenBefore := make(map[string]bool) | ||
// var rerr error | ||
|
||
// ws.wasm.IterateCodeInfos(ctx, func(id uint64, info types.CodeInfo) bool { | ||
// // Many code ids may point to the same code hash... only sync it once | ||
// hexHash := hex.EncodeToString(info.CodeHash) | ||
// // if seenBefore, just skip this one and move to the next | ||
// if seenBefore[hexHash] { | ||
// return false | ||
// } | ||
// seenBefore[hexHash] = true | ||
|
||
// // load code and abort on error | ||
// wasmBytes, err := ws.wasm.GetByteCode(ctx, id) | ||
// if err != nil { | ||
// rerr = err | ||
// return true | ||
// } | ||
|
||
// compressedWasm, err := ioutils.GzipIt(wasmBytes) | ||
// if err != nil { | ||
// rerr = err | ||
// return true | ||
// } | ||
|
||
// err = snapshot.WriteExtensionItem(protoWriter, compressedWasm) | ||
// if err != nil { | ||
// rerr = err | ||
// return true | ||
// } | ||
|
||
// return false | ||
// }) | ||
|
||
// return rerr | ||
// } | ||
|
||
// func (ws *WasmSnapshotter) Restore( | ||
// height uint64, format uint32, protoReader protoio.Reader, | ||
// ) (snapshot.SnapshotItem, error) { | ||
// if format == SnapshotFormat { | ||
// return ws.processAllItems(height, protoReader, restoreV1, finalizeV1) | ||
// } | ||
// return snapshot.SnapshotItem{}, snapshot.ErrUnknownFormat | ||
// } | ||
|
||
// func restoreV1(ctx sdk.Context, k *Keeper, compressedCode []byte) error { | ||
// wasmCode, err := ioutils.Uncompress(compressedCode, k.GetMaxWasmCodeSize(ctx)) | ||
// if err != nil { | ||
// return sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) | ||
// } | ||
|
||
// // FIXME: check which codeIDs the checksum matches?? | ||
// _, err = k.wasmVM.Create(wasmCode) | ||
// if err != nil { | ||
// return sdkerrors.Wrap(types.ErrCreateFailed, err.Error()) | ||
// } | ||
// return nil | ||
// } | ||
|
||
// func finalizeV1(ctx sdk.Context, k *Keeper) error { | ||
// // FIXME: ensure all codes have been uploaded? | ||
// return k.InitializePinnedCodes(ctx) | ||
// } | ||
|
||
// func (ws *WasmSnapshotter) processAllItems( | ||
// height uint64, | ||
// protoReader protoio.Reader, | ||
// cb func(sdk.Context, *Keeper, []byte) error, | ||
// finalize func(sdk.Context, *Keeper) error, | ||
// ) (snapshot.SnapshotItem, error) { | ||
// ctx := sdk.NewContext(ws.cms, tmproto.Header{Height: int64(height)}, false, log.NewNopLogger()) | ||
|
||
// // keep the last item here... if we break, it will either be empty (if we hit io.EOF) | ||
// // or contain the last item (if we hit payload == nil) | ||
// var item snapshot.SnapshotItem | ||
// for { | ||
// item = snapshot.SnapshotItem{} | ||
// err := protoReader.ReadMsg(&item) | ||
// if err == io.EOF { | ||
// break | ||
// } else if err != nil { | ||
// return snapshot.SnapshotItem{}, sdkerrors.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 { | ||
// break | ||
// } | ||
|
||
// if err := cb(ctx, ws.wasm, payload.Payload); err != nil { | ||
// return snapshot.SnapshotItem{}, sdkerrors.Wrap(err, "processing snapshot item") | ||
// } | ||
// } | ||
|
||
// return item, finalize(ctx, ws.wasm) | ||
// } |
Oops, something went wrong.