@agoric/cosmos 0.35.0-upgrade-14-dev-c8f9e7b.0 → 0.35.0-upgrade-16a-dev-fb592e4.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/CHANGELOG.md +121 -77
- package/MAINTAINERS.md +3 -0
- package/Makefile +36 -26
- package/ante/ante.go +7 -9
- package/ante/inbound_test.go +3 -2
- package/ante/vm_admission.go +2 -1
- package/app/app.go +212 -140
- package/app/upgrade.go +76 -0
- package/cmd/agd/agvm.go +42 -0
- package/cmd/agd/main.go +130 -11
- package/cmd/libdaemon/main.go +64 -53
- package/cmd/libdaemon/main_test.go +2 -1
- package/daemon/cmd/root.go +171 -74
- package/daemon/cmd/root_test.go +189 -1
- package/daemon/main.go +4 -2
- package/e2e_test/Makefile +29 -0
- package/e2e_test/README.md +100 -0
- package/e2e_test/go.mod +217 -0
- package/e2e_test/go.sum +1323 -0
- package/e2e_test/ibc_conformance_test.go +56 -0
- package/e2e_test/pfm_test.go +613 -0
- package/e2e_test/util.go +271 -0
- package/git-revision.txt +1 -1
- package/go.mod +22 -11
- package/go.sum +17 -13
- package/package.json +9 -5
- package/proto/agoric/swingset/genesis.proto +4 -0
- package/proto/agoric/swingset/swingset.proto +1 -1
- package/proto/agoric/vlocalchain/.clang-format +7 -0
- package/proto/agoric/vlocalchain/vlocalchain.proto +31 -0
- package/proto/agoric/vtransfer/genesis.proto +18 -0
- package/scripts/protocgen.sh +7 -8
- package/types/kv_entry_helpers.go +42 -0
- package/upgradegaia.sh +8 -8
- package/vm/action.go +5 -4
- package/vm/action_test.go +31 -11
- package/vm/client.go +113 -0
- package/vm/client_test.go +182 -0
- package/vm/controller.go +17 -40
- package/vm/core_proposals.go +22 -2
- package/vm/jsonrpcconn/jsonrpcconn.go +160 -0
- package/vm/jsonrpcconn/jsonrpcconn_test.go +126 -0
- package/vm/proto_json.go +38 -0
- package/vm/proto_json_test.go +103 -0
- package/vm/server.go +124 -0
- package/x/swingset/abci.go +10 -10
- package/x/swingset/alias.go +2 -0
- package/x/swingset/client/cli/tx.go +4 -0
- package/x/swingset/genesis.go +84 -24
- package/x/swingset/handler.go +2 -1
- package/x/swingset/keeper/extension_snapshotter.go +2 -2
- package/x/swingset/keeper/keeper.go +13 -25
- package/x/swingset/keeper/msg_server.go +18 -18
- package/x/swingset/keeper/proposal.go +3 -3
- package/x/swingset/keeper/querier.go +12 -11
- package/x/swingset/keeper/swing_store_exports_handler.go +21 -6
- package/x/swingset/keeper/test_utils.go +16 -0
- package/x/swingset/module.go +7 -7
- package/x/swingset/proposal_handler.go +2 -1
- package/x/swingset/testing/queue.go +17 -0
- package/x/swingset/types/default-params.go +1 -1
- package/x/swingset/types/expected_keepers.go +3 -2
- package/x/swingset/types/genesis.pb.go +78 -25
- package/x/swingset/types/msgs.go +44 -24
- package/x/swingset/types/params.go +2 -1
- package/x/swingset/types/proposal.go +5 -4
- package/x/swingset/types/swingset.pb.go +1 -1
- package/x/vbank/genesis.go +0 -2
- package/x/vbank/handler.go +2 -1
- package/x/vbank/keeper/querier.go +4 -3
- package/x/vbank/module.go +0 -5
- package/x/vbank/types/msgs.go +0 -12
- package/x/vbank/vbank.go +9 -9
- package/x/vbank/vbank_test.go +2 -2
- package/x/vibc/alias.go +3 -0
- package/x/vibc/handler.go +16 -9
- package/x/vibc/keeper/keeper.go +102 -65
- package/x/vibc/keeper/triggers.go +101 -0
- package/x/vibc/module.go +5 -8
- package/x/vibc/types/expected_keepers.go +13 -0
- package/x/vibc/types/ibc_module.go +336 -0
- package/x/vibc/types/receiver.go +170 -0
- package/x/vlocalchain/alias.go +19 -0
- package/x/vlocalchain/handler.go +21 -0
- package/x/vlocalchain/keeper/keeper.go +279 -0
- package/x/vlocalchain/keeper/keeper_test.go +97 -0
- package/x/vlocalchain/types/codec.go +34 -0
- package/x/vlocalchain/types/key.go +27 -0
- package/x/vlocalchain/types/msgs.go +16 -0
- package/x/vlocalchain/types/vlocalchain.pb.go +1072 -0
- package/x/vlocalchain/vlocalchain.go +114 -0
- package/x/vlocalchain/vlocalchain_test.go +434 -0
- package/x/vstorage/handler.go +2 -1
- package/x/vstorage/keeper/grpc_query.go +0 -1
- package/x/vstorage/keeper/keeper.go +13 -20
- package/x/vstorage/keeper/querier.go +6 -5
- package/x/vstorage/keeper/querier_test.go +4 -3
- package/x/vstorage/module.go +0 -5
- package/x/vstorage/testing/queue.go +27 -0
- package/x/vtransfer/alias.go +13 -0
- package/x/vtransfer/genesis.go +39 -0
- package/x/vtransfer/genesis_test.go +12 -0
- package/x/vtransfer/handler.go +20 -0
- package/x/vtransfer/ibc_middleware.go +186 -0
- package/x/vtransfer/ibc_middleware_test.go +448 -0
- package/x/vtransfer/keeper/keeper.go +281 -0
- package/x/vtransfer/module.go +124 -0
- package/x/vtransfer/types/expected_keepers.go +38 -0
- package/x/vtransfer/types/genesis.pb.go +327 -0
- package/x/vtransfer/types/key.go +9 -0
- package/x/vtransfer/types/msgs.go +9 -0
- package/ante/fee.go +0 -96
- package/proto/agoric/lien/genesis.proto +0 -25
- package/proto/agoric/lien/lien.proto +0 -25
- package/x/lien/alias.go +0 -17
- package/x/lien/genesis.go +0 -58
- package/x/lien/genesis_test.go +0 -101
- package/x/lien/keeper/account.go +0 -290
- package/x/lien/keeper/keeper.go +0 -255
- package/x/lien/keeper/keeper_test.go +0 -623
- package/x/lien/lien.go +0 -205
- package/x/lien/lien_test.go +0 -533
- package/x/lien/module.go +0 -115
- package/x/lien/spec/01_concepts.md +0 -146
- package/x/lien/spec/02_messages.md +0 -96
- package/x/lien/types/accountkeeper.go +0 -81
- package/x/lien/types/accountstate.go +0 -27
- package/x/lien/types/expected_keepers.go +0 -18
- package/x/lien/types/genesis.pb.go +0 -567
- package/x/lien/types/key.go +0 -25
- package/x/lien/types/lien.pb.go +0 -403
- package/x/vibc/ibc.go +0 -394
- /package/{src/index.cjs → index.cjs} +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Package jsonrpcconn provides a way to multiplex an io stream into two
|
|
3
|
+
streams where incoming JSON-RPC requests go to one stream and incoming
|
|
4
|
+
JSON-RPC responses go to another. Outputs are merged.
|
|
5
|
+
|
|
6
|
+
The JSON-RPCv1 protocol is peer-to-peer, but the implementation in the Go
|
|
7
|
+
standard library only supports client-server. By multiplexing a single
|
|
8
|
+
io.ReadWriteCloser stream into separate server (receives requests) and
|
|
9
|
+
client (receives responses) streams, two RPC halves can share the same
|
|
10
|
+
underlying connection.
|
|
11
|
+
*/
|
|
12
|
+
package jsonrpcconn
|
|
13
|
+
|
|
14
|
+
import (
|
|
15
|
+
"encoding/json"
|
|
16
|
+
"io"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
// jsonRpcMsg can unmarshal either a JSON-RPC
|
|
20
|
+
// request or response object.
|
|
21
|
+
type jsonRpcMsg struct {
|
|
22
|
+
Error json.RawMessage `json:"error"`
|
|
23
|
+
Id json.RawMessage `json:"id"`
|
|
24
|
+
Method *string `json:"method"`
|
|
25
|
+
Params []json.RawMessage `json:"params"`
|
|
26
|
+
Result json.RawMessage `json:"result"`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// mux holds the underlying connection and the pipe reader/writer
|
|
30
|
+
// pairs for the server (request) and client (response) sides.
|
|
31
|
+
// Any protocol error or closing any channel will cause shutdown.
|
|
32
|
+
type mux struct {
|
|
33
|
+
conn io.ReadWriteCloser
|
|
34
|
+
reqReader *io.PipeReader
|
|
35
|
+
reqWriter *io.PipeWriter
|
|
36
|
+
respReader *io.PipeReader
|
|
37
|
+
respWriter *io.PipeWriter
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func newMux(conn io.ReadWriteCloser) mux {
|
|
41
|
+
reqReader, reqWriter := io.Pipe()
|
|
42
|
+
respReader, respWriter := io.Pipe()
|
|
43
|
+
m := mux{
|
|
44
|
+
conn: conn,
|
|
45
|
+
reqReader: reqReader,
|
|
46
|
+
reqWriter: reqWriter,
|
|
47
|
+
respReader: respReader,
|
|
48
|
+
respWriter: respWriter,
|
|
49
|
+
}
|
|
50
|
+
go m.input()
|
|
51
|
+
return m
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func (m mux) input() {
|
|
55
|
+
var err error
|
|
56
|
+
dec := json.NewDecoder(m.conn)
|
|
57
|
+
for {
|
|
58
|
+
// read the next JSON value, preserve its wire format
|
|
59
|
+
var raw json.RawMessage
|
|
60
|
+
err = dec.Decode(&raw)
|
|
61
|
+
if err != nil {
|
|
62
|
+
break
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// parse as JSON-RPC
|
|
66
|
+
var msg jsonRpcMsg
|
|
67
|
+
err = json.Unmarshal(raw, &msg)
|
|
68
|
+
if err != nil {
|
|
69
|
+
break
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// send to one of the outputs
|
|
73
|
+
if msg.Method != nil {
|
|
74
|
+
// presume a request, the consumer will handle any missing fields
|
|
75
|
+
_, err = m.reqWriter.Write(raw)
|
|
76
|
+
} else {
|
|
77
|
+
// presume a response, the consumer will handle any missing fields
|
|
78
|
+
_, err = m.respWriter.Write(raw)
|
|
79
|
+
}
|
|
80
|
+
if err != nil {
|
|
81
|
+
break
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
m.reqWriter.CloseWithError(err)
|
|
85
|
+
m.respWriter.CloseWithError(err)
|
|
86
|
+
m.conn.Close()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// clientChan is a view of the mux for the client channel.
|
|
90
|
+
type clientChan mux
|
|
91
|
+
|
|
92
|
+
// Close implements the io.Closer interface.
|
|
93
|
+
func (c clientChan) Close() error {
|
|
94
|
+
return c.conn.Close()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Read implements the io.Reader interface.
|
|
98
|
+
func (c clientChan) Read(p []byte) (int, error) {
|
|
99
|
+
return c.respReader.Read(p)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Write implements the io.Writer interface.
|
|
103
|
+
func (c clientChan) Write(p []byte) (int, error) {
|
|
104
|
+
return c.conn.Write(p)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// serverChan is a view of the mux for the server channel.
|
|
108
|
+
type serverChan mux
|
|
109
|
+
|
|
110
|
+
// Close implements the io.Closer interface.
|
|
111
|
+
func (s serverChan) Close() error {
|
|
112
|
+
return s.conn.Close()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Read implements the io.Reader interface.
|
|
116
|
+
func (s serverChan) Read(p []byte) (int, error) {
|
|
117
|
+
return s.reqReader.Read(p)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Write implements the io.Writer interface.
|
|
121
|
+
func (s serverChan) Write(p []byte) (int, error) {
|
|
122
|
+
return s.conn.Write(p)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ClientServerConn multiplexes an input/output stream for the JSON-RPCv1
|
|
126
|
+
// protocol into streams specific for client traffic and server traffic.
|
|
127
|
+
// Full JSON objects must be written atomically to either stream to
|
|
128
|
+
// interleave correctly.
|
|
129
|
+
func ClientServerConn(conn io.ReadWriteCloser) (clientConn io.ReadWriteCloser, serverConn io.ReadWriteCloser) {
|
|
130
|
+
m := newMux(conn)
|
|
131
|
+
clientConn = clientChan(m)
|
|
132
|
+
serverConn = serverChan(m)
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
type conn struct {
|
|
137
|
+
rd io.ReadCloser
|
|
138
|
+
wr io.WriteCloser
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Close implments the io.Closer interface.
|
|
142
|
+
func (e conn) Close() error {
|
|
143
|
+
e.rd.Close()
|
|
144
|
+
return e.wr.Close()
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Read implements the io.Reader interface.
|
|
148
|
+
func (e conn) Read(p []byte) (int, error) {
|
|
149
|
+
return e.rd.Read(p)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Write implements the io.Writer interface.
|
|
153
|
+
func (e conn) Write(p []byte) (int, error) {
|
|
154
|
+
return e.wr.Write(p)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// NewConn returns a connection from a reader and a writer.
|
|
158
|
+
func NewConn(rd io.ReadCloser, wr io.WriteCloser) io.ReadWriteCloser {
|
|
159
|
+
return conn{rd: rd, wr: wr}
|
|
160
|
+
}
|
|
@@ -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
|
+
}
|
package/vm/proto_json.go
ADDED
|
@@ -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
|
+
}
|
package/x/swingset/abci.go
CHANGED
|
@@ -15,27 +15,27 @@ import (
|
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
type beginBlockAction struct {
|
|
18
|
-
vm.ActionHeader `actionType:"BEGIN_BLOCK"`
|
|
19
|
-
ChainID
|
|
20
|
-
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 :=
|
|
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 :=
|
|
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 :=
|
|
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 :=
|
|
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)
|
package/x/swingset/alias.go
CHANGED
|
@@ -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
|
|