@agoric/cosmos 0.35.0-u15.0 → 0.35.0-u16.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 -149
- package/MAINTAINERS.md +3 -0
- package/Makefile +36 -26
- package/ante/ante.go +6 -5
- package/ante/inbound_test.go +3 -2
- package/ante/vm_admission.go +2 -1
- package/app/app.go +206 -147
- 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 +164 -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 +12 -7
- package/go.sum +13 -9
- package/package.json +8 -4
- 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 +16 -5
- 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/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
|
@@ -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
|
|
package/x/swingset/genesis.go
CHANGED
|
@@ -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
|
|
56
|
-
|
|
57
|
-
|
|
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.
|
|
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:
|
|
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
|
-
|
|
101
|
-
// The export will fail if the swing-store does not contain all replay artifacts
|
|
147
|
+
eventHandler,
|
|
102
148
|
keeper.SwingStoreExportOptions{
|
|
103
|
-
ArtifactMode: keeper.
|
|
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
|
-
|
|
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
|
}
|
package/x/swingset/handler.go
CHANGED
|
@@ -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,
|
|
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:
|
|
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:
|
|
307
|
+
SwingStoreRestoreOptions{ArtifactMode: SwingStoreArtifactModeOperational, ExportDataMode: SwingStoreExportDataModeAll},
|
|
308
308
|
)
|
|
309
309
|
}
|