@agoric/cosmos 0.35.0-u12.0 → 0.35.0-u14.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/Makefile +25 -12
  3. package/ante/ante.go +7 -5
  4. package/ante/inbound_test.go +8 -0
  5. package/app/app.go +139 -108
  6. package/app/export.go +13 -9
  7. package/app/sim_test.go +4 -4
  8. package/cmd/agd/main.go +5 -3
  9. package/cmd/libdaemon/main.go +5 -2
  10. package/daemon/cmd/genaccounts.go +13 -9
  11. package/daemon/cmd/root.go +38 -17
  12. package/daemon/cmd/root_test.go +1 -1
  13. package/daemon/cmd/testnet.go +17 -6
  14. package/daemon/main.go +3 -2
  15. package/git-revision.txt +1 -1
  16. package/go.mod +117 -76
  17. package/go.sum +858 -210
  18. package/package.json +3 -3
  19. package/proto/agoric/vstorage/query.proto +53 -1
  20. package/scripts/protocgen.sh +12 -1
  21. package/third_party/proto/buf.yaml +1 -0
  22. package/third_party/proto/cosmos/base/query/v1beta1/pagination.proto +4 -1
  23. package/third_party/proto/cosmos/base/v1beta1/coin.proto +7 -4
  24. package/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto +16 -6
  25. package/third_party/proto/cosmos_proto/cosmos.proto +97 -0
  26. package/third_party/proto/google/api/annotations.proto +1 -1
  27. package/third_party/proto/google/api/http.proto +181 -120
  28. package/third_party/proto/google/api/httpbody.proto +9 -6
  29. package/third_party/proto/google/protobuf/any.proto +1 -7
  30. package/third_party/proto/ibc/core/channel/v1/channel.proto +15 -1
  31. package/third_party/proto/ibc/core/client/v1/client.proto +9 -6
  32. package/upgradegaia.sh +13 -4
  33. package/vm/action.go +133 -0
  34. package/vm/action_test.go +129 -0
  35. package/vm/controller.go +9 -16
  36. package/vm/core_proposals.go +31 -0
  37. package/x/lien/keeper/account.go +16 -11
  38. package/x/lien/keeper/keeper.go +5 -4
  39. package/x/lien/keeper/keeper_test.go +9 -9
  40. package/x/lien/lien.go +6 -4
  41. package/x/lien/lien_test.go +20 -16
  42. package/x/swingset/abci.go +25 -33
  43. package/x/swingset/client/cli/query.go +2 -2
  44. package/x/swingset/client/cli/tx.go +48 -33
  45. package/x/swingset/client/proposal_handler.go +2 -17
  46. package/x/swingset/keeper/keeper.go +69 -15
  47. package/x/swingset/keeper/keeper_test.go +1 -1
  48. package/x/swingset/keeper/migrations.go +7 -2
  49. package/x/swingset/keeper/msg_server.go +66 -49
  50. package/x/swingset/keeper/proposal.go +14 -8
  51. package/x/swingset/keeper/querier.go +14 -6
  52. package/x/swingset/keeper/swing_store_exports_handler.go +5 -1
  53. package/x/swingset/proposal_handler.go +3 -3
  54. package/x/swingset/swingset.go +4 -2
  55. package/x/swingset/types/codec.go +2 -2
  56. package/x/swingset/types/default-params.go +22 -16
  57. package/x/swingset/types/expected_keepers.go +11 -0
  58. package/x/swingset/types/msgs.go +43 -2
  59. package/x/swingset/types/msgs.pb.go +16 -16
  60. package/x/swingset/types/params.go +74 -0
  61. package/x/swingset/types/params_test.go +116 -0
  62. package/x/swingset/types/proposal.go +5 -5
  63. package/x/swingset/types/types.go +30 -28
  64. package/x/vbank/keeper/keeper.go +3 -2
  65. package/x/vbank/keeper/querier.go +6 -2
  66. package/x/vbank/keeper/rewards.go +1 -1
  67. package/x/vbank/vbank.go +19 -17
  68. package/x/vbank/vbank_test.go +18 -18
  69. package/x/vibc/handler.go +3 -8
  70. package/x/vibc/ibc.go +79 -126
  71. package/x/vibc/keeper/keeper.go +19 -18
  72. package/x/vibc/types/expected_keepers.go +13 -5
  73. package/x/vibc/types/msgs.go +1 -1
  74. package/x/vibc/types/msgs.pb.go +1 -1
  75. package/x/vstorage/README.md +138 -0
  76. package/x/vstorage/capdata/capdata.go +298 -0
  77. package/x/vstorage/capdata/capdata_test.go +352 -0
  78. package/x/vstorage/client/cli/query.go +51 -4
  79. package/x/vstorage/keeper/grpc_query.go +221 -0
  80. package/x/vstorage/keeper/keeper.go +3 -2
  81. package/x/vstorage/keeper/keeper_grpc_test.go +300 -0
  82. package/x/vstorage/keeper/keeper_test.go +1 -1
  83. package/x/vstorage/keeper/querier.go +6 -2
  84. package/x/vstorage/keeper/querier_test.go +112 -0
  85. package/x/vstorage/types/query.pb.go +646 -36
  86. package/x/vstorage/types/query.pb.gw.go +119 -0
  87. package/x/vstorage/vstorage.go +16 -15
  88. package/x/vstorage/vstorage_test.go +5 -5
  89. package/x/swingset/legacy/v32/params.go +0 -37
  90. package/x/swingset/legacy/v32/params_test.go +0 -133
  91. /package/{src/index.cjs → index.cjs} +0 -0
@@ -21,15 +21,13 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer {
21
21
  var _ types.MsgServer = msgServer{}
22
22
 
23
23
  type deliverInboundAction struct {
24
- Type string `json:"type"`
25
- Peer string `json:"peer"`
26
- Messages [][]interface{} `json:"messages"`
27
- Ack uint64 `json:"ack"`
28
- BlockHeight int64 `json:"blockHeight"`
29
- BlockTime int64 `json:"blockTime"`
24
+ vm.ActionHeader `actionType:"DELIVER_INBOUND"`
25
+ Peer string `json:"peer"`
26
+ Messages [][]interface{} `json:"messages"`
27
+ Ack uint64 `json:"ack"`
30
28
  }
31
29
 
32
- func (keeper msgServer) routeAction(ctx sdk.Context, msg vm.ControllerAdmissionMsg, action vm.Jsonable) error {
30
+ func (keeper msgServer) routeAction(ctx sdk.Context, msg vm.ControllerAdmissionMsg, action vm.Action) error {
33
31
  isHighPriority, err := msg.IsHighPriority(ctx, keeper)
34
32
  if err != nil {
35
33
  return err
@@ -45,20 +43,15 @@ func (keeper msgServer) routeAction(ctx sdk.Context, msg vm.ControllerAdmissionM
45
43
  func (keeper msgServer) DeliverInbound(goCtx context.Context, msg *types.MsgDeliverInbound) (*types.MsgDeliverInboundResponse, error) {
46
44
  ctx := sdk.UnwrapSDKContext(goCtx)
47
45
 
46
+ // msg.Nums and msg.Messages must be zipped into an array of [num, message] pairs.
48
47
  messages := make([][]interface{}, len(msg.Messages))
49
48
  for i, message := range msg.Messages {
50
- messages[i] = make([]interface{}, 2)
51
- messages[i][0] = msg.Nums[i]
52
- messages[i][1] = message
49
+ messages[i] = []interface{}{msg.Nums[i], message}
53
50
  }
54
-
55
51
  action := &deliverInboundAction{
56
- Type: "DELIVER_INBOUND",
57
- Peer: msg.Submitter.String(),
58
- Messages: messages,
59
- Ack: msg.Ack,
60
- BlockHeight: ctx.BlockHeight(),
61
- BlockTime: ctx.BlockTime().Unix(),
52
+ Peer: msg.Submitter.String(),
53
+ Messages: messages,
54
+ Ack: msg.Ack,
62
55
  }
63
56
 
64
57
  err := keeper.routeAction(ctx, msg, action)
@@ -70,26 +63,26 @@ func (keeper msgServer) DeliverInbound(goCtx context.Context, msg *types.MsgDeli
70
63
  }
71
64
 
72
65
  type walletAction struct {
73
- Type string `json:"type"` // WALLET_ACTION
74
- Owner string `json:"owner"`
75
- Action string `json:"action"`
76
- BlockHeight int64 `json:"blockHeight"`
77
- BlockTime int64 `json:"blockTime"`
66
+ vm.ActionHeader `actionType:"WALLET_ACTION"`
67
+ Owner string `json:"owner"`
68
+ Action string `json:"action"`
78
69
  }
79
70
 
80
71
  func (keeper msgServer) WalletAction(goCtx context.Context, msg *types.MsgWalletAction) (*types.MsgWalletActionResponse, error) {
81
72
  ctx := sdk.UnwrapSDKContext(goCtx)
82
73
 
74
+ err := keeper.provisionIfNeeded(ctx, msg.Owner)
75
+ if err != nil {
76
+ return nil, err
77
+ }
78
+
83
79
  action := &walletAction{
84
- Type: "WALLET_ACTION",
85
- Owner: msg.Owner.String(),
86
- Action: msg.Action,
87
- BlockHeight: ctx.BlockHeight(),
88
- BlockTime: ctx.BlockTime().Unix(),
80
+ Owner: msg.Owner.String(),
81
+ Action: msg.Action,
89
82
  }
90
83
  // fmt.Fprintf(os.Stderr, "Context is %+v\n", ctx)
91
84
 
92
- err := keeper.routeAction(ctx, msg, action)
85
+ err = keeper.routeAction(ctx, msg, action)
93
86
  // fmt.Fprintln(os.Stderr, "Returned from SwingSet", out, err)
94
87
  if err != nil {
95
88
  return nil, err
@@ -98,25 +91,25 @@ func (keeper msgServer) WalletAction(goCtx context.Context, msg *types.MsgWallet
98
91
  }
99
92
 
100
93
  type walletSpendAction struct {
101
- Type string `json:"type"` // WALLET_SPEND_ACTION
102
- Owner string `json:"owner"`
103
- SpendAction string `json:"spendAction"`
104
- BlockHeight int64 `json:"blockHeight"`
105
- BlockTime int64 `json:"blockTime"`
94
+ vm.ActionHeader `actionType:"WALLET_SPEND_ACTION"`
95
+ Owner string `json:"owner"`
96
+ SpendAction string `json:"spendAction"`
106
97
  }
107
98
 
108
99
  func (keeper msgServer) WalletSpendAction(goCtx context.Context, msg *types.MsgWalletSpendAction) (*types.MsgWalletSpendActionResponse, error) {
109
100
  ctx := sdk.UnwrapSDKContext(goCtx)
110
101
 
102
+ err := keeper.provisionIfNeeded(ctx, msg.Owner)
103
+ if err != nil {
104
+ return nil, err
105
+ }
106
+
111
107
  action := &walletSpendAction{
112
- Type: "WALLET_SPEND_ACTION",
113
108
  Owner: msg.Owner.String(),
114
109
  SpendAction: msg.SpendAction,
115
- BlockHeight: ctx.BlockHeight(),
116
- BlockTime: ctx.BlockTime().Unix(),
117
110
  }
118
111
  // fmt.Fprintf(os.Stderr, "Context is %+v\n", ctx)
119
- err := keeper.routeAction(ctx, msg, action)
112
+ err = keeper.routeAction(ctx, msg, action)
120
113
  if err != nil {
121
114
  return nil, err
122
115
  }
@@ -124,10 +117,42 @@ func (keeper msgServer) WalletSpendAction(goCtx context.Context, msg *types.MsgW
124
117
  }
125
118
 
126
119
  type provisionAction struct {
120
+ vm.ActionHeader `actionType:"PLEASE_PROVISION"`
127
121
  *types.MsgProvision
128
- Type string `json:"type"` // PLEASE_PROVISION
129
- BlockHeight int64 `json:"blockHeight"`
130
- BlockTime int64 `json:"blockTime"`
122
+ AutoProvision bool `json:"autoProvision"`
123
+ }
124
+
125
+ // provisionIfNeeded generates a provision action if no smart wallet is already
126
+ // provisioned for the account. This assumes that all messages for
127
+ // non-provisioned smart wallets allowed by the admission AnteHandler should
128
+ // auto-provision the smart wallet.
129
+ func (keeper msgServer) provisionIfNeeded(ctx sdk.Context, owner sdk.AccAddress) error {
130
+ // We need to generate a provision action until the smart wallet has
131
+ // been fully provisioned by the controller. This is because a provision is
132
+ // not guaranteed to succeed (e.g. lack of provision pool funds)
133
+ walletState := keeper.GetSmartWalletState(ctx, owner)
134
+ if walletState == types.SmartWalletStateProvisioned {
135
+ return nil
136
+ }
137
+
138
+ msg := &types.MsgProvision{
139
+ Address: owner,
140
+ Submitter: owner,
141
+ PowerFlags: []string{types.PowerFlagSmartWallet},
142
+ }
143
+
144
+ action := &provisionAction{
145
+ MsgProvision: msg,
146
+ AutoProvision: true,
147
+ }
148
+
149
+ err := keeper.routeAction(ctx, msg, action)
150
+ // fmt.Fprintln(os.Stderr, "Returned from SwingSet", out, err)
151
+ if err != nil {
152
+ return err
153
+ }
154
+
155
+ return nil
131
156
  }
132
157
 
133
158
  func (keeper msgServer) Provision(goCtx context.Context, msg *types.MsgProvision) (*types.MsgProvisionResponse, error) {
@@ -140,9 +165,6 @@ func (keeper msgServer) Provision(goCtx context.Context, msg *types.MsgProvision
140
165
 
141
166
  action := &provisionAction{
142
167
  MsgProvision: msg,
143
- Type: "PLEASE_PROVISION",
144
- BlockHeight: ctx.BlockHeight(),
145
- BlockTime: ctx.BlockTime().Unix(),
146
168
  }
147
169
 
148
170
  // Create the account, if it doesn't already exist.
@@ -162,10 +184,8 @@ func (keeper msgServer) Provision(goCtx context.Context, msg *types.MsgProvision
162
184
  }
163
185
 
164
186
  type installBundleAction struct {
187
+ vm.ActionHeader `actionType:"INSTALL_BUNDLE"`
165
188
  *types.MsgInstallBundle
166
- Type string `json:"type"` // INSTALL_BUNDLE
167
- BlockHeight int64 `json:"blockHeight"`
168
- BlockTime int64 `json:"blockTime"`
169
189
  }
170
190
 
171
191
  func (keeper msgServer) InstallBundle(goCtx context.Context, msg *types.MsgInstallBundle) (*types.MsgInstallBundleResponse, error) {
@@ -177,9 +197,6 @@ func (keeper msgServer) InstallBundle(goCtx context.Context, msg *types.MsgInsta
177
197
  }
178
198
  action := &installBundleAction{
179
199
  MsgInstallBundle: msg,
180
- Type: "INSTALL_BUNDLE",
181
- BlockHeight: ctx.BlockHeight(),
182
- BlockTime: ctx.BlockTime().Unix(),
183
200
  }
184
201
 
185
202
  err = keeper.routeAction(ctx, msg, action)
@@ -1,26 +1,32 @@
1
1
  package keeper
2
2
 
3
3
  import (
4
+ "context"
5
+
4
6
  sdk "github.com/cosmos/cosmos-sdk/types"
5
7
 
8
+ "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
6
9
  "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/types"
10
+ "github.com/cosmos/cosmos-sdk/baseapp"
7
11
  )
8
12
 
9
13
  type coreEvalAction struct {
10
- Type string `json:"type"` // CORE_EVAL
11
- Evals []types.CoreEval `json:"evals"`
12
- BlockHeight int64 `json:"blockHeight"`
13
- BlockTime int64 `json:"blockTime"`
14
+ vm.ActionHeader `actionType:"CORE_EVAL"`
15
+ Evals []types.CoreEval `json:"evals"`
14
16
  }
15
17
 
16
18
  // CoreEvalProposal tells SwingSet to evaluate the given JS code.
17
19
  func (k Keeper) CoreEvalProposal(ctx sdk.Context, p *types.CoreEvalProposal) error {
18
20
  action := &coreEvalAction{
19
- Type: "CORE_EVAL",
20
- Evals: p.Evals,
21
- BlockHeight: ctx.BlockHeight(),
22
- BlockTime: ctx.BlockTime().Unix(),
21
+ Evals: p.Evals,
23
22
  }
24
23
 
24
+ // While the CoreEvalProposal was originally created by a transaction, by the time it
25
+ // passes by governance, we no longer have its provenance information, so we need to
26
+ // synthesize unique context information.
27
+ // We use a fixed placeholder value for the txHash context. We use `0` for the message
28
+ // index which assumes there is a single proposal per block.
29
+ ctx = ctx.WithContext(context.WithValue(ctx.Context(), baseapp.TxHashContextKey, "x/gov"))
30
+ ctx = ctx.WithContext(context.WithValue(ctx.Context(), baseapp.TxMsgIdxContextKey, 0))
25
31
  return k.PushHighPriorityAction(ctx, action)
26
32
  }
@@ -24,17 +24,27 @@ const (
24
24
  // NewQuerier is the module level router for state queries
25
25
  func NewQuerier(keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
26
26
  return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err error) {
27
- switch path[0] {
27
+ var queryType string
28
+ if len(path) > 0 {
29
+ queryType = path[0]
30
+ }
31
+ switch queryType {
28
32
  case QueryEgress:
33
+ if len(path) < 2 || path[1] == "" {
34
+ return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "missing egress address")
35
+ }
29
36
  return queryEgress(ctx, path[1], req, keeper, legacyQuerierCdc)
30
37
  case QueryMailbox:
31
- return queryMailbox(ctx, path[1:], req, keeper, legacyQuerierCdc)
38
+ if len(path) < 2 || path[1] == "" {
39
+ return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "missing mailbox peer")
40
+ }
41
+ return queryMailbox(ctx, path[1], req, keeper, legacyQuerierCdc)
32
42
  case LegacyQueryStorage:
33
43
  return legacyQueryStorage(ctx, strings.Join(path[1:], "/"), req, keeper, legacyQuerierCdc)
34
44
  case LegacyQueryKeys:
35
45
  return legacyQueryKeys(ctx, strings.Join(path[1:], "/"), req, keeper, legacyQuerierCdc)
36
46
  default:
37
- return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown swingset query endpoint")
47
+ return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown swingset query path")
38
48
  }
39
49
  }
40
50
  }
@@ -60,9 +70,7 @@ func queryEgress(ctx sdk.Context, bech32 string, req abci.RequestQuery, keeper K
60
70
  }
61
71
 
62
72
  // nolint: unparam
63
- func queryMailbox(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) (res []byte, err error) {
64
- peer := path[0]
65
-
73
+ func queryMailbox(ctx sdk.Context, peer string, req abci.RequestQuery, keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) (res []byte, err error) {
66
74
  value := keeper.GetMailbox(ctx, peer)
67
75
 
68
76
  if value == "" {
@@ -751,11 +751,15 @@ func (exportsHandler SwingStoreExportsHandler) RestoreExport(provider SwingStore
751
751
  }
752
752
  defer os.RemoveAll(exportDir)
753
753
 
754
+ exportsHandler.logger.Info("creating swing-store restore", "exportDir", exportDir, "height", blockHeight)
755
+
754
756
  err = WriteSwingStoreExportToDirectory(provider, exportDir)
755
757
  if err != nil {
756
758
  return err
757
759
  }
758
760
 
761
+ exportsHandler.logger.Info("restoring swing-store", "exportDir", exportDir, "height", blockHeight)
762
+
759
763
  action := &swingStoreRestoreExportAction{
760
764
  Type: swingStoreExportActionType,
761
765
  BlockHeight: blockHeight,
@@ -772,7 +776,7 @@ func (exportsHandler SwingStoreExportsHandler) RestoreExport(provider SwingStore
772
776
  return err
773
777
  }
774
778
 
775
- exportsHandler.logger.Info("restored swing-store export", "exportDir", exportDir, "height", blockHeight)
779
+ exportsHandler.logger.Info("restored swing-store", "exportDir", exportDir, "height", blockHeight)
776
780
 
777
781
  return nil
778
782
  }
@@ -3,15 +3,15 @@ package swingset
3
3
  import (
4
4
  sdk "github.com/cosmos/cosmos-sdk/types"
5
5
  sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
6
- govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
6
+ govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
7
7
 
8
8
  "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
9
9
  "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/types"
10
10
  )
11
11
 
12
12
  // NewSwingSetProposalHandler defines the SwingSet proposal handler
13
- func NewSwingSetProposalHandler(k keeper.Keeper) govtypes.Handler {
14
- return func(ctx sdk.Context, content govtypes.Content) error {
13
+ func NewSwingSetProposalHandler(k keeper.Keeper) govv1beta1.Handler {
14
+ return func(ctx sdk.Context, content govv1beta1.Content) error {
15
15
  switch c := content.(type) {
16
16
  case *types.CoreEvalProposal:
17
17
  return k.CoreEvalProposal(ctx, c)
@@ -1,6 +1,7 @@
1
1
  package swingset
2
2
 
3
3
  import (
4
+ "context"
4
5
  "encoding/json"
5
6
  "fmt"
6
7
  "io"
@@ -33,7 +34,8 @@ func NewPortHandler(k Keeper) vm.PortHandler {
33
34
  // Receive implements the vm.PortHandler method.
34
35
  // It receives and processes an inbound message, returning the
35
36
  // JSON-serialized response or an error.
36
- func (ph portHandler) Receive(ctx *vm.ControllerContext, str string) (string, error) {
37
+ func (ph portHandler) Receive(cctx context.Context, str string) (string, error) {
38
+ ctx := sdk.UnwrapSDKContext(cctx)
37
39
  var msg swingsetMessage
38
40
  err := json.Unmarshal([]byte(str), &msg)
39
41
  if err != nil {
@@ -42,7 +44,7 @@ func (ph portHandler) Receive(ctx *vm.ControllerContext, str string) (string, er
42
44
 
43
45
  switch msg.Method {
44
46
  case SwingStoreUpdateExportData:
45
- return ph.handleSwingStoreUpdateExportData(ctx.Context, msg.Args)
47
+ return ph.handleSwingStoreUpdateExportData(ctx, msg.Args)
46
48
 
47
49
  default:
48
50
  return "", fmt.Errorf("unrecognized swingset method %s", msg.Method)
@@ -6,7 +6,7 @@ import (
6
6
  cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
7
7
  sdk "github.com/cosmos/cosmos-sdk/types"
8
8
  "github.com/cosmos/cosmos-sdk/types/msgservice"
9
- govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
9
+ govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
10
10
  )
11
11
 
12
12
  var (
@@ -44,7 +44,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
44
44
  &MsgWalletSpendAction{},
45
45
  )
46
46
  registry.RegisterImplementations(
47
- (*govtypes.Content)(nil),
47
+ (*govv1beta1.Content)(nil),
48
48
  &CoreEvalProposal{},
49
49
  )
50
50
  msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
@@ -11,20 +11,24 @@ import (
11
11
  // experience if they don't.
12
12
 
13
13
  const (
14
- BeansPerFeeUnit = "feeUnit"
15
- BeansPerInboundTx = "inboundTx"
16
- BeansPerBlockComputeLimit = "blockComputeLimit"
17
- BeansPerMessage = "message"
18
- BeansPerMessageByte = "messageByte"
19
- BeansPerMinFeeDebit = "minFeeDebit"
20
- BeansPerStorageByte = "storageByte"
21
- BeansPerVatCreation = "vatCreation"
22
- BeansPerXsnapComputron = "xsnapComputron"
14
+ BeansPerFeeUnit = "feeUnit"
15
+ BeansPerInboundTx = "inboundTx"
16
+ BeansPerBlockComputeLimit = "blockComputeLimit"
17
+ BeansPerMessage = "message"
18
+ BeansPerMessageByte = "messageByte"
19
+ BeansPerMinFeeDebit = "minFeeDebit"
20
+ BeansPerStorageByte = "storageByte"
21
+ BeansPerVatCreation = "vatCreation"
22
+ BeansPerXsnapComputron = "xsnapComputron"
23
+ BeansPerSmartWalletProvision = "smartWalletProvision"
23
24
 
24
25
  // QueueSize keys.
25
26
  // Keep up-to-date with updateQueueAllowed() in packanges/cosmic-swingset/src/launch-chain.js
26
27
  QueueInbound = "inbound"
27
28
  QueueInboundMempool = "inbound_mempool"
29
+
30
+ // PowerFlags.
31
+ PowerFlagSmartWallet = "SMART_WALLET"
28
32
  )
29
33
 
30
34
  var (
@@ -43,17 +47,18 @@ var (
43
47
 
44
48
  // TODO: create the cost model we want, and update these to be more principled.
45
49
  // These defaults currently make deploying an ag-solo cost less than $1.00.
46
- DefaultBeansPerFeeUnit = sdk.NewUint(1_000_000_000_000) // $1
47
- DefaultBeansPerInboundTx = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(100)) // $0.01
48
- DefaultBeansPerMessage = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(1_000)) // $0.001
49
- DefaultBeansPerMessageByte = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(50_000)) // $0.00002
50
- DefaultBeansPerMinFeeDebit = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(5)) // $0.2
51
- DefaultBeansPerStorageByte = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(500)) // $0.002
50
+ DefaultBeansPerFeeUnit = sdk.NewUint(1_000_000_000_000) // $1
51
+ DefaultBeansPerInboundTx = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(100)) // $0.01
52
+ DefaultBeansPerMessage = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(1_000)) // $0.001
53
+ DefaultBeansPerMessageByte = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(50_000)) // $0.00002
54
+ DefaultBeansPerMinFeeDebit = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(5)) // $0.2
55
+ DefaultBeansPerStorageByte = DefaultBeansPerFeeUnit.Quo(sdk.NewUint(500)) // $0.002
56
+ DefaultBeansPerSmartWalletProvision = DefaultBeansPerFeeUnit // $1
52
57
 
53
58
  DefaultBootstrapVatConfig = "@agoric/vats/decentral-core-config.json"
54
59
 
55
60
  DefaultPowerFlagFees = []PowerFlagFee{
56
- NewPowerFlagFee("SMART_WALLET", sdk.NewCoins(sdk.NewInt64Coin("ubld", 10_000_000))),
61
+ NewPowerFlagFee(PowerFlagSmartWallet, sdk.NewCoins(sdk.NewInt64Coin("ubld", 10_000_000))),
57
62
  }
58
63
 
59
64
  DefaultInboundQueueMax = int32(1_000)
@@ -75,5 +80,6 @@ func DefaultBeansPerUnit() []StringBeans {
75
80
  NewStringBeans(BeansPerStorageByte, DefaultBeansPerStorageByte),
76
81
  NewStringBeans(BeansPerVatCreation, DefaultBeansPerVatCreation),
77
82
  NewStringBeans(BeansPerXsnapComputron, DefaultBeansPerXsnapComputron),
83
+ NewStringBeans(BeansPerSmartWalletProvision, DefaultBeansPerSmartWalletProvision),
78
84
  }
79
85
  }
@@ -5,6 +5,15 @@ import (
5
5
  authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
6
6
  )
7
7
 
8
+ type SmartWalletState uint8
9
+
10
+ const (
11
+ SmartWalletStateUnspecified SmartWalletState = iota
12
+ SmartWalletStateNone
13
+ SmartWalletStatePending
14
+ SmartWalletStateProvisioned
15
+ )
16
+
8
17
  type AccountKeeper interface {
9
18
  GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
10
19
  NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
@@ -15,4 +24,6 @@ type SwingSetKeeper interface {
15
24
  GetBeansPerUnit(ctx sdk.Context) map[string]sdk.Uint
16
25
  ChargeBeans(ctx sdk.Context, addr sdk.AccAddress, beans sdk.Uint) error
17
26
  IsHighPriorityAddress(ctx sdk.Context, addr sdk.AccAddress) (bool, error)
27
+ GetSmartWalletState(ctx sdk.Context, addr sdk.AccAddress) SmartWalletState
28
+ ChargeForSmartWallet(ctx sdk.Context, addr sdk.AccAddress) error
18
29
  }
@@ -48,6 +48,33 @@ func chargeAdmission(ctx sdk.Context, keeper SwingSetKeeper, addr sdk.AccAddress
48
48
  return keeper.ChargeBeans(ctx, addr, beans)
49
49
  }
50
50
 
51
+ // checkSmartWalletProvisioned verifies if a smart wallet message (MsgWalletAction
52
+ // and MsgWalletSpendAction) can be delivered for the owner's address. A message
53
+ // is allowed if a smart wallet is already provisioned for the address, or if the
54
+ // provisioning fee is charged successfully.
55
+ // All messages for non-provisioned smart wallets allowed here will result in
56
+ // an auto-provision action generated by the msg server.
57
+ func checkSmartWalletProvisioned(ctx sdk.Context, keeper SwingSetKeeper, addr sdk.AccAddress) error {
58
+ walletState := keeper.GetSmartWalletState(ctx, addr)
59
+
60
+ switch walletState {
61
+ case SmartWalletStateProvisioned:
62
+ // The address already has a smart wallet
63
+ return nil
64
+ case SmartWalletStatePending:
65
+ // A provision (either explicit or automatic) may be pending execution in
66
+ // the controller, or if we ever allow multiple swingset messages per
67
+ // transaction, a previous message may have provisioned the wallet.
68
+ return nil
69
+ default:
70
+ // Charge for the smart wallet.
71
+ // This is a separate charge from the smart wallet action which triggered the check
72
+ // TODO: Currently this call does not mark the smart wallet provisioning as
73
+ // pending, resulting in multiple provisioning charges for the owner.
74
+ return keeper.ChargeForSmartWallet(ctx, addr)
75
+ }
76
+ }
77
+
51
78
  func NewMsgDeliverInbound(msgs *Messages, submitter sdk.AccAddress) *MsgDeliverInbound {
52
79
  return &MsgDeliverInbound{
53
80
  Messages: msgs.Messages,
@@ -137,6 +164,11 @@ func (msg MsgWalletAction) CheckAdmissibility(ctx sdk.Context, data interface{})
137
164
  return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "data must be a SwingSetKeeper, not a %T", data)
138
165
  }
139
166
 
167
+ err := checkSmartWalletProvisioned(ctx, keeper, msg.Owner)
168
+ if err != nil {
169
+ return err
170
+ }
171
+
140
172
  return chargeAdmission(ctx, keeper, msg.Owner, []string{msg.Action}, 0)
141
173
  }
142
174
 
@@ -204,6 +236,11 @@ func (msg MsgWalletSpendAction) CheckAdmissibility(ctx sdk.Context, data interfa
204
236
  return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "data must be a SwingSetKeeper, not a %T", data)
205
237
  }
206
238
 
239
+ err := checkSmartWalletProvisioned(ctx, keeper, msg.Owner)
240
+ if err != nil {
241
+ return err
242
+ }
243
+
207
244
  return chargeAdmission(ctx, keeper, msg.Owner, []string{msg.SpendAction}, 0)
208
245
  }
209
246
 
@@ -271,8 +308,12 @@ func (msg MsgProvision) ValidateBasic() error {
271
308
 
272
309
  // CheckAdmissibility implements the vm.ControllerAdmissionMsg interface.
273
310
  func (msg MsgProvision) CheckAdmissibility(ctx sdk.Context, data interface{}) error {
274
- // We have our own fee charging mechanism within Swingset itself,
275
- // so there are no admission restriction here.
311
+ // TODO: consider disallowing a provision message for a smart wallet if the
312
+ // smart wallet is already provisioned or pending provisioning. However we
313
+ // currently do not track whether a smart wallet is pending provisioning.
314
+
315
+ // For explicitly provisioning, swingset will take care of charging,
316
+ // so we skip admission fees.
276
317
  return nil
277
318
  }
278
319
 
@@ -433,7 +433,7 @@ type MsgInstallBundle struct {
433
433
  Submitter github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,2,opt,name=submitter,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"submitter" yaml:"submitter"`
434
434
  // Either bundle or compressed_bundle will be set.
435
435
  // Default compression algorithm is gzip.
436
- CompressedBundle []byte `protobuf:"bytes,3,opt,name=compressed_bundle,json=compressedBundle,proto3" json:"compressedBundle" yaml:"bcompressedBndle"`
436
+ CompressedBundle []byte `protobuf:"bytes,3,opt,name=compressed_bundle,json=compressedBundle,proto3" json:"compressedBundle" yaml:"compressedBundle"`
437
437
  // Size in bytes of uncompression of compressed_bundle.
438
438
  UncompressedSize int64 `protobuf:"varint,4,opt,name=uncompressed_size,json=uncompressedSize,proto3" json:"uncompressedSize"`
439
439
  }
@@ -553,7 +553,7 @@ func init() {
553
553
  func init() { proto.RegisterFile("agoric/swingset/msgs.proto", fileDescriptor_788baa062b181a57) }
554
554
 
555
555
  var fileDescriptor_788baa062b181a57 = []byte{
556
- // 789 bytes of a gzipped FileDescriptorProto
556
+ // 788 bytes of a gzipped FileDescriptorProto
557
557
  0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xcf, 0x6f, 0xe3, 0x44,
558
558
  0x14, 0x8e, 0xe3, 0x50, 0x36, 0xaf, 0xd9, 0x6d, 0x63, 0x95, 0xad, 0xd7, 0x0b, 0x99, 0xac, 0xa5,
559
559
  0x15, 0x01, 0xd4, 0x44, 0xb0, 0xb7, 0xed, 0x29, 0x16, 0x42, 0x5a, 0xa4, 0xa0, 0xc5, 0x2b, 0x84,
@@ -590,20 +590,20 @@ var fileDescriptor_788baa062b181a57 = []byte{
590
590
  0x01, 0x8d, 0x2d, 0xcf, 0x33, 0x66, 0xc1, 0xc4, 0xc3, 0xca, 0x0b, 0xd8, 0x1a, 0xf3, 0x7f, 0xf9,
591
591
  0xe9, 0x3c, 0x4d, 0x18, 0xca, 0x91, 0x94, 0xa1, 0x87, 0xc2, 0x9e, 0x88, 0x75, 0x33, 0x27, 0x96,
592
592
  0x57, 0x56, 0xbf, 0x87, 0x95, 0x29, 0xdf, 0x40, 0xdb, 0x26, 0x7e, 0x98, 0xc1, 0x78, 0x72, 0x9c,
593
- 0x3b, 0x96, 0x79, 0xe7, 0x41, 0xc2, 0xd0, 0x6e, 0x45, 0x1a, 0x85, 0xf7, 0xfd, 0xdc, 0xfb, 0x02,
594
- 0x25, 0x56, 0xb1, 0x26, 0x56, 0x86, 0xd0, 0x9e, 0x05, 0x0b, 0xf5, 0xa9, 0x7b, 0x89, 0xf9, 0x89,
595
- 0xc9, 0xc6, 0x5e, 0x56, 0x7d, 0x91, 0x7c, 0xe3, 0x5e, 0x62, 0x73, 0x0d, 0xd1, 0x35, 0x50, 0x57,
596
- 0xf7, 0xb6, 0xd8, 0xf8, 0x4f, 0xae, 0x65, 0x90, 0x47, 0xd4, 0x51, 0xbe, 0x85, 0x87, 0xcb, 0x9b,
597
- 0xff, 0xac, 0xbf, 0xf2, 0x1a, 0xe8, 0xaf, 0xd6, 0xd0, 0x3e, 0xb8, 0x55, 0x52, 0xb4, 0x51, 0x4e,
598
- 0xe0, 0xd1, 0xca, 0x8b, 0x42, 0xdf, 0x94, 0xbc, 0xac, 0xd1, 0x3e, 0xbc, 0x5d, 0x53, 0x76, 0x38,
599
- 0x82, 0xd6, 0xd2, 0xc3, 0xb4, 0xbb, 0x29, 0x77, 0x51, 0xa1, 0xf5, 0x6e, 0x53, 0x94, 0xb5, 0x5d,
600
- 0x68, 0xaf, 0x3f, 0xf9, 0x9e, 0xff, 0x73, 0xfa, 0x82, 0x4c, 0x3b, 0xf8, 0x4f, 0xb2, 0xb2, 0xd5,
601
- 0x97, 0xd0, 0xac, 0x1e, 0x50, 0xef, 0x6d, 0xca, 0x2d, 0x69, 0xed, 0xf9, 0xbf, 0xd2, 0x45, 0x49,
602
- 0xe3, 0xab, 0xdf, 0xe6, 0x1d, 0xe9, 0x6a, 0xde, 0x91, 0xae, 0xe7, 0x1d, 0xe9, 0xc7, 0x9b, 0x4e,
603
- 0xed, 0xea, 0xa6, 0x53, 0xfb, 0xfd, 0xa6, 0x53, 0x3b, 0x3a, 0x5c, 0x98, 0xf9, 0xa1, 0xf8, 0x20,
604
- 0x10, 0x15, 0xf9, 0xcc, 0x3b, 0xc4, 0xb3, 0x02, 0xa7, 0xb8, 0x0c, 0xdf, 0x57, 0xdf, 0x0a, 0xfc,
605
- 0x32, 0x8c, 0xb7, 0xf8, 0x67, 0xc0, 0x8b, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x99, 0x11, 0x18,
606
- 0xbe, 0x4b, 0x08, 0x00, 0x00,
593
+ 0x3b, 0x96, 0x79, 0xe7, 0x41, 0xc2, 0xd0, 0x6e, 0x45, 0x1a, 0x85, 0xf7, 0x7d, 0x61, 0x60, 0x95,
594
+ 0xd1, 0xcd, 0x35, 0xb1, 0x32, 0x84, 0xf6, 0x2c, 0x58, 0xa8, 0x4f, 0xdd, 0x4b, 0xcc, 0x4f, 0x4c,
595
+ 0x36, 0xf6, 0xb2, 0xea, 0x8b, 0xe4, 0x1b, 0xf7, 0x12, 0x9b, 0x6b, 0x88, 0xae, 0x81, 0xba, 0xba,
596
+ 0xb7, 0xc5, 0xc6, 0x7f, 0x72, 0x2d, 0x83, 0x3c, 0xa2, 0x8e, 0xf2, 0x2d, 0x3c, 0x5c, 0xde, 0xfc,
597
+ 0x67, 0xfd, 0x95, 0xd7, 0x40, 0x7f, 0xb5, 0x86, 0xf6, 0xc1, 0xad, 0x92, 0xa2, 0x8d, 0x72, 0x02,
598
+ 0x8f, 0x56, 0x5e, 0x14, 0xfa, 0xa6, 0xe4, 0x65, 0x8d, 0xf6, 0xe1, 0xed, 0x9a, 0xb2, 0xc3, 0x11,
599
+ 0xb4, 0x96, 0x1e, 0xa6, 0xdd, 0x4d, 0xb9, 0x8b, 0x0a, 0xad, 0x77, 0x9b, 0xa2, 0xac, 0xed, 0x42,
600
+ 0x7b, 0xfd, 0xc9, 0xf7, 0xfc, 0x9f, 0xd3, 0x17, 0x64, 0xda, 0xc1, 0x7f, 0x92, 0x95, 0xad, 0xbe,
601
+ 0x84, 0x66, 0xf5, 0x80, 0x7a, 0x6f, 0x53, 0x6e, 0x49, 0x6b, 0xcf, 0xff, 0x95, 0x2e, 0x4a, 0x1a,
602
+ 0x5f, 0xfd, 0x36, 0xef, 0x48, 0x57, 0xf3, 0x8e, 0x74, 0x3d, 0xef, 0x48, 0x3f, 0xde, 0x74, 0x6a,
603
+ 0x57, 0x37, 0x9d, 0xda, 0xef, 0x37, 0x9d, 0xda, 0xd1, 0xe1, 0xc2, 0xcc, 0x0f, 0xc5, 0x07, 0x81,
604
+ 0xa8, 0xc8, 0x67, 0xde, 0x21, 0x9e, 0x15, 0x38, 0xc5, 0x65, 0xf8, 0xbe, 0xfa, 0x56, 0xe0, 0x97,
605
+ 0x61, 0xbc, 0xc5, 0x3f, 0x03, 0x5e, 0xfc, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x51, 0x66, 0x1b, 0xd5,
606
+ 0x4b, 0x08, 0x00, 0x00,
607
607
  }
608
608
 
609
609
  // Reference imports to suppress errors if they are not otherwise used.