From c6bf0e26cdcc4ecd78ba2bdbe7a29463d52da36a Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Wed, 26 Aug 2020 13:28:59 -0600 Subject: [PATCH] fix: use and export x/swingset/storage for all on-chain storage --- packages/cosmic-swingset/lib/launch-chain.js | 2 +- .../cosmic-swingset/x/swingset/genesis.go | 60 +++------------- .../x/swingset/internal/keeper/keeper.go | 69 +++++++++---------- 3 files changed, 41 insertions(+), 90 deletions(-) diff --git a/packages/cosmic-swingset/lib/launch-chain.js b/packages/cosmic-swingset/lib/launch-chain.js index d761017b8e1..a671b0e5642 100644 --- a/packages/cosmic-swingset/lib/launch-chain.js +++ b/packages/cosmic-swingset/lib/launch-chain.js @@ -142,7 +142,7 @@ export async function launch( } const [savedHeight, savedActions] = JSON.parse( - storage.get(SWING_STORE_META_KEY) || '[-1, []]', + storage.get(SWING_STORE_META_KEY) || '[0, []]', ); return { deliverInbound, diff --git a/packages/cosmic-swingset/x/swingset/genesis.go b/packages/cosmic-swingset/x/swingset/genesis.go index c90ec1b44a4..37375833527 100644 --- a/packages/cosmic-swingset/x/swingset/genesis.go +++ b/packages/cosmic-swingset/x/swingset/genesis.go @@ -3,84 +3,42 @@ package swingset import ( // "fmt" - "encoding/json" - "fmt" - "github.com/Agoric/agoric-sdk/packages/cosmic-swingset/x/swingset/internal/types" sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/tendermint/abci/types" ) type GenesisState struct { - // TODO: Provisioning records - Egresses []types.Egress `json:"egresses"` + Storage map[string]string `json:"storage"` } func NewGenesisState() GenesisState { return GenesisState{ - Egresses: []types.Egress{}, + Storage: make(map[string]string), } } func ValidateGenesis(data GenesisState) error { - for _, egress := range data.Egresses { - if egress.Peer.Empty() { - return fmt.Errorf("empty peer for egress nicknamed %s", egress.Nickname) - } - } return nil } func DefaultGenesisState() GenesisState { return GenesisState{ - Egresses: []types.Egress{}, + Storage: make(map[string]string), } } func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) []abci.ValidatorUpdate { - for _, egress := range data.Egresses { - msg := MsgProvision{ - Address: egress.Peer, - Nickname: egress.Nickname, - PowerFlags: egress.PowerFlags, - } - action := &provisionAction{ - MsgProvision: msg, - Type: "PLEASE_PROVISION", - BlockHeight: ctx.BlockHeight(), - BlockTime: ctx.BlockTime().Unix(), - } - - // fmt.Fprintf(os.Stderr, "Context is %+v\n", ctx) - b, err := json.Marshal(action) - if err != nil { - continue - } - - // Reproduce the egress in our state. - egress := types.NewEgress(msg.Nickname, msg.Address, msg.PowerFlags) - err = keeper.SetEgress(ctx, egress) - if err != nil { - panic(err) - } - - _, err = keeper.CallToController(ctx, string(b)) - // fmt.Fprintln(os.Stderr, "Returned from SwingSet", out, err) - if err != nil { - panic(err) - } - } - // Flush the genesis transactions. - valup, err := EndBlock(ctx, abci.RequestEndBlock{}, keeper) - if err != nil { - panic(err) + var storage types.Storage + for key, value := range data.Storage { + storage.Value = value + keeper.SetStorage(ctx, key, storage) } - return valup + return []abci.ValidatorUpdate{} } func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState { - // TODO: Preserve the SwingSet transcript gs := NewGenesisState() - gs.Egresses = k.ExportEgresses(ctx) + gs.Storage = k.ExportStorage(ctx) return gs } diff --git a/packages/cosmic-swingset/x/swingset/internal/keeper/keeper.go b/packages/cosmic-swingset/x/swingset/internal/keeper/keeper.go index 3988e3f1b10..5dfd44ffe8b 100644 --- a/packages/cosmic-swingset/x/swingset/internal/keeper/keeper.go +++ b/packages/cosmic-swingset/x/swingset/internal/keeper/keeper.go @@ -1,6 +1,7 @@ package keeper import ( + "encoding/json" "fmt" "sort" "strings" @@ -62,41 +63,43 @@ func (k Keeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) s return k.bankKeeper.GetBalance(ctx, addr, denom) } +// GetEgress gets the entire egress struct for a peer func (k Keeper) GetEgress(ctx sdk.Context, addr sdk.AccAddress) types.Egress { - store := ctx.KVStore(k.storeKey) - - egressStore := prefix.NewStore(store, types.EgressPrefix) - - addrBytes := addr.Bytes() - if !egressStore.Has(addrBytes) { + path := "egress." + addr.String() + storage := k.GetStorage(ctx, path) + if storage.Value == "" { return types.Egress{} } - bz := egressStore.Get(addrBytes) var egress types.Egress - k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &egress) + err := json.Unmarshal([]byte(storage.Value), &egress) + if err != nil { + panic(err) + } + return egress } +// SetEgress sets the egress struct for a peer, and ensures its account exists func (k Keeper) SetEgress(ctx sdk.Context, egress types.Egress) error { - store := ctx.KVStore(k.storeKey) + path := "egress." + egress.Peer.String() - egressStore := prefix.NewStore(store, types.EgressPrefix) - - addr := egress.Peer - addrBytes := addr.Bytes() + json, err := json.Marshal(egress) + if err != nil { + return err + } - // Make note that this egress exists. - egressStore.Set(addrBytes, k.cdc.MustMarshalBinaryLengthPrefixed(egress)) + storage := types.Storage{string(json)} + k.SetStorage(ctx, path, storage) // Now make sure the corresponding account has been initialised. - if acc := k.accountKeeper.GetAccount(ctx, addr); acc != nil { + if acc := k.accountKeeper.GetAccount(ctx, egress.Peer); acc != nil { // Account already exists. return nil } // Create an account object with the specified address. - acc := k.accountKeeper.NewAccountWithAddress(ctx, addr) + acc := k.accountKeeper.NewAccountWithAddress(ctx, egress.Peer) // Store it in the keeper (panics on error). k.accountKeeper.SetAccount(ctx, acc) @@ -105,21 +108,21 @@ func (k Keeper) SetEgress(ctx sdk.Context, egress types.Egress) error { return nil } -// ExportEgresses fetches all egresses -func (k Keeper) ExportEgresses(ctx sdk.Context) []types.Egress { +// ExportStorage fetches all storage +func (k Keeper) ExportStorage(ctx sdk.Context) map[string]string { store := ctx.KVStore(k.storeKey) - egressStore := prefix.NewStore(store, types.EgressPrefix) - egresses := []types.Egress{} + dataStore := prefix.NewStore(store, types.DataPrefix) - iterator := sdk.KVStorePrefixIterator(egressStore, nil) + iterator := sdk.KVStorePrefixIterator(dataStore, nil) + exported := make(map[string]string) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { - var egress types.Egress - k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &egress) - egresses = append(egresses, egress) + var storage types.Storage + k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &storage) + exported[string(iterator.Key())] = storage.Value } - return egresses + return exported } // GetStorage gets generic storage @@ -204,24 +207,14 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetMailbox gets the entire mailbox struct for a peer func (k Keeper) GetMailbox(ctx sdk.Context, peer string) types.Storage { - store := ctx.KVStore(k.storeKey) - dataStore := prefix.NewStore(store, types.DataPrefix) path := "mailbox." + peer - if !dataStore.Has([]byte(path)) { - return types.NewMailbox() - } - bz := dataStore.Get([]byte(path)) - var mailbox types.Storage - k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &mailbox) - return mailbox + return k.GetStorage(ctx, path) } // SetMailbox sets the entire mailbox struct for a peer func (k Keeper) SetMailbox(ctx sdk.Context, peer string, mailbox types.Storage) { - store := ctx.KVStore(k.storeKey) - dataStore := prefix.NewStore(store, types.DataPrefix) path := "mailbox." + peer - dataStore.Set([]byte(path), k.cdc.MustMarshalBinaryLengthPrefixed(mailbox)) + k.SetStorage(ctx, path, mailbox) } // GetPeersIterator works over all peers in which the keys are the peers and the values are the mailbox