Skip to content

Commit 13dc588

Browse files
committed
feat: further along the path of state export and migration
1 parent 8058cec commit 13dc588

File tree

20 files changed

+313
-96
lines changed

20 files changed

+313
-96
lines changed

packages/cosmic-swingset/Makefile

+8-6
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ scenario2-setup-nobuild:
8181
mkdir t1/bootstrap
8282
$(AGCH) --home=t1/bootstrap keys add bootstrap --keyring-backend=test
8383
$(AGCH) --home=t1/bootstrap keys show -a bootstrap --keyring-backend=test > t1/bootstrap-address
84-
$(AGC) --home=t1/n0 add-genesis-account `cat t1/bootstrap-address` 100000000uagstake
84+
$(AGC) --home=t1/n0 add-genesis-account `cat t1/bootstrap-address` 100000000uagstake,100provisionpass,100sendpacketpass
8585
# Create the (singleton) chain node.
8686
$(AGC) --home=t1/n0 gentx --keyring-backend=test --home-client=t1/bootstrap --name=bootstrap --amount=1000000uagstake
8787
$(AGC) --home=t1/n0 collect-gentxs
@@ -91,17 +91,19 @@ scenario2-setup-nobuild:
9191
$(MAKE) set-local-gci-ingress
9292

9393
scenario2-run-chain:
94-
ROLE=two_chain BOOT_ADDRESS=`cat t1/bootstrap-address` $(NODE_DEBUG) \
94+
ROLE=two_chain $(NODE_DEBUG) \
9595
`$(BREAK_CHAIN) && echo --inspect-brk` $(AGC) --home=t1/n0 start --pruning=nothing
9696

9797
# Provision and start a client.
9898
scenario2-run-client: t1-provision-one t1-start-ag-solo
9999

100-
# Provision the ag-solo from the bootstrap address (idempotent).
100+
# Provision the ag-solo from an provisionpass-holding address (idempotent).
101101
t1-provision-one:
102-
$(AGCH) --home=t1/bootstrap tx swingset provision-one --keyring-backend=test --from=bootstrap \
103-
--gas=auto --gas-adjustment=1.2 --broadcast-mode=block --yes --chain-id=$(CHAIN_ID) \
104-
t1/$(BASE_PORT) `cat t1/$(BASE_PORT)/ag-cosmos-helper-address`
102+
addr=$$(cat t1/$(BASE_PORT)/ag-cosmos-helper-address); \
103+
$(AGCH) --home=t1/bootstrap query swingset egress $$addr --chain-id=$(CHAIN_ID) || \
104+
$(AGCH) --home=t1/bootstrap tx swingset provision-one --keyring-backend=test --from=bootstrap \
105+
--gas=auto --gas-adjustment=1.3 --broadcast-mode=block --yes --chain-id=$(CHAIN_ID) \
106+
t1/$(BASE_PORT) $$addr | tee /dev/stderr | grep -q 'code: 0'
105107

106108
# Actually start the ag-solo.
107109
t1-start-ag-solo:

packages/cosmic-swingset/app/app.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package app
22

33
import (
4+
"fmt"
45
"io"
56
"os"
67

@@ -122,6 +123,8 @@ type AgoricApp struct {
122123

123124
invCheckPeriod uint
124125

126+
controllerInited bool
127+
125128
// keys to access the substores
126129
keys map[string]*sdk.KVStoreKey
127130
tKeys map[string]*sdk.TransientStoreKey
@@ -287,7 +290,7 @@ func NewAgoricApp(
287290
app.swingSetKeeper = swingset.NewKeeper(
288291
app.cdc, keys[swingset.StoreKey],
289292
app.ibcKeeper.ChannelKeeper, &app.ibcKeeper.PortKeeper,
290-
app.accountKeeper,
293+
app.accountKeeper, app.bankKeeper,
291294
scopedSwingSetKeeper,
292295
)
293296
// This function is tricky to get right, so we inject it ourselves.
@@ -418,8 +421,24 @@ func NewAgoricApp(
418421
// Name returns the name of the App
419422
func (app *AgoricApp) Name() string { return app.BaseApp.Name() }
420423

424+
func (app *AgoricApp) MustInitController(ctx sdk.Context) {
425+
if app.controllerInited {
426+
return
427+
}
428+
app.controllerInited = true
429+
430+
// Begin initializing the controller here.
431+
msg := fmt.Sprintf(`{"type":"AG_COSMOS_INIT","ibcPort":%d,"storagePort":%d}`, app.IBCPort, swingset.GetPort("storage"))
432+
_, err := app.swingSetKeeper.CallToController(ctx, msg)
433+
if err != nil {
434+
fmt.Fprintln(os.Stderr, "Cannot initialize Controller", err)
435+
os.Exit(1)
436+
}
437+
}
438+
421439
// BeginBlocker application updates every begin block
422440
func (app *AgoricApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
441+
app.MustInitController(ctx)
423442
return app.mm.BeginBlock(ctx, req)
424443
}
425444

@@ -430,6 +449,8 @@ func (app *AgoricApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci
430449

431450
// InitChainer application update at chain initialization
432451
func (app *AgoricApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
452+
app.MustInitController(ctx)
453+
433454
var genesisState simapp.GenesisState
434455
app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState)
435456

packages/cosmic-swingset/lib/ag-solo/vats/bootstrap.js

+42-36
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ import { makeBridgeManager } from './bridge';
1212

1313
const NUM_IBC_PORTS = 3;
1414

15+
// The old way of provisioning used an environment variable that
16+
// was an account ACL. The new way uses "provisionpass", a
17+
// "bearer token" that is checked in handler.go before a provision
18+
// transaction is even sent to the JS side.
19+
const FIXME_DEPRECATED_BOOT_ADDRESS = true;
20+
1521
console.debug(`loading bootstrap.js`);
1622

1723
function parseArgs(argv) {
@@ -214,9 +220,6 @@ export default function setup(syscall, state, helpers) {
214220
async fromBridge(_srcID, obj) {
215221
switch (obj.type) {
216222
case 'PLEASE_PROVISION': {
217-
if (!packetSendersWhitelist.includes(obj.submitter)) {
218-
throw Error('Permission denied');
219-
}
220223
const { nickname, address } = obj;
221224
return E(vats.provisioning)
222225
.pleaseProvision(nickname, address, PROVISIONER_INDEX)
@@ -321,7 +324,7 @@ export default function setup(syscall, state, helpers) {
321324

322325
D(devices.mailbox).registerInboundHandler(vats.vattp);
323326
await E(vats.vattp).registerMailboxDevice(devices.mailbox);
324-
if (bootAddress) {
327+
if (FIXME_DEPRECATED_BOOT_ADDRESS && bootAddress) {
325328
// FIXME: The old way: register egresses for the addresses.
326329
await Promise.all(
327330
[bootAddress, ...additionalAddresses].map(addr =>
@@ -349,23 +352,25 @@ export default function setup(syscall, state, helpers) {
349352
// Must occur after makeChainBundler.
350353
await registerNetworkProtocols(vats, bridgeManager, pswl);
351354

352-
// accept provisioning requests from the controller
353-
const provisioner = harden({
354-
pleaseProvision(nickname, pubkey) {
355-
console.debug('Provisioning', nickname, pubkey);
356-
return E(vats.provisioning).pleaseProvision(
357-
nickname,
358-
pubkey,
359-
PROVISIONER_INDEX,
360-
);
361-
},
362-
});
363-
// bootAddress holds the pubkey of controller
364-
await E(vats.comms).addEgress(
365-
bootAddress,
366-
KEY_REG_INDEX,
367-
provisioner,
368-
);
355+
if (FIXME_DEPRECATED_BOOT_ADDRESS && bootAddress) {
356+
// accept provisioning requests from the controller
357+
const provisioner = harden({
358+
pleaseProvision(nickname, pubkey) {
359+
console.debug('Provisioning', nickname, pubkey);
360+
return E(vats.provisioning).pleaseProvision(
361+
nickname,
362+
pubkey,
363+
PROVISIONER_INDEX,
364+
);
365+
},
366+
});
367+
// bootAddress holds the pubkey of controller
368+
await E(vats.comms).addEgress(
369+
bootAddress,
370+
KEY_REG_INDEX,
371+
provisioner,
372+
);
373+
}
369374
break;
370375
}
371376
case 'controller':
@@ -447,22 +452,23 @@ export default function setup(syscall, state, helpers) {
447452
);
448453

449454
await registerNetworkProtocols(vats, bridgeManager, pswl);
450-
451-
const demoProvider = harden({
452-
// build a chain-side bundle for a client.
453-
async getDemoBundle(nickname) {
454-
return chainBundler.createUserBundle(nickname);
455-
},
456-
});
457-
await Promise.all(
458-
[bootAddress, ...additionalAddresses].map(addr =>
459-
E(vats.comms).addEgress(
460-
addr,
461-
PROVISIONER_INDEX,
462-
demoProvider,
455+
if (FIXME_DEPRECATED_BOOT_ADDRESS && bootAddress) {
456+
const demoProvider = harden({
457+
// build a chain-side bundle for a client.
458+
async getDemoBundle(nickname) {
459+
return chainBundler.createUserBundle(nickname);
460+
},
461+
});
462+
await Promise.all(
463+
[bootAddress, ...additionalAddresses].map(addr =>
464+
E(vats.comms).addEgress(
465+
addr,
466+
PROVISIONER_INDEX,
467+
demoProvider,
468+
),
463469
),
464-
),
465-
);
470+
);
471+
}
466472
break;
467473
}
468474
case 'two_client': {

packages/cosmic-swingset/lib/ag-solo/vats/ibc.js

+1-12
Original file line numberDiff line numberDiff line change
@@ -699,18 +699,7 @@ EOF
699699
}
700700

701701
case 'sendPacket': {
702-
const { packet, sender } = obj;
703-
if (!packetSendersWhitelist.includes(sender)) {
704-
console.error(
705-
sender,
706-
'does not appear in the sendPacket whitelist',
707-
packetSendersWhitelist,
708-
);
709-
throw Error(
710-
`${sender} does not appear in the sendPacket whitelist`,
711-
);
712-
}
713-
702+
const { packet } = obj;
714703
const { source_port: portID, source_channel: channelID } = packet;
715704
const channelKey = `${channelID}:${portID}`;
716705
const seqToAck = channelKeyToSeqAck.get(channelKey);

packages/cosmic-swingset/lib/ag-solo/vats/vat-provisioning.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function build(E) {
1515
}
1616

1717
async function pleaseProvision(nickname, pubkey) {
18-
const chainBundle = E(bundler).createUserBundle(nickname);
18+
let chainBundle;
1919
const fetch = harden({
2020
getDemoBundle() {
2121
return chainBundle;
@@ -28,6 +28,10 @@ function build(E) {
2828

2929
const INDEX = 1;
3030
await E(comms).addEgress(pubkey, INDEX, fetch);
31+
32+
// Do this here so that any side-effects don't happen unless
33+
// the egress has been successfully added.
34+
chainBundle = E(bundler).createUserBundle(nickname);
3135
return { ingressIndex: INDEX };
3236
}
3337

packages/cosmic-swingset/lib/chain-main.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -201,25 +201,25 @@ export default async function main(progname, args, { path, env, agcc }) {
201201

202202
let blockManager;
203203
async function toSwingSet(action, _replier) {
204-
// console.log(`toSwingSet`, action, replier);
205-
if (action.type === AG_COSMOS_INIT) {
206-
// console.error('got AG_COSMOS_INIT', action);
207-
if (!process.env.BOOT_ADDRESS) {
208-
throw Error(`You must set $BOOT_ADDRESS to run a chain node`);
209-
}
204+
// console.log(`toSwingSet`, action);
205+
if (action.ibcPort) {
210206
portNums.dibc = action.ibcPort;
211-
return true;
212207
}
213208

214209
if (action.storagePort) {
215210
// Initialize the storage for this particular transaction.
216211
// console.log(` setting portNums.storage to`, action.storagePort);
217212
portNums.storage = action.storagePort;
213+
}
218214

219-
if (!blockManager) {
220-
const fns = await launchAndInitializeSwingSet();
221-
blockManager = makeBlockManager(fns);
222-
}
215+
if (!blockManager) {
216+
const fns = await launchAndInitializeSwingSet();
217+
blockManager = makeBlockManager(fns);
218+
}
219+
220+
if (action.type === AG_COSMOS_INIT) {
221+
// console.error('got AG_COSMOS_INIT', action);
222+
return true;
223223
}
224224

225225
return blockManager(action);

packages/cosmic-swingset/lib/daemon/main.go

+1-11
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func makeNewApp(sendToController Sender) func(logger log.Logger, db dbm.DB, trac
105105
}
106106

107107
// fmt.Println("Starting daemon!")
108-
abci := app.NewAgoricApp(
108+
return app.NewAgoricApp(
109109
sendToController, logger, db, traceStore, true, invCheckPeriod, skipUpgradeHeights,
110110
viper.GetString(flags.FlagHome),
111111
baseapp.SetPruning(store.NewPruningOptionsFromString(viper.GetString("pruning"))),
@@ -114,16 +114,6 @@ func makeNewApp(sendToController Sender) func(logger log.Logger, db dbm.DB, trac
114114
baseapp.SetHaltTime(viper.GetUint64(server.FlagHaltTime)),
115115
baseapp.SetInterBlockCache(cache),
116116
)
117-
msg := fmt.Sprintf(`{"type":"AG_COSMOS_INIT","ibcPort":%d}`, abci.IBCPort)
118-
119-
// fmt.Println("Sending to Node", msg)
120-
_, err := sendToController(true, msg)
121-
// fmt.Println("Received AG_COSMOS_INIT response", ret, err)
122-
if err != nil {
123-
fmt.Fprintln(os.Stderr, "Cannot initialize Controller", err)
124-
os.Exit(1)
125-
}
126-
return abci
127117
}
128118
}
129119

packages/cosmic-swingset/lib/launch-chain.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export async function launch(
154154
}
155155

156156
const [savedHeight, savedActions] = JSON.parse(
157-
storage.get(SWING_STORE_META_KEY) || '[0, []]',
157+
storage.get(SWING_STORE_META_KEY) || '[-1, []]',
158158
);
159159
return {
160160
deliverInbound,

packages/cosmic-swingset/x/swingset/alias.go

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ var (
2626

2727
type (
2828
Keeper = keeper.Keeper
29+
Egress = types.Egress
2930
MsgDeliverInbound = types.MsgDeliverInbound
3031
MsgProvision = types.MsgProvision
3132
MsgSendPacket = types.MsgSendPacket

packages/cosmic-swingset/x/swingset/client/cli/query.go

+22
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command {
2121
RunE: client.ValidateCmd,
2222
}
2323
swingsetQueryCmd.AddCommand(flags.GetCommands(
24+
GetCmdGetEgress(storeKey, cdc),
2425
GetCmdGetStorage(storeKey, cdc),
2526
GetCmdGetKeys(storeKey, cdc),
2627
GetCmdMailbox(storeKey, cdc),
@@ -29,6 +30,27 @@ func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command {
2930
return swingsetQueryCmd
3031
}
3132

33+
func GetCmdGetEgress(queryRoute string, cdc *codec.Codec) *cobra.Command {
34+
return &cobra.Command{
35+
Use: "egress [account]",
36+
Short: "get egress nickname for account",
37+
Args: cobra.ExactArgs(1),
38+
RunE: func(cmd *cobra.Command, args []string) error {
39+
cliCtx := context.NewCLIContext().WithCodec(cdc)
40+
bech32 := args[0]
41+
42+
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/egress/%s", queryRoute, bech32), nil)
43+
if err != nil {
44+
return err
45+
}
46+
47+
var out types.QueryResEgress
48+
cdc.MustUnmarshalJSON(res, &out)
49+
return cliCtx.PrintOutput(out)
50+
},
51+
}
52+
}
53+
3254
// GetCmdGetStorage queries information about storage
3355
func GetCmdGetStorage(queryRoute string, cdc *codec.Codec) *cobra.Command {
3456
return &cobra.Command{

packages/cosmic-swingset/x/swingset/client/rest/query.go

+15
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ import (
1111
"github.com/gorilla/mux"
1212
)
1313

14+
func getEgressHandler(cliCtx context.CLIContext, storeName string) http.HandlerFunc {
15+
return func(w http.ResponseWriter, r *http.Request) {
16+
vars := mux.Vars(r)
17+
paramType := vars[peerName]
18+
19+
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/egress/%s", storeName, paramType), nil)
20+
if err != nil {
21+
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
22+
return
23+
}
24+
25+
rest.PostProcessResponse(w, cliCtx, res)
26+
}
27+
}
28+
1429
func getStorageHandler(cliCtx context.CLIContext, storeName string) http.HandlerFunc {
1530
return func(w http.ResponseWriter, r *http.Request) {
1631
vars := mux.Vars(r)

0 commit comments

Comments
 (0)