Skip to content

Commit

Permalink
fix: use and export x/swingset/storage for all on-chain storage
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Aug 26, 2020
1 parent 9a3d54b commit c6bf0e2
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 90 deletions.
2 changes: 1 addition & 1 deletion packages/cosmic-swingset/lib/launch-chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
60 changes: 9 additions & 51 deletions packages/cosmic-swingset/x/swingset/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
69 changes: 31 additions & 38 deletions packages/cosmic-swingset/x/swingset/internal/keeper/keeper.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
"encoding/json"
"fmt"
"sort"
"strings"
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit c6bf0e2

Please sign in to comment.