Skip to content

Commit

Permalink
feat: further along the path of state export and migration
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Jun 18, 2020
1 parent 8058cec commit 13dc588
Show file tree
Hide file tree
Showing 20 changed files with 313 additions and 96 deletions.
14 changes: 8 additions & 6 deletions packages/cosmic-swingset/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ scenario2-setup-nobuild:
mkdir t1/bootstrap
$(AGCH) --home=t1/bootstrap keys add bootstrap --keyring-backend=test
$(AGCH) --home=t1/bootstrap keys show -a bootstrap --keyring-backend=test > t1/bootstrap-address
$(AGC) --home=t1/n0 add-genesis-account `cat t1/bootstrap-address` 100000000uagstake
$(AGC) --home=t1/n0 add-genesis-account `cat t1/bootstrap-address` 100000000uagstake,100provisionpass,100sendpacketpass
# Create the (singleton) chain node.
$(AGC) --home=t1/n0 gentx --keyring-backend=test --home-client=t1/bootstrap --name=bootstrap --amount=1000000uagstake
$(AGC) --home=t1/n0 collect-gentxs
Expand All @@ -91,17 +91,19 @@ scenario2-setup-nobuild:
$(MAKE) set-local-gci-ingress

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

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

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

# Actually start the ag-solo.
t1-start-ag-solo:
Expand Down
23 changes: 22 additions & 1 deletion packages/cosmic-swingset/app/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"fmt"
"io"
"os"

Expand Down Expand Up @@ -122,6 +123,8 @@ type AgoricApp struct {

invCheckPeriod uint

controllerInited bool

// keys to access the substores
keys map[string]*sdk.KVStoreKey
tKeys map[string]*sdk.TransientStoreKey
Expand Down Expand Up @@ -287,7 +290,7 @@ func NewAgoricApp(
app.swingSetKeeper = swingset.NewKeeper(
app.cdc, keys[swingset.StoreKey],
app.ibcKeeper.ChannelKeeper, &app.ibcKeeper.PortKeeper,
app.accountKeeper,
app.accountKeeper, app.bankKeeper,
scopedSwingSetKeeper,
)
// This function is tricky to get right, so we inject it ourselves.
Expand Down Expand Up @@ -418,8 +421,24 @@ func NewAgoricApp(
// Name returns the name of the App
func (app *AgoricApp) Name() string { return app.BaseApp.Name() }

func (app *AgoricApp) MustInitController(ctx sdk.Context) {
if app.controllerInited {
return
}
app.controllerInited = true

// Begin initializing the controller here.
msg := fmt.Sprintf(`{"type":"AG_COSMOS_INIT","ibcPort":%d,"storagePort":%d}`, app.IBCPort, swingset.GetPort("storage"))
_, err := app.swingSetKeeper.CallToController(ctx, msg)
if err != nil {
fmt.Fprintln(os.Stderr, "Cannot initialize Controller", err)
os.Exit(1)
}
}

// BeginBlocker application updates every begin block
func (app *AgoricApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
app.MustInitController(ctx)
return app.mm.BeginBlock(ctx, req)
}

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

// InitChainer application update at chain initialization
func (app *AgoricApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
app.MustInitController(ctx)

var genesisState simapp.GenesisState
app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState)

Expand Down
78 changes: 42 additions & 36 deletions packages/cosmic-swingset/lib/ag-solo/vats/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import { makeBridgeManager } from './bridge';

const NUM_IBC_PORTS = 3;

// The old way of provisioning used an environment variable that
// was an account ACL. The new way uses "provisionpass", a
// "bearer token" that is checked in handler.go before a provision
// transaction is even sent to the JS side.
const FIXME_DEPRECATED_BOOT_ADDRESS = true;

console.debug(`loading bootstrap.js`);

function parseArgs(argv) {
Expand Down Expand Up @@ -214,9 +220,6 @@ export default function setup(syscall, state, helpers) {
async fromBridge(_srcID, obj) {
switch (obj.type) {
case 'PLEASE_PROVISION': {
if (!packetSendersWhitelist.includes(obj.submitter)) {
throw Error('Permission denied');
}
const { nickname, address } = obj;
return E(vats.provisioning)
.pleaseProvision(nickname, address, PROVISIONER_INDEX)
Expand Down Expand Up @@ -321,7 +324,7 @@ export default function setup(syscall, state, helpers) {

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

// accept provisioning requests from the controller
const provisioner = harden({
pleaseProvision(nickname, pubkey) {
console.debug('Provisioning', nickname, pubkey);
return E(vats.provisioning).pleaseProvision(
nickname,
pubkey,
PROVISIONER_INDEX,
);
},
});
// bootAddress holds the pubkey of controller
await E(vats.comms).addEgress(
bootAddress,
KEY_REG_INDEX,
provisioner,
);
if (FIXME_DEPRECATED_BOOT_ADDRESS && bootAddress) {
// accept provisioning requests from the controller
const provisioner = harden({
pleaseProvision(nickname, pubkey) {
console.debug('Provisioning', nickname, pubkey);
return E(vats.provisioning).pleaseProvision(
nickname,
pubkey,
PROVISIONER_INDEX,
);
},
});
// bootAddress holds the pubkey of controller
await E(vats.comms).addEgress(
bootAddress,
KEY_REG_INDEX,
provisioner,
);
}
break;
}
case 'controller':
Expand Down Expand Up @@ -447,22 +452,23 @@ export default function setup(syscall, state, helpers) {
);

await registerNetworkProtocols(vats, bridgeManager, pswl);

const demoProvider = harden({
// build a chain-side bundle for a client.
async getDemoBundle(nickname) {
return chainBundler.createUserBundle(nickname);
},
});
await Promise.all(
[bootAddress, ...additionalAddresses].map(addr =>
E(vats.comms).addEgress(
addr,
PROVISIONER_INDEX,
demoProvider,
if (FIXME_DEPRECATED_BOOT_ADDRESS && bootAddress) {
const demoProvider = harden({
// build a chain-side bundle for a client.
async getDemoBundle(nickname) {
return chainBundler.createUserBundle(nickname);
},
});
await Promise.all(
[bootAddress, ...additionalAddresses].map(addr =>
E(vats.comms).addEgress(
addr,
PROVISIONER_INDEX,
demoProvider,
),
),
),
);
);
}
break;
}
case 'two_client': {
Expand Down
13 changes: 1 addition & 12 deletions packages/cosmic-swingset/lib/ag-solo/vats/ibc.js
Original file line number Diff line number Diff line change
Expand Up @@ -699,18 +699,7 @@ EOF
}

case 'sendPacket': {
const { packet, sender } = obj;
if (!packetSendersWhitelist.includes(sender)) {
console.error(
sender,
'does not appear in the sendPacket whitelist',
packetSendersWhitelist,
);
throw Error(
`${sender} does not appear in the sendPacket whitelist`,
);
}

const { packet } = obj;
const { source_port: portID, source_channel: channelID } = packet;
const channelKey = `${channelID}:${portID}`;
const seqToAck = channelKeyToSeqAck.get(channelKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function build(E) {
}

async function pleaseProvision(nickname, pubkey) {
const chainBundle = E(bundler).createUserBundle(nickname);
let chainBundle;
const fetch = harden({
getDemoBundle() {
return chainBundle;
Expand All @@ -28,6 +28,10 @@ function build(E) {

const INDEX = 1;
await E(comms).addEgress(pubkey, INDEX, fetch);

// Do this here so that any side-effects don't happen unless
// the egress has been successfully added.
chainBundle = E(bundler).createUserBundle(nickname);
return { ingressIndex: INDEX };
}

Expand Down
22 changes: 11 additions & 11 deletions packages/cosmic-swingset/lib/chain-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,25 +201,25 @@ export default async function main(progname, args, { path, env, agcc }) {

let blockManager;
async function toSwingSet(action, _replier) {
// console.log(`toSwingSet`, action, replier);
if (action.type === AG_COSMOS_INIT) {
// console.error('got AG_COSMOS_INIT', action);
if (!process.env.BOOT_ADDRESS) {
throw Error(`You must set $BOOT_ADDRESS to run a chain node`);
}
// console.log(`toSwingSet`, action);
if (action.ibcPort) {
portNums.dibc = action.ibcPort;
return true;
}

if (action.storagePort) {
// Initialize the storage for this particular transaction.
// console.log(` setting portNums.storage to`, action.storagePort);
portNums.storage = action.storagePort;
}

if (!blockManager) {
const fns = await launchAndInitializeSwingSet();
blockManager = makeBlockManager(fns);
}
if (!blockManager) {
const fns = await launchAndInitializeSwingSet();
blockManager = makeBlockManager(fns);
}

if (action.type === AG_COSMOS_INIT) {
// console.error('got AG_COSMOS_INIT', action);
return true;
}

return blockManager(action);
Expand Down
12 changes: 1 addition & 11 deletions packages/cosmic-swingset/lib/daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func makeNewApp(sendToController Sender) func(logger log.Logger, db dbm.DB, trac
}

// fmt.Println("Starting daemon!")
abci := app.NewAgoricApp(
return app.NewAgoricApp(
sendToController, logger, db, traceStore, true, invCheckPeriod, skipUpgradeHeights,
viper.GetString(flags.FlagHome),
baseapp.SetPruning(store.NewPruningOptionsFromString(viper.GetString("pruning"))),
Expand All @@ -114,16 +114,6 @@ func makeNewApp(sendToController Sender) func(logger log.Logger, db dbm.DB, trac
baseapp.SetHaltTime(viper.GetUint64(server.FlagHaltTime)),
baseapp.SetInterBlockCache(cache),
)
msg := fmt.Sprintf(`{"type":"AG_COSMOS_INIT","ibcPort":%d}`, abci.IBCPort)

// fmt.Println("Sending to Node", msg)
_, err := sendToController(true, msg)
// fmt.Println("Received AG_COSMOS_INIT response", ret, err)
if err != nil {
fmt.Fprintln(os.Stderr, "Cannot initialize Controller", err)
os.Exit(1)
}
return abci
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/cosmic-swingset/lib/launch-chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export async function launch(
}

const [savedHeight, savedActions] = JSON.parse(
storage.get(SWING_STORE_META_KEY) || '[0, []]',
storage.get(SWING_STORE_META_KEY) || '[-1, []]',
);
return {
deliverInbound,
Expand Down
1 change: 1 addition & 0 deletions packages/cosmic-swingset/x/swingset/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ var (

type (
Keeper = keeper.Keeper
Egress = types.Egress
MsgDeliverInbound = types.MsgDeliverInbound
MsgProvision = types.MsgProvision
MsgSendPacket = types.MsgSendPacket
Expand Down
22 changes: 22 additions & 0 deletions packages/cosmic-swingset/x/swingset/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command {
RunE: client.ValidateCmd,
}
swingsetQueryCmd.AddCommand(flags.GetCommands(
GetCmdGetEgress(storeKey, cdc),
GetCmdGetStorage(storeKey, cdc),
GetCmdGetKeys(storeKey, cdc),
GetCmdMailbox(storeKey, cdc),
Expand All @@ -29,6 +30,27 @@ func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command {
return swingsetQueryCmd
}

func GetCmdGetEgress(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "egress [account]",
Short: "get egress nickname for account",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
bech32 := args[0]

res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/egress/%s", queryRoute, bech32), nil)
if err != nil {
return err
}

var out types.QueryResEgress
cdc.MustUnmarshalJSON(res, &out)
return cliCtx.PrintOutput(out)
},
}
}

// GetCmdGetStorage queries information about storage
func GetCmdGetStorage(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Expand Down
15 changes: 15 additions & 0 deletions packages/cosmic-swingset/x/swingset/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ import (
"github.com/gorilla/mux"
)

func getEgressHandler(cliCtx context.CLIContext, storeName string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
paramType := vars[peerName]

res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/egress/%s", storeName, paramType), nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}

rest.PostProcessResponse(w, cliCtx, res)
}
}

func getStorageHandler(cliCtx context.CLIContext, storeName string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
Expand Down
Loading

0 comments on commit 13dc588

Please sign in to comment.