@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
package/upgradegaia.sh
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
set -ueo pipefail
|
|
9
9
|
|
|
10
10
|
test $# -eq 2 || {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
echo "Usage: $0 <FROM_BRANCH> <TO_BRANCH>" 1>&2
|
|
12
|
+
exit 1
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
FROM_BRANCH="$1"
|
|
@@ -23,8 +23,8 @@ for tag in "$FROM_BRANCH" "$TO_BRANCH"; do
|
|
|
23
23
|
qtag=${tag//\//_}
|
|
24
24
|
for root in Makefile app cmd/gaiad; do
|
|
25
25
|
case "$root" in
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
Makefile) echo "$root" ;;
|
|
27
|
+
*) git ls-tree --name-only --full-tree -r "$tag:$root" | sed -e "s!^!$root/!" ;;
|
|
28
28
|
esac
|
|
29
29
|
done | while read -r src; do
|
|
30
30
|
# echo "$src"
|
|
@@ -36,12 +36,12 @@ for tag in "$FROM_BRANCH" "$TO_BRANCH"; do
|
|
|
36
36
|
done
|
|
37
37
|
|
|
38
38
|
echo "Compute 3-way diffs between Gaia and us"
|
|
39
|
-
(cd "$tmp/${FROM_BRANCH//\//_}" && find . -type f -print)
|
|
40
|
-
while read -r src; do
|
|
39
|
+
(cd "$tmp/${FROM_BRANCH//\//_}" && find . -type f -print) \
|
|
40
|
+
| while read -r src; do
|
|
41
41
|
# echo "$src"
|
|
42
42
|
case "$src" in
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
./cmd/gaiad/*) our=${src//cmd\/gaiad/daemon} ;;
|
|
44
|
+
*) our=$src ;;
|
|
45
45
|
esac
|
|
46
46
|
|
|
47
47
|
new="$tmp/diff3/$our"
|
package/vm/action.go
CHANGED
|
@@ -18,7 +18,7 @@ var (
|
|
|
18
18
|
type Jsonable interface{}
|
|
19
19
|
|
|
20
20
|
type Action interface {
|
|
21
|
-
GetActionHeader() ActionHeader
|
|
21
|
+
GetActionHeader() *ActionHeader
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// ActionPusher enqueues data for later consumption by the controller.
|
|
@@ -27,14 +27,14 @@ type ActionPusher func(ctx sdk.Context, action Action) error
|
|
|
27
27
|
// ActionHeader should be embedded in all actions. It is populated by PopulateAction.
|
|
28
28
|
type ActionHeader struct {
|
|
29
29
|
// Type defaults to the `actionType:"..."` tag of the embedder's ActionHeader field.
|
|
30
|
-
Type string `json:"type"`
|
|
30
|
+
Type string `json:"type,omitempty"`
|
|
31
31
|
// BlockHeight defaults to sdk.Context.BlockHeight().
|
|
32
32
|
BlockHeight int64 `json:"blockHeight,omitempty"`
|
|
33
33
|
// BlockTime defaults to sdk.Context.BlockTime().Unix().
|
|
34
34
|
BlockTime int64 `json:"blockTime,omitempty"`
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
func (ah ActionHeader) GetActionHeader() ActionHeader {
|
|
37
|
+
func (ah *ActionHeader) GetActionHeader() *ActionHeader {
|
|
38
38
|
return ah
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -129,5 +129,6 @@ func PopulateAction(ctx sdk.Context, action Action) Action {
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
|
|
132
|
+
|
|
133
|
+
return newActionDescPtr.Interface().(Action)
|
|
133
134
|
}
|
package/vm/action_test.go
CHANGED
|
@@ -10,9 +10,11 @@ import (
|
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
var (
|
|
13
|
-
_ vm.Action =
|
|
13
|
+
_ vm.Action = Defaults{}
|
|
14
14
|
_ vm.Action = &Defaults{}
|
|
15
|
+
_ vm.Action = dataAction{}
|
|
15
16
|
_ vm.Action = &dataAction{}
|
|
17
|
+
_ vm.Action = &Trivial{}
|
|
16
18
|
)
|
|
17
19
|
|
|
18
20
|
type Trivial struct {
|
|
@@ -29,8 +31,8 @@ type Defaults struct {
|
|
|
29
31
|
Any interface{}
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
func (d Defaults) GetActionHeader() vm.ActionHeader {
|
|
33
|
-
return vm.ActionHeader{}
|
|
34
|
+
func (d Defaults) GetActionHeader() *vm.ActionHeader {
|
|
35
|
+
return &vm.ActionHeader{}
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
type dataAction struct {
|
|
@@ -52,6 +54,10 @@ func TestActionContext(t *testing.T) {
|
|
|
52
54
|
&Trivial{Abc: 123, def: "zot"},
|
|
53
55
|
&Trivial{Abc: 123, def: "zot"},
|
|
54
56
|
},
|
|
57
|
+
{"not a pointer", emptyCtx,
|
|
58
|
+
&Trivial{Abc: 123, def: "zot"},
|
|
59
|
+
Trivial{Abc: 123, def: "zot"},
|
|
60
|
+
},
|
|
55
61
|
{"block height",
|
|
56
62
|
emptyCtx.WithBlockHeight(998),
|
|
57
63
|
&Trivial{Abc: 123, def: "zot"},
|
|
@@ -67,6 +73,20 @@ func TestActionContext(t *testing.T) {
|
|
|
67
73
|
&Defaults{},
|
|
68
74
|
&Defaults{"abc", 123, 4.56, true, nil},
|
|
69
75
|
},
|
|
76
|
+
{"data action no pointer",
|
|
77
|
+
emptyCtx,
|
|
78
|
+
dataAction{},
|
|
79
|
+
dataAction{
|
|
80
|
+
ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION"},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{"data action pointer",
|
|
84
|
+
emptyCtx,
|
|
85
|
+
&dataAction{},
|
|
86
|
+
&dataAction{
|
|
87
|
+
ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION"},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
70
90
|
{"data action defaults",
|
|
71
91
|
emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
|
|
72
92
|
&dataAction{Data: []byte("hello")},
|
|
@@ -75,30 +95,30 @@ func TestActionContext(t *testing.T) {
|
|
|
75
95
|
},
|
|
76
96
|
{"data action override Type",
|
|
77
97
|
emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
|
|
78
|
-
|
|
98
|
+
dataAction{Data: []byte("hello2"),
|
|
79
99
|
ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION2"}},
|
|
80
|
-
|
|
100
|
+
dataAction{Data: []byte("hello2"),
|
|
81
101
|
ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION2", BlockHeight: 998, BlockTime: 1}},
|
|
82
102
|
},
|
|
83
103
|
{"data action override BlockHeight",
|
|
84
104
|
emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
|
|
85
|
-
|
|
105
|
+
dataAction{Data: []byte("hello2"),
|
|
86
106
|
ActionHeader: &vm.ActionHeader{BlockHeight: 999}},
|
|
87
|
-
|
|
107
|
+
dataAction{Data: []byte("hello2"),
|
|
88
108
|
ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION", BlockHeight: 999, BlockTime: 1}},
|
|
89
109
|
},
|
|
90
110
|
{"data action override BlockTime",
|
|
91
111
|
emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
|
|
92
|
-
|
|
112
|
+
dataAction{Data: []byte("hello2"),
|
|
93
113
|
ActionHeader: &vm.ActionHeader{BlockTime: 2}},
|
|
94
|
-
|
|
114
|
+
dataAction{Data: []byte("hello2"),
|
|
95
115
|
ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION", BlockHeight: 998, BlockTime: 2}},
|
|
96
116
|
},
|
|
97
117
|
{"data action override all defaults",
|
|
98
118
|
emptyCtx.WithBlockHeight(998).WithBlockTime(time.UnixMicro(1_000_000)),
|
|
99
|
-
|
|
119
|
+
dataAction{Data: []byte("hello2"),
|
|
100
120
|
ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION2", BlockHeight: 999, BlockTime: 2}},
|
|
101
|
-
|
|
121
|
+
dataAction{Data: []byte("hello2"),
|
|
102
122
|
ActionHeader: &vm.ActionHeader{Type: "DATA_ACTION2", BlockHeight: 999, BlockTime: 2}},
|
|
103
123
|
},
|
|
104
124
|
}
|
package/vm/client.go
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
package vm
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"fmt"
|
|
6
|
+
"net/rpc"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// ReceiveMessageMethod is the name of the method we call in order to have the
|
|
10
|
+
// VM receive a Message.
|
|
11
|
+
const ReceiveMessageMethod = "agvm.ReceiveMessage"
|
|
12
|
+
|
|
13
|
+
// Message is what we send to the VM.
|
|
14
|
+
type Message struct {
|
|
15
|
+
Port int
|
|
16
|
+
Data string
|
|
17
|
+
NeedsReply bool
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ClientCodec implements rpc.ClientCodec.
|
|
21
|
+
var _ rpc.ClientCodec = (*ClientCodec)(nil)
|
|
22
|
+
|
|
23
|
+
// ClientCodec implements a net/rpc ClientCodec for the "bridge" between the Go
|
|
24
|
+
// runtime and the VM in the single-process dual-runtime configuration.
|
|
25
|
+
//
|
|
26
|
+
// We expect to call it via the legacy API with signature:
|
|
27
|
+
// sendToController func(needsReply bool, msg string) (string, error)
|
|
28
|
+
// where msg and the returned string are JSON-encoded values.
|
|
29
|
+
//
|
|
30
|
+
// Note that the net/rpc framework cannot express a call that does not expect a
|
|
31
|
+
// response, so we'll note such calls by sending with a reply port of 0 and
|
|
32
|
+
// having the WriteRequest() method fabricate a Receive() call to clear the rpc
|
|
33
|
+
// state.
|
|
34
|
+
type ClientCodec struct {
|
|
35
|
+
ctx context.Context
|
|
36
|
+
send func(port, rPort int, msg string)
|
|
37
|
+
outbound map[int]rpc.Request
|
|
38
|
+
inbound chan *rpc.Response
|
|
39
|
+
replies map[uint64]string
|
|
40
|
+
replyToRead uint64
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// NewClientCodec creates a new ClientCodec.
|
|
44
|
+
func NewClientCodec(ctx context.Context, send func(int, int, string)) *ClientCodec {
|
|
45
|
+
return &ClientCodec{
|
|
46
|
+
ctx: ctx,
|
|
47
|
+
send: send,
|
|
48
|
+
outbound: make(map[int]rpc.Request),
|
|
49
|
+
inbound: make(chan *rpc.Response),
|
|
50
|
+
replies: make(map[uint64]string),
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// WriteRequest sends a request to the VM.
|
|
55
|
+
func (cc *ClientCodec) WriteRequest(r *rpc.Request, body interface{}) error {
|
|
56
|
+
if r.ServiceMethod != ReceiveMessageMethod {
|
|
57
|
+
return fmt.Errorf("unknown method %s", r.ServiceMethod)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
msg, ok := body.(Message)
|
|
61
|
+
if !ok {
|
|
62
|
+
return fmt.Errorf("body %T is not a Message", body)
|
|
63
|
+
}
|
|
64
|
+
rPort := int(r.Seq + 1) // rPort is 1-indexed to indicate it's required
|
|
65
|
+
cc.outbound[rPort] = *r
|
|
66
|
+
var senderReplyPort int
|
|
67
|
+
if msg.NeedsReply {
|
|
68
|
+
senderReplyPort = rPort
|
|
69
|
+
}
|
|
70
|
+
cc.send(msg.Port, senderReplyPort, msg.Data)
|
|
71
|
+
if !msg.NeedsReply {
|
|
72
|
+
return cc.Receive(rPort, false, "<no-reply-requested>")
|
|
73
|
+
}
|
|
74
|
+
return nil
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ReadResponseHeader decodes a response header from the VM.
|
|
78
|
+
func (cc *ClientCodec) ReadResponseHeader(r *rpc.Response) error {
|
|
79
|
+
resp := <-cc.inbound
|
|
80
|
+
*r = *resp
|
|
81
|
+
cc.replyToRead = r.Seq
|
|
82
|
+
return nil
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ReadResponseBody decodes a response body (currently just string) from the VM.
|
|
86
|
+
func (cc *ClientCodec) ReadResponseBody(body interface{}) error {
|
|
87
|
+
if body != nil {
|
|
88
|
+
*body.(*string) = cc.replies[cc.replyToRead]
|
|
89
|
+
}
|
|
90
|
+
delete(cc.replies, cc.replyToRead)
|
|
91
|
+
return nil
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Receive is called by the VM to send a response to the client.
|
|
95
|
+
func (cc *ClientCodec) Receive(rPort int, isError bool, data string) error {
|
|
96
|
+
outb := cc.outbound[rPort]
|
|
97
|
+
delete(cc.outbound, rPort)
|
|
98
|
+
resp := &rpc.Response{
|
|
99
|
+
ServiceMethod: outb.ServiceMethod,
|
|
100
|
+
Seq: outb.Seq,
|
|
101
|
+
}
|
|
102
|
+
if isError {
|
|
103
|
+
resp.Error = data
|
|
104
|
+
} else {
|
|
105
|
+
cc.replies[resp.Seq] = data
|
|
106
|
+
}
|
|
107
|
+
cc.inbound <- resp
|
|
108
|
+
return nil
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
func (cc *ClientCodec) Close() error {
|
|
112
|
+
return nil
|
|
113
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
package vm_test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"fmt"
|
|
7
|
+
"net/rpc"
|
|
8
|
+
"testing"
|
|
9
|
+
"time"
|
|
10
|
+
|
|
11
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
type errorWrapper struct {
|
|
15
|
+
Error string `json:"error"`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ConnectVMClientCodec creates an RPC client codec and a sender to the
|
|
19
|
+
// in-process implementation of the VM.
|
|
20
|
+
func ConnectVMClientCodec(ctx context.Context, nodePort int, sendFunc func(int, int, string)) (*vm.ClientCodec, vm.Sender) {
|
|
21
|
+
vmClientCodec := vm.NewClientCodec(ctx, sendFunc)
|
|
22
|
+
vmClient := rpc.NewClientWithCodec(vmClientCodec)
|
|
23
|
+
|
|
24
|
+
sendToNode := func(ctx context.Context, needReply bool, jsonRequest string) (jsonReply string, err error) {
|
|
25
|
+
if jsonRequest == "shutdown" {
|
|
26
|
+
return "", vmClientCodec.Close()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
msg := vm.Message{
|
|
30
|
+
Port: nodePort,
|
|
31
|
+
NeedsReply: needReply,
|
|
32
|
+
Data: jsonRequest,
|
|
33
|
+
}
|
|
34
|
+
var reply string
|
|
35
|
+
err = vmClient.Call(vm.ReceiveMessageMethod, msg, &reply)
|
|
36
|
+
return reply, err
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return vmClientCodec, sendToNode
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type Fixture struct {
|
|
43
|
+
SendToNode vm.Sender
|
|
44
|
+
SendToGo func(port int, msgStr string) string
|
|
45
|
+
ReplyToGo func(replyPort int, isError bool, respStr string) int
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
func NewFixture(t *testing.T) *Fixture {
|
|
49
|
+
nodePort := 42
|
|
50
|
+
|
|
51
|
+
f := &Fixture{}
|
|
52
|
+
agdServer := vm.NewAgdServer()
|
|
53
|
+
|
|
54
|
+
sendFunc := func(port int, reply int, str string) {
|
|
55
|
+
switch str {
|
|
56
|
+
case "ping":
|
|
57
|
+
time.AfterFunc(100*time.Millisecond, func() {
|
|
58
|
+
fmt.Printf("sendFunc: port=%d, reply=%d, str=%s\n", port, reply, str)
|
|
59
|
+
if reply != 0 {
|
|
60
|
+
f.ReplyToGo(reply, false, "pong")
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
case "wait":
|
|
64
|
+
time.AfterFunc(300*time.Millisecond, func() {
|
|
65
|
+
fmt.Printf("sendFunc: port=%d, reply=%d, str=%s\n", port, reply, str)
|
|
66
|
+
if reply != 0 {
|
|
67
|
+
f.ReplyToGo(reply, false, "done-waiting")
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
default:
|
|
71
|
+
t.Errorf("Unexpected message %s", str)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
vmClientCodec, sendToNode := ConnectVMClientCodec(
|
|
76
|
+
context.Background(),
|
|
77
|
+
int(nodePort),
|
|
78
|
+
sendFunc,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
f.SendToNode = sendToNode
|
|
82
|
+
f.SendToGo = func(port int, msgStr string) string {
|
|
83
|
+
fmt.Println("Send to Go", msgStr)
|
|
84
|
+
var respStr string
|
|
85
|
+
message := &vm.Message{
|
|
86
|
+
Port: int(port),
|
|
87
|
+
NeedsReply: true,
|
|
88
|
+
Data: msgStr,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
err := agdServer.ReceiveMessage(message, &respStr)
|
|
92
|
+
if err == nil {
|
|
93
|
+
return respStr
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// fmt.Fprintln(os.Stderr, "Cannot receive from controller", err)
|
|
97
|
+
errResp := errorWrapper{
|
|
98
|
+
Error: err.Error(),
|
|
99
|
+
}
|
|
100
|
+
respBytes, err := json.Marshal(&errResp)
|
|
101
|
+
if err != nil {
|
|
102
|
+
panic(err)
|
|
103
|
+
}
|
|
104
|
+
return string(respBytes)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
f.ReplyToGo = func(replyPort int, isError bool, respStr string) int {
|
|
108
|
+
if err := vmClientCodec.Receive(replyPort, isError, respStr); err != nil {
|
|
109
|
+
return 1
|
|
110
|
+
}
|
|
111
|
+
return 0
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return f
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
func TestClient_oneOutbound(t *testing.T) {
|
|
118
|
+
f := NewFixture(t)
|
|
119
|
+
|
|
120
|
+
// Try one blocking call.
|
|
121
|
+
ret, err := f.SendToNode(context.Background(), true, "ping")
|
|
122
|
+
if err != nil {
|
|
123
|
+
t.Error(err)
|
|
124
|
+
}
|
|
125
|
+
if ret != "pong" {
|
|
126
|
+
t.Errorf("ping want pong, got %s", ret)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
func TestClient_ShortBg(t *testing.T) {
|
|
131
|
+
|
|
132
|
+
f := NewFixture(t)
|
|
133
|
+
|
|
134
|
+
// Try a short background call with a long overlapping call.
|
|
135
|
+
done := make(chan struct{})
|
|
136
|
+
go func() {
|
|
137
|
+
defer close(done)
|
|
138
|
+
ret, err := f.SendToNode(context.Background(), true, "ping")
|
|
139
|
+
if err != nil {
|
|
140
|
+
t.Error(err)
|
|
141
|
+
}
|
|
142
|
+
if ret != "pong" {
|
|
143
|
+
t.Errorf("ping want pong, got %s", ret)
|
|
144
|
+
}
|
|
145
|
+
}()
|
|
146
|
+
|
|
147
|
+
ret, err := f.SendToNode(context.Background(), true, "wait")
|
|
148
|
+
if err != nil {
|
|
149
|
+
t.Error(err)
|
|
150
|
+
}
|
|
151
|
+
if ret != "done-waiting" {
|
|
152
|
+
t.Errorf("wait want done-waiting, got %s", ret)
|
|
153
|
+
}
|
|
154
|
+
<-done
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
func TestClient_LongBg(t *testing.T) {
|
|
158
|
+
|
|
159
|
+
f := NewFixture(t)
|
|
160
|
+
|
|
161
|
+
// Try a long background call with a short overlapping call.
|
|
162
|
+
done := make(chan struct{})
|
|
163
|
+
go func() {
|
|
164
|
+
defer close(done)
|
|
165
|
+
ret, err := f.SendToNode(context.Background(), true, "wait")
|
|
166
|
+
if err != nil {
|
|
167
|
+
t.Error(err)
|
|
168
|
+
}
|
|
169
|
+
if ret != "done-waiting" {
|
|
170
|
+
t.Errorf("ping want done-waiting, got %s", ret)
|
|
171
|
+
}
|
|
172
|
+
}()
|
|
173
|
+
|
|
174
|
+
ret, err := f.SendToNode(context.Background(), true, "ping")
|
|
175
|
+
if err != nil {
|
|
176
|
+
t.Error(err)
|
|
177
|
+
}
|
|
178
|
+
if ret != "pong" {
|
|
179
|
+
t.Errorf("wait want pong, got %s", ret)
|
|
180
|
+
}
|
|
181
|
+
<-done
|
|
182
|
+
}
|
package/vm/controller.go
CHANGED
|
@@ -7,6 +7,9 @@ import (
|
|
|
7
7
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
8
8
|
)
|
|
9
9
|
|
|
10
|
+
// Sender makes a request of our associated VM.
|
|
11
|
+
type Sender func(ctx context.Context, needReply bool, jsonRequest string) (jsonReply string, err error)
|
|
12
|
+
|
|
10
13
|
type ControllerAdmissionMsg interface {
|
|
11
14
|
sdk.Msg
|
|
12
15
|
CheckAdmissibility(sdk.Context, interface{}) error
|
|
@@ -21,52 +24,26 @@ type ControllerAdmissionMsg interface {
|
|
|
21
24
|
IsHighPriority(sdk.Context, interface{}) (bool, error)
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
var wrappedEmptySDKContext = sdk.WrapSDKContext(
|
|
25
|
-
sdk.Context{}.WithContext(context.Background()),
|
|
26
|
-
)
|
|
27
|
-
var controllerContext context.Context = wrappedEmptySDKContext
|
|
28
|
-
|
|
29
27
|
type PortHandler interface {
|
|
30
28
|
Receive(context.Context, string) (string, error)
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
var nameToPort = make(map[string]int)
|
|
36
|
-
var lastPort = 0
|
|
37
|
-
|
|
38
|
-
func SetControllerContext(ctx sdk.Context) func() {
|
|
39
|
-
// We are only called by the controller, so we assume that it is billing its
|
|
40
|
-
// own meter usage.
|
|
41
|
-
controllerContext = sdk.WrapSDKContext(ctx.WithGasMeter(sdk.NewInfiniteGasMeter()))
|
|
42
|
-
return func() {
|
|
43
|
-
controllerContext = wrappedEmptySDKContext
|
|
44
|
-
}
|
|
31
|
+
type protectedPortHandler struct {
|
|
32
|
+
inner PortHandler
|
|
45
33
|
}
|
|
46
34
|
|
|
47
|
-
func
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
func UnregisterPortHandler(portNum int) error {
|
|
59
|
-
delete(portToHandler, portNum)
|
|
60
|
-
name := portToName[portNum]
|
|
61
|
-
delete(portToName, portNum)
|
|
62
|
-
delete(nameToPort, name)
|
|
63
|
-
return nil
|
|
35
|
+
func (h protectedPortHandler) Receive(ctx context.Context, str string) (ret string, err error) {
|
|
36
|
+
defer func() {
|
|
37
|
+
if r := recover(); r != nil {
|
|
38
|
+
// Propagate just the string, not the error stack or we will invite
|
|
39
|
+
// nondeterminism.
|
|
40
|
+
err = fmt.Errorf("panic: %s", r)
|
|
41
|
+
}
|
|
42
|
+
}()
|
|
43
|
+
ret, err = h.inner.Receive(ctx, str)
|
|
44
|
+
return
|
|
64
45
|
}
|
|
65
46
|
|
|
66
|
-
func
|
|
67
|
-
|
|
68
|
-
if handler == nil {
|
|
69
|
-
return "", fmt.Errorf("unregistered port %d", portNum)
|
|
70
|
-
}
|
|
71
|
-
return handler.Receive(controllerContext, msg)
|
|
47
|
+
func NewProtectedPortHandler(inner PortHandler) PortHandler {
|
|
48
|
+
return protectedPortHandler{inner}
|
|
72
49
|
}
|
package/vm/core_proposals.go
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
package vm
|
|
2
2
|
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"fmt"
|
|
6
|
+
)
|
|
7
|
+
|
|
3
8
|
// CoreProposalStep is a set of core proposal configs which are executed
|
|
4
9
|
// concurrently
|
|
5
10
|
type CoreProposalStep []Jsonable
|
|
@@ -11,12 +16,27 @@ type CoreProposals struct {
|
|
|
11
16
|
Steps []CoreProposalStep `json:"steps"`
|
|
12
17
|
}
|
|
13
18
|
|
|
19
|
+
type ArbitraryCoreProposal struct {
|
|
20
|
+
Json json.RawMessage
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func NewArbitraryCoreProposal(jsonStr string) *ArbitraryCoreProposal {
|
|
24
|
+
return &ArbitraryCoreProposal{Json: []byte(jsonStr)}
|
|
25
|
+
}
|
|
26
|
+
|
|
14
27
|
// CoreProposalStepForModules generates a single core proposal step from
|
|
15
28
|
// the given modules, which will be executed concurrently during that step
|
|
16
|
-
func CoreProposalStepForModules(modules ...
|
|
29
|
+
func CoreProposalStepForModules(modules ...Jsonable) CoreProposalStep {
|
|
17
30
|
step := make([]Jsonable, len(modules))
|
|
18
31
|
for i := range modules {
|
|
19
|
-
|
|
32
|
+
switch m := modules[i].(type) {
|
|
33
|
+
case ArbitraryCoreProposal:
|
|
34
|
+
step[i] = m.Json
|
|
35
|
+
case string:
|
|
36
|
+
step[i] = m
|
|
37
|
+
default:
|
|
38
|
+
panic(fmt.Errorf("unexpected step type %T", m))
|
|
39
|
+
}
|
|
20
40
|
}
|
|
21
41
|
return step
|
|
22
42
|
}
|