@agoric/cosmos 0.34.2-dev-ecf2d8e.0 → 0.35.0-other-dev-70beeb7.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 +45 -0
- package/app/app.go +103 -14
- package/app/const.go +6 -0
- package/cmd/agd/main.go +11 -133
- package/cmd/libdaemon/main.go +53 -67
- package/daemon/cmd/root.go +24 -55
- package/daemon/main.go +1 -3
- package/git-revision.txt +1 -1
- package/package.json +3 -3
- package/proto/agoric/vstorage/query.proto +1 -53
- package/vm/controller.go +18 -8
- package/x/lien/lien.go +4 -6
- package/x/lien/lien_test.go +15 -19
- package/x/swingset/abci.go +2 -3
- package/x/swingset/swingset.go +2 -4
- package/x/swingset/types/default-params.go +1 -1
- package/x/swingset/types/msgs.pb.go +16 -16
- package/x/vbank/vbank.go +10 -11
- package/x/vbank/vbank_test.go +5 -5
- package/x/vibc/ibc.go +11 -12
- package/x/vibc/keeper/keeper.go +15 -1
- package/x/vibc/types/expected_keepers.go +1 -2
- package/x/vstorage/keeper/grpc_query.go +0 -221
- package/x/vstorage/keeper/querier.go +11 -31
- package/x/vstorage/types/path_keys.go +10 -22
- package/x/vstorage/types/path_keys_test.go +18 -84
- package/x/vstorage/types/query.pb.go +36 -646
- package/x/vstorage/types/query.pb.gw.go +0 -119
- package/x/vstorage/vstorage.go +15 -16
- package/x/vstorage/vstorage_test.go +4 -4
- package/cmd/agd/agvm.go +0 -42
- package/vm/client.go +0 -113
- package/vm/client_test.go +0 -184
- package/vm/jsonrpcconn/jsonrpcconn.go +0 -160
- package/vm/jsonrpcconn/jsonrpcconn_test.go +0 -126
- package/vm/server.go +0 -23
- package/x/vstorage/README.md +0 -95
- package/x/vstorage/capdata/capdata.go +0 -298
- package/x/vstorage/capdata/capdata_test.go +0 -352
- package/x/vstorage/keeper/keeper_grpc_test.go +0 -300
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,51 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.35.0-u11.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/cosmos@0.34.1...@agoric/cosmos@0.35.0-u11.0) (2023-08-24)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### ⚠ BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* **cosmos:** add required export-dir export cmd option
|
|
12
|
+
* remove deprecated `ag-cosmos-helper`
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **agd:** try harder to find cosmic-swingset ([a1d1666](https://github.com/Agoric/agoric-sdk/commit/a1d1666997c2f5b9c7bf14748f6d9603c0b3c5f9))
|
|
17
|
+
* **cosmic-swingset:** add repair-metadata snapshot restore option ([ebbb982](https://github.com/Agoric/agoric-sdk/commit/ebbb9829f1f845c0932ae92b23d0d43be9a0e196))
|
|
18
|
+
* **cosmic-swingset:** replace import/export options ([393b91b](https://github.com/Agoric/agoric-sdk/commit/393b91baaa25c61364955102e8cfcdcaec90870d))
|
|
19
|
+
* **cosmic-swingset:** use x/swingset for swing-store export data ([3336b62](https://github.com/Agoric/agoric-sdk/commit/3336b62fbb10bd2293a832f8c30e590530d14213))
|
|
20
|
+
* **cosmos:** add required export-dir export cmd option ([8d2571c](https://github.com/Agoric/agoric-sdk/commit/8d2571c51c2fe08d630dd2897d7e5e1b45ab45c9))
|
|
21
|
+
* **cosmos:** fix and migrate swing-store ([6ba1957](https://github.com/Agoric/agoric-sdk/commit/6ba19571688518dcfdc4553a0c822695a61908b1))
|
|
22
|
+
* **cosmos:** KVEntry implements json Marshaler and Unmarshaller ([6d2fe11](https://github.com/Agoric/agoric-sdk/commit/6d2fe11d144c5bbdc1611b59c84b6842e8084cb9))
|
|
23
|
+
* **cosmos:** spawn JS on export command ([fe4eb56](https://github.com/Agoric/agoric-sdk/commit/fe4eb56facf83569aa343f098e97c6229556afa9))
|
|
24
|
+
* **cosmos:** wire new swingset port handler ([3361b25](https://github.com/Agoric/agoric-sdk/commit/3361b25ddaa00116476d3de1107e800499ab5c21))
|
|
25
|
+
* **x/swingset:** add store data to genesis ([df72903](https://github.com/Agoric/agoric-sdk/commit/df729030643a097262ad1393503d380e243107eb))
|
|
26
|
+
* **x/swingset:** add WaitUntilSwingStoreExportDone ([f8acd22](https://github.com/Agoric/agoric-sdk/commit/f8acd22381ff3da4682bcb0cdcf71665095506a4))
|
|
27
|
+
* **x/swingset:** allow taking snapshot latest height ([0c0e742](https://github.com/Agoric/agoric-sdk/commit/0c0e74227d34d49ac7ce76ce8e92715816d5ea6a))
|
|
28
|
+
* **x/swingset:** export swing store in genesis ([e5f9425](https://github.com/Agoric/agoric-sdk/commit/e5f9425e74c7235323cd6b1b88540b73b57a69a6))
|
|
29
|
+
* **x/swingset:** import swing store from genesis state ([2446cf4](https://github.com/Agoric/agoric-sdk/commit/2446cf43bb13aad7de0805cd7e33c966d2e31016))
|
|
30
|
+
* Cosmos upgrade handler calls swingset ([66f7bcc](https://github.com/Agoric/agoric-sdk/commit/66f7bccce7ce30cf5b9e1e5321710567c05723cb))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* **cosmos:** don't init controller before upgrade ([e567c21](https://github.com/Agoric/agoric-sdk/commit/e567c21a224d239c467f740bb937f84b18db9dd7))
|
|
36
|
+
* **cosmos:** module order independent init and bootstrap ([3ce4012](https://github.com/Agoric/agoric-sdk/commit/3ce4012ea99b39b2d6bfd422b1d7ea7a7e904568))
|
|
37
|
+
* **cosmos:** prevent Golang error wrapping stack frame divergence ([1d8acf6](https://github.com/Agoric/agoric-sdk/commit/1d8acf6270cadfbcdafb1081360155260d031ac1))
|
|
38
|
+
* **cosmos:** Support building on Linux aarch64 ([475708e](https://github.com/Agoric/agoric-sdk/commit/475708e63bb95d75184072547ca92586a978c5a0))
|
|
39
|
+
* **x/swingset:** enforce snapshot restore before init ([c946d58](https://github.com/Agoric/agoric-sdk/commit/c946d5866ef956c198d7ea14936eb9904aa272ae))
|
|
40
|
+
* **x/swingset:** guard snapshot restore for concurrency ([5320a30](https://github.com/Agoric/agoric-sdk/commit/5320a30a873455764104e13d89131e30a93a238c))
|
|
41
|
+
* **x/swingset:** switch export/import to replay artifact level ([c037ea3](https://github.com/Agoric/agoric-sdk/commit/c037ea3931877fe4d56df5b82cc7c3eb77a84a53))
|
|
42
|
+
* **x/vstorage:** value can be empty in genesis data ([9a51df5](https://github.com/Agoric/agoric-sdk/commit/9a51df515b87638b869564ab08445a0ce0d55707))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Build System
|
|
46
|
+
|
|
47
|
+
* remove deprecated `ag-cosmos-helper` ([ee43112](https://github.com/Agoric/agoric-sdk/commit/ee431121e3f93406896f8a9e7d949fbf1427c44e))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
6
51
|
### [0.34.1](https://github.com/Agoric/agoric-sdk/compare/@agoric/cosmos@0.34.0...@agoric/cosmos@0.34.1) (2023-06-09)
|
|
7
52
|
|
|
8
53
|
**Note:** Version bump only for package @agoric/cosmos
|
package/app/app.go
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package gaia
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
"context"
|
|
5
4
|
"encoding/json"
|
|
6
5
|
"fmt"
|
|
7
6
|
"io"
|
|
@@ -288,7 +287,7 @@ func NewGaiaApp(
|
|
|
288
287
|
appOpts servertypes.AppOptions,
|
|
289
288
|
baseAppOptions ...func(*baseapp.BaseApp),
|
|
290
289
|
) *GaiaApp {
|
|
291
|
-
defaultController := func(
|
|
290
|
+
defaultController := func(needReply bool, str string) (string, error) {
|
|
292
291
|
fmt.Fprintln(os.Stderr, "FIXME: Would upcall to controller with", str)
|
|
293
292
|
return "", nil
|
|
294
293
|
}
|
|
@@ -300,7 +299,7 @@ func NewGaiaApp(
|
|
|
300
299
|
}
|
|
301
300
|
|
|
302
301
|
func NewAgoricApp(
|
|
303
|
-
sendToController func(
|
|
302
|
+
sendToController func(bool, string) (string, error),
|
|
304
303
|
logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool,
|
|
305
304
|
homePath string, invCheckPeriod uint, encodingConfig gaiaappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp),
|
|
306
305
|
) *GaiaApp {
|
|
@@ -450,7 +449,7 @@ func NewAgoricApp(
|
|
|
450
449
|
app.CheckControllerInited(true)
|
|
451
450
|
// We use SwingSet-level metering to charge the user for the call.
|
|
452
451
|
defer vm.SetControllerContext(ctx)()
|
|
453
|
-
return sendToController(
|
|
452
|
+
return sendToController(true, str)
|
|
454
453
|
}
|
|
455
454
|
|
|
456
455
|
setBootstrapNeeded := func() {
|
|
@@ -482,7 +481,7 @@ func NewAgoricApp(
|
|
|
482
481
|
if err != nil {
|
|
483
482
|
return "", err
|
|
484
483
|
}
|
|
485
|
-
return sendToController(
|
|
484
|
+
return sendToController(true, string(bz))
|
|
486
485
|
},
|
|
487
486
|
)
|
|
488
487
|
|
|
@@ -791,18 +790,13 @@ func NewAgoricApp(
|
|
|
791
790
|
app.SetBeginBlocker(app.BeginBlocker)
|
|
792
791
|
app.SetEndBlocker(app.EndBlocker)
|
|
793
792
|
|
|
794
|
-
const (
|
|
795
|
-
upgradeName = "agoric-upgrade-12"
|
|
796
|
-
upgradeNameTest = "agorictest-upgrade-12"
|
|
797
|
-
)
|
|
798
|
-
|
|
799
793
|
app.UpgradeKeeper.SetUpgradeHandler(
|
|
800
794
|
upgradeName,
|
|
801
|
-
|
|
795
|
+
upgrade11Handler(app, upgradeName),
|
|
802
796
|
)
|
|
803
797
|
app.UpgradeKeeper.SetUpgradeHandler(
|
|
804
798
|
upgradeNameTest,
|
|
805
|
-
|
|
799
|
+
upgrade11Handler(app, upgradeNameTest),
|
|
806
800
|
)
|
|
807
801
|
|
|
808
802
|
if loadLatest {
|
|
@@ -825,13 +819,108 @@ func NewAgoricApp(
|
|
|
825
819
|
return app
|
|
826
820
|
}
|
|
827
821
|
|
|
828
|
-
|
|
829
|
-
|
|
822
|
+
type swingStoreMigrationEventHandler struct {
|
|
823
|
+
swingStore sdk.KVStore
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
func (eventHandler swingStoreMigrationEventHandler) OnExportStarted(height uint64, retrieveSwingStoreExport func() error) error {
|
|
827
|
+
return retrieveSwingStoreExport()
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
func (eventHandler swingStoreMigrationEventHandler) OnExportRetrieved(provider swingsetkeeper.SwingStoreExportProvider) (err error) {
|
|
831
|
+
exportDataReader, err := provider.GetExportDataReader()
|
|
832
|
+
if err != nil {
|
|
833
|
+
return err
|
|
834
|
+
}
|
|
835
|
+
defer exportDataReader.Close()
|
|
836
|
+
|
|
837
|
+
var hasExportData bool
|
|
838
|
+
|
|
839
|
+
for {
|
|
840
|
+
entry, err := exportDataReader.Read()
|
|
841
|
+
if err == io.EOF {
|
|
842
|
+
break
|
|
843
|
+
} else if err != nil {
|
|
844
|
+
return err
|
|
845
|
+
}
|
|
846
|
+
hasExportData = true
|
|
847
|
+
if !entry.HasValue() {
|
|
848
|
+
return fmt.Errorf("no value for export data key %s", entry.Key())
|
|
849
|
+
}
|
|
850
|
+
eventHandler.swingStore.Set([]byte(entry.Key()), []byte(entry.StringValue()))
|
|
851
|
+
}
|
|
852
|
+
if !hasExportData {
|
|
853
|
+
return fmt.Errorf("export data had no entries")
|
|
854
|
+
}
|
|
855
|
+
return nil
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// upgrade11Handler performs standard upgrade actions plus custom actions for upgrade-11.
|
|
859
|
+
func upgrade11Handler(app *GaiaApp, targetUpgrade string) func(sdk.Context, upgradetypes.Plan, module.VersionMap) (module.VersionMap, error) {
|
|
830
860
|
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVm module.VersionMap) (module.VersionMap, error) {
|
|
831
861
|
app.CheckControllerInited(false)
|
|
832
862
|
// Record the plan to send to SwingSet
|
|
833
863
|
app.upgradePlan = &plan
|
|
834
864
|
|
|
865
|
+
// Perform swing-store migrations. We do this in the app upgrade handler
|
|
866
|
+
// since it involves multiple modules (x/vstorage and x/swingset) which
|
|
867
|
+
// don't strictly have a version change on their own.
|
|
868
|
+
|
|
869
|
+
// We are at the begining of the upgrade block, so all stores are commited
|
|
870
|
+
// as of the end of the previous block
|
|
871
|
+
savedBlockHeight := uint64(ctx.BlockHeight() - 1)
|
|
872
|
+
|
|
873
|
+
// First, repair swing-store metadata in case this node was previously
|
|
874
|
+
// initialized from a state-sync snapshot. This is done with a check on the
|
|
875
|
+
// block height to catch early any hangover related mismatch.
|
|
876
|
+
// Only entries related to missing historical metadata are imported, but we
|
|
877
|
+
// don't know what these look like here, so we provide it all.
|
|
878
|
+
getSwingStoreExportDataFromVstorage := func() (reader agorictypes.KVEntryReader, err error) {
|
|
879
|
+
return agorictypes.NewVstorageDataEntriesReader(
|
|
880
|
+
app.VstorageKeeper.ExportStorageFromPrefix(ctx, swingsetkeeper.StoragePathSwingStore),
|
|
881
|
+
), nil
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// We're not restoring any artifact to swing-store, nor have any to provide
|
|
885
|
+
readNoArtifact := func() (artifact swingsettypes.SwingStoreArtifact, err error) {
|
|
886
|
+
return artifact, io.EOF
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
err := app.SwingStoreExportsHandler.RestoreExport(
|
|
890
|
+
swingsetkeeper.SwingStoreExportProvider{
|
|
891
|
+
BlockHeight: savedBlockHeight,
|
|
892
|
+
GetExportDataReader: getSwingStoreExportDataFromVstorage,
|
|
893
|
+
ReadNextArtifact: readNoArtifact,
|
|
894
|
+
},
|
|
895
|
+
swingsetkeeper.SwingStoreRestoreOptions{
|
|
896
|
+
ArtifactMode: swingsetkeeper.SwingStoreArtifactModeNone,
|
|
897
|
+
ExportDataMode: swingsetkeeper.SwingStoreExportDataModeRepairMetadata,
|
|
898
|
+
},
|
|
899
|
+
)
|
|
900
|
+
if err != nil {
|
|
901
|
+
return nil, err
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// Then migrate the swing-store shadow copy:
|
|
905
|
+
// 1. Remove the swing-store "export data" shadow-copy entries from vstorage.
|
|
906
|
+
// 2. Export swing-store "export-data" (as of the previous block) through a
|
|
907
|
+
// handler that writes every entry into the swingset module's new Store.
|
|
908
|
+
app.VstorageKeeper.RemoveEntriesWithPrefix(ctx, swingsetkeeper.StoragePathSwingStore)
|
|
909
|
+
err = app.SwingStoreExportsHandler.InitiateExport(
|
|
910
|
+
savedBlockHeight,
|
|
911
|
+
swingStoreMigrationEventHandler{swingStore: app.SwingSetKeeper.GetSwingStore(ctx)},
|
|
912
|
+
swingsetkeeper.SwingStoreExportOptions{
|
|
913
|
+
ArtifactMode: swingsetkeeper.SwingStoreArtifactModeNone,
|
|
914
|
+
ExportDataMode: swingsetkeeper.SwingStoreExportDataModeAll,
|
|
915
|
+
},
|
|
916
|
+
)
|
|
917
|
+
if err == nil {
|
|
918
|
+
err = swingsetkeeper.WaitUntilSwingStoreExportDone()
|
|
919
|
+
}
|
|
920
|
+
if err != nil {
|
|
921
|
+
return nil, err
|
|
922
|
+
}
|
|
923
|
+
|
|
835
924
|
// Always run module migrations
|
|
836
925
|
mvm, err := app.mm.RunMigrations(ctx, app.configurator, fromVm)
|
|
837
926
|
if err != nil {
|
package/app/const.go
ADDED
package/cmd/agd/main.go
CHANGED
|
@@ -1,158 +1,36 @@
|
|
|
1
1
|
package main
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
"context"
|
|
5
|
-
"errors"
|
|
6
|
-
"net/rpc"
|
|
7
|
-
"net/rpc/jsonrpc"
|
|
8
4
|
"os"
|
|
9
|
-
"os/exec"
|
|
10
5
|
"syscall"
|
|
11
|
-
"time"
|
|
12
6
|
|
|
13
|
-
"github.com/spf13/cast"
|
|
14
7
|
"github.com/tendermint/tendermint/libs/log"
|
|
15
8
|
|
|
16
9
|
gaia "github.com/Agoric/agoric-sdk/golang/cosmos/app"
|
|
17
10
|
"github.com/Agoric/agoric-sdk/golang/cosmos/daemon"
|
|
18
11
|
daemoncmd "github.com/Agoric/agoric-sdk/golang/cosmos/daemon/cmd"
|
|
19
|
-
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
20
|
-
"github.com/Agoric/agoric-sdk/golang/cosmos/vm/jsonrpcconn"
|
|
21
|
-
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
|
22
12
|
)
|
|
23
13
|
|
|
24
|
-
// TerminateSubprocessGracePeriod is how long we wait between closing the pipe
|
|
25
|
-
// waiting for it to exit, then sending a termination signal.
|
|
26
|
-
const TerminateSubprocessGracePeriod = 3 * time.Second
|
|
27
|
-
|
|
28
|
-
// KillSubprocessGracePeriod is how long we wait between sending a subprocess a
|
|
29
|
-
// termination signal, waiting for it to exit, then killing it.
|
|
30
|
-
const KillSubprocessGracePeriod = 5 * time.Second
|
|
31
|
-
|
|
32
|
-
// makeShutdown returns a function that terminates the vm.
|
|
33
|
-
func makeShutdown(cmd *exec.Cmd, writer *os.File) func() error {
|
|
34
|
-
return func() error {
|
|
35
|
-
// Stop talking to the subprocess.
|
|
36
|
-
_ = writer.Close()
|
|
37
|
-
go func() {
|
|
38
|
-
// Wait a bit.
|
|
39
|
-
time.Sleep(TerminateSubprocessGracePeriod)
|
|
40
|
-
// Then punch it in the shoulder.
|
|
41
|
-
_ = cmd.Process.Signal(os.Interrupt)
|
|
42
|
-
// Wait a bit.
|
|
43
|
-
time.Sleep(KillSubprocessGracePeriod)
|
|
44
|
-
// Then blow it away.
|
|
45
|
-
_ = cmd.Process.Kill()
|
|
46
|
-
}()
|
|
47
|
-
// Wait for it to keel over.
|
|
48
|
-
return cmd.Wait()
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// main is the entry point of the agd daemon. It determines whether to
|
|
54
|
-
// initialize JSON-RPC communications with the separate `--split-vm` VM process,
|
|
55
|
-
// or just to give up control entirely to another binary.
|
|
56
14
|
func main() {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
nodePort := 1
|
|
61
|
-
sendToNode := func(ctx context.Context, needReply bool, str string) (string, error) {
|
|
62
|
-
if vmClient == nil {
|
|
63
|
-
return "", errors.New("sendToVM called without VM client set up")
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if str == "shutdown" {
|
|
67
|
-
// We could ask nicely, but don't bother.
|
|
68
|
-
if shutdown != nil {
|
|
69
|
-
return "", shutdown()
|
|
70
|
-
}
|
|
71
|
-
return "", nil
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
msg := vm.Message{
|
|
75
|
-
Port: nodePort,
|
|
76
|
-
NeedsReply: needReply,
|
|
77
|
-
Data: str,
|
|
78
|
-
}
|
|
79
|
-
var reply string
|
|
80
|
-
err := vmClient.Call(vm.ReceiveMessageMethod, msg, &reply)
|
|
81
|
-
return reply, err
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
exitCode := 0
|
|
85
|
-
launchVM := func(logger log.Logger, appOpts servertypes.AppOptions) error {
|
|
15
|
+
// We need to delegate to our default app for running the actual chain.
|
|
16
|
+
launchVM := func(logger log.Logger) {
|
|
86
17
|
args := []string{"ag-chain-cosmos", "--home", gaia.DefaultNodeHome}
|
|
87
18
|
args = append(args, os.Args[1:]...)
|
|
88
19
|
|
|
89
|
-
binary :=
|
|
90
|
-
if
|
|
91
|
-
|
|
92
|
-
if lookErr != nil {
|
|
93
|
-
return lookErr
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// We completely delegate to our default app for running the actual chain.
|
|
97
|
-
logger.Info("agd delegating to JS executable", "binary", binary, "args", args)
|
|
98
|
-
return syscall.Exec(binary, args, os.Environ())
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Split the execution between us and the VM.
|
|
102
|
-
agdFromVm, vmToAgd, err := os.Pipe()
|
|
103
|
-
if err != nil {
|
|
104
|
-
return err
|
|
105
|
-
}
|
|
106
|
-
vmFromAgd, agdToVm, err := os.Pipe()
|
|
107
|
-
if err != nil {
|
|
108
|
-
return err
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Start the command running, then continue.
|
|
112
|
-
args[0] = binary
|
|
113
|
-
cmd := NewVMCommand(logger, binary, args, vmFromAgd, vmToAgd)
|
|
114
|
-
shutdown = makeShutdown(cmd, agdToVm)
|
|
115
|
-
|
|
116
|
-
if err := cmd.Start(); err != nil {
|
|
117
|
-
return err
|
|
118
|
-
}
|
|
119
|
-
if vmFromAgd.Close() != nil {
|
|
120
|
-
return err
|
|
121
|
-
}
|
|
122
|
-
if vmToAgd.Close() != nil {
|
|
123
|
-
return err
|
|
20
|
+
binary, lookErr := FindCosmicSwingsetBinary()
|
|
21
|
+
if lookErr != nil {
|
|
22
|
+
panic(lookErr)
|
|
124
23
|
}
|
|
125
24
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// Set up the VM server.
|
|
131
|
-
vmServer := rpc.NewServer()
|
|
132
|
-
if err := vmServer.RegisterName("agd", vm.NewAgdServer()); err != nil {
|
|
133
|
-
return err
|
|
25
|
+
logger.Info("agd delegating to JS executable", "binary", binary, "args", args)
|
|
26
|
+
execErr := syscall.Exec(binary, args, os.Environ())
|
|
27
|
+
if execErr != nil {
|
|
28
|
+
panic(execErr)
|
|
134
29
|
}
|
|
135
|
-
go vmServer.ServeCodec(jsonrpc.NewServerCodec(serverConn))
|
|
136
|
-
|
|
137
|
-
// Set up the VM client.
|
|
138
|
-
vmClient = jsonrpc.NewClient(clientConn)
|
|
139
|
-
|
|
140
|
-
go func() {
|
|
141
|
-
// Premature exit from `agd start` should exit the process.
|
|
142
|
-
_ = cmd.Wait()
|
|
143
|
-
os.Exit(exitCode)
|
|
144
|
-
}()
|
|
145
|
-
|
|
146
|
-
return nil
|
|
147
30
|
}
|
|
148
31
|
|
|
32
|
+
daemoncmd.OnStartHook = launchVM
|
|
149
33
|
daemoncmd.OnExportHook = launchVM
|
|
150
|
-
daemoncmd.OnStartHook = func (logger log.Logger, appOpts servertypes.AppOptions) error {
|
|
151
|
-
// We tried running start, which should never exit, so exit with non-zero
|
|
152
|
-
// code if we do.
|
|
153
|
-
exitCode = 99
|
|
154
|
-
return launchVM(logger, appOpts)
|
|
155
|
-
}
|
|
156
34
|
|
|
157
|
-
daemon.RunWithController(
|
|
35
|
+
daemon.RunWithController(nil)
|
|
158
36
|
}
|
package/cmd/libdaemon/main.go
CHANGED
|
@@ -10,9 +10,8 @@ package main
|
|
|
10
10
|
import "C"
|
|
11
11
|
|
|
12
12
|
import (
|
|
13
|
-
"context"
|
|
14
13
|
"encoding/json"
|
|
15
|
-
"
|
|
14
|
+
"errors"
|
|
16
15
|
"os"
|
|
17
16
|
"path/filepath"
|
|
18
17
|
|
|
@@ -22,7 +21,6 @@ import (
|
|
|
22
21
|
"github.com/Agoric/agoric-sdk/golang/cosmos/daemon"
|
|
23
22
|
daemoncmd "github.com/Agoric/agoric-sdk/golang/cosmos/daemon/cmd"
|
|
24
23
|
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
25
|
-
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
|
26
24
|
)
|
|
27
25
|
|
|
28
26
|
type goReturn = struct {
|
|
@@ -32,32 +30,8 @@ type goReturn = struct {
|
|
|
32
30
|
|
|
33
31
|
const SwingSetPort = 123
|
|
34
32
|
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
|
|
38
|
-
// ConnectVMClientCodec creates an RPC client codec and a sender to the
|
|
39
|
-
// in-process implementation of the VM.
|
|
40
|
-
func ConnectVMClientCodec(ctx context.Context, nodePort int, sendFunc func(int, int, string)) (*vm.ClientCodec, daemoncmd.Sender) {
|
|
41
|
-
vmClientCodec = vm.NewClientCodec(context.Background(), sendFunc)
|
|
42
|
-
vmClient := rpc.NewClientWithCodec(vmClientCodec)
|
|
43
|
-
|
|
44
|
-
sendToNode := func(ctx context.Context, needReply bool, str string) (string, error) {
|
|
45
|
-
if str == "shutdown" {
|
|
46
|
-
return "", vmClientCodec.Close()
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
msg := vm.Message{
|
|
50
|
-
Port: nodePort,
|
|
51
|
-
NeedsReply: needReply,
|
|
52
|
-
Data: str,
|
|
53
|
-
}
|
|
54
|
-
var reply string
|
|
55
|
-
err := vmClient.Call(vm.ReceiveMessageMethod, msg, &reply)
|
|
56
|
-
return reply, err
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return vmClientCodec, sendToNode
|
|
60
|
-
}
|
|
33
|
+
var replies = map[int]chan goReturn{}
|
|
34
|
+
var lastReply = 0
|
|
61
35
|
|
|
62
36
|
//export RunAgCosmosDaemon
|
|
63
37
|
func RunAgCosmosDaemon(nodePort C.int, toNode C.sendFunc, cosmosArgs []*C.char) C.int {
|
|
@@ -68,39 +42,46 @@ func RunAgCosmosDaemon(nodePort C.int, toNode C.sendFunc, cosmosArgs []*C.char)
|
|
|
68
42
|
|
|
69
43
|
gaia.DefaultNodeHome = filepath.Join(userHomeDir, ".ag-chain-cosmos")
|
|
70
44
|
daemoncmd.AppName = "ag-chain-cosmos"
|
|
71
|
-
if err := os.Setenv(daemoncmd.EmbeddedVmEnvVar, "libdaemon"); err != nil {
|
|
72
|
-
panic(err)
|
|
73
|
-
}
|
|
74
45
|
|
|
75
|
-
|
|
46
|
+
// FIXME: Decouple the sending logic from the Cosmos app.
|
|
47
|
+
sendToNode := func(needReply bool, str string) (string, error) {
|
|
48
|
+
var rPort int
|
|
49
|
+
if needReply {
|
|
50
|
+
lastReply++
|
|
51
|
+
rPort = lastReply
|
|
52
|
+
replies[rPort] = make(chan goReturn)
|
|
53
|
+
}
|
|
76
54
|
|
|
77
|
-
|
|
78
|
-
C.invokeSendFunc(toNode,
|
|
79
|
-
|
|
55
|
+
// Send the message
|
|
56
|
+
C.invokeSendFunc(toNode, nodePort, C.int(rPort), C.CString(str))
|
|
57
|
+
if !needReply {
|
|
58
|
+
// Return immediately
|
|
59
|
+
// fmt.Fprintln(os.Stderr, "Don't wait")
|
|
60
|
+
return "<no-reply-requested>", nil
|
|
61
|
+
}
|
|
80
62
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
63
|
+
// Block the sending goroutine while we wait for the reply
|
|
64
|
+
// fmt.Fprintln(os.Stderr, "Waiting for", rPort)
|
|
65
|
+
ret := <-replies[rPort]
|
|
66
|
+
delete(replies, rPort)
|
|
67
|
+
// fmt.Fprintln(os.Stderr, "Woken, got", ret)
|
|
68
|
+
return ret.str, ret.err
|
|
69
|
+
}
|
|
87
70
|
|
|
88
71
|
args := make([]string, len(cosmosArgs))
|
|
89
72
|
for i, s := range cosmosArgs {
|
|
90
73
|
args[i] = C.GoString(s)
|
|
91
74
|
}
|
|
92
|
-
|
|
93
75
|
// fmt.Fprintln(os.Stderr, "Starting Cosmos", args)
|
|
94
76
|
os.Args = args
|
|
95
77
|
go func() {
|
|
96
78
|
// We run in the background, but exit when the job is over.
|
|
97
79
|
// swingset.SendToNode("hello from Initial Go!")
|
|
98
80
|
exitCode := 0
|
|
99
|
-
daemoncmd.OnStartHook = func(logger log.Logger
|
|
81
|
+
daemoncmd.OnStartHook = func(logger log.Logger) {
|
|
100
82
|
// We tried running start, which should never exit, so exit with non-zero
|
|
101
83
|
// code if we ever stop.
|
|
102
84
|
exitCode = 99
|
|
103
|
-
return nil
|
|
104
85
|
}
|
|
105
86
|
daemon.RunWithController(sendToNode)
|
|
106
87
|
// fmt.Fprintln(os.Stderr, "Shutting down Cosmos")
|
|
@@ -113,10 +94,22 @@ func RunAgCosmosDaemon(nodePort C.int, toNode C.sendFunc, cosmosArgs []*C.char)
|
|
|
113
94
|
//export ReplyToGo
|
|
114
95
|
func ReplyToGo(replyPort C.int, isError C.int, resp C.Body) C.int {
|
|
115
96
|
respStr := C.GoString(resp)
|
|
116
|
-
// fmt.
|
|
117
|
-
|
|
118
|
-
|
|
97
|
+
// fmt.Fprintln(os.Stderr, "Reply to Go", respStr)
|
|
98
|
+
returnCh := replies[int(replyPort)]
|
|
99
|
+
if returnCh == nil {
|
|
100
|
+
// Unexpected reply.
|
|
101
|
+
// This is okay, since the caller decides whether or
|
|
102
|
+
// not she wants to listen for replies.
|
|
103
|
+
return C.int(0)
|
|
119
104
|
}
|
|
105
|
+
// Wake up the waiting goroutine
|
|
106
|
+
ret := goReturn{}
|
|
107
|
+
if int(isError) == 0 {
|
|
108
|
+
ret.str = respStr
|
|
109
|
+
} else {
|
|
110
|
+
ret.err = errors.New(respStr)
|
|
111
|
+
}
|
|
112
|
+
returnCh <- ret
|
|
120
113
|
return C.int(0)
|
|
121
114
|
}
|
|
122
115
|
|
|
@@ -128,27 +121,20 @@ type errorWrapper struct {
|
|
|
128
121
|
func SendToGo(port C.int, msg C.Body) C.Body {
|
|
129
122
|
msgStr := C.GoString(msg)
|
|
130
123
|
// fmt.Fprintln(os.Stderr, "Send to Go", msgStr)
|
|
131
|
-
|
|
132
|
-
message := &vm.Message{
|
|
133
|
-
Port: int(port),
|
|
134
|
-
NeedsReply: true,
|
|
135
|
-
Data: msgStr,
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
err := agdServer.ReceiveMessage(message, &respStr)
|
|
139
|
-
if err == nil {
|
|
140
|
-
return C.CString(respStr)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// fmt.Fprintln(os.Stderr, "Cannot receive from controller", err)
|
|
144
|
-
errResp := errorWrapper{
|
|
145
|
-
Error: err.Error(),
|
|
146
|
-
}
|
|
147
|
-
respBytes, err := json.Marshal(&errResp)
|
|
124
|
+
respStr, err := vm.ReceiveFromController(int(port), msgStr)
|
|
148
125
|
if err != nil {
|
|
149
|
-
|
|
126
|
+
// fmt.Fprintln(os.Stderr, "Cannot receive from controller", err)
|
|
127
|
+
errResp := errorWrapper{
|
|
128
|
+
Error: err.Error(),
|
|
129
|
+
}
|
|
130
|
+
respBytes, err := json.Marshal(&errResp)
|
|
131
|
+
if err != nil {
|
|
132
|
+
panic(err)
|
|
133
|
+
}
|
|
134
|
+
// fmt.Fprintln(os.Stderr, "Marshaled", errResp, respBytes)
|
|
135
|
+
respStr = string(respBytes)
|
|
150
136
|
}
|
|
151
|
-
return C.CString(
|
|
137
|
+
return C.CString(respStr)
|
|
152
138
|
}
|
|
153
139
|
|
|
154
140
|
// Do nothing in main.
|