@agoric/cosmos 0.35.0-u12.0 → 0.35.0-upgrade-14-dev-1eb5b91.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/cosmos",
3
- "version": "0.35.0-u12.0",
3
+ "version": "0.35.0-upgrade-14-dev-1eb5b91.0+1eb5b91",
4
4
  "description": "Connect JS to the Cosmos blockchain SDK",
5
5
  "parsers": {
6
6
  "js": "mjs"
@@ -35,5 +35,5 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
- "gitHead": "ee5a5fdad9187a6b1b7b26b772b6564c0db3062e"
38
+ "gitHead": "1eb5b91cd8b085f1e62b1eb84fdebf72e4a3fbd9"
39
39
  }
package/vm/action.go ADDED
@@ -0,0 +1,130 @@
1
+ package vm
2
+
3
+ import (
4
+ "reflect"
5
+ "strconv"
6
+ "time"
7
+
8
+ sdk "github.com/cosmos/cosmos-sdk/types"
9
+ )
10
+
11
+ var (
12
+ zeroTime = time.Time{}
13
+ actionHeaderType = reflect.TypeOf(ActionHeader{})
14
+ _ Action = &ActionHeader{}
15
+ )
16
+
17
+ // Jsonable is a value, j, that can be passed through json.Marshal(j).
18
+ type Jsonable interface{}
19
+
20
+ type Action interface {
21
+ GetActionHeader() ActionHeader
22
+ }
23
+
24
+ // ActionPusher enqueues data for later consumption by the controller.
25
+ type ActionPusher func(ctx sdk.Context, action Action) error
26
+
27
+ // ActionHeader should be embedded in all actions. It is populated by PopulateAction.
28
+ type ActionHeader struct {
29
+ // Type defaults to the `actionType:"..."` tag of the embedder's ActionHeader field.
30
+ Type string `json:"type"`
31
+ // BlockHeight defaults to sdk.Context.BlockHeight().
32
+ BlockHeight int64 `json:"blockHeight,omitempty"`
33
+ // BlockTime defaults to sdk.Context.BlockTime().Unix().
34
+ BlockTime int64 `json:"blockTime,omitempty"`
35
+ }
36
+
37
+ func (ah ActionHeader) GetActionHeader() ActionHeader {
38
+ return ah
39
+ }
40
+
41
+ // SetActionHeaderFromContext provides defaults to an ActionHeader.
42
+ func SetActionHeaderFromContext(ctx sdk.Context, actionType string, ah *ActionHeader) {
43
+ // Default the action type.
44
+ if len(ah.Type) == 0 {
45
+ ah.Type = actionType
46
+ }
47
+
48
+ // Default the block height.
49
+ if ah.BlockHeight == 0 {
50
+ ah.BlockHeight = ctx.BlockHeight()
51
+ }
52
+
53
+ if ah.BlockTime == 0 {
54
+ // Only default to a non-zero block time.
55
+ if blockTime := ctx.BlockTime(); blockTime != zeroTime {
56
+ ah.BlockTime = blockTime.Unix()
57
+ }
58
+ }
59
+ }
60
+
61
+ // PopulateAction interprets `default:"..."` tags and specially handles an
62
+ // embedded ActionHeader struct.
63
+ func PopulateAction(ctx sdk.Context, action Action) Action {
64
+ oldRv := reflect.Indirect(reflect.ValueOf(action))
65
+ if oldRv.Kind() != reflect.Struct {
66
+ return action
67
+ }
68
+
69
+ // Shallow copy to a new value.
70
+ rp := reflect.New(oldRv.Type())
71
+ rv := reflect.Indirect(rp)
72
+ for i := 0; i < rv.NumField(); i++ {
73
+ oldField := oldRv.Field(i)
74
+ field := rv.Field(i)
75
+ fieldType := rv.Type().Field(i)
76
+ if !field.CanSet() {
77
+ continue
78
+ }
79
+
80
+ // Copy from original.
81
+ field.Set(oldField)
82
+
83
+ // Populate any ActionHeader struct.
84
+ var ahp *ActionHeader
85
+ if fieldType.Type == actionHeaderType {
86
+ ahp = field.Addr().Interface().(*ActionHeader)
87
+ } else if fieldType.Type == reflect.PtrTo(actionHeaderType) {
88
+ if field.IsNil() {
89
+ ahp = &ActionHeader{}
90
+ } else {
91
+ ahp = field.Interface().(*ActionHeader)
92
+ }
93
+ }
94
+ if ahp != nil {
95
+ actionTypeTag, _ := fieldType.Tag.Lookup("actionType")
96
+ ah := *ahp
97
+ SetActionHeaderFromContext(ctx, actionTypeTag, &ah)
98
+ if field.Kind() == reflect.Ptr {
99
+ field.Set(reflect.ValueOf(&ah))
100
+ } else {
101
+ field.Set(reflect.ValueOf(ah))
102
+ }
103
+ continue
104
+ }
105
+
106
+ // Still zero value, try default struct field tag.
107
+ defaultTag, _ := fieldType.Tag.Lookup("default")
108
+ if !field.IsZero() || len(defaultTag) == 0 {
109
+ continue
110
+ }
111
+
112
+ switch field.Kind() {
113
+ case reflect.String:
114
+ field.SetString(defaultTag)
115
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
116
+ if val, err := strconv.ParseInt(defaultTag, 0, 64); err == nil {
117
+ field.SetInt(val)
118
+ }
119
+ case reflect.Bool:
120
+ if val, err := strconv.ParseBool(defaultTag); err == nil {
121
+ field.SetBool(val)
122
+ }
123
+ case reflect.Float32, reflect.Float64:
124
+ if val, err := strconv.ParseFloat(defaultTag, 64); err == nil {
125
+ field.SetFloat(val)
126
+ }
127
+ }
128
+ }
129
+ return rv.Interface().(Action)
130
+ }
@@ -0,0 +1,129 @@
1
+ package vm_test
2
+
3
+ import (
4
+ "encoding/json"
5
+ "testing"
6
+ "time"
7
+
8
+ "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
9
+ sdk "github.com/cosmos/cosmos-sdk/types"
10
+ )
11
+
12
+ var (
13
+ _ vm.Action = &Trivial{}
14
+ _ vm.Action = &Defaults{}
15
+ _ vm.Action = &dataAction{}
16
+ )
17
+
18
+ type Trivial struct {
19
+ vm.ActionHeader
20
+ Abc int
21
+ def string
22
+ }
23
+
24
+ type Defaults struct {
25
+ String string `default:"abc"`
26
+ Int int `default:"123"`
27
+ Float float64 `default:"4.56"`
28
+ Bool bool `default:"true"`
29
+ Any interface{}
30
+ }
31
+
32
+ func (d Defaults) GetActionHeader() vm.ActionHeader {
33
+ return vm.ActionHeader{}
34
+ }
35
+
36
+ type dataAction struct {
37
+ *vm.ActionHeader `actionType:"DATA_ACTION"`
38
+ Data []byte
39
+ }
40
+
41
+ func TestActionContext(t *testing.T) {
42
+ emptyCtx := sdk.Context{}
43
+
44
+ testCases := []struct {
45
+ name string
46
+ ctx sdk.Context
47
+ in vm.Action
48
+ expectedOut interface{}
49
+ }{
50
+ {"nil", emptyCtx, nil, nil},
51
+ {"no context", emptyCtx,
52
+ &Trivial{Abc: 123, def: "zot"},
53
+ &Trivial{Abc: 123, def: "zot"},
54
+ },
55
+ {"block height",
56
+ emptyCtx.WithBlockHeight(998),
57
+ &Trivial{Abc: 123, def: "zot"},
58
+ &Trivial{ActionHeader: vm.ActionHeader{BlockHeight: 998}, Abc: 123, def: "zot"},
59
+ },
60
+ {"block time",
61
+ emptyCtx.WithBlockTime(time.UnixMicro(1_000_000)),
62
+ &Trivial{Abc: 123, def: "zot"},
63
+ &Trivial{Abc: 123, def: "zot", ActionHeader: vm.ActionHeader{BlockTime: 1}},
64
+ },
65
+ {"default tags",
66
+ emptyCtx,
67
+ &Defaults{},
68
+ &Defaults{"abc", 123, 4.56, true, nil},
69
+ },
70
+ {"data action defaults",
71
+ emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
72
+ &dataAction{Data: []byte("hello")},
73
+ &dataAction{Data: []byte("hello"),
74
+ ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION", BlockHeight: 998, BlockTime: 1}},
75
+ },
76
+ {"data action override Type",
77
+ emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
78
+ &dataAction{Data: []byte("hello2"),
79
+ ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION2"}},
80
+ &dataAction{Data: []byte("hello2"),
81
+ ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION2", BlockHeight: 998, BlockTime: 1}},
82
+ },
83
+ {"data action override BlockHeight",
84
+ emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
85
+ &dataAction{Data: []byte("hello2"),
86
+ ActionHeader: &vm.ActionHeader{BlockHeight: 999}},
87
+ &dataAction{Data: []byte("hello2"),
88
+ ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION", BlockHeight: 999, BlockTime: 1}},
89
+ },
90
+ {"data action override BlockTime",
91
+ emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
92
+ &dataAction{Data: []byte("hello2"),
93
+ ActionHeader: &vm.ActionHeader{BlockTime: 2}},
94
+ &dataAction{Data: []byte("hello2"),
95
+ ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION", BlockHeight: 998, BlockTime: 2}},
96
+ },
97
+ {"data action override all defaults",
98
+ emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
99
+ &dataAction{Data: []byte("hello2"),
100
+ ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION2", BlockHeight: 999, BlockTime: 2}},
101
+ &dataAction{Data: []byte("hello2"),
102
+ ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION2", BlockHeight: 999, BlockTime: 2}},
103
+ },
104
+ }
105
+
106
+ for _, tc := range testCases {
107
+ tc := tc
108
+ t.Run(tc.name, func(t *testing.T) {
109
+ jstr := func(in interface{}) string {
110
+ bz, err := json.Marshal(in)
111
+ if err != nil {
112
+ t.Fatal(err)
113
+ }
114
+ return string(bz)
115
+ }
116
+ jsonIn := jstr(tc.in)
117
+ out := vm.PopulateAction(tc.ctx, tc.in)
118
+ jsonIn2 := jstr(tc.in)
119
+ if jsonIn != jsonIn2 {
120
+ t.Errorf("unexpected mutated input: %s to %s", jsonIn, jsonIn2)
121
+ }
122
+ jsonOut := jstr(out)
123
+ jsonExpectedOut := jstr(tc.expectedOut)
124
+ if jsonOut != jsonExpectedOut {
125
+ t.Errorf("expected %s, got %s", jsonExpectedOut, jsonOut)
126
+ }
127
+ })
128
+ }
129
+ }
package/vm/controller.go CHANGED
@@ -25,12 +25,6 @@ type ControllerAdmissionMsg interface {
25
25
  IsHighPriority(sdk.Context, interface{}) (bool, error)
26
26
  }
27
27
 
28
- // Jsonable is a value, j, that can be passed through json.Marshal(j).
29
- type Jsonable interface{}
30
-
31
- // ActionPusher enqueues data for later consumption by the controller.
32
- type ActionPusher func(ctx sdk.Context, action Jsonable) error
33
-
34
28
  var controllerContext ControllerContext
35
29
 
36
30
  type PortHandler interface {
@@ -0,0 +1,31 @@
1
+ package vm
2
+
3
+ // CoreProposalStep is a set of core proposal configs which are executed
4
+ // concurrently
5
+ type CoreProposalStep []Jsonable
6
+
7
+ // CoreProposals is one possible shape for core proposals expressed as a series
8
+ // of sequential steps
9
+ // see SequentialCoreProposals in packages/deploy-script-support/src/extract-proposal.js
10
+ type CoreProposals struct {
11
+ Steps []CoreProposalStep `json:"steps"`
12
+ }
13
+
14
+ // CoreProposalStepForModules generates a single core proposal step from
15
+ // the given modules, which will be executed concurrently during that step
16
+ func CoreProposalStepForModules(modules ...string) CoreProposalStep {
17
+ step := make([]Jsonable, len(modules))
18
+ for i := range modules {
19
+ step[i] = modules[i]
20
+ }
21
+ return step
22
+ }
23
+
24
+ // CoreProposalsFromSteps returns a CoreProposals from the given steps
25
+ func CoreProposalsFromSteps(steps ...CoreProposalStep) *CoreProposals {
26
+ if steps == nil {
27
+ // Deal with https://github.com/golang/go/issues/37711
28
+ return &CoreProposals{Steps: []CoreProposalStep{}}
29
+ }
30
+ return &CoreProposals{Steps: steps}
31
+ }
@@ -16,16 +16,16 @@ import (
16
16
  // In addition to the methods declared in authtypes.AccountI, additional
17
17
  // expectations are enforced dynamically through casting and reflection:
18
18
  //
19
- // - non-module accounts are expected to obey the GenesisAccount interface,
20
- // i.e. to have a Validate() method;
19
+ // - non-module accounts are expected to obey the GenesisAccount interface,
20
+ // i.e. to have a Validate() method;
21
21
  //
22
- // - UnpackInterfacesMessage is needed for unpacking accounts embedded
23
- // in an Any message;
22
+ // - UnpackInterfacesMessage is needed for unpacking accounts embedded
23
+ // in an Any message;
24
24
  //
25
- // - MarshalYAML() is used for String rendering;
25
+ // - MarshalYAML() is used for String rendering;
26
26
  //
27
- // - protobuf Messages are expected to implement a number of "XXX"-prefixed
28
- // methods not visible in the Message interface.
27
+ // - protobuf Messages are expected to implement a number of "XXX"-prefixed
28
+ // methods not visible in the Message interface.
29
29
  //
30
30
  // Declaring the expected methods here allows them to implicitly fall through
31
31
  // to an embedded omniAccount.
@@ -116,7 +116,7 @@ func (uva unlockedVestingAccount) GetOriginalVesting() sdk.Coins {
116
116
  return sdk.NewCoins()
117
117
  }
118
118
 
119
- //GetDelegatedFree implements the vestexported.VestingAccount interface.
119
+ // GetDelegatedFree implements the vestexported.VestingAccount interface.
120
120
  func (uva unlockedVestingAccount) GetDelegatedFree() sdk.Coins {
121
121
  return uva.lien.Delegated
122
122
  }
@@ -172,6 +172,11 @@ func (fca fakeClawbackAccount) PostReward(ctx sdk.Context, reward sdk.Coins, act
172
172
  return nil
173
173
  }
174
174
 
175
+ // ReturnGrants implements the vestexported.ClawbackVestingAccountI interface.
176
+ func (fca fakeClawbackAccount) ReturnGrants(ctx sdk.Context, action vestexported.ReturnGrantAction) error {
177
+ return action.TakeGrants(ctx, fca.omniGrantAccount) // XXX or just fail here
178
+ }
179
+
175
180
  // LienAccount wraps an omniClawbackAccount to implement lien encumbrance.
176
181
  // The LockedCoins() method is the maximum of the coins locked for
177
182
  // liens, and the coins locked in the underlying VestingAccount.
@@ -112,7 +112,7 @@ func makeTestKit() testKit {
112
112
  sk := stakingkeeper.NewKeeper(cdc, stakingStoreKey, wak, bk, stakingSpace)
113
113
 
114
114
  // lien keeper
115
- pushAction := func(sdk.Context, vm.Jsonable) error {
115
+ pushAction := func(sdk.Context, vm.Action) error {
116
116
  return nil
117
117
  }
118
118
  keeper := NewKeeper(cdc, lienStoreKey, wak, bk, sk, pushAction)
@@ -2,6 +2,7 @@ package swingset
2
2
 
3
3
  import (
4
4
  // "os"
5
+ "context"
5
6
  "fmt"
6
7
  "time"
7
8
 
@@ -9,38 +10,34 @@ import (
9
10
  sdk "github.com/cosmos/cosmos-sdk/types"
10
11
  abci "github.com/tendermint/tendermint/abci/types"
11
12
 
13
+ "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
12
14
  "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/types"
13
15
  )
14
16
 
15
17
  type beginBlockAction struct {
16
- Type string `json:"type"`
17
- BlockHeight int64 `json:"blockHeight"`
18
- BlockTime int64 `json:"blockTime"`
19
- ChainID string `json:"chainID"`
20
- Params types.Params `json:"params"`
18
+ vm.ActionHeader `actionType:"BEGIN_BLOCK"`
19
+ ChainID string `json:"chainID"`
20
+ Params types.Params `json:"params"`
21
21
  }
22
22
 
23
23
  type endBlockAction struct {
24
- Type string `json:"type"`
25
- BlockHeight int64 `json:"blockHeight"`
26
- BlockTime int64 `json:"blockTime"`
24
+ vm.ActionHeader `actionType:"END_BLOCK"`
27
25
  }
28
26
 
29
27
  type commitBlockAction struct {
30
- Type string `json:"type"`
31
- BlockHeight int64 `json:"blockHeight"`
32
- BlockTime int64 `json:"blockTime"`
28
+ vm.ActionHeader `actionType:"COMMIT_BLOCK"`
29
+ }
30
+
31
+ type afterCommitBlockAction struct {
32
+ vm.ActionHeader `actionType:"AFTER_COMMIT_BLOCK"`
33
33
  }
34
34
 
35
35
  func BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock, keeper Keeper) error {
36
36
  defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
37
37
 
38
38
  action := &beginBlockAction{
39
- Type: "BEGIN_BLOCK",
40
- BlockHeight: ctx.BlockHeight(),
41
- BlockTime: ctx.BlockTime().Unix(),
42
- ChainID: ctx.ChainID(),
43
- Params: keeper.GetParams(ctx),
39
+ ChainID: ctx.ChainID(),
40
+ Params: keeper.GetParams(ctx),
44
41
  }
45
42
  _, err := keeper.BlockingSend(ctx, action)
46
43
  // fmt.Fprintf(os.Stderr, "BEGIN_BLOCK Returned from SwingSet: %s, %v\n", out, err)
@@ -59,11 +56,7 @@ var endBlockTime int64
59
56
  func EndBlock(ctx sdk.Context, req abci.RequestEndBlock, keeper Keeper) ([]abci.ValidatorUpdate, error) {
60
57
  defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker)
61
58
 
62
- action := &endBlockAction{
63
- Type: "END_BLOCK",
64
- BlockHeight: ctx.BlockHeight(),
65
- BlockTime: ctx.BlockTime().Unix(),
66
- }
59
+ action := &endBlockAction{}
67
60
  _, err := keeper.BlockingSend(ctx, action)
68
61
 
69
62
  // fmt.Fprintf(os.Stderr, "END_BLOCK Returned from SwingSet: %s, %v\n", out, err)
@@ -80,15 +73,18 @@ func EndBlock(ctx sdk.Context, req abci.RequestEndBlock, keeper Keeper) ([]abci.
80
73
  return []abci.ValidatorUpdate{}, nil
81
74
  }
82
75
 
76
+ func getEndBlockContext() sdk.Context {
77
+ return sdk.Context{}.
78
+ WithContext(context.Background()).
79
+ WithBlockHeight(endBlockHeight).
80
+ WithBlockTime(time.Unix(endBlockTime, 0))
81
+ }
82
+
83
83
  func CommitBlock(keeper Keeper) error {
84
84
  defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), "commit_blocker")
85
85
 
86
- action := &commitBlockAction{
87
- Type: "COMMIT_BLOCK",
88
- BlockHeight: endBlockHeight,
89
- BlockTime: endBlockTime,
90
- }
91
- _, err := keeper.BlockingSend(sdk.Context{}, action)
86
+ action := &commitBlockAction{}
87
+ _, err := keeper.BlockingSend(getEndBlockContext(), action)
92
88
 
93
89
  // fmt.Fprintf(os.Stderr, "COMMIT_BLOCK Returned from SwingSet: %s, %v\n", out, err)
94
90
  if err != nil {
@@ -102,12 +98,8 @@ func CommitBlock(keeper Keeper) error {
102
98
  func AfterCommitBlock(keeper Keeper) error {
103
99
  // defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), "commit_blocker")
104
100
 
105
- action := &commitBlockAction{
106
- Type: "AFTER_COMMIT_BLOCK",
107
- BlockHeight: endBlockHeight,
108
- BlockTime: endBlockTime,
109
- }
110
- _, err := keeper.BlockingSend(sdk.Context{}, action)
101
+ action := &afterCommitBlockAction{}
102
+ _, err := keeper.BlockingSend(getEndBlockContext(), action)
111
103
 
112
104
  // fmt.Fprintf(os.Stderr, "AFTER_COMMIT_BLOCK Returned from SwingSet: %s, %v\n", out, err)
113
105
  if err != nil {
@@ -37,6 +37,12 @@ const (
37
37
  StoragePathSwingStore = "swingStore"
38
38
  )
39
39
 
40
+ const (
41
+ // WalletStoragePathSegment matches the value of WALLET_STORAGE_PATH_SEGMENT
42
+ // packages/vats/src/core/startWalletFactory.js
43
+ WalletStoragePathSegment = "wallet"
44
+ )
45
+
40
46
  const (
41
47
  stateKey = "state"
42
48
  swingStoreKeyPrefix = "swingStore."
@@ -104,6 +110,16 @@ func NewKeeper(
104
110
  }
105
111
  }
106
112
 
113
+ func populateAction(ctx sdk.Context, action vm.Action) (vm.Action, error) {
114
+ action = vm.PopulateAction(ctx, action)
115
+ ah := action.GetActionHeader()
116
+ if len(ah.Type) == 0 {
117
+ return nil, fmt.Errorf("action %q cannot have an empty ActionHeader.Type", action)
118
+ }
119
+
120
+ return action, nil
121
+ }
122
+
107
123
  // pushAction appends an action to the controller's specified inbound queue.
108
124
  // The queue is kept in the kvstore so that changes are properly reverted if the
109
125
  // kvstore is rolled back. By the time the block manager runs, it can commit
@@ -112,7 +128,11 @@ func NewKeeper(
112
128
  //
113
129
  // The inbound queue's format is documented by `makeChainQueue` in
114
130
  // `packages/cosmic-swingset/src/helpers/make-queue.js`.
115
- func (k Keeper) pushAction(ctx sdk.Context, inboundQueuePath string, action vm.Jsonable) error {
131
+ func (k Keeper) pushAction(ctx sdk.Context, inboundQueuePath string, action vm.Action) error {
132
+ action, err := populateAction(ctx, action)
133
+ if err != nil {
134
+ return err
135
+ }
116
136
  txHash, txHashOk := ctx.Context().Value(baseapp.TxHashContextKey).(string)
117
137
  if !txHashOk {
118
138
  txHash = "unknown"
@@ -137,12 +157,12 @@ func (k Keeper) pushAction(ctx sdk.Context, inboundQueuePath string, action vm.J
137
157
  }
138
158
 
139
159
  // PushAction appends an action to the controller's actionQueue.
140
- func (k Keeper) PushAction(ctx sdk.Context, action vm.Jsonable) error {
160
+ func (k Keeper) PushAction(ctx sdk.Context, action vm.Action) error {
141
161
  return k.pushAction(ctx, StoragePathActionQueue, action)
142
162
  }
143
163
 
144
164
  // PushAction appends an action to the controller's highPriorityQueue.
145
- func (k Keeper) PushHighPriorityAction(ctx sdk.Context, action vm.Jsonable) error {
165
+ func (k Keeper) PushHighPriorityAction(ctx sdk.Context, action vm.Action) error {
146
166
  return k.pushAction(ctx, StoragePathHighPriorityQueue, action)
147
167
  }
148
168
 
@@ -151,6 +171,20 @@ func (k Keeper) IsHighPriorityAddress(ctx sdk.Context, addr sdk.AccAddress) (boo
151
171
  return k.vstorageKeeper.HasEntry(ctx, path), nil
152
172
  }
153
173
 
174
+ // GetSmartWalletState returns the provision state of the smart wallet for the account address
175
+ func (k Keeper) GetSmartWalletState(ctx sdk.Context, addr sdk.AccAddress) types.SmartWalletState {
176
+ // walletStoragePath is path of `walletStorageNode` constructed in
177
+ // `provideSmartWallet` from packages/smart-wallet/src/walletFactory.js
178
+ walletStoragePath := StoragePathCustom + "." + WalletStoragePathSegment + "." + addr.String()
179
+
180
+ // TODO: implement a pending provision state
181
+ if k.vstorageKeeper.HasEntry(ctx, walletStoragePath) {
182
+ return types.SmartWalletStateProvisioned
183
+ }
184
+
185
+ return types.SmartWalletStateNone
186
+ }
187
+
154
188
  func (k Keeper) InboundQueueLength(ctx sdk.Context) (int32, error) {
155
189
  size := sdk.NewInt(0)
156
190
 
@@ -214,7 +248,11 @@ func (k Keeper) UpdateQueueAllowed(ctx sdk.Context) error {
214
248
  // until the response. It is orthogonal to PushAction, and should only be used
215
249
  // by SwingSet to perform block lifecycle events (BEGIN_BLOCK, END_BLOCK,
216
250
  // COMMIT_BLOCK).
217
- func (k Keeper) BlockingSend(ctx sdk.Context, action vm.Jsonable) (string, error) {
251
+ func (k Keeper) BlockingSend(ctx sdk.Context, action vm.Action) (string, error) {
252
+ action, err := populateAction(ctx, action)
253
+ if err != nil {
254
+ return "", err
255
+ }
218
256
  bz, err := json.Marshal(action)
219
257
  if err != nil {
220
258
  return "", err
@@ -315,6 +353,25 @@ func (k Keeper) ChargeBeans(ctx sdk.Context, addr sdk.AccAddress, beans sdk.Uint
315
353
  return nil
316
354
  }
317
355
 
356
+ // ChargeForSmartWallet charges the fee for provisioning a smart wallet.
357
+ func (k Keeper) ChargeForSmartWallet(ctx sdk.Context, addr sdk.AccAddress) error {
358
+ beansPerUnit := k.GetBeansPerUnit(ctx)
359
+ beans := beansPerUnit[types.BeansPerSmartWalletProvision]
360
+ err := k.ChargeBeans(ctx, addr, beans)
361
+ if err != nil {
362
+ return err
363
+ }
364
+
365
+ // TODO: mark that a smart wallet provision is pending. However in that case,
366
+ // auto-provisioning should still be performed (but without fees being charged),
367
+ // until the controller actually provisions the smart wallet (the operation may
368
+ // transiently fail, requiring retries until success).
369
+ // However the provisioning code is not currently idempotent, and has side
370
+ // effects when the smart wallet is already provisioned.
371
+
372
+ return nil
373
+ }
374
+
318
375
  // makeFeeMenu returns a map from power flag to its fee. In the case of duplicates, the
319
376
  // first one wins.
320
377
  func makeFeeMenu(powerFlagFees []types.PowerFlagFee) map[string]sdk.Coins {
@@ -1,7 +1,7 @@
1
1
  package keeper
2
2
 
3
3
  import (
4
- v32 "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/legacy/v32"
4
+ "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/types"
5
5
  sdk "github.com/cosmos/cosmos-sdk/types"
6
6
  )
7
7
 
@@ -17,8 +17,13 @@ func NewMigrator(keeper Keeper) Migrator {
17
17
 
18
18
  // Migrate1to2 migrates from version 1 to 2.
19
19
  func (m Migrator) Migrate1to2(ctx sdk.Context) error {
20
+ return m.MigrateParams(ctx)
21
+ }
22
+
23
+ // MigrateParams migrates params by setting new params to their default value
24
+ func (m Migrator) MigrateParams(ctx sdk.Context) error {
20
25
  params := m.keeper.GetParams(ctx)
21
- newParams, err := v32.UpdateParams(params)
26
+ newParams, err := types.UpdateParams(params)
22
27
  if err != nil {
23
28
  return err
24
29
  }