diff --git a/a3p-integration/proposals/z:acceptance/genesis-test.sh b/a3p-integration/proposals/z:acceptance/genesis-test.sh new file mode 100755 index 00000000000..b2262e404cf --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/genesis-test.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +source /usr/src/upgrade-test-scripts/env_setup.sh + +export_genesis() { + GENESIS_EXPORT_DIR="$1" + shift + GENESIS_HEIGHT_ARG= + + if [ -n "$1" ]; then + GENESIS_HEIGHT_ARG="--height $1" + shift + fi + + agd export --export-dir "$GENESIS_EXPORT_DIR" $GENESIS_HEIGHT_ARG "$@" +} + +killAgd +FORK_TEST_DIR="$(mktemp -t -d fork-test-XXX)" +mkdir -p "$FORK_TEST_DIR/config" +cp /root/.agoric/config/priv_validator_key.json "$FORK_TEST_DIR/config" +agd --home "$FORK_TEST_DIR" tendermint unsafe-reset-all + +export_genesis "$FORK_TEST_DIR/config" +startAgd --home "$FORK_TEST_DIR" diff --git a/a3p-integration/proposals/z:acceptance/test.sh b/a3p-integration/proposals/z:acceptance/test.sh index 0447826a85d..7e4b0145a04 100755 --- a/a3p-integration/proposals/z:acceptance/test.sh +++ b/a3p-integration/proposals/z:acceptance/test.sh @@ -13,3 +13,4 @@ yarn ava ./*.test.js ./create-kread-item-test.sh ./state-sync-snapshots-test.sh +./genesis-test.sh diff --git a/golang/cosmos/proto/agoric/swingset/genesis.proto b/golang/cosmos/proto/agoric/swingset/genesis.proto index 8a178e4e12e..d725acd5238 100644 --- a/golang/cosmos/proto/agoric/swingset/genesis.proto +++ b/golang/cosmos/proto/agoric/swingset/genesis.proto @@ -17,6 +17,10 @@ message GenesisState { repeated SwingStoreExportDataEntry swing_store_export_data = 4 [ (gogoproto.jsontag) = "swingStoreExportData" ]; + + string swing_store_export_data_hash = 5 [ + (gogoproto.jsontag) = "swingStoreExportDataHash" + ]; } // A SwingStore "export data" entry. diff --git a/golang/cosmos/types/kv_entry_helpers.go b/golang/cosmos/types/kv_entry_helpers.go index 7ee16de189a..3a1ac0ceaf2 100644 --- a/golang/cosmos/types/kv_entry_helpers.go +++ b/golang/cosmos/types/kv_entry_helpers.go @@ -232,3 +232,45 @@ func EncodeKVEntryReaderToJsonl(reader KVEntryReader, bytesWriter io.Writer) (er } } } + +var _ KVEntryReader = &kvHookingReader{} + +// kvHookingReader is a KVEntryReader backed by another KVEntryReader which +// provides callbacks for read and close +type kvHookingReader struct { + reader KVEntryReader + onRead func(entry KVEntry) error + onClose func() error +} + +// NewKVHookingReader returns a KVEntryReader backed by another KVEntryReader +func NewKVHookingReader(reader KVEntryReader, onRead func(entry KVEntry) error, onClose func() error) KVEntryReader { + return &kvHookingReader{ + reader, + onRead, + onClose, + } +} + +// Read yields the next KVEntry from the source reader +// Implements KVEntryReader +func (hr kvHookingReader) Read() (next KVEntry, err error) { + next, err = hr.reader.Read() + + if err == nil { + err = hr.onRead(next) + } + + return next, err +} + +// Close releases the underlying source reader +// Implements KVEntryReader +func (hr kvHookingReader) Close() error { + err := hr.reader.Close() + if err == nil { + err = hr.onClose() + } + + return err +} diff --git a/golang/cosmos/x/swingset/genesis.go b/golang/cosmos/x/swingset/genesis.go index 4d3d17528a7..56c6e06e5ba 100644 --- a/golang/cosmos/x/swingset/genesis.go +++ b/golang/cosmos/x/swingset/genesis.go @@ -2,7 +2,13 @@ package swingset import ( // "os" + "bytes" + "crypto/sha256" + "encoding/hex" + "encoding/json" "fmt" + "hash" + "strings" agoric "github.com/Agoric/agoric-sdk/golang/cosmos/types" "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper" @@ -35,8 +41,10 @@ func InitGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingStore k.SetState(ctx, data.GetState()) swingStoreExportData := data.GetSwingStoreExportData() - if len(swingStoreExportData) == 0 { + if len(swingStoreExportData) == 0 && data.SwingStoreExportDataHash == "" { return true + } else if data.SwingStoreExportDataHash != "" && len(swingStoreExportData) > 0 { + panic("Swingset genesis state cannot have both export data and hash of export data") } artifactProvider, err := keeper.OpenSwingStoreExportDirectory(swingStoreExportDir) @@ -46,15 +54,62 @@ func InitGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingStore swingStore := k.GetSwingStore(ctx) - for _, entry := range swingStoreExportData { - swingStore.Set([]byte(entry.Key), []byte(entry.Value)) - } - snapshotHeight := uint64(ctx.BlockHeight()) - getExportDataReader := func() (agoric.KVEntryReader, error) { - exportDataIterator := swingStore.Iterator(nil, nil) - return agoric.NewKVIteratorReader(exportDataIterator), nil + var getExportDataReader func() (agoric.KVEntryReader, error) + + if len(swingStoreExportData) > 0 { + for _, entry := range swingStoreExportData { + swingStore.Set([]byte(entry.Key), []byte(entry.Value)) + } + getExportDataReader = func() (agoric.KVEntryReader, error) { + exportDataIterator := swingStore.Iterator(nil, nil) + return agoric.NewKVIteratorReader(exportDataIterator), nil + } + } else { + hashParts := strings.SplitN(data.SwingStoreExportDataHash, ":", 2) + if len(hashParts) != 2 { + panic(fmt.Errorf("invalid swing-store export data hash %s", data.SwingStoreExportDataHash)) + } + if hashParts[0] != "sha256" { + panic(fmt.Errorf("invalid swing-store export data hash algorithm %s, expected sha256", hashParts[0])) + } + sha256Hash, err := hex.DecodeString(hashParts[1]) + if err != nil { + panic(err) + } + getExportDataReader = func() (agoric.KVEntryReader, error) { + kvReader, err := artifactProvider.GetExportDataReader() + if err != nil { + return nil, err + } + + if kvReader == nil { + return nil, fmt.Errorf("swing-store export has no export data") + } + + hasher := sha256.New() + encoder := json.NewEncoder(hasher) + encoder.SetEscapeHTML(false) + + return agoric.NewKVHookingReader(kvReader, func(entry agoric.KVEntry) error { + key := []byte(entry.Key()) + + if !entry.HasValue() { + swingStore.Delete(key) + } else { + swingStore.Set(key, []byte(entry.StringValue())) + } + + return encoder.Encode(entry) + }, func() error { + sum := hasher.Sum(nil) + if !bytes.Equal(sum, sha256Hash) { + return fmt.Errorf("swing-store data sha256sum didn't match. expected %x, got %x", sha256Hash, sum) + } + return nil + }), nil + } } err = swingStoreExportsHandler.RestoreExport( @@ -79,25 +134,17 @@ func ExportGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingSto gs := &types.GenesisState{ Params: k.GetParams(ctx), State: k.GetState(ctx), - SwingStoreExportData: []*types.SwingStoreExportDataEntry{}, - } - - exportDataIterator := k.GetSwingStore(ctx).Iterator(nil, nil) - defer exportDataIterator.Close() - for ; exportDataIterator.Valid(); exportDataIterator.Next() { - entry := types.SwingStoreExportDataEntry{ - Key: string(exportDataIterator.Key()), - Value: string(exportDataIterator.Value()), - } - gs.SwingStoreExportData = append(gs.SwingStoreExportData, &entry) + SwingStoreExportData: nil, } snapshotHeight := uint64(ctx.BlockHeight()) + eventHandler := swingStoreGenesisEventHandler{exportDir: swingStoreExportDir, snapshotHeight: snapshotHeight, swingStore: k.GetSwingStore(ctx), hasher: sha256.New()} + err := swingStoreExportsHandler.InitiateExport( // The export will fail if the export of a historical height was requested snapshotHeight, - swingStoreGenesisEventHandler{exportDir: swingStoreExportDir, snapshotHeight: snapshotHeight}, + eventHandler, keeper.SwingStoreExportOptions{ ArtifactMode: keeper.SwingStoreArtifactModeOperational, ExportDataMode: keeper.SwingStoreExportDataModeSkip, @@ -112,12 +159,16 @@ func ExportGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingSto panic(err) } + gs.SwingStoreExportDataHash = fmt.Sprintf("sha256:%x", eventHandler.hasher.Sum(nil)) + return gs } type swingStoreGenesisEventHandler struct { exportDir string snapshotHeight uint64 + swingStore sdk.KVStore + hasher hash.Hash } func (eventHandler swingStoreGenesisEventHandler) OnExportStarted(height uint64, retrieveSwingStoreExport func() error) error { @@ -131,7 +182,17 @@ func (eventHandler swingStoreGenesisEventHandler) OnExportRetrieved(provider kee artifactsProvider := keeper.SwingStoreExportProvider{ GetExportDataReader: func() (agoric.KVEntryReader, error) { - return nil, nil + exportDataIterator := eventHandler.swingStore.Iterator(nil, nil) + kvReader := agoric.NewKVIteratorReader(exportDataIterator) + eventHandler.hasher.Reset() + encoder := json.NewEncoder(eventHandler.hasher) + encoder.SetEscapeHTML(false) + + return agoric.NewKVHookingReader(kvReader, func(entry agoric.KVEntry) error { + return encoder.Encode(entry) + }, func() error { + return nil + }), nil }, ReadNextArtifact: provider.ReadNextArtifact, } diff --git a/golang/cosmos/x/swingset/keeper/swing_store_exports_handler.go b/golang/cosmos/x/swingset/keeper/swing_store_exports_handler.go index 4ca69b25656..0a1fe798f27 100644 --- a/golang/cosmos/x/swingset/keeper/swing_store_exports_handler.go +++ b/golang/cosmos/x/swingset/keeper/swing_store_exports_handler.go @@ -787,7 +787,18 @@ func (exportsHandler SwingStoreExportsHandler) RestoreExport(provider SwingStore // a jsonl-like file, before saving the export manifest linking these together. // The export manifest filename and overall export format is common with the JS // swing-store import/export logic. -func WriteSwingStoreExportToDirectory(provider SwingStoreExportProvider, exportDir string) error { +func WriteSwingStoreExportToDirectory(provider SwingStoreExportProvider, exportDir string) (err error) { + handleDeferError := func(fn func() error) { + deferError := fn() + if err == nil { + err = deferError + } else if deferError != nil { + // Safe to wrap error and use detailed error info since this error + // will not go back into swingset layers + err = sdkioerrors.Wrapf(err, "deferred error %+v", deferError) + } + } + manifest := exportManifest{ BlockHeight: provider.BlockHeight, } @@ -798,14 +809,14 @@ func WriteSwingStoreExportToDirectory(provider SwingStoreExportProvider, exportD } if exportDataReader != nil { - defer exportDataReader.Close() + defer handleDeferError(exportDataReader.Close) manifest.Data = exportDataFilename exportDataFile, err := os.OpenFile(filepath.Join(exportDir, exportDataFilename), os.O_CREATE|os.O_WRONLY, exportedFilesMode) if err != nil { return err } - defer exportDataFile.Close() + defer handleDeferError(exportDataFile.Close) err = agoric.EncodeKVEntryReaderToJsonl(exportDataReader, exportDataFile) if err != nil { diff --git a/golang/cosmos/x/swingset/types/genesis.pb.go b/golang/cosmos/x/swingset/types/genesis.pb.go index 47d94b1e51f..6dc92574c50 100644 --- a/golang/cosmos/x/swingset/types/genesis.pb.go +++ b/golang/cosmos/x/swingset/types/genesis.pb.go @@ -25,9 +25,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // The initial or exported state. type GenesisState struct { - Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` - State State `protobuf:"bytes,3,opt,name=state,proto3" json:"state"` - SwingStoreExportData []*SwingStoreExportDataEntry `protobuf:"bytes,4,rep,name=swing_store_export_data,json=swingStoreExportData,proto3" json:"swingStoreExportData"` + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` + State State `protobuf:"bytes,3,opt,name=state,proto3" json:"state"` + SwingStoreExportData []*SwingStoreExportDataEntry `protobuf:"bytes,4,rep,name=swing_store_export_data,json=swingStoreExportData,proto3" json:"swingStoreExportData"` + SwingStoreExportDataHash string `protobuf:"bytes,5,opt,name=swing_store_export_data_hash,json=swingStoreExportDataHash,proto3" json:"swingStoreExportDataHash"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -84,6 +85,13 @@ func (m *GenesisState) GetSwingStoreExportData() []*SwingStoreExportDataEntry { return nil } +func (m *GenesisState) GetSwingStoreExportDataHash() string { + if m != nil { + return m.SwingStoreExportDataHash + } + return "" +} + // A SwingStore "export data" entry. type SwingStoreExportDataEntry struct { Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -145,28 +153,30 @@ func init() { func init() { proto.RegisterFile("agoric/swingset/genesis.proto", fileDescriptor_49b057311de9d296) } var fileDescriptor_49b057311de9d296 = []byte{ - // 334 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xcf, 0x4b, 0x02, 0x41, - 0x1c, 0xc5, 0x77, 0xf2, 0x07, 0x38, 0x06, 0xc5, 0x22, 0xb9, 0x09, 0x8d, 0xe2, 0x49, 0x82, 0x76, - 0xc0, 0xe8, 0x52, 0xa7, 0x2c, 0xe9, 0x1a, 0x2b, 0x5d, 0xba, 0xc8, 0xa8, 0xc3, 0xb4, 0xa8, 0x3b, - 0xcb, 0x7c, 0xc7, 0x52, 0xfa, 0x27, 0xfa, 0x13, 0xfa, 0x73, 0x3c, 0x7a, 0xec, 0x24, 0xa1, 0x97, - 0xe8, 0x6f, 0xe8, 0x10, 0x3b, 0xa3, 0x04, 0x6a, 0xb7, 0xb7, 0xfb, 0x79, 0xef, 0x0d, 0x33, 0x0f, - 0x9f, 0x30, 0x21, 0x55, 0xd8, 0xa5, 0xf0, 0x12, 0x46, 0x02, 0xb8, 0xa6, 0x82, 0x47, 0x1c, 0x42, - 0xf0, 0x63, 0x25, 0xb5, 0x74, 0x0f, 0x2c, 0xf6, 0xd7, 0xb8, 0x54, 0x10, 0x52, 0x48, 0xc3, 0x68, - 0xa2, 0xac, 0xad, 0x44, 0x36, 0x5b, 0xd6, 0xc2, 0xf2, 0xea, 0x0f, 0xc2, 0xfb, 0x77, 0xb6, 0xb8, - 0xa5, 0x99, 0xe6, 0xee, 0x05, 0xce, 0xc6, 0x4c, 0xb1, 0x21, 0x78, 0x7b, 0x15, 0x54, 0xcb, 0xd7, - 0x8b, 0xfe, 0xc6, 0x41, 0xfe, 0xbd, 0xc1, 0x8d, 0xf4, 0x74, 0x5e, 0x76, 0x82, 0x95, 0xd9, 0xad, - 0xe3, 0x0c, 0x24, 0x79, 0x2f, 0x65, 0x52, 0x47, 0x5b, 0x29, 0xd3, 0xbe, 0x0a, 0x59, 0xab, 0xfb, - 0x8a, 0x8b, 0x06, 0xb7, 0x41, 0x4b, 0xc5, 0xdb, 0x7c, 0x1c, 0x4b, 0xa5, 0xdb, 0x3d, 0xa6, 0x99, - 0x97, 0xae, 0xa4, 0x6a, 0xf9, 0xfa, 0xe9, 0x76, 0x4b, 0x22, 0x5a, 0x89, 0xbd, 0x69, 0xdc, 0xb7, - 0x4c, 0xb3, 0x66, 0xa4, 0xd5, 0xa4, 0xe1, 0x7d, 0xcf, 0xcb, 0x05, 0xd8, 0x81, 0x83, 0x9d, 0x7f, - 0x2f, 0xd3, 0x5f, 0xef, 0x65, 0xa7, 0x7a, 0x83, 0x8f, 0xff, 0xad, 0x74, 0x0f, 0x71, 0xaa, 0xcf, - 0x27, 0x1e, 0xaa, 0xa0, 0x5a, 0x2e, 0x48, 0xa4, 0x5b, 0xc0, 0x99, 0x67, 0x36, 0x18, 0x71, 0xf3, - 0x36, 0xb9, 0xc0, 0x7e, 0x34, 0x1e, 0xa6, 0x0b, 0x82, 0x66, 0x0b, 0x82, 0x3e, 0x17, 0x04, 0xbd, - 0x2d, 0x89, 0x33, 0x5b, 0x12, 0xe7, 0x63, 0x49, 0x9c, 0xc7, 0x2b, 0x11, 0xea, 0xa7, 0x51, 0xc7, - 0xef, 0xca, 0x21, 0xbd, 0xb6, 0x43, 0xd8, 0x1b, 0x9d, 0x41, 0xaf, 0x4f, 0x85, 0x1c, 0xb0, 0x48, - 0xd0, 0xae, 0x84, 0xa1, 0x04, 0x3a, 0xfe, 0xdb, 0x48, 0x4f, 0x62, 0x0e, 0x9d, 0xac, 0x59, 0xe8, - 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0x94, 0xe9, 0x22, 0x36, 0x09, 0x02, 0x00, 0x00, + // 363 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xcd, 0x4a, 0xc3, 0x40, + 0x14, 0x85, 0x93, 0xfe, 0x41, 0xa7, 0x82, 0x12, 0x8a, 0x8d, 0xa5, 0x26, 0xa5, 0xab, 0x22, 0x98, + 0x40, 0xc5, 0x8d, 0xae, 0x8c, 0x16, 0x5d, 0x4a, 0x8a, 0x1b, 0x11, 0xc2, 0xb4, 0x1d, 0x26, 0xa1, + 0x6d, 0x26, 0xe4, 0x4e, 0xb5, 0xc5, 0x97, 0xf0, 0x11, 0x7c, 0x9c, 0x2e, 0xbb, 0x14, 0x17, 0x45, + 0xda, 0x8d, 0xf4, 0x29, 0x24, 0x33, 0x2d, 0x42, 0x7f, 0x76, 0x27, 0xf9, 0xce, 0x39, 0x37, 0xdc, + 0x1b, 0x74, 0x8a, 0x29, 0x8b, 0x83, 0x8e, 0x0d, 0x6f, 0x41, 0x48, 0x81, 0x70, 0x9b, 0x92, 0x90, + 0x40, 0x00, 0x56, 0x14, 0x33, 0xce, 0xb4, 0x43, 0x89, 0xad, 0x35, 0x2e, 0x17, 0x29, 0xa3, 0x4c, + 0x30, 0x3b, 0x51, 0xd2, 0x56, 0x36, 0x36, 0x5b, 0xd6, 0x42, 0xf2, 0xda, 0x77, 0x0a, 0x1d, 0xdc, + 0xcb, 0xe2, 0x16, 0xc7, 0x9c, 0x68, 0x97, 0x28, 0x17, 0xe1, 0x18, 0x0f, 0x40, 0x4f, 0x55, 0xd5, + 0x7a, 0xa1, 0x51, 0xb2, 0x36, 0x06, 0x59, 0x8f, 0x02, 0x3b, 0x99, 0xc9, 0xcc, 0x54, 0xdc, 0x95, + 0x59, 0x6b, 0xa0, 0x2c, 0x24, 0x79, 0x3d, 0x2d, 0x52, 0xc7, 0x5b, 0x29, 0xd1, 0xbe, 0x0a, 0x49, + 0xab, 0xf6, 0x8e, 0x4a, 0x02, 0x7b, 0xc0, 0x59, 0x4c, 0x3c, 0x32, 0x8a, 0x58, 0xcc, 0xbd, 0x2e, + 0xe6, 0x58, 0xcf, 0x54, 0xd3, 0xf5, 0x42, 0xe3, 0x6c, 0xbb, 0x25, 0x11, 0xad, 0xc4, 0xde, 0x14, + 0xee, 0x3b, 0xcc, 0x71, 0x33, 0xe4, 0xf1, 0xd8, 0xd1, 0x97, 0x33, 0xb3, 0x08, 0x3b, 0xb0, 0xbb, + 0xf3, 0xad, 0xf6, 0x82, 0x2a, 0x7b, 0x86, 0x7b, 0x3e, 0x06, 0x5f, 0xcf, 0x56, 0xd5, 0x7a, 0xde, + 0xa9, 0x2c, 0x67, 0xa6, 0xbe, 0x2b, 0xff, 0x80, 0xc1, 0x77, 0xf7, 0x92, 0xab, 0xcc, 0xef, 0xa7, + 0xa9, 0xd4, 0x6e, 0xd1, 0xc9, 0xde, 0x0f, 0xd6, 0x8e, 0x50, 0xba, 0x47, 0xc6, 0xba, 0x9a, 0xcc, + 0x71, 0x13, 0xa9, 0x15, 0x51, 0xf6, 0x15, 0xf7, 0x87, 0x44, 0x6c, 0x3e, 0xef, 0xca, 0x07, 0xe7, + 0x69, 0x32, 0x37, 0xd4, 0xe9, 0xdc, 0x50, 0x7f, 0xe6, 0x86, 0xfa, 0xb1, 0x30, 0x94, 0xe9, 0xc2, + 0x50, 0xbe, 0x16, 0x86, 0xf2, 0x7c, 0x4d, 0x03, 0xee, 0x0f, 0xdb, 0x56, 0x87, 0x0d, 0xec, 0x1b, + 0x79, 0x66, 0xb9, 0xaf, 0x73, 0xe8, 0xf6, 0x6c, 0xca, 0xfa, 0x38, 0xa4, 0x76, 0x87, 0xc1, 0x80, + 0x81, 0x3d, 0xfa, 0xff, 0x03, 0xf8, 0x38, 0x22, 0xd0, 0xce, 0x89, 0xfb, 0x5f, 0xfc, 0x05, 0x00, + 0x00, 0xff, 0xff, 0x1b, 0x95, 0x41, 0xea, 0x67, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -189,6 +199,13 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.SwingStoreExportDataHash) > 0 { + i -= len(m.SwingStoreExportDataHash) + copy(dAtA[i:], m.SwingStoreExportDataHash) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.SwingStoreExportDataHash))) + i-- + dAtA[i] = 0x2a + } if len(m.SwingStoreExportData) > 0 { for iNdEx := len(m.SwingStoreExportData) - 1; iNdEx >= 0; iNdEx-- { { @@ -290,6 +307,10 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + l = len(m.SwingStoreExportDataHash) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -445,6 +466,38 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SwingStoreExportDataHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SwingStoreExportDataHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:])