@agoric/cosmos 0.35.0-u15.0 → 0.35.0-u16.1

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 (131) hide show
  1. package/CHANGELOG.md +123 -143
  2. package/MAINTAINERS.md +3 -0
  3. package/Makefile +36 -26
  4. package/ante/ante.go +6 -5
  5. package/ante/inbound_test.go +3 -2
  6. package/ante/vm_admission.go +2 -1
  7. package/app/app.go +206 -147
  8. package/app/upgrade.go +77 -0
  9. package/cmd/agd/agvm.go +42 -0
  10. package/cmd/agd/main.go +130 -11
  11. package/cmd/libdaemon/main.go +64 -53
  12. package/cmd/libdaemon/main_test.go +2 -1
  13. package/daemon/cmd/root.go +164 -74
  14. package/daemon/cmd/root_test.go +189 -1
  15. package/daemon/main.go +4 -2
  16. package/e2e_test/Makefile +29 -0
  17. package/e2e_test/README.md +100 -0
  18. package/e2e_test/go.mod +217 -0
  19. package/e2e_test/go.sum +1323 -0
  20. package/e2e_test/ibc_conformance_test.go +56 -0
  21. package/e2e_test/pfm_test.go +613 -0
  22. package/e2e_test/util.go +271 -0
  23. package/git-revision.txt +1 -1
  24. package/go.mod +12 -7
  25. package/go.sum +13 -9
  26. package/package.json +8 -4
  27. package/proto/agoric/swingset/genesis.proto +4 -0
  28. package/proto/agoric/swingset/swingset.proto +1 -1
  29. package/proto/agoric/vlocalchain/.clang-format +7 -0
  30. package/proto/agoric/vlocalchain/vlocalchain.proto +31 -0
  31. package/proto/agoric/vtransfer/genesis.proto +18 -0
  32. package/scripts/protocgen.sh +7 -8
  33. package/types/kv_entry_helpers.go +42 -0
  34. package/upgradegaia.sh +8 -8
  35. package/vm/action.go +5 -4
  36. package/vm/action_test.go +31 -11
  37. package/vm/client.go +113 -0
  38. package/vm/client_test.go +182 -0
  39. package/vm/controller.go +17 -40
  40. package/vm/core_proposals.go +22 -2
  41. package/vm/jsonrpcconn/jsonrpcconn.go +160 -0
  42. package/vm/jsonrpcconn/jsonrpcconn_test.go +126 -0
  43. package/vm/proto_json.go +38 -0
  44. package/vm/proto_json_test.go +103 -0
  45. package/vm/server.go +124 -0
  46. package/x/swingset/abci.go +10 -10
  47. package/x/swingset/alias.go +2 -0
  48. package/x/swingset/client/cli/tx.go +4 -0
  49. package/x/swingset/genesis.go +84 -24
  50. package/x/swingset/handler.go +2 -1
  51. package/x/swingset/keeper/extension_snapshotter.go +2 -2
  52. package/x/swingset/keeper/keeper.go +13 -25
  53. package/x/swingset/keeper/msg_server.go +18 -18
  54. package/x/swingset/keeper/proposal.go +3 -3
  55. package/x/swingset/keeper/querier.go +12 -11
  56. package/x/swingset/keeper/swing_store_exports_handler.go +16 -5
  57. package/x/swingset/keeper/test_utils.go +16 -0
  58. package/x/swingset/module.go +7 -7
  59. package/x/swingset/proposal_handler.go +2 -1
  60. package/x/swingset/testing/queue.go +17 -0
  61. package/x/swingset/types/default-params.go +1 -1
  62. package/x/swingset/types/expected_keepers.go +3 -2
  63. package/x/swingset/types/genesis.pb.go +78 -25
  64. package/x/swingset/types/msgs.go +44 -24
  65. package/x/swingset/types/params.go +2 -1
  66. package/x/swingset/types/proposal.go +5 -4
  67. package/x/swingset/types/swingset.pb.go +1 -1
  68. package/x/vbank/genesis.go +0 -2
  69. package/x/vbank/handler.go +2 -1
  70. package/x/vbank/keeper/querier.go +4 -3
  71. package/x/vbank/module.go +0 -5
  72. package/x/vbank/types/msgs.go +0 -12
  73. package/x/vbank/vbank.go +9 -9
  74. package/x/vbank/vbank_test.go +2 -2
  75. package/x/vibc/alias.go +3 -0
  76. package/x/vibc/handler.go +16 -9
  77. package/x/vibc/keeper/keeper.go +102 -65
  78. package/x/vibc/keeper/triggers.go +101 -0
  79. package/x/vibc/module.go +5 -8
  80. package/x/vibc/types/expected_keepers.go +13 -0
  81. package/x/vibc/types/ibc_module.go +336 -0
  82. package/x/vibc/types/receiver.go +170 -0
  83. package/x/vlocalchain/alias.go +19 -0
  84. package/x/vlocalchain/handler.go +21 -0
  85. package/x/vlocalchain/keeper/keeper.go +279 -0
  86. package/x/vlocalchain/keeper/keeper_test.go +97 -0
  87. package/x/vlocalchain/types/codec.go +34 -0
  88. package/x/vlocalchain/types/key.go +27 -0
  89. package/x/vlocalchain/types/msgs.go +16 -0
  90. package/x/vlocalchain/types/vlocalchain.pb.go +1072 -0
  91. package/x/vlocalchain/vlocalchain.go +114 -0
  92. package/x/vlocalchain/vlocalchain_test.go +434 -0
  93. package/x/vstorage/handler.go +2 -1
  94. package/x/vstorage/keeper/grpc_query.go +0 -1
  95. package/x/vstorage/keeper/keeper.go +13 -20
  96. package/x/vstorage/keeper/querier.go +6 -5
  97. package/x/vstorage/keeper/querier_test.go +4 -3
  98. package/x/vstorage/module.go +0 -5
  99. package/x/vstorage/testing/queue.go +27 -0
  100. package/x/vtransfer/alias.go +13 -0
  101. package/x/vtransfer/genesis.go +39 -0
  102. package/x/vtransfer/genesis_test.go +12 -0
  103. package/x/vtransfer/handler.go +20 -0
  104. package/x/vtransfer/ibc_middleware.go +186 -0
  105. package/x/vtransfer/ibc_middleware_test.go +448 -0
  106. package/x/vtransfer/keeper/keeper.go +281 -0
  107. package/x/vtransfer/module.go +124 -0
  108. package/x/vtransfer/types/expected_keepers.go +38 -0
  109. package/x/vtransfer/types/genesis.pb.go +327 -0
  110. package/x/vtransfer/types/key.go +9 -0
  111. package/x/vtransfer/types/msgs.go +9 -0
  112. package/proto/agoric/lien/genesis.proto +0 -25
  113. package/proto/agoric/lien/lien.proto +0 -25
  114. package/x/lien/alias.go +0 -17
  115. package/x/lien/genesis.go +0 -58
  116. package/x/lien/genesis_test.go +0 -101
  117. package/x/lien/keeper/account.go +0 -290
  118. package/x/lien/keeper/keeper.go +0 -255
  119. package/x/lien/keeper/keeper_test.go +0 -623
  120. package/x/lien/lien.go +0 -205
  121. package/x/lien/lien_test.go +0 -533
  122. package/x/lien/module.go +0 -115
  123. package/x/lien/spec/01_concepts.md +0 -146
  124. package/x/lien/spec/02_messages.md +0 -96
  125. package/x/lien/types/accountkeeper.go +0 -81
  126. package/x/lien/types/accountstate.go +0 -27
  127. package/x/lien/types/expected_keepers.go +0 -18
  128. package/x/lien/types/genesis.pb.go +0 -567
  129. package/x/lien/types/key.go +0 -25
  130. package/x/lien/types/lien.pb.go +0 -403
  131. package/x/vibc/ibc.go +0 -394
@@ -0,0 +1,126 @@
1
+ package jsonrpcconn_test
2
+
3
+ import (
4
+ "fmt"
5
+ "net"
6
+ "net/rpc"
7
+ "net/rpc/jsonrpc"
8
+ "testing"
9
+
10
+ "github.com/Agoric/agoric-sdk/golang/cosmos/vm/jsonrpcconn"
11
+ )
12
+
13
+ /*
14
+ type testConn struct {
15
+ input *bytes.Buffer
16
+ output *bytes.Buffer
17
+ done chan struct{}
18
+ }
19
+
20
+ func newTestConn(input string) io.ReadWriteCloser {
21
+ return testConn{
22
+ input: bytes.NewBufferString(input),
23
+ output: new(bytes.Buffer),
24
+ done: make(chan struct{}),
25
+ }
26
+ }
27
+
28
+ func (tc testConn) Read(p []byte) (int, error) {
29
+ n, err := tc.input.Read(p)
30
+ if err == io.EOF {
31
+ <-tc.done
32
+ }
33
+ return n, err
34
+ }
35
+
36
+ func (tc testConn) Write(p []byte) (int, error) {
37
+ return tc.output.Write(p)
38
+ }
39
+
40
+ func (tc testConn) Close() error {
41
+ close(tc.done)
42
+ return nil
43
+ }
44
+
45
+ func TestMux(t *testing.T) {
46
+ input := `{"id": 1, "method": "foo", "params": [1, 2]}
47
+ {"id": "aaa", "result": true, "error": null}
48
+ {"id": null, "method": "bar", "params": ["string", 3, false]}`
49
+ tc := newTestConn(input)
50
+ client, server := jsonrpcconn.ClientServerConn(tc)
51
+ client.Read
52
+ var wg sync.WaitGroup
53
+ wg.Add(2)
54
+ go func() {
55
+
56
+ }()
57
+ wg.Wait()
58
+ } */
59
+
60
+ type Args struct {
61
+ A, B int
62
+ }
63
+
64
+ type Arith struct{}
65
+
66
+ func (a *Arith) Add(args Args, reply *int) error {
67
+ *reply = args.A + args.B
68
+ return nil
69
+ }
70
+
71
+ func (a *Arith) Mul(args Args, reply *int) error {
72
+ *reply = args.A * args.B
73
+ return nil
74
+ }
75
+
76
+ func (a *Arith) Oops(args Args, reply *int) error {
77
+ return fmt.Errorf("oops")
78
+ }
79
+
80
+ func TestJsonRPC(t *testing.T) {
81
+ left, right := net.Pipe()
82
+ leftClientConn, leftServerConn := jsonrpcconn.ClientServerConn(left)
83
+ rightClientConn, rightServerConn := jsonrpcconn.ClientServerConn(right)
84
+
85
+ leftClient := jsonrpc.NewClient(leftClientConn)
86
+ leftServer := rpc.NewServer()
87
+ err := leftServer.RegisterName("foo", new(Arith))
88
+ if err != nil {
89
+ t.Fatal(err)
90
+ }
91
+ go leftServer.ServeCodec(jsonrpc.NewServerCodec(leftServerConn))
92
+
93
+ rightClient := jsonrpc.NewClient(rightClientConn)
94
+ rightServer := rpc.NewServer()
95
+ err = rightServer.RegisterName("bar", new(Arith))
96
+ if err != nil {
97
+ t.Fatal(err)
98
+ }
99
+ go rightServer.ServeCodec(jsonrpc.NewServerCodec(rightServerConn))
100
+
101
+ var reply int
102
+ err = leftClient.Call("bar.Add", Args{1, 2}, &reply)
103
+ if err != nil {
104
+ t.Error(err)
105
+ }
106
+ if reply != 3 {
107
+ t.Errorf("bar.Add want 3, got %d", reply)
108
+ }
109
+
110
+ err = rightClient.Call("foo.Mul", Args{2, 3}, &reply)
111
+ if err != nil {
112
+ t.Error(err)
113
+ }
114
+ if reply != 6 {
115
+ t.Errorf("foo.Mul want 6, got %d", reply)
116
+ }
117
+
118
+ err = leftClient.Call("bar.Oops", Args{7, 11}, &reply)
119
+ if err == nil {
120
+ t.Errorf("bar.Oops want error, got reply %d", reply)
121
+ } else if err.Error() != "oops" {
122
+ t.Errorf(`bar.Oops want error "oops", got "%s"`, err.Error())
123
+ }
124
+ leftClient.Close()
125
+ rightClient.Close()
126
+ }
@@ -0,0 +1,38 @@
1
+ package vm
2
+
3
+ import (
4
+ "encoding/json"
5
+
6
+ "github.com/gogo/protobuf/jsonpb"
7
+ "github.com/gogo/protobuf/proto"
8
+ )
9
+
10
+ // We need jsonpb for its access to the global registry.
11
+ var marshaller = jsonpb.Marshaler{EmitDefaults: true}
12
+
13
+ func ProtoJSONMarshal(val interface{}) ([]byte, error) {
14
+ if pm, ok := val.(proto.Message); ok {
15
+ var s string
16
+ s, err := marshaller.MarshalToString(pm)
17
+ return []byte(s), err
18
+ }
19
+
20
+ // Marshal a non-proto value to JSON.
21
+ return json.Marshal(val)
22
+ }
23
+
24
+ // ProtoJSONMarshalSlice marshals a slice of proto messages and non-proto values to
25
+ // a single JSON byte slice.
26
+ func ProtoJSONMarshalSlice(vals []interface{}) ([]byte, error) {
27
+ var err error
28
+ jsonSlice := make([]json.RawMessage, len(vals))
29
+ for i, val := range vals {
30
+ jsonSlice[i], err = ProtoJSONMarshal(val)
31
+ if err != nil {
32
+ return nil, err
33
+ }
34
+ }
35
+
36
+ // Marshal the JSON array to a single JSON byte slice.
37
+ return json.Marshal(jsonSlice)
38
+ }
@@ -0,0 +1,103 @@
1
+ package vm_test
2
+
3
+ import (
4
+ "bytes"
5
+ "strings"
6
+ "testing"
7
+
8
+ "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
9
+
10
+ sdk "github.com/cosmos/cosmos-sdk/types"
11
+
12
+ banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
13
+ stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
14
+ )
15
+
16
+ func TestProtoJSONMarshal(t *testing.T) {
17
+ accAddr, err := sdk.AccAddressFromHexUnsafe("0123456789")
18
+ if err != nil {
19
+ panic(err)
20
+ }
21
+ valAddr, err := sdk.ValAddressFromHex("9876543210")
22
+ if err != nil {
23
+ panic(err)
24
+ }
25
+ coin := sdk.NewInt64Coin("uatom", 1234567)
26
+
27
+ testCases := []struct {
28
+ name string
29
+ create func() interface{}
30
+ expected string
31
+ }{
32
+ {
33
+ "nil",
34
+ func() interface{} {
35
+ return nil
36
+ },
37
+ `null`,
38
+ },
39
+ {
40
+ "primitive number",
41
+ func() interface{} {
42
+ return 12345
43
+ },
44
+ `12345`,
45
+ },
46
+ {
47
+ "MsgDelegate",
48
+ func() interface{} {
49
+ return stakingtypes.NewMsgDelegate(accAddr, valAddr, coin)
50
+ },
51
+ `{"delegatorAddress":"cosmos1qy352eufjjmc9c","validatorAddress":"cosmosvaloper1npm9gvss52mlmk","amount":{"denom":"uatom","amount":"1234567"}}`,
52
+ },
53
+ {
54
+ "QueryDenomOwnersResponse",
55
+ func() interface{} {
56
+ return &banktypes.QueryDenomOwnersResponse{
57
+ DenomOwners: []*banktypes.DenomOwner{
58
+ {
59
+ Address: accAddr.String(),
60
+ Balance: coin,
61
+ },
62
+ {
63
+ Address: valAddr.String(),
64
+ Balance: coin.Add(coin),
65
+ },
66
+ },
67
+ }
68
+ },
69
+ `{"denomOwners":[{"address":"cosmos1qy352eufjjmc9c","balance":{"denom":"uatom","amount":"1234567"}},{"address":"cosmosvaloper1npm9gvss52mlmk","balance":{"denom":"uatom","amount":"2469134"}}],"pagination":null}`,
70
+ },
71
+ }
72
+
73
+ for _, tc := range testCases {
74
+ t.Run(tc.name, func(t *testing.T) {
75
+ val := tc.create()
76
+ bz, err := vm.ProtoJSONMarshal(val)
77
+ if err != nil {
78
+ t.Errorf("ProtoJSONMarshal of %q failed %v", val, err)
79
+ }
80
+ if !bytes.Equal(bz, []byte(tc.expected)) {
81
+ t.Errorf("ProtoJSONMarshal of %q returned %q, expected %q", val, string(bz), tc.expected)
82
+ }
83
+ })
84
+ }
85
+
86
+ t.Run("all in a slice", func(t *testing.T) {
87
+ vals := make([]interface{}, len(testCases))
88
+ expectedJson := make([]string, len(testCases))
89
+ for i, tc := range testCases {
90
+ vals[i] = tc.create()
91
+ expectedJson[i] = tc.expected
92
+ }
93
+ bz, err := vm.ProtoJSONMarshalSlice(vals)
94
+ if err != nil {
95
+ t.Errorf("ProtoJSONMarshalSlice of %q failed %v", vals, err)
96
+ }
97
+
98
+ expected := "[" + strings.Join(expectedJson, ",") + "]"
99
+ if !bytes.Equal(bz, []byte(expected)) {
100
+ t.Errorf("ProtoJSONMarshalSlice of %q returned %q, expected %q", vals, string(bz), expected)
101
+ }
102
+ })
103
+ }
package/vm/server.go ADDED
@@ -0,0 +1,124 @@
1
+ package vm
2
+
3
+ import (
4
+ "context"
5
+ "fmt"
6
+ "sync"
7
+
8
+ sdk "github.com/cosmos/cosmos-sdk/types"
9
+ )
10
+
11
+ // AgdServer manages communication from the VM to the ABCI app. The structure
12
+ // is mutable and the mutex must be held to read or write any field.
13
+ type AgdServer struct {
14
+ currentCtx context.Context
15
+ mtx sync.Mutex
16
+ // zero is an out-of-bounds port number
17
+ lastPort int
18
+ // portToHandler[i] is nonzero iff portToName[i] is nonempty
19
+ portToHandler map[int]PortHandler
20
+ // portToName[nameToPort[s]] == s && nameToPort[portToName[i]] == i for all i, s
21
+ portToName map[int]string
22
+ nameToPort map[string]int
23
+ }
24
+
25
+ var wrappedEmptySDKContext = sdk.WrapSDKContext(
26
+ sdk.Context{}.WithContext(context.Background()),
27
+ )
28
+
29
+ // NewAgdServer returns a pointer to a new AgdServer with empty context and port
30
+ // mappings.
31
+ func NewAgdServer() *AgdServer {
32
+ return &AgdServer{
33
+ currentCtx: wrappedEmptySDKContext,
34
+ mtx: sync.Mutex{},
35
+ portToHandler: make(map[int]PortHandler),
36
+ portToName: make(map[int]string),
37
+ nameToPort: make(map[string]int),
38
+ }
39
+ }
40
+
41
+ // SetControllerContext sets the context to the given argument and returns a function
42
+ // which will reset the context to an empty context (not the old context).
43
+ func (s *AgdServer) SetControllerContext(ctx sdk.Context) func() {
44
+ // We are only called by the controller, so we assume that it is billing its
45
+ // own meter usage.
46
+ s.mtx.Lock()
47
+ defer s.mtx.Unlock()
48
+ s.currentCtx = sdk.WrapSDKContext(ctx.WithGasMeter(sdk.NewInfiniteGasMeter()))
49
+ return func() {
50
+ s.mtx.Lock()
51
+ defer s.mtx.Unlock()
52
+ s.currentCtx = wrappedEmptySDKContext
53
+ }
54
+ }
55
+
56
+ // getContextAndHandler returns the current context and the handler for the
57
+ // given port number.
58
+ func (s *AgdServer) getContextAndHandler(port int) (context.Context, PortHandler) {
59
+ s.mtx.Lock()
60
+ defer s.mtx.Unlock()
61
+ ctx := s.currentCtx
62
+ handler := s.portToHandler[port]
63
+ return ctx, handler
64
+ }
65
+
66
+ // ReceiveMessage is the method the VM calls in order to have agd receive a
67
+ // Message.
68
+ func (s *AgdServer) ReceiveMessage(msg *Message, reply *string) error {
69
+ ctx, handler := s.getContextAndHandler(msg.Port)
70
+ if handler == nil {
71
+ return fmt.Errorf("unregistered port %d", msg.Port)
72
+ }
73
+ resp, err := handler.Receive(ctx, msg.Data)
74
+ *reply = resp
75
+ return err
76
+ }
77
+
78
+ // GetPort returns the port number for the given port name, or 0 if the name is
79
+ // not registered.
80
+ func (s *AgdServer) GetPort(name string) int {
81
+ s.mtx.Lock()
82
+ defer s.mtx.Unlock()
83
+ return s.nameToPort[name]
84
+ }
85
+
86
+ // MustRegisterPortHandler attempts to RegisterPortHandler, panicing on error.
87
+ func (s *AgdServer) MustRegisterPortHandler(name string, portHandler PortHandler) int {
88
+ port, err := s.RegisterPortHandler(name, portHandler)
89
+ if err != nil {
90
+ panic(err)
91
+ }
92
+ return port
93
+ }
94
+
95
+ // RegisterPortHandler registers the handler to a new port number, then maps the name to it,
96
+ // returning the port number. If the name was previously in use, an error is returned.
97
+ func (s *AgdServer) RegisterPortHandler(name string, portHandler PortHandler) (int, error) {
98
+ s.mtx.Lock()
99
+ defer s.mtx.Unlock()
100
+ if _, ok := s.nameToPort[name]; ok {
101
+ return 0, fmt.Errorf("name %s already in use", name)
102
+ }
103
+ s.lastPort++
104
+ s.portToHandler[s.lastPort] = NewProtectedPortHandler(portHandler)
105
+ s.portToName[s.lastPort] = name
106
+ s.nameToPort[name] = s.lastPort
107
+ return s.lastPort, nil
108
+ }
109
+
110
+ // UnregisterPortHandler unregisters the handler and name mappings for this port
111
+ // number, and the reverse mapping for its name, if any of these exist. If
112
+ // portNum is not registered, return an error.
113
+ func (s *AgdServer) UnregisterPortHandler(portNum int) error {
114
+ s.mtx.Lock()
115
+ defer s.mtx.Unlock()
116
+ if s.portToHandler[portNum] == nil {
117
+ return fmt.Errorf("port %d not registered", portNum)
118
+ }
119
+ delete(s.portToHandler, portNum)
120
+ name := s.portToName[portNum]
121
+ delete(s.portToName, portNum)
122
+ delete(s.nameToPort, name)
123
+ return nil
124
+ }
@@ -15,27 +15,27 @@ import (
15
15
  )
16
16
 
17
17
  type beginBlockAction struct {
18
- vm.ActionHeader `actionType:"BEGIN_BLOCK"`
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
- vm.ActionHeader `actionType:"END_BLOCK"`
24
+ *vm.ActionHeader `actionType:"END_BLOCK"`
25
25
  }
26
26
 
27
27
  type commitBlockAction struct {
28
- vm.ActionHeader `actionType:"COMMIT_BLOCK"`
28
+ *vm.ActionHeader `actionType:"COMMIT_BLOCK"`
29
29
  }
30
30
 
31
31
  type afterCommitBlockAction struct {
32
- vm.ActionHeader `actionType:"AFTER_COMMIT_BLOCK"`
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
- action := &beginBlockAction{
38
+ action := beginBlockAction{
39
39
  ChainID: ctx.ChainID(),
40
40
  Params: keeper.GetParams(ctx),
41
41
  }
@@ -56,7 +56,7 @@ var endBlockTime int64
56
56
  func EndBlock(ctx sdk.Context, req abci.RequestEndBlock, keeper Keeper) ([]abci.ValidatorUpdate, error) {
57
57
  defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker)
58
58
 
59
- action := &endBlockAction{}
59
+ action := endBlockAction{}
60
60
  _, err := keeper.BlockingSend(ctx, action)
61
61
 
62
62
  // fmt.Fprintf(os.Stderr, "END_BLOCK Returned from SwingSet: %s, %v\n", out, err)
@@ -83,7 +83,7 @@ func getEndBlockContext() sdk.Context {
83
83
  func CommitBlock(keeper Keeper) error {
84
84
  defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), "commit_blocker")
85
85
 
86
- action := &commitBlockAction{}
86
+ action := commitBlockAction{}
87
87
  _, err := keeper.BlockingSend(getEndBlockContext(), action)
88
88
 
89
89
  // fmt.Fprintf(os.Stderr, "COMMIT_BLOCK Returned from SwingSet: %s, %v\n", out, err)
@@ -98,7 +98,7 @@ func CommitBlock(keeper Keeper) error {
98
98
  func AfterCommitBlock(keeper Keeper) error {
99
99
  // defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), "commit_blocker")
100
100
 
101
- action := &afterCommitBlockAction{}
101
+ action := afterCommitBlockAction{}
102
102
  _, err := keeper.BlockingSend(getEndBlockContext(), action)
103
103
 
104
104
  // fmt.Fprintf(os.Stderr, "AFTER_COMMIT_BLOCK Returned from SwingSet: %s, %v\n", out, err)
@@ -24,6 +24,8 @@ type (
24
24
  Keeper = keeper.Keeper
25
25
  SwingStoreExportsHandler = keeper.SwingStoreExportsHandler
26
26
  ExtensionSnapshotter = keeper.ExtensionSnapshotter
27
+ ActionContext = types.ActionContext
28
+ InboundQueueRecord = types.InboundQueueRecord
27
29
  Egress = types.Egress
28
30
  MsgDeliverInbound = types.MsgDeliverInbound
29
31
  MsgProvision = types.MsgProvision
@@ -253,11 +253,13 @@ Specify at least one pair of permit.json and code.js files`,
253
253
  return err
254
254
  }
255
255
 
256
+ //nolint:staticcheck // Agoric is still using the legacy proposal shape
256
257
  title, err := cmd.Flags().GetString(govcli.FlagTitle)
257
258
  if err != nil {
258
259
  return err
259
260
  }
260
261
 
262
+ //nolint:staticcheck // Agoric is still using the legacy proposal shape
261
263
  description, err := cmd.Flags().GetString(govcli.FlagDescription)
262
264
  if err != nil {
263
265
  return err
@@ -315,7 +317,9 @@ Specify at least one pair of permit.json and code.js files`,
315
317
  },
316
318
  }
317
319
 
320
+ //nolint:staticcheck // Agoric is still using the legacy proposal shape
318
321
  cmd.Flags().String(govcli.FlagTitle, "", "title of proposal")
322
+ //nolint:staticcheck // Agoric is still using the legacy proposal shape
319
323
  cmd.Flags().String(govcli.FlagDescription, "", "description of proposal")
320
324
  cmd.Flags().String(govcli.FlagDeposit, "", "deposit for proposal")
321
325
 
@@ -2,7 +2,13 @@ package swingset
2
2
 
3
3
  import (
4
4
  // "os"
5
+ "bytes"
6
+ "crypto/sha256"
7
+ "encoding/hex"
8
+ "encoding/json"
5
9
  "fmt"
10
+ "hash"
11
+ "strings"
6
12
 
7
13
  agoric "github.com/Agoric/agoric-sdk/golang/cosmos/types"
8
14
  "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
@@ -35,8 +41,10 @@ func InitGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingStore
35
41
  k.SetState(ctx, data.GetState())
36
42
 
37
43
  swingStoreExportData := data.GetSwingStoreExportData()
38
- if len(swingStoreExportData) == 0 {
44
+ if len(swingStoreExportData) == 0 && data.SwingStoreExportDataHash == "" {
39
45
  return true
46
+ } else if data.SwingStoreExportDataHash != "" && len(swingStoreExportData) > 0 {
47
+ panic("Swingset genesis state cannot have both export data and hash of export data")
40
48
  }
41
49
 
42
50
  artifactProvider, err := keeper.OpenSwingStoreExportDirectory(swingStoreExportDir)
@@ -46,15 +54,62 @@ func InitGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingStore
46
54
 
47
55
  swingStore := k.GetSwingStore(ctx)
48
56
 
49
- for _, entry := range swingStoreExportData {
50
- swingStore.Set([]byte(entry.Key), []byte(entry.Value))
51
- }
52
-
53
57
  snapshotHeight := uint64(ctx.BlockHeight())
54
58
 
55
- getExportDataReader := func() (agoric.KVEntryReader, error) {
56
- exportDataIterator := swingStore.Iterator(nil, nil)
57
- return agoric.NewKVIteratorReader(exportDataIterator), nil
59
+ var getExportDataReader func() (agoric.KVEntryReader, error)
60
+
61
+ if len(swingStoreExportData) > 0 {
62
+ for _, entry := range swingStoreExportData {
63
+ swingStore.Set([]byte(entry.Key), []byte(entry.Value))
64
+ }
65
+ getExportDataReader = func() (agoric.KVEntryReader, error) {
66
+ exportDataIterator := swingStore.Iterator(nil, nil)
67
+ return agoric.NewKVIteratorReader(exportDataIterator), nil
68
+ }
69
+ } else {
70
+ hashParts := strings.SplitN(data.SwingStoreExportDataHash, ":", 2)
71
+ if len(hashParts) != 2 {
72
+ panic(fmt.Errorf("invalid swing-store export data hash %s", data.SwingStoreExportDataHash))
73
+ }
74
+ if hashParts[0] != "sha256" {
75
+ panic(fmt.Errorf("invalid swing-store export data hash algorithm %s, expected sha256", hashParts[0]))
76
+ }
77
+ sha256Hash, err := hex.DecodeString(hashParts[1])
78
+ if err != nil {
79
+ panic(err)
80
+ }
81
+ getExportDataReader = func() (agoric.KVEntryReader, error) {
82
+ kvReader, err := artifactProvider.GetExportDataReader()
83
+ if err != nil {
84
+ return nil, err
85
+ }
86
+
87
+ if kvReader == nil {
88
+ return nil, fmt.Errorf("swing-store export has no export data")
89
+ }
90
+
91
+ hasher := sha256.New()
92
+ encoder := json.NewEncoder(hasher)
93
+ encoder.SetEscapeHTML(false)
94
+
95
+ return agoric.NewKVHookingReader(kvReader, func(entry agoric.KVEntry) error {
96
+ key := []byte(entry.Key())
97
+
98
+ if !entry.HasValue() {
99
+ swingStore.Delete(key)
100
+ } else {
101
+ swingStore.Set(key, []byte(entry.StringValue()))
102
+ }
103
+
104
+ return encoder.Encode(entry)
105
+ }, func() error {
106
+ sum := hasher.Sum(nil)
107
+ if !bytes.Equal(sum, sha256Hash) {
108
+ return fmt.Errorf("swing-store data sha256sum didn't match. expected %x, got %x", sha256Hash, sum)
109
+ }
110
+ return nil
111
+ }), nil
112
+ }
58
113
  }
59
114
 
60
115
  err = swingStoreExportsHandler.RestoreExport(
@@ -64,7 +119,7 @@ func InitGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingStore
64
119
  ReadNextArtifact: artifactProvider.ReadNextArtifact,
65
120
  },
66
121
  keeper.SwingStoreRestoreOptions{
67
- ArtifactMode: keeper.SwingStoreArtifactModeReplay,
122
+ ArtifactMode: keeper.SwingStoreArtifactModeOperational,
68
123
  ExportDataMode: keeper.SwingStoreExportDataModeAll,
69
124
  },
70
125
  )
@@ -79,28 +134,19 @@ func ExportGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingSto
79
134
  gs := &types.GenesisState{
80
135
  Params: k.GetParams(ctx),
81
136
  State: k.GetState(ctx),
82
- SwingStoreExportData: []*types.SwingStoreExportDataEntry{},
83
- }
84
-
85
- exportDataIterator := k.GetSwingStore(ctx).Iterator(nil, nil)
86
- defer exportDataIterator.Close()
87
- for ; exportDataIterator.Valid(); exportDataIterator.Next() {
88
- entry := types.SwingStoreExportDataEntry{
89
- Key: string(exportDataIterator.Key()),
90
- Value: string(exportDataIterator.Value()),
91
- }
92
- gs.SwingStoreExportData = append(gs.SwingStoreExportData, &entry)
137
+ SwingStoreExportData: nil,
93
138
  }
94
139
 
95
140
  snapshotHeight := uint64(ctx.BlockHeight())
96
141
 
142
+ eventHandler := swingStoreGenesisEventHandler{exportDir: swingStoreExportDir, snapshotHeight: snapshotHeight, swingStore: k.GetSwingStore(ctx), hasher: sha256.New()}
143
+
97
144
  err := swingStoreExportsHandler.InitiateExport(
98
145
  // The export will fail if the export of a historical height was requested
99
146
  snapshotHeight,
100
- swingStoreGenesisEventHandler{exportDir: swingStoreExportDir, snapshotHeight: snapshotHeight},
101
- // The export will fail if the swing-store does not contain all replay artifacts
147
+ eventHandler,
102
148
  keeper.SwingStoreExportOptions{
103
- ArtifactMode: keeper.SwingStoreArtifactModeReplay,
149
+ ArtifactMode: keeper.SwingStoreArtifactModeOperational,
104
150
  ExportDataMode: keeper.SwingStoreExportDataModeSkip,
105
151
  },
106
152
  )
@@ -113,12 +159,16 @@ func ExportGenesis(ctx sdk.Context, k Keeper, swingStoreExportsHandler *SwingSto
113
159
  panic(err)
114
160
  }
115
161
 
162
+ gs.SwingStoreExportDataHash = fmt.Sprintf("sha256:%x", eventHandler.hasher.Sum(nil))
163
+
116
164
  return gs
117
165
  }
118
166
 
119
167
  type swingStoreGenesisEventHandler struct {
120
168
  exportDir string
121
169
  snapshotHeight uint64
170
+ swingStore sdk.KVStore
171
+ hasher hash.Hash
122
172
  }
123
173
 
124
174
  func (eventHandler swingStoreGenesisEventHandler) OnExportStarted(height uint64, retrieveSwingStoreExport func() error) error {
@@ -132,7 +182,17 @@ func (eventHandler swingStoreGenesisEventHandler) OnExportRetrieved(provider kee
132
182
 
133
183
  artifactsProvider := keeper.SwingStoreExportProvider{
134
184
  GetExportDataReader: func() (agoric.KVEntryReader, error) {
135
- return nil, nil
185
+ exportDataIterator := eventHandler.swingStore.Iterator(nil, nil)
186
+ kvReader := agoric.NewKVIteratorReader(exportDataIterator)
187
+ eventHandler.hasher.Reset()
188
+ encoder := json.NewEncoder(eventHandler.hasher)
189
+ encoder.SetEscapeHTML(false)
190
+
191
+ return agoric.NewKVHookingReader(kvReader, func(entry agoric.KVEntry) error {
192
+ return encoder.Encode(entry)
193
+ }, func() error {
194
+ return nil
195
+ }), nil
136
196
  },
137
197
  ReadNextArtifact: provider.ReadNextArtifact,
138
198
  }
@@ -5,6 +5,7 @@ import (
5
5
 
6
6
  "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
7
7
 
8
+ sdkioerrors "cosmossdk.io/errors"
8
9
  sdk "github.com/cosmos/cosmos-sdk/types"
9
10
  sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
10
11
  )
@@ -29,7 +30,7 @@ func NewHandler(k Keeper) sdk.Handler {
29
30
 
30
31
  default:
31
32
  errMsg := fmt.Sprintf("Unrecognized swingset Msg type: %T", msg)
32
- return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
33
+ return nil, sdkioerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
33
34
  }
34
35
  }
35
36
  }
@@ -125,7 +125,7 @@ func (snapshotter *ExtensionSnapshotter) InitiateSnapshot(height int64) error {
125
125
  blockHeight := uint64(height)
126
126
 
127
127
  return snapshotter.swingStoreExportsHandler.InitiateExport(blockHeight, snapshotter, SwingStoreExportOptions{
128
- ArtifactMode: SwingStoreArtifactModeReplay,
128
+ ArtifactMode: SwingStoreArtifactModeOperational,
129
129
  ExportDataMode: SwingStoreExportDataModeSkip,
130
130
  })
131
131
  }
@@ -304,6 +304,6 @@ func (snapshotter *ExtensionSnapshotter) RestoreExtension(blockHeight uint64, fo
304
304
 
305
305
  return snapshotter.swingStoreExportsHandler.RestoreExport(
306
306
  SwingStoreExportProvider{BlockHeight: blockHeight, GetExportDataReader: getExportDataReader, ReadNextArtifact: readNextArtifact},
307
- SwingStoreRestoreOptions{ArtifactMode: SwingStoreArtifactModeReplay, ExportDataMode: SwingStoreExportDataModeAll},
307
+ SwingStoreRestoreOptions{ArtifactMode: SwingStoreArtifactModeOperational, ExportDataMode: SwingStoreExportDataModeAll},
308
308
  )
309
309
  }