diff --git a/.github/actions/post-test/action.yml b/.github/actions/post-test/action.yml
index edd06556b2b..457c928618e 100644
--- a/.github/actions/post-test/action.yml
+++ b/.github/actions/post-test/action.yml
@@ -32,7 +32,8 @@ runs:
export DD_ENV="ci"
export DD_SITE="${{ inputs.datadog-site }}"
- timeout 15 npx @datadog/datadog-ci junit upload --service agoric-sdk ./packages/*/junit.xml
+ npx @datadog/datadog-ci --version
+ timeout 30 npx @datadog/datadog-ci junit upload --service agoric-sdk ./packages/*/junit.xml
fi
- name: upload coverage prepare
shell: bash
diff --git a/.github/actions/restore-golang/action.yml b/.github/actions/restore-golang/action.yml
index 66f762f0020..2623e455874 100644
--- a/.github/actions/restore-golang/action.yml
+++ b/.github/actions/restore-golang/action.yml
@@ -21,7 +21,7 @@ runs:
path: ${{ inputs.path }}
clean: 'false'
submodules: 'true'
- - uses: actions/setup-go@v4
+ - uses: actions/setup-go@v5
with:
cache-dependency-path: ${{ inputs.path }}/golang/cosmos/go.sum
go-version: ${{ inputs.go-version }}
diff --git a/.github/actions/restore-node/action.yml b/.github/actions/restore-node/action.yml
index c2143659c95..0ca3a9db6cc 100644
--- a/.github/actions/restore-node/action.yml
+++ b/.github/actions/restore-node/action.yml
@@ -111,6 +111,10 @@ runs:
shell: bash
run: git config --global url."https://github.com/".insteadOf ssh://git@github.com/
+ # Before setup-node because that action runs `yarn cache dir`. See https://github.com/actions/setup-node/issues/480#issuecomment-1915448139
+ - run: corepack enable
+ shell: bash
+
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
@@ -122,9 +126,6 @@ runs:
- uses: kenchan0130/actions-system-info@master
id: system-info
- - run: corepack enable
- shell: bash
-
- name: restore built files
id: built
uses: actions/cache@v4
@@ -181,18 +182,13 @@ runs:
mkdir -p node_modules/.cache/agoric
date > node_modules/.cache/agoric/yarn-built
- - name: git dirty check
- working-directory: ${{ inputs.path }}
- shell: bash
- run: |-
- set -x
- # Fail if `git status` reports anything other than the following:
- # * an untracked endo-sha.txt from above
- # * work tree files that have been staged without further changes
- # (e.g., package.json or yarn.lock) as indicated by the Y position
- # in "XY PATH" being a space
- if [ -n "$(git status --porcelain | grep -vE '^[?][?] endo-sha.txt$|^. '; true)" ]; then
- git status
- echo "Unexpected dirty git status" 1>&2
- exit 1
- fi
+ - name: Validate Git Tree Cleanliness
+ uses: pyTooling/Actions/with-post-step@v1.0.7
+ with:
+ main: |
+ bash "$SRC/.github/actions/restore-node/check-git-status.sh" "$SRC" "$IGNORE_DIRTY_YARN_LOCK"
+ post: |
+ bash "$SRC/.github/actions/restore-node/check-git-status.sh" "$SRC" "$IGNORE_DIRTY_YARN_LOCK"
+ env:
+ SRC: ${{ inputs.path }}
+ IGNORE_DIRTY_YARN_LOCK: ${{ steps.endo-branch.outputs.result != 'NOPE' }}
diff --git a/.github/actions/restore-node/check-git-status.sh b/.github/actions/restore-node/check-git-status.sh
new file mode 100644
index 00000000000..b0575af43be
--- /dev/null
+++ b/.github/actions/restore-node/check-git-status.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Set verbose execution
+set -x
+
+# Navigate to the specified directory
+cd "$1" || exit $?
+
+# Get the value of IGNORE_ENDO_BRANCH
+ignore_dirty_yarn_lock=$2 || exit $?
+
+# Check for unexpected changes
+# Fail if git status detects changes
+changes=$(git status --porcelain)
+
+if [ "$ignore_dirty_yarn_lock" = true ]; then
+ # When integration is requested with a specific Endo branch, ignore changes:
+ # - package.json has a modified `"resolutions":` field,
+ # - yarn.lock is changed because of those resolutions.
+ # For more details, refer to https://github.com/Agoric/agoric-sdk/issues/9850.
+ changes=$(echo "$changes" | grep -v " yarn.lock")
+fi
+
+if [ -n "$changes" ]; then
+ git status
+ echo "Unexpected dirty git status in Agoric SDK path"
+ exit 1
+fi
diff --git a/.github/workflow-templates/test-dapp.yml b/.github/workflow-templates/test-dapp.yml
deleted file mode 100644
index 4dcb655ccea..00000000000
--- a/.github/workflow-templates/test-dapp.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: Test Dapp
-
-on:
- pull_request:
-
-jobs:
- test-dapp:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- node-version: ['18.x']
-
- steps:
- - uses: actions/checkout@v4
- with:
- submodules: 'true'
- path: ./agoric-sdk
- - uses: ./agoric-sdk/.github/actions/restore-node
- with:
- node-version: ${{ matrix.node-version }}
- path: ./agoric-sdk
-
- - name: yarn link
- run: |
- yarn link-cli ~/bin/agoric
- echo "/home/runner/bin" >> $GITHUB_PATH
- working-directory: ./agoric-sdk
-
- # Select a branch on dapp to test against by adding text to the body of the
- # pull request. For example: #dapp-encouragement-branch: zoe-release-0.7.0
- # The default is 'main'
- - name: Get the appropriate dapp branch
- id: get-branch
- uses: actions/github-script@v7
- with:
- result-encoding: string
- script: |
- let branch = 'main';
- if (context.payload.pull_request) {
- const { body } = context.payload.pull_request;
- const regex = /^\#[[INSERT_DAPP_NAME]]-branch:\s+(\S+)/m;
- const result = regex.exec(body);
- if (result) {
- branch = result[1];
- }
- }
- console.log(branch);
- return branch;
-
- - name: Check out dapp
- uses: actions/checkout@v4
- with:
- repository: Agoric/[[INSERT_DAPP_NAME]]
- path: dapp
- ref: ${{steps.get-branch.outputs.result}}
-
- - name: Agoric install in dapp
- run: agoric install
- working-directory: ./dapp
-
- - name: yarn build in dapp
- run: yarn build
- working-directory: ./dapp
-
- - name: yarn test in dapp
- run: yarn test
- working-directory: ./dapp
diff --git a/.github/workflows/README.md b/.github/workflows/README.md
new file mode 100644
index 00000000000..5d5d26b95bd
--- /dev/null
+++ b/.github/workflows/README.md
@@ -0,0 +1,8 @@
+# Github Workflows
+
+We use these for CI. Some other workflows that we aren't currently using are:
+
+* [dapp template](https://github.com/Agoric/agoric-sdk/blob/7a08c6af641c62d8b0ef4a0c35090b6216a5be34/.github/workflow-templates/test-dapp.yml#L1)
+* [ag-solo on xs](https://github.com/Agoric/agoric-sdk/blob/7a08c6af641c62d8b0ef4a0c35090b6216a5be34/.github/workflows/ag-solo-xs.yml.DISABLED#L1)
+* [Test Dapp Treasury](https://github.com/Agoric/agoric-sdk/blob/7a08c6af641c62d8b0ef4a0c35090b6216a5be34/.github/workflows/test-dapp-treasury.yml.DISABLED#L1)
+* [Update Hackathon branch](https://github.com/Agoric/agoric-sdk/blob/7a08c6af641c62d8b0ef4a0c35090b6216a5be34/.github/workflows/update-hackathon-branch.yml.DISABLED#L1)
diff --git a/.github/workflows/after-merge.yml b/.github/workflows/after-merge.yml
index 7e5ad81b603..1c8747d8cee 100644
--- a/.github/workflows/after-merge.yml
+++ b/.github/workflows/after-merge.yml
@@ -109,7 +109,7 @@ jobs:
run: 'yarn test:c8-all || :'
- name: generate coverage/html reports
run: mkdir -p coverage/tmp && yarn c8 report --reporter=html-spa --reports-dir=coverage/html --temp-directory=coverage/tmp
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage
@@ -153,7 +153,7 @@ jobs:
env:
AUTOBENCH_METRICS_URL: ${{ secrets.AUTOBENCH_METRICS_URL }}
run: cd packages/swingset-runner && yarn ci:autobench
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
with:
name: benchmarkstats.json
path: packages/swingset-runner/benchstats*.json
diff --git a/.github/workflows/ag-solo-xs.yml.DISABLED b/.github/workflows/ag-solo-xs.yml.DISABLED
deleted file mode 100644
index 921c0cd1675..00000000000
--- a/.github/workflows/ag-solo-xs.yml.DISABLED
+++ /dev/null
@@ -1,76 +0,0 @@
-name: ag-solo on xs
-
-# xs builds are a bit more expensive, so only run them on PRs that target
-# default
-
-on:
- push:
- branches:
- # $default-branch
- - master
- - 'release-*'
- - 'dev-*'
-
-jobs:
- xs-build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: '18.x'
- - name: cache node modules
- uses: actions/cache@v4
- with:
- path: ~/.cache/yarn
- key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
- - name: yarn install --frozen-lockfile
- run: yarn install --frozen-lockfile
- - name: yarn build
- run: yarn build
- - name: install moddable linux CLI SDK ag08
- run: |
- cd $HOME
- curl -L https://github.com/dckc/moddable/releases/download/ag08/moddable-linux-sdk.tgz | tar xzf -
- - name: install tape-xs ag03
- # ISSUE: merge into agoric-sdk?
- run: |
- cd $HOME
- curl -L https://github.com/agoric-labs/tape-xs/archive/ag03.tar.gz | tar xzf -
- mv tape-xs-ag03 tape-xs
- cd tape-xs
- yarn install
- - name: create /usr/local/bin/noflake
- run: |
- nf=/usr/local/bin/noflake
- sudo tee "$nf" <<\EOF >/dev/null
- #! /bin/sh
- # noflake: rerun a command until it doesn't flake out
- CMD=${1+"$@"}
- FLAKE_STATUS=2
- RETRIES=3
- status=$FLAKE_STATUS
- tries=0
- while test $tries -le $RETRIES -a $status -eq $FLAKE_STATUS; do
- tries=`expr $tries + 1`
- echo 1>&2 "noflake: try number $tries of: $CMD"
- $CMD
- status=$?
- echo 1>&2 "noflake: exit status $status"
- done
- exit $status
- EOF
- sudo chmod +x "$nf"
- - name: test eventual-send on xs
- run: |
- export MODDABLE=$HOME/moddable
- export PATH=$MODDABLE/build/bin/lin/release:$PATH
- export TAPE=$HOME/tape-xs
- cd packages/eventual-send
- node -r esm $TAPE/bin/tape-xs-build.js $PWD test/test*.js
- noflake mcconfig -m -p x-cli-lin test-xs-manifest.json
- $MODDABLE/build/bin/lin/release/eventual-send
diff --git a/.github/workflows/comment-on-base-branch-change.yml b/.github/workflows/comment-on-base-branch-change.yml
new file mode 100644
index 00000000000..efcaf02df95
--- /dev/null
+++ b/.github/workflows/comment-on-base-branch-change.yml
@@ -0,0 +1,22 @@
+name: Post Integration Test Comment on Base Branch Change
+
+on:
+ pull_request:
+ types:
+ - edited
+
+jobs:
+ trigger:
+ runs-on: ubuntu-latest
+ if: ${{ github.event.changes.base && github.event.pull_request.base.ref == 'master' }}
+ steps:
+ - name: Post a comment on the PR
+ uses: actions/github-script@v6
+ with:
+ script: |
+ github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.payload.pull_request.number,
+ body: "Base branch is changed to master. Please re-run the integration tests by adding 'force:integration' label."
+ })
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 21054c163d3..bbc34f77819 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -12,6 +12,7 @@ on:
workflow_dispatch:
env:
REGISTRY: ghcr.io
+ DOCKER_PLATFORMS: linux/amd64,linux/arm64/v8
jobs:
snapshot:
@@ -33,23 +34,35 @@ jobs:
SNAPSHOT_TAG="${TIMESTAMP}-${SHORT_SHA}"
echo "tag=$SNAPSHOT_TAG" >> $GITHUB_OUTPUT
- docker-parallel-build:
- needs: snapshot
- runs-on: ubuntu-latest
+ docker-sdk:
permissions:
+ # allow issuing OIDC tokens for this workflow run
+ id-token: write
+ # allow at least reading the repo contents, add other permissions if necessary
contents: read
+ # to push the resulting images
packages: write
- strategy:
- matrix:
- platform:
- - linux/amd64
- - linux/arm64/v8
+ needs: snapshot
+ runs-on: 'depot-ubuntu-22.04-16' # ubuntu-latest
+ outputs:
+ tag: '${{ steps.docker-tags.outputs.tags }}'
+ tags: '${{ steps.docker-tags.outputs.tags }} ${{ needs.snapshot.outputs.tag }}'
steps:
- uses: actions/checkout@v4
+ - uses: depot/setup-action@v1
+ with:
+ oidc: true # to set DEPOT_TOKEN for later steps
+ - run: depot configure-docker
+ - name: Log in to the Container registry
+ uses: docker/login-action@v3
+ # see https://docs.github.com/en/actions/publishing-packages/publishing-docker-images
+ with:
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ registry: ${{ env.REGISTRY }}
- name: Save BUILD_TAG
run: |
- ARCH=$(echo '${{ matrix.platform }}' | tr / _)
- echo "BUILD_TAG=${{ needs.snapshot.outputs.tag }}-$ARCH" >> $GITHUB_ENV
+ echo "BUILD_TAG=${{ needs.snapshot.outputs.tag }}" >> $GITHUB_ENV
- name: Save GIT_REVISION
run: echo "GIT_REVISION=$(git rev-parse HEAD)" >> $GITHUB_ENV
- name: Save GIT_COMMIT
@@ -57,85 +70,14 @@ jobs:
- name: Save commit hash, url of submodules to environment
run: |
node packages/xsnap/src/build.js --show-env >> $GITHUB_ENV
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v2
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
- with:
- buildkitd-flags: --debug
- - name: Login to Docker Registry
- uses: docker/login-action@v2
- with:
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- registry: ${{ env.REGISTRY }}
- name: Build and Push ssh-node
- uses: docker/build-push-action@v4
+ uses: depot/build-push-action@v1
with:
file: packages/deployment/Dockerfile.ssh-node
context: packages/deployment/docker
- platforms: ${{ matrix.platform }}
+ platforms: ${{ env.DOCKER_PLATFORMS }}
push: true
tags: '${{ env.REGISTRY }}/agoric/ssh-node:${{ env.BUILD_TAG }}'
- - name: Build and Push sdk
- uses: docker/build-push-action@v4
- with:
- file: packages/deployment/Dockerfile.sdk
- context: ./
- platforms: ${{ matrix.platform }}
- push: true
- tags: '${{ env.REGISTRY }}/agoric/agoric-sdk:${{ env.BUILD_TAG }}'
- # When changing/adding entries here, make sure to search the whole
- # project for `@@AGORIC_DOCKER_SUBMODULES@@`
- build-args: |
- GIT_COMMIT=${{env.GIT_COMMIT}}
- MODDABLE_COMMIT_HASH=${{env.MODDABLE_COMMIT_HASH}}
- MODDABLE_URL=${{env.MODDABLE_URL}}
- XSNAP_NATIVE_COMMIT_HASH=${{env.XSNAP_NATIVE_COMMIT_HASH}}
- XSNAP_NATIVE_URL=${{env.XSNAP_NATIVE_URL}}
- GIT_REVISION=${{env.GIT_REVISION}}
- - name: Build and Push setup
- uses: docker/build-push-action@v4
- with:
- file: packages/deployment/Dockerfile
- context: packages/deployment
- platforms: ${{ matrix.platform }}
- tags: '${{ env.REGISTRY }}/agoric/cosmic-swingset-setup:${{ env.BUILD_TAG }}'
- push: true
- build-args: |
- TAG=${{ env.BUILD_TAG }}
- - name: notify on failure
- if: failure()
- uses: ./.github/actions/notify-status
- with:
- webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
- from: ${{ secrets.NOTIFY_EMAIL_FROM }}
- to: ${{ secrets.NOTIFY_EMAIL_TO }}
- password: ${{ secrets.NOTIFY_EMAIL_PASSWORD }}
-
- # Publish the build's multiarch images to Docker Registry.
- docker-sdk:
- needs: [docker-parallel-build, snapshot]
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- outputs:
- tag: '${{ steps.docker-tags.outputs.tags }}'
- tags: '${{ steps.docker-tags.outputs.tags }} ${{ needs.snapshot.outputs.tag }}'
- steps:
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v2
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
- with:
- buildkitd-flags: --debug
- - name: Login to Docker Registry
- uses: docker/login-action@v2
- with:
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- registry: ${{ env.REGISTRY }}
- name: Compute tags
id: docker-tags
run: |
@@ -168,67 +110,44 @@ jobs:
DOCKER_TAGS="latest $SDK_TAG"
;;
esac
+ DOCKER_TAGS="$DOCKER_TAGS $BUILD_TAG"
echo "tags=$DOCKER_TAGS" >> $GITHUB_OUTPUT
-
- - name: Push SDK multiarch
- run: |
- set -ex
- for IMAGE in agoric/agoric-sdk agoric/ssh-node agoric/cosmic-swingset-setup; do
- for TAG in ${{ steps.docker-tags.outputs.tags }} ${{ needs.snapshot.outputs.tag }}; do
- sources=
- for ARCH in linux/amd64 linux/arm64/v8; do
- uarch=$(echo "$ARCH" | tr / _)
- BUILD_TAG="${{ needs.snapshot.outputs.tag }}-$uarch"
- sources="$sources $REGISTRY/$IMAGE:$BUILD_TAG"
- done
- docker buildx imagetools create --tag "$REGISTRY/$IMAGE:$TAG"$sources
- done
- done
-
- # This is currently needed for the relayer integration test framework.
- # It just runs agoric/agoric-sdk with a "single-node" argument.
- docker-ibc-alpha:
- needs: [docker-sdk, snapshot]
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- if: ${{ needs.docker-sdk.outputs.tag }} != dev
- steps:
- - uses: actions/checkout@v4
- - name: Save SDK_TAG
- run: echo "SDK_TAG=${{ needs.snapshot.outputs.tag }}" >> $GITHUB_ENV
- name: Prefix tags
id: prefix-tags
run: |
IMAGE="$REGISTRY/agoric/agoric-sdk"
- for TAG in ibc-alpha; do
+ for TAG in ${{ steps.docker-tags.outputs.tags }}; do
PREFIXED="$PREFIXED$sep$IMAGE:$TAG"
sep=,
done
echo "tags=$PREFIXED" >> $GITHUB_OUTPUT
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v2
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
- with:
- buildkitd-flags: --debug
- - name: Login to Docker Registry
- uses: docker/login-action@v2
- with:
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- registry: ${{ env.REGISTRY }}
- - name: Build and Push
- uses: docker/build-push-action@v4
+ - name: Build and Push sdk
+ uses: depot/build-push-action@v1
with:
- file: packages/deployment/Dockerfile.ibc-alpha
- context: packages/deployment/docker
- platforms: linux/amd64,linux/arm64/v8
+ file: packages/deployment/Dockerfile.sdk
+ context: ./
+ platforms: ${{ env.DOCKER_PLATFORMS }}
push: true
tags: '${{ steps.prefix-tags.outputs.tags }}'
+ # When changing/adding entries here, make sure to search the whole
+ # project for `@@AGORIC_DOCKER_SUBMODULES@@`
+ build-args: |
+ GIT_COMMIT=${{env.GIT_COMMIT}}
+ MODDABLE_COMMIT_HASH=${{env.MODDABLE_COMMIT_HASH}}
+ MODDABLE_URL=${{env.MODDABLE_URL}}
+ XSNAP_NATIVE_COMMIT_HASH=${{env.XSNAP_NATIVE_COMMIT_HASH}}
+ XSNAP_NATIVE_URL=${{env.XSNAP_NATIVE_URL}}
+ GIT_REVISION=${{env.GIT_REVISION}}
+ - name: Build and Push setup
+ uses: depot/build-push-action@v1
+ with:
+ file: packages/deployment/Dockerfile
+ context: packages/deployment
+ platforms: ${{ env.DOCKER_PLATFORMS }}
+ tags: '${{ env.REGISTRY }}/agoric/cosmic-swingset-setup:${{ env.BUILD_TAG }}'
+ push: true
build-args: |
- SDK_TAG=${{env.SDK_TAG}}
+ TAG=${{ env.BUILD_TAG }}
- name: notify on failure
if: failure()
uses: ./.github/actions/notify-status
@@ -240,9 +159,13 @@ jobs:
docker-solo:
needs: [docker-sdk, snapshot]
- runs-on: ubuntu-latest
+ runs-on: 'depot-ubuntu-22.04-16' # ubuntu-latest
permissions:
+ # allow issuing OIDC tokens for this workflow run
+ id-token: write
+ # allow at least reading the repo contents, add other permissions if necessary
contents: read
+ # to push the resulting images
packages: write
steps:
- uses: actions/checkout@v4
@@ -257,24 +180,22 @@ jobs:
sep=,
done
echo "tags=$PREFIXED" >> $GITHUB_OUTPUT
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v2
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
+ - uses: depot/setup-action@v1
with:
- buildkitd-flags: --debug
+ oidc: true # to set DEPOT_TOKEN for later steps
+ - run: depot configure-docker
- name: Login to Docker Registry
- uses: docker/login-action@v2
+ uses: docker/login-action@v3
with:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
registry: ${{ env.REGISTRY }}
- name: Build and Push
- uses: docker/build-push-action@v4
+ uses: depot/build-push-action@v1
with:
file: packages/solo/Dockerfile
context: packages/solo
- platforms: linux/amd64,linux/arm64/v8
+ platforms: ${{ env.DOCKER_PLATFORMS }}
push: true
tags: '${{ steps.prefix-tags.outputs.tags }}'
build-args: |
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index ffa5ed10c71..8236bb04b55 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -23,7 +23,7 @@ jobs:
mode: [no-failure]
steps:
- uses: actions/checkout@v4
- - uses: actions/setup-go@v4
+ - uses: actions/setup-go@v5
with:
go-version: '>=1.20'
cache: false
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 3e3794c832e..a01d25ebad1 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -88,7 +88,8 @@ jobs:
git reset --hard HEAD
git clean -f
git config user.email "noreply@agoric.com"
- REGISTRY_PUBLISH_WORKSPACES="$HOME/endo" scripts/registry.sh bg-publish ${{ matrix.cli }}
+ REGISTRY_PUBLISH_WORKSPACES="$HOME/endo"
+ timeout 900 scripts/registry.sh bg-publish ${{ matrix.cli }}
- name: run agoric-cli integration-test
# These integration tests can be flaky so retry automatically
@@ -99,6 +100,7 @@ jobs:
# won't increase the time for this workflow to complete.
timeout_minutes: 20
command: scripts/registry.sh test ${{ matrix.cli }} ${{steps.get-branch.outputs.result}}
+ on_retry_command: rm -f $HOME/bin/agoric
- name: notify on failure
if: >
@@ -201,7 +203,7 @@ jobs:
echo yes | ../agoric-sdk/packages/deployment/scripts/setup.sh destroy || true
env:
NETWORK_NAME: chaintest
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
if: always()
with:
name: deployment-test-results-${{ env.NOW }}
@@ -246,7 +248,7 @@ jobs:
with:
node-version: '18.x'
# Rebuilding the SDK image with resolved endo packages is not currently supported
- # and since we can't build core eval submissions form the SDK using a newer endo,
+ # and since we can't build core eval submissions from the SDK using a newer endo,
# simply ignore any endo branch integration (this means we don't have full coverage)
ignore-endo-branch: 'true'
id: restore-node
@@ -272,6 +274,30 @@ jobs:
- name: run proposals tests
run: yarn test
working-directory: a3p-integration
+ - name: collect all core eval scripts
+ # Core eval scripts will be copied under /tmp/core_eval_scripts directory
+ # colons in the parent directory name will be replaced with dashes
+ run: |
+ find . -type d -path "./a3p-integration/proposals/*/submission" | while read -r dir; do
+ # Get the parent directory name
+ parent_dir=$(basename "$(dirname "$dir")")
+ # Replace colons with dashes in the parent directory name
+ sanitized_parent_dir=${parent_dir//:/-}
+ # Create the destination directory under /tmp/core_eval_scripts if it doesn't exist
+ destination_dir="/tmp/core_eval_scripts/$sanitized_parent_dir"
+ mkdir -p "$destination_dir"
+ # Copy everything from the $dir to the destination directory
+ cp -r "$dir"/* "$destination_dir/"
+ echo "Copied contents of $dir to $destination_dir"
+ done
+ - name: archive core eval scripts
+ # The core eval scripts can be found at the bottom of `Summary` page of
+ # `Integration tests` workflow once the workflow is completed.
+ # Ref: https://github.com/actions/upload-artifact?tab=readme-ov-file#where-does-the-upload-go
+ uses: actions/upload-artifact@v4
+ with:
+ name: core-eval-scripts
+ path: /tmp/core_eval_scripts
- name: notify on failure
if: failure() && github.event_name != 'pull_request'
uses: ./.github/actions/notify-status
@@ -298,6 +324,7 @@ jobs:
- getting-started
- deployment-test
- test-docker-build
+ - test-multichain-e2e
if: >-
always() &&
needs.pre_check.result == 'success' &&
diff --git a/.github/workflows/manage-integration-check.yml b/.github/workflows/manage-integration-check.yml
index f3eef54a108..889554d9da5 100644
--- a/.github/workflows/manage-integration-check.yml
+++ b/.github/workflows/manage-integration-check.yml
@@ -16,7 +16,7 @@ jobs:
if: ${{ github.event.action == 'requested' || github.event.action == 'in_progress' }}
with:
script: |
- const external_id = context.payload.workflow_run.html_url;
+ const external_id = context.payload.workflow_run.html_url + "-" + context.payload.workflow_run.run_attempt;
const head_sha = context.payload.workflow_run.head_sha;
const runs = await github.paginate(github.rest.checks.listForRef, {
...context.repo,
@@ -25,7 +25,7 @@ jobs:
external_id,
})
core.debug(`integration-test-result check runs: ${JSON.stringify(runs, null, 2)}`);
- const filtRuns = runs.filter(run => run.status !== 'completed');
+ const filtRuns = runs.filter(run => run.external_id === external_id);
const descRuns = filtRuns.sort((a, b) => Date.parse(b.started_at) - Date.parse(a.started_at));
const run = descRuns[0];
@@ -42,7 +42,7 @@ jobs:
external_id,
output: {
title: "Integration Test Aggregate Result",
- summary: `Synthetic check capturing the result of the integration-test workflow run`,
+ summary: `Synthetic check capturing the result of the integration-test workflow run (attempt ${context.payload.workflow_run.run_attempt})`,
}
});
return check.data.id;
@@ -56,7 +56,7 @@ jobs:
result-encoding: string
script: |
// Update the check run
- const external_id = context.payload.workflow_run.html_url;
+ const external_id = context.payload.workflow_run.html_url + "-" + context.payload.workflow_run.run_attempt;
const head_sha = context.payload.workflow_run.head_sha;
const runs = await github.paginate(github.rest.checks.listForRef, {
...context.repo,
@@ -65,12 +65,23 @@ jobs:
external_id,
})
core.debug(`integration-test-result check runs: ${JSON.stringify(runs, null, 2)}`);
- const filtRuns = runs.filter(run => run.status !== 'completed');
+ const filtRuns = runs.filter(run => run.status !== 'completed' && run.external_id === external_id);
const descRuns = filtRuns.sort((a, b) => Date.parse(b.started_at) - Date.parse(a.started_at));
const run = descRuns[0];
if (!run) {
- core.setFailed(`No integration-test-result check found for commit ${head_sha} ${external_id}`);
+ const check = await github.rest.checks.create({
+ ...context.repo,
+ head_sha,
+ name: "integration-test-result",
+ status: "completed",
+ conclusion: context.payload.workflow_run.conclusion,
+ external_id,
+ output: {
+ title: "Integration Test Aggregate Result",
+ summary: `Synthetic check capturing the result of the integration-test workflow run (attempt ${context.payload.workflow_run.run_attempt})`,
+ }
+ });
return;
}
diff --git a/.github/workflows/mergify-ready.yml b/.github/workflows/mergify-ready.yml
index 604fb7f9dd2..86439df95f4 100644
--- a/.github/workflows/mergify-ready.yml
+++ b/.github/workflows/mergify-ready.yml
@@ -77,14 +77,43 @@ jobs:
fixup_commits=
for commit in $(git rev-list $BASE_SHA..$HEAD_SHA); do
- case $(git show --pretty=format:%s -s $commit) in fixup\!*|squash\!*)
+ case $(git show --pretty=format:%s -s $commit) in fixup\!*|squash\!*|amend\!*)
fixup_commits="$fixup_commits\n$commit"
;;
esac
done
if [ -n "$fixup_commits" ]; then
- echo "Error: fixup/squash commits found in $BASE_LABEL..$HEAD_LABEL"
+ echo "Error: fixup/squash/amend commits found in $BASE_LABEL..$HEAD_LABEL"
echo -e "$fixup_commits"
exit 1
fi
+
+ no-fixup-commits:
+ runs-on: ubuntu-latest
+ if: >-
+ github.event_name == 'pull_request' &&
+ github.event.pull_request.draft == false &&
+ github.event.pull_request.base.ref == 'master' &&
+ contains(github.event.pull_request.labels.*.name, 'automerge:rebase') &&
+ !contains(github.event.pull_request.labels.*.name, 'bypass:linear-history')
+
+ env:
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
+ BASE_SHA: ${{ github.event.pull_request.base.sha }}
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Check for fixup commits
+ id: fixup-commits
+ run: |
+ if [[ $(git rev-list "$BASE_SHA".."$HEAD_SHA" --grep="^\(fixup\|amend\|squash\)! " | wc -l) -eq 0 ]]; then
+ echo "No fixup/amend/squash commits found in commit history"
+ else
+ echo "fixup/amend/squash commits found in commit history"
+ exit 1
+ fi
diff --git a/.github/workflows/multichain-e2e.yml b/.github/workflows/multichain-e2e.yml
index 1ac66c7a8d6..718e9d2974d 100644
--- a/.github/workflows/multichain-e2e.yml
+++ b/.github/workflows/multichain-e2e.yml
@@ -43,7 +43,7 @@ jobs:
# uses ghcr.io/agoric/agoric-sdk:dev image (latest master)
values: ./agoric-sdk/multichain-testing/config.yaml
port-forward: true
- version: 0.2.2
+ version: 0.2.10
timeout: 30m
namespace: agoric-multichain
diff --git a/.github/workflows/test-dapp-treasury.yml.DISABLED b/.github/workflows/test-dapp-treasury.yml.DISABLED
deleted file mode 100644
index f27e09dfc83..00000000000
--- a/.github/workflows/test-dapp-treasury.yml.DISABLED
+++ /dev/null
@@ -1,82 +0,0 @@
-name: Test Dapp Treasury
-
-on:
- pull_request:
- merge_group:
- schedule:
- - cron: '17 6 * * *'
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- test-dapp:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- node-version: ['18.x']
-
- steps:
- - uses: actions/checkout@v4
- with:
- submodules: 'true'
- path: ./agoric-sdk
- - uses: ./agoric-sdk/.github/actions/restore-node
- with:
- node-version: ${{ matrix.node-version }}
- path: ./agoric-sdk
-
- - name: yarn link
- run: |
- yarn link-cli ~/bin/agoric
- echo "/home/runner/bin" >> $GITHUB_PATH
- working-directory: ./agoric-sdk
-
- # Select a branch on dapp to test against by adding text to the body of the
- # pull request. For example: #dapp-encouragement-branch: zoe-release-0.7.0
- # The default is 'main'
- - name: Get the appropriate dapp branch
- id: get-branch
- uses: actions/github-script@v7
- with:
- result-encoding: string
- script: |
- let branch = 'main';
- if (context.payload.pull_request) {
- const { body } = context.payload.pull_request;
- const regex = /^\#dapp-treasury-branch:\s+(\S+)/m;
- const result = regex.exec(body);
- if (result) {
- branch = result[1];
- }
- }
- console.log(branch);
- return branch;
-
- - name: Check out dapp
- uses: actions/checkout@v4
- with:
- repository: Agoric/dapp-treasury
- path: dapp
- ref: ${{steps.get-branch.outputs.result}}
-
- - name: Agoric install in dapp
- run: agoric install
- working-directory: ./dapp
-
- - name: yarn build in dapp
- run: yarn build
- working-directory: ./dapp
-
- - name: yarn test in dapp
- run: yarn test
- working-directory: ./dapp
-
- - name: notify on failure
- if: failure() && github.event_name != 'pull_request'
- uses: ./agoric-sdk/.github/actions/notify-status
- with:
- webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
- from: ${{ secrets.NOTIFY_EMAIL_FROM }}
- to: ${{ secrets.NOTIFY_EMAIL_TO }}
- password: ${{ secrets.NOTIFY_EMAIL_PASSWORD }}
diff --git a/.github/workflows/test-documentation.yml b/.github/workflows/test-documentation.yml
index a3ba41c7146..bade8a4cd19 100644
--- a/.github/workflows/test-documentation.yml
+++ b/.github/workflows/test-documentation.yml
@@ -26,12 +26,6 @@ jobs:
node-version: ${{ matrix.node-version }}
path: ./agoric-sdk
- - name: yarn link
- run: |
- yarn link-cli ~/bin/agoric
- echo "/home/runner/bin" >> $GITHUB_PATH
- working-directory: ./agoric-sdk
-
# Select a branch on dapp to test against by adding text to the body of the
# pull request. For example: #dapp-encouragement-branch: zoe-release-0.7.0
# The default is 'main'
@@ -60,8 +54,10 @@ jobs:
path: dapp
ref: ${{steps.get-branch.outputs.result}}
- - name: Agoric install in dapp
- run: agoric install
+ - name: point dapp to agoric-SDK HEAD
+ # This assumes the dapp uses Yarn 4 and its other deps are compatible
+ # with the versions in the agoric-sdk packages.
+ run: yarn link ../agoric-sdk --all --relative
working-directory: ./dapp
- name: yarn build in dapp
diff --git a/.github/workflows/update-hackathon-branch.yml.DISABLED b/.github/workflows/update-hackathon-branch.yml.DISABLED
deleted file mode 100644
index 7b31a5d5f56..00000000000
--- a/.github/workflows/update-hackathon-branch.yml.DISABLED
+++ /dev/null
@@ -1,21 +0,0 @@
-# when 'master' changes, update the 'hackathon' branch to match
-
-name: update-hackathon-branch
-
-# *only* run upon changes to 'master': ignore PRs and other branches
-on:
- push:
- branches: [ master ]
-
-jobs:
- update-hackathon:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/github-script@v7
- with:
- github-token: ${{secrets.GITHUB_TOKEN}}
- script: |
- let repo = { owner: 'Agoric', repo: 'agoric-sdk' };
- let f = await github.git.getRef({ref: 'heads/master', ...repo});
- let sha = f.data.object.sha;
- await github.git.updateRef({ref: 'heads/hackathon-2020-11', sha, ...repo});
diff --git a/.gitignore b/.gitignore
index 924317ab198..ec596f3ce77 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,8 +42,14 @@ typings/
# Output of 'npm pack'
*.tgz
-# Yarn Integrity file
-.yarn-integrity
+# Yarn (https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/sdks
+!.yarn/versions
# dotenv environment variables file
.env
@@ -68,3 +74,8 @@ api-docs
chaintest
_testoutput.txt
+
+
+junit.xml
+endo-sha.txt
+.aider*
diff --git a/.mergify.yml b/.mergify.yml
index 7876545d36d..5cd1c2db2c9 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -1,11 +1,10 @@
# Linear queue for the main branch.
-queue_rules:
- - name: main
- commit_message_template: |-
+shared:
+ commit_message_template: &commit-message-template |-
{{ title }} (#{{ number }})
{{ body | trim }}
- queue_conditions:
+ queue_conditions: &queue-conditions
- base=master
- or:
- check-pending=integration-test-result
@@ -18,39 +17,132 @@ queue_rules:
- and: # breakage fails like we thought
- check-failure=breakage
- label=proto:expect-breakage
- merge_conditions:
+ high_priority_queue_conditions: &high-priority-queue-conditions
+ - and: *queue-conditions
+ - label=priority:high
+ merge_conditions: &merge-conditions
- base=master
+ # Rebase PRs with fixup commits are allowed to enter the merge queue but
+ # should not be allowed to merge if there are leftover fixup commits after rebase
+ - or:
+ - label=bypass:linear-history
+ - check-success=no-fixup-commits
+ - check-skipped=no-fixup-commits
# Require integration tests before merging only
- or:
- label=bypass:integration
- check-success=integration-test-result
-
-pull_request_rules:
- - name: merge to master
- conditions:
+ pr_queue_merge_conditions: &pr-queue-merge-conditions
- base=master
- label=automerge:no-update
- or:
- '#commits-behind=0'
- label=bypass:linear-history
+ pr_queue_rebase_conditions: &pr-queue-rebase-conditions
+ - base=master
+ - label=automerge:rebase
+ - or:
+ - '#commits-behind>0'
+ - linear-history
+ pr_queue_squash_conditions: &pr-queue-squash-conditions
+ - base=master
+ - label=automerge:squash
+
+queue_rules:
+ - name: high_priority_rebase
+ commit_message_template: *commit-message-template
+ queue_conditions: *high-priority-queue-conditions
+ merge_conditions: *merge-conditions
+ merge_method: merge
+ update_method: rebase
+
+ - name: high_priority_merge
+ commit_message_template: *commit-message-template
+ queue_conditions: *high-priority-queue-conditions
+ merge_conditions: *merge-conditions
+ disallow_checks_interruption_from_queues:
+ - high_priority_rebase
+ merge_method: merge
+
+ - name: high_priority_squash
+ commit_message_template: *commit-message-template
+ queue_conditions: *high-priority-queue-conditions
+ merge_conditions: *merge-conditions
+ disallow_checks_interruption_from_queues:
+ - high_priority_rebase
+ - high_priority_merge
+ merge_method: squash
+
+ - name: rebase
+ commit_message_template: *commit-message-template
+ queue_conditions: *queue-conditions
+ merge_conditions: *merge-conditions
+ merge_method: merge
+ update_method: rebase
+
+ - name: merge
+ commit_message_template: *commit-message-template
+ queue_conditions: *queue-conditions
+ merge_conditions: *merge-conditions
+ disallow_checks_interruption_from_queues:
+ - rebase
+ merge_method: merge
+
+ - name: squash
+ commit_message_template: *commit-message-template
+ queue_conditions: *queue-conditions
+ merge_conditions: *merge-conditions
+ disallow_checks_interruption_from_queues:
+ - rebase
+ - merge
+ merge_method: squash
+
+pull_request_rules:
+ - name: high priority - merge to master
+ conditions:
+ - and: *pr-queue-merge-conditions
+ - label=priority:high
actions:
queue:
- name: main
- merge_method: merge
- - name: rebase updates then merge to master
+ name: high_priority_merge
+ - name: high priority - rebase updates then merge to master
conditions:
- - base=master
- - label=automerge:rebase
+ - and: *pr-queue-rebase-conditions
+ - label=priority:high
+ actions:
+ queue:
+ name: high_priority_rebase
+ - name: high priority - squash to master
+ conditions:
+ - and: *pr-queue-squash-conditions
+ - label=priority:high
+ actions:
+ queue:
+ name: high_priority_squash
+ - name: merge to master
+ conditions: *pr-queue-merge-conditions
actions:
queue:
- name: main
- merge_method: merge
- update_method: rebase
+ name: merge
+ - name: rebase updates then merge to master
+ conditions: *pr-queue-rebase-conditions
+ actions:
+ queue:
+ name: rebase
- name: squash to master
+ conditions: *pr-queue-squash-conditions
+ actions:
+ queue:
+ name: squash
+ - name: rebase and autosquash
conditions:
- base=master
- - label=automerge:squash
+ - label=automerge:rebase
+ - '#commits-behind=0'
+ - or:
+ - -linear-history
+ - check-failure=no-fixup-commits
+ - -draft
actions:
- queue:
- name: main
- merge_method: squash
+ rebase:
+ autosquash: true
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a333432f255..6ed779df299 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -79,6 +79,8 @@ We've also squashed follow-up commits manually (through an interactive rebase)
after a PR had been approved and tests were passing, then landed the stack with
"Rebase and merge" or "Create merge commit".
+For details on authoring, merging, and reviewing PRs, see [Pull Requests Guidelines](https://github.com/Agoric/agoric-sdk/wiki/GitHub-Pull-Requests).
+
[CC]: https://www.conventionalcommits.org/en/v1.0.0/
### Integration tests
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
index 7ef3fcbf856..6f3ac44d1ba 100644
--- a/MAINTAINERS.md
+++ b/MAINTAINERS.md
@@ -8,17 +8,18 @@
We would like to have similar behavior regardless of whether a chain launched from a release upgrades a predecessor or starts clean. Since we are currently not in a position where we can upgrade all vats, our release must not include behavioral changes to code running in any vat that it is not explicitly upgrading. The easiest way to accomplish that is by avoiding any changes to code included in vats, however this is not always feasible.
-We maintain `release-*` branches which represent a fork of the `master` dev branch at a given point:
-- `release-pismo` is the previous/archived release branch used before the "bulldozer" upgrade which threw away all JavaScript state.
-- `release-mainnet1B` is our current release branch. Despite its name, it has lived beyond the "mainnet-1" phase of the agoric-3 chain.
+We previously maintained `release-*` branches which represented a fork of the `master` dev branch at a given point:
+- `release-pismo` is the original/archived release branch used before the "bulldozer" upgrade which threw away all JavaScript state.
+- `release-mainnet1B` was our previous release branch up until `agoric-upgrade-15`. Despite its name, it lived beyond the "mainnet-1" phase of the agoric-3 chain.
-Release branches should only ever be updated when publishing a new release.
+We don't expect these previous release branches to ever be updated again.
+
+Starting with `agoric-upgrade-16`, we try to release directly from `master` by creating a `dev-release-*` release branch. These branches allow us to work on the release concurrently with other engineering efforts, and are not currently merged back once the release is complete.
Releases are tagged commits from the above release branches, with a corresponding entry in https://github.com/Agoric/agoric-sdk/releases .
To ease the maintenance process, we want to avoid any commit original to the release branch that has no direct equivalent on the `master` branch, except when needed to generate or test a specific release. To satisfy that, we usually directly cherry-pick commits and PRs from the `master` branch. We do not expect to merge the release branches back into `master`.
-To clearly delineate separate releases from each other on the release branch, we now use "dev release" branches to compile all changes going into a release before merging that branch into the release branch when the release is cut. It also allows us to re-scope a release if needed without having to revert commits on the release branch.
## Preparing for a Release
@@ -26,7 +27,7 @@ To clearly delineate separate releases from each other on the release branch, we
The Release Owner and other appropriate stakeholders must agree on:
-- _**base branch**_: This should be `release-mainnet1B`, but might need to vary for a patch release.
+- _**base branch**_: This should be `master`, but might need to vary for a patch release.
- _**release label**_: This is used for the git tags, and is currently expected to follow a
sequential pattern (example: `agoric-upgrade-8`).
@@ -38,31 +39,34 @@ The Release Owner and other appropriate stakeholders must agree on:
`upgrade-8-rc0`).
- _**upgrade name**_: This is used to coordinate with the cosmos-sdk UpgradeKeeper.
- The name used to upgrade mainnet is currently expected to match the _**release label**_, but
- other networks should use distinct names that indicate their testing-oriented purpose
- (examples: `agorictest-upgrade-8`, `agorictest-upgrade-8-2`).
+ The primary name is currently expected to match the _**release label**_, but test networks may require extra names if multiple rounds of upgrade validation are necessary to test a release.
+ (examples: `agoric-upgrade-8-2`).
### Create the "dev release" branch
-- [ ] When a new release is planned, create a new branch from branch `release-mainnet1B` with a name like `dev-$releaseShortLabel` (example: `dev-upgrade-8`). This can be done from the command line or the [GitHub Branches UI](https://github.com/Agoric/agoric-sdk/branches).
+- [ ] When a new release is planned, create a new branch from the [_**base branch**_](#assign-release-parameters) (`master`) with a name like `dev-$releaseShortLabel` (example: `dev-upgrade-8`). This can be done from the command line or the [GitHub Branches UI](https://github.com/Agoric/agoric-sdk/branches).
- [ ] Initialize the new branch for the planned upgrade:
- - [ ] In **golang/cosmos/app/app.go**, update the `upgradeName` constants and the associated upgrade handler function name to correspond with the [_**upgrade name**_](#assign-release-parameters).
- Remove from the function any logic specific to the previous upgrade (e.g., core proposals).
- - [ ] Ensure that **a3p-integration/package.json** has an object-valued `agoricSyntheticChain` property with `fromTag` set to the [agoric-3-proposals Docker images](https://github.com/Agoric/agoric-3-proposals/pkgs/container/agoric-3-proposals) tag associated with the previous release
- (example: `use-upgrade-7`).
- - [ ] Ensure that **a3p-integration/proposals** contains a single subdirectory with the following characteristics
- - named like "$prefix:[_**release short label**_](#assign-release-parameters)" per [agoric-3-proposals: Naming](https://github.com/Agoric/agoric-3-proposals#naming) (conventionally using "a" for the unreleased $prefix, e.g. `a:upgrade-8`)
+ - [ ] In **golang/cosmos/app/upgrade.go**
+ - [ ] Update the `upgradeNamesOfThisVersion` constant to list all the [_**upgrade name**_](#assign-release-parameters) used by this release.
+ - [ ] Update the `isPrimaryUpgradeName` function to reflect the updated [_**upgrade name**_](#assign-release-parameters) list.
+ - [ ] Rename the upgrade handler function to match the release, example: `upgrade8Handler`.
+ - [ ] Verify that the upgrade handler function has no logic specific to the previous upgrade (e.g., core proposals).
+ - [ ] In **golang/cosmos/app/app.go**, make sure that the call to `SetUpgradeHandler` uses the renamed upgrade handler function above.
+ - [ ] Verify that **a3p-integration/package.json** has an object-valued `agoricSyntheticChain` property with `fromTag` set to the [agoric-3-proposals Docker images](https://github.com/Agoric/agoric-3-proposals/pkgs/container/agoric-3-proposals) tag associated with the previous release
+ (example: `use-upgrade-7`) or latest core-eval passed on chain (example: `use-vaults-auction`).
+ - [ ] Ensure that the first subdirectory in **a3p-integration/proposals** has the following characteristics. This is commonly created by renaming the `n:upgrade-next` directory after verifying no other proposals exist before that, and updating the **package.json** file in it.
+ - named like "$prefix:[_**release short label**_](#assign-release-parameters)" per [agoric-3-proposals: Naming](https://github.com/Agoric/agoric-3-proposals#naming) (conventionally using "a" for the unreleased $prefix, e.g. `a:upgrade-8`).
- containing a **package.json** having an object-valued `agoricProposal` property with `sdkImageTag` set to "unreleased" and `planName` set to the [_**upgrade name**_](#assign-release-parameters)
- containing other files appropriate for the upgrade per [agoric-3-proposals: Files](https://github.com/Agoric/agoric-3-proposals#files)
- For example, see the [upgrade-14 PR](https://github.com/Agoric/agoric-sdk/pull/8755).
+ For example, see the [upgrade-17 PR](https://github.com/Agoric/agoric-sdk/pull/10088).
### Populate the "dev release" branch
-For each set of changes to include:
+For each set of changes to include after the base branch point:
- [ ] Create a work branch from the "dev release" branch.
-- [ ] Cherry-pick approved changes from `master` onto this work branch.
- - Avoid any cherry-pick that has side-effects on code you do not wish to be upgraded. For example, a change impacting deployed vat code that is not meant to be part of the upgrade (comment/types only changes may be acceptable, but will still result in new bundles, so should be avoided if possible). Chain software code is usually safe to upgrade as long as integration with code running inside vats doesn't change. For example, the host side of any bridge and the set of swingset syscalls must remain backwards compatible.
+- [ ] Cherry-pick approved changes from `master` onto this work branch, or revert any changes that were included before the base branch point but that are not meant to be released.
+ - Avoid any changes that has side-effects on code you do not wish to be upgraded. For example, a change impacting deployed vat code that is not meant to be part of the upgrade (comment/types only changes are usually considered acceptable, even though they will result in new bundles that should be behaviorally equivalent). Chain software code is usually safe to upgrade as long as integration with code running inside vats doesn't change. For example, the host side of any bridge and the set of swingset syscalls must remain backwards compatible.
- For integrating a single PR (best suited to vat code changes which often require manual adaptation):
- [ ] Cherry-pick the commits of the `master` PR onto the work branch with minimal/mechanical conflict resolutions.
It's acceptable to author the changes on the "dev release" based work branch and then rebase them to a master PR, as long as the PRs lands at "about the same time" (`master` PR **MUST** be merged before a release is cut).
@@ -322,7 +326,7 @@ to pass and for reviewer approval.
Generate a template:
```sh
- ./scripts/gen-github-release > release.md
+ ./scripts/gen-github-release.sh {prerelease | latest} > release.md
```
Then replace the remaining `$`-prefixed placeholders, filling in
the [_**validator oriented release description**_](#describe-the-release) and using
@@ -447,3 +451,35 @@ Push this branch and create a pull request.
```sh
git push origin "$USER-sync-endo-$NOW"
```
+
+At this time, syncing Endo versions will break the optional `documentation`
+`test-dapp` test, and that cannot be fixed until after the Endo sync merges.
+When the above steps lead to changes merged into this repository,
+in `agoric-sdk/documentation`:
+
+```sh
+# in agoric/documentation
+git checkout --branch "$USER-sync-endo-$NOW"
+$ENDO/scripts/sync-verions.sh ~/endo
+git commit -am 'chore: Sync Endo versions'
+yarn
+git commit -am 'chore: Update yarn.lock'
+git push origin "$USER-sync-endo-$NOW"
+```
+
+Create a pull request from that branch.
+
+To verify that the changes to `documentation` are sufficient to settle CI for
+this repository, return to `agoric-sdk`, create a branch off of the current
+head, create an empty commit, push that change to Github, and create a draft
+pull request with `#documentation-branch: $USER-sync-docs-$NOW` in the
+description.
+
+```sh
+# in agoric/agoric-sdk
+git checkout origin/master
+git commit --allow-empty -m 'Poke CI for documentation integration testing'
+git checkout -b "$USER-sync-docs-$NOW"
+# Capture description in clipboard (Mac) for reference on Github.
+echo "#documentation-branch: $USER-sync-docs-$NOW" | pbcopy # Linux: xclip -i
+```
diff --git a/README.md b/README.md
index f133d22b643..562d7713cdc 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,11 @@
# Agoric Platform SDK
+![unit tests status](https://github.com/Agoric/agoric-sdk/actions/workflows/test-all-packages.yml/badge.svg)
+![integration tests status](https://github.com/Agoric/agoric-sdk/actions/workflows/integration.yml/badge.svg)
+[![license](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE)
+[![Mutable.ai Auto Wiki](https://img.shields.io/badge/Auto_Wiki-Mutable.ai-blue)](https://wiki.mutable.ai/Agoric/agoric-sdk)
+
This repository contains most of the packages that make up the upper
layers of the Agoric platform, with
[the endo repository](https://github.com/endojs/endo)
diff --git a/a3p-integration/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch b/a3p-integration/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch
deleted file mode 100644
index 3d01386399d..00000000000
--- a/a3p-integration/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/dist/upgrade-test-scripts/env_setup.sh b/dist/upgrade-test-scripts/env_setup.sh
-index 617a0fbe7efdfa457e28fc52806dba1b323930d8..25f52a6cf133dca830bd0dcd47c91700e6a8effe 100755
---- a/dist/upgrade-test-scripts/env_setup.sh
-+++ b/dist/upgrade-test-scripts/env_setup.sh
-@@ -100,7 +100,7 @@ killAgd() {
- AGD_PID=$(cat $HOME/.agoric/agd.pid)
- kill $AGD_PID
- rm $HOME/.agoric/agd.pid
-- wait $AGD_PID || true
-+ tail --pid=$AGD_PID -f /dev/null || true
- }
-
- provisionSmartWallet() {
diff --git a/a3p-integration/README.md b/a3p-integration/README.md
index 192f3b40042..fd8e68d2322 100644
--- a/a3p-integration/README.md
+++ b/a3p-integration/README.md
@@ -46,7 +46,7 @@ cannot access SDK code. Their names must be lower case.
In the release branches, the end-to-end `a3p-integration` test usually only has
a single proposal package named `a:upgrade-NN`, which performs a chain software
upgrade proposal to the corresponding upgrade plan. In the `master` branch, the
-next release's changes are staged in `a:upgrade-next`. There may also be
+next release's changes are staged in `n:upgrade-next`. There may also be
core-eval proposal packages, either before or after the chain software upgrade
proposal.
@@ -60,16 +60,16 @@ For a chain software upgrade proposal, the `type` is `"Software Upgrade Proposal
- `sdkImageTag` is the docker image tag to use that contains the upgraded chain software. It has a value of `unreleased`, which is the tag for the image that is built from the enclosing `agoric-sdk` repository.
-- `planName` is the "upgrade name" included in the proposal which must match the value in the upgraded chain software. In the `master` branch its value is `UNRELEASED_UPGRADE`. In the release branches, it's `agoric-upgrade-NN`.
+- `planName` is the "upgrade name" included in the proposal which must match the value in the upgraded chain software. In the `master` branch its value is `UNRELEASED_A3P_INTEGRATION`. In the release branches, it's `agoric-upgrade-NN`.
- `upgradeInfo` contains other details passed to the governance proposal. In
particular, it can have a `coreProposals` field which instructs the chain
software to run other core proposals in addition to the one configured in the
chain software's upgrade handler (see `CoreProposalSteps` in
- `/golang/cosmos/app/app.go`).
+ `/golang/cosmos/app/upgrade.go`).
- See **Generating core-eval submissions** below for details.
-For an (evolving) example, see `a:upgrade-next` in master.
+For an (evolving) example, see `n:upgrade-next` in master.
### Core-eval proposal
@@ -115,7 +115,7 @@ The `yarn build` script automates 3 steps:
## Generate a docker image with the `agoric-sdk` chain software
-The chain software upgrade proposal contained in this end-to-end integration test performs an upgrade of the agoric-3 synthetic chain to an `UNRELEASED_UPGRADE` plan name (or the corresponding upgrade plan name for release branches). It loads the docker image `ghcr.io/agoric/agoric-sdk:unreleased` for the software implementing that upgrade (both in the `master` branch or in release branches).
+The chain software upgrade proposal contained in this end-to-end integration test performs an upgrade of the agoric-3 synthetic chain to an `UNRELEASED_A3P_INTEGRATION` plan name (or the corresponding upgrade plan name for release branches). It loads the docker image `ghcr.io/agoric/agoric-sdk:unreleased` for the software implementing that upgrade (both in the `master` branch or in release branches).
The upgrade handler is implemented by the code in the enclosing `agoric-sdk` repository. After any change to the chain software or vat code upgraded through core proposals, the image must be regenerated. This is automatically done by the `build:sdk` script, but can also be performed manually using:
@@ -202,7 +202,7 @@ That's because you didn't create an image from the local `agoric-sdk`. Run `yarn
If you get an error like,
```
-panic: UPGRADE "UNRELEASED_UPGRADE" NEEDED at height: 1101: {"coreProposals":["@agoric/builders/scripts/vats/init-network.js"]}
+panic: UPGRADE "UNRELEASED_A3P_INTEGRATION" NEEDED at height: 1101: {"coreProposals":["@agoric/builders/scripts/vats/init-network.js"]}
```
Means your SDK image is different than the one expected by the upgrade proposal. To build the correct image, run `yarn build:sdk`.
diff --git a/a3p-integration/debug-current.sh b/a3p-integration/debug-current.sh
index fb14c1b0f02..93a15440a4c 100755
--- a/a3p-integration/debug-current.sh
+++ b/a3p-integration/debug-current.sh
@@ -1,8 +1,8 @@
#!/bin/sh
-# Convience script to debug the current proposal being worked on.
+# Convenience script to debug the current proposal being worked on.
-scripts/build-submission.sh proposals/b:enable-orchestration testing/start-valueVow.js start-valueVow
-scripts/build-submission.sh proposals/b:enable-orchestration testing/restart-valueVow.js restart-valueVow
+scripts/build-submission.sh proposals/z:acceptance testing/start-valueVow.js start-valueVow
+scripts/build-submission.sh proposals/z:acceptance testing/restart-valueVow.js restart-valueVow
-yarn test -m orch --debug
+yarn test -m acceptance --debug
diff --git a/a3p-integration/package.json b/a3p-integration/package.json
index 71207d38918..12cee1cf696 100644
--- a/a3p-integration/package.json
+++ b/a3p-integration/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"agoricSyntheticChain": {
- "fromTag": "latest"
+ "fromTag": "use-vaults-auctions"
},
"scripts": {
"build": "yarn run build:sdk && yarn run build:submissions && yarn run build:synthetic-chain",
@@ -12,7 +12,7 @@
"doctor": "yarn synthetic-chain doctor"
},
"dependencies": {
- "@agoric/synthetic-chain": "patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch",
+ "@agoric/synthetic-chain": "^0.3.0",
"@types/better-sqlite3": "^7.6.9"
},
"packageManager": "yarn@4.2.2",
diff --git a/a3p-integration/proposals/README.md b/a3p-integration/proposals/README.md
new file mode 100644
index 00000000000..d982ef3e92b
--- /dev/null
+++ b/a3p-integration/proposals/README.md
@@ -0,0 +1,102 @@
+# Draft proposals
+
+## How to publish a proposal once approved
+
+`a3p-integration` holds draft proposals to test in agoric-sdk that they perform
+as expected. Once a proposal has been approved by BLD stakers it executes on
+chain and the proposal is no longer a draft. That requires moving it to the
+agoric-3-proposals repo to become part of the `latest` image.
+
+Steps:
+1. Get the upgrade branch
+2. Build the submissions
+3. Migrate the proposal
+4. Update the `latest` iamge
+
+### Get the proposal's branch
+
+We need the actual proposal that was sent to stakers. In the case of upgrades
+(chain-halting) it will be a dedicated release branch. (E.g.
+https://github.com/Agoric/agoric-sdk/tree/dev-upgrade-16/). If you're
+publishing an "upgrade" proposal and it's called `n:upgrade-next`, keep looking;
+that is only a draft.
+
+### Build the submissions
+
+The proposals use `sdk-generate` to ensure that CI is always testing the latest
+version. But to publish we need a fixed version, to match the software upgrade
+that the BLD stakers decided on.
+
+To build that artifact,
+```
+cd a3p-integration
+scripts/build-all-submissions.sh
+```
+
+It's best practice for each output directory to end in `-submission` to make the
+migration simpler. For example,
+```
+ "sdk-generate": [
+ "vats/probe-zcf-bundle.js probe-submission",
+ "vats/test-localchain.js localchaintest-submission"
+ ],
+```
+
+### Migrate the proposal
+
+Figure out the serial number of the proposal that was voted on. Keep a link to
+it to reference.
+
+In agoric-3-proposals, make a new `proposals/NN:PROPOSAL_NAME` directory where
+NN is the proposal's serial number. If the proposal is a chain-halting upgrade
+then it would be `NN:upgrade-KK` where KK is the agoric-sdk upgrade handler
+serial number.
+
+Copy the contents of the agoric-sdk proposal to this new directory.
+
+Verify that `planName` references the go upgrade handler.
+
+Remove `sdk-generate` from package.json (because the files are already generated
+and will be checked in with the PR).
+
+Change `releaseNotes` to reference that actual release notes. [For example](https://github.com/Agoric/agoric-3-proposals/blob/c70cf299b0efc3758991639a03b92cc33867a5bf/proposals/65%3Aupgrade-13/package.json#L3),
+```
+ "releaseNotes": "https://github.com/Agoric/agoric-sdk/releases/tag/agoric-upgrade-13",
+```
+
+Change `sdkImageTag` to the number mentioned in the release notes (search for
+`ghcr.io/agoric/agoric-sdk:`) [For example](https://github.com/Agoric/agoric-3-proposals/blob/c70cf299b0efc3758991639a03b92cc33867a5bf/proposals/65%3Aupgrade-13/package.json#L3C1-L4C1),
+```
+ "sdkImageTag": "39",
+```
+
+# Update the `latest` image
+
+Once you have the new proposal in agoric-3-propals, send a PR to merge it into
+the repo. The PR's CI will test it and once the PR is merged it will update the
+`latest` image.
+
+## How to revise this directory after
+
+Once a new proposal is merged into agoric-3-proposals, take the proposal name
+(the part after the colon) and use it in the fromTag value in a3p-integration's
+package.json. For example, `a:my-proposal` becomes `"fromTag": "use-my-proposal"`.
+
+The `agoricSyntheticChain.fromTag` should generally work with a value of 'latest',
+but that causes problems whenever agoric-3-proposals publishes a new image with changes
+that a3p-integration doesn't yet expect.
+
+So we specify a particular *use* image. E.g. `use-upgrade-16`.
+See https://ghcr.io/agoric/agoric-3-proposals for the available tags.
+
+If you're changing the fromTag to a a new SDK version (e.g. a new chain-halting
+upgrade) then you also need to revise the `upgrade-next` proposal to be able to
+apply on top of that upgrade. In master it should already have these values,
+which should be maintained:
+```
+ "releaseNotes": false,
+ "sdkImageTag": "unreleased",
+ "planName": "UNRELEASED_A3P_INTEGRATION",
+```
+
+But you will have to remove from [upgrade.go](/golang/cosmos/app/upgrade.go) whatever proposals were already executed.
diff --git a/a3p-integration/proposals/a:upgrade-next/README.md b/a3p-integration/proposals/a:upgrade-next/README.md
deleted file mode 100644
index 478b94307fc..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Proposal to upgrade the chain software
-
-The `UNRELEASED_UPGRADE` software upgrade may include core proposals defined in
-its upgrade handler. See `CoreProposalSteps` in the `unreleasedUpgradeHandler`
-in [golang/cosmos/app/app.go](../../../golang/cosmos/app/app.go).
-
-This test proposal may also include `coreProposals` in its `upgradeInfo`, which
-are executed after those defined in that upgrade handler. See `agoricProposal`
-in [package.json](./package.json).
-
-The "binaries" property of `upgradeInfo` is now required since Cosmos SDK 0.46, however it cannot be computed for an unreleased upgrade. To disable the check, `releaseNotes` is set to `false`.
diff --git a/a3p-integration/proposals/a:upgrade-next/initial.test.js b/a3p-integration/proposals/a:upgrade-next/initial.test.js
deleted file mode 100644
index 649a08be4f5..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/initial.test.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import test from 'ava';
-
-import { getVatDetails } from '@agoric/synthetic-chain';
-
-const vats = {
- network: { incarnation: 0 },
- ibc: { incarnation: 0 },
- localchain: { incarnation: 0 },
- walletFactory: { incarnation: 3 },
- zoe: { incarnation: 2 },
-};
-
-test(`vat details`, async t => {
- await null;
- for (const [vatName, expected] of Object.entries(vats)) {
- const actual = await getVatDetails(vatName);
- t.like(actual, expected, `${vatName} details mismatch`);
- }
-});
diff --git a/a3p-integration/proposals/a:upgrade-next/probeZcfBundleCap.test.js b/a3p-integration/proposals/a:upgrade-next/probeZcfBundleCap.test.js
deleted file mode 100644
index 75237d2f013..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/probeZcfBundleCap.test.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import test from 'ava';
-
-import {
- evalBundles,
- getIncarnation,
- getVatDetails,
-} from '@agoric/synthetic-chain';
-
-const SUBMISSION_DIR = 'probe-submission';
-
-test('upgrade Zoe to verify ZcfBundleCap endures', async t => {
- await null;
- t.assert((await getIncarnation('zoe')) === 2, 'zoe incarnation must be one');
-
- // Before the test, the Wallet Factory should be using the legacy ZCF
- const detailsBefore = await getVatDetails('walletFactory');
- t.true(detailsBefore.incarnation >= 2, 'wf incarnation must be >= 2');
-
- await evalBundles(SUBMISSION_DIR);
-
- const detailsAfter = await getVatDetails('walletFactory');
- t.is(
- detailsAfter.incarnation,
- detailsBefore.incarnation + 2,
- 'wf incarnation must increase by 2',
- );
-
- // The test restarts the WalletFactory, so it'll use the recently assigned
- // ZCF bundle. It then restarts Zoe, so it'll revert to whichever ZCF bundle
- // made it to persistent store. We then restart the Wallet Factory and see if
- // it's gone back to the ZCF that Zoe initially knew about. If we could get the
- // ZCF bundleID here from the probe, we'd explicitly check for that. Instead,
- // we have to be content that it did indeed use the newly assigned bundle in
- // manual tests.
- t.not(detailsAfter.bundleID, detailsBefore.bundleID);
-});
diff --git a/a3p-integration/proposals/a:upgrade-next/provisioning-test-submission/send-script-permit.json b/a3p-integration/proposals/a:upgrade-next/provisioning-test-submission/send-script-permit.json
deleted file mode 100644
index 27ba77ddaf6..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/provisioning-test-submission/send-script-permit.json
+++ /dev/null
@@ -1 +0,0 @@
-true
diff --git a/a3p-integration/proposals/a:upgrade-next/provisioning-test-submission/send-script.tjs b/a3p-integration/proposals/a:upgrade-next/provisioning-test-submission/send-script.tjs
deleted file mode 100644
index f27af8cccd5..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/provisioning-test-submission/send-script.tjs
+++ /dev/null
@@ -1,28 +0,0 @@
-#! false node --ignore-this-line
-/* global E */
-
-///
-///
-
-/**
- * Send a payment by looking up deposit facet via namesByAddress.
- *
- * see ./post.test.js
- *
- * @param {BootstrapPowers} powers
- */
-const sendIt = async powers => {
- const addr = '{{ADDRESS}}';
- const {
- consume: { namesByAddress, zoe },
- instance: {
- consume: { reserve },
- },
- } = powers;
- const pf = E(zoe).getPublicFacet(reserve);
- const anInvitation = await E(pf).makeAddCollateralInvitation();
- const addressDepositFacet = E(namesByAddress).lookup(addr, 'depositFacet');
- await E(addressDepositFacet).receive(anInvitation);
-};
-
-sendIt;
diff --git a/a3p-integration/proposals/a:upgrade-next/provisioning.test.js b/a3p-integration/proposals/a:upgrade-next/provisioning.test.js
deleted file mode 100644
index e31ffbb89a8..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/provisioning.test.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// @ts-check
-
-import test from 'ava';
-import { readFile, writeFile } from 'node:fs/promises';
-
-import {
- getIncarnation,
- getUser,
- evalBundles,
- waitForBlock,
- agoric,
-} from '@agoric/synthetic-chain';
-
-const SUBMISSION_DIR = 'provisioning-test-submission';
-
-/**
- * @param {string} fileName base file name without .tjs extension
- * @param {Record} replacements
- */
-const replaceTemplateValuesInFile = async (fileName, replacements) => {
- let script = await readFile(`${fileName}.tjs`, 'utf-8');
- for (const [template, value] of Object.entries(replacements)) {
- script = script.replaceAll(`{{${template}}}`, value);
- }
- await writeFile(`${fileName}.js`, script);
-};
-
-test.serial(`provisioning vat was upgraded`, async t => {
- const incarnation = await getIncarnation('provisioning');
-
- t.is(incarnation, 1);
-});
-
-test.serial(`send invitation via namesByAddress`, async t => {
- const addr = await getUser('gov1');
-
- await replaceTemplateValuesInFile(`${SUBMISSION_DIR}/send-script`, {
- ADDRESS: addr,
- });
-
- await evalBundles(SUBMISSION_DIR);
-
- await waitForBlock(2); // enough time for invitation to arrive?
- const update = await agoric.follow('-lF', `:published.wallet.${addr}`);
- t.is(update.updated, 'balance');
- t.notDeepEqual(update.currentAmount.value, []);
- t.log('balance value', update.currentAmount.value);
- t.log('balance brand', update.currentAmount.brand);
- // XXX agoric follow returns brands as strings
- t.regex(update.currentAmount.brand, /Invitation/);
-});
diff --git a/a3p-integration/proposals/a:upgrade-next/upgradeVaults.js b/a3p-integration/proposals/a:upgrade-next/upgradeVaults.js
deleted file mode 100644
index 981daeba326..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/upgradeVaults.js
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env node
-
-import assert from 'node:assert/strict';
-import {
- generateOracleMap,
- getPriceQuote,
- pushPrices,
- registerOraclesForBrand,
-} from './agd-tools.js';
-
-const BRANDNAMES = ['ATOM', 'stATOM', 'stTIA', 'stOSMO', 'stkATOM'];
-const oraclesByBrand = generateOracleMap('u16', BRANDNAMES);
-
-// There are no old prices for the other currencies.
-const atomOutPre = await getPriceQuote('ATOM');
-assert.equal(atomOutPre, '+12010000');
-
-console.log('adding oracle for each brand');
-await registerOraclesForBrand('ATOM', oraclesByBrand);
-await registerOraclesForBrand('stATOM', oraclesByBrand);
-await registerOraclesForBrand('stTIA', oraclesByBrand);
-await registerOraclesForBrand('stOSMO', oraclesByBrand);
-await registerOraclesForBrand('stkATOM', oraclesByBrand);
-
-console.log('pushing new prices');
-await pushPrices(11.2, 'ATOM', oraclesByBrand);
-await pushPrices(11.3, 'stTIA', oraclesByBrand);
-await pushPrices(11.4, 'stATOM', oraclesByBrand);
-await pushPrices(11.5, 'stOSMO', oraclesByBrand);
-await pushPrices(11.6, 'stkATOM', oraclesByBrand);
diff --git a/a3p-integration/proposals/a:upgrade-next/upgradeVaults.test.js b/a3p-integration/proposals/a:upgrade-next/upgradeVaults.test.js
deleted file mode 100644
index 1670cdd2e92..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/upgradeVaults.test.js
+++ /dev/null
@@ -1,128 +0,0 @@
-import test from 'ava';
-
-import {
- agops,
- ATOM_DENOM,
- getISTBalance,
- getVatDetails,
- openVault,
- USER1ADDR,
-} from '@agoric/synthetic-chain';
-
-import {
- bankSend,
- BID_OFFER_ID,
- checkForOracle,
- createBid,
- generateOracleMap,
- getLiveOffers,
- getPriceQuote,
- getVaultPrices,
- pushPrices,
-} from './agd-tools.js';
-import { getDetailsMatchingVats } from './vatDetails.js';
-
-const checkPriceFeedVatsUpdated = async t => {
- const atomDetails = await getVatDetails('ATOM-USD_price_feed');
- // both the original and the new ATOM vault are incarnation 0
- t.is(atomDetails.incarnation, 0);
- const stAtomDetails = await getVatDetails('stATOM');
- t.is(stAtomDetails.incarnation, 0);
- const stOsmoDetails = await getVatDetails('stOSMO');
- t.is(stOsmoDetails.incarnation, 0);
- const stTiaDetails = await getVatDetails('stTIA');
- t.is(stTiaDetails.incarnation, 0);
- await Promise.all([
- checkForOracle(t, 'ATOM'),
- checkForOracle(t, 'stATOM'),
- checkForOracle(t, 'stTIA'),
- checkForOracle(t, 'stOSMO'),
- checkForOracle(t, 'stkATOM'),
- ]);
-};
-
-const BRANDNAMES = ['ATOM', 'stATOM', 'stTIA', 'stOSMO', 'stkATOM'];
-const oraclesByBrand = generateOracleMap('u16', BRANDNAMES);
-
-const checkNewQuotes = async t => {
- t.log('awaiting new quotes');
- const atomOut = await getPriceQuote('ATOM');
- t.is(atomOut, '+11200000');
- const tiaOut = await getPriceQuote('stTIA');
- t.is(tiaOut, '+11300000');
- const stAtomOut = await getPriceQuote('stATOM');
- t.is(stAtomOut, '+11400000');
- const osmoOut = await getPriceQuote('stOSMO');
- t.is(osmoOut, '+11500000');
- const stkAtomOut = await getPriceQuote('stkATOM');
- t.is(stkAtomOut, '+11600000');
-};
-
-const createNewBid = async t => {
- await createBid('20', USER1ADDR, BID_OFFER_ID);
- const liveOffer = await getLiveOffers(USER1ADDR);
- t.true(liveOffer[0].includes(BID_OFFER_ID));
-};
-
-const openMarginalVault = async t => {
- let user1IST = await getISTBalance(USER1ADDR);
- await bankSend(USER1ADDR, `20000000${ATOM_DENOM}`);
- const currentVaults = await agops.vaults('list', '--from', USER1ADDR);
-
- t.log('opening a vault');
- await openVault(USER1ADDR, 5, 10);
- user1IST += 5;
- const istBalanceAfterVaultOpen = await getISTBalance(USER1ADDR);
- t.is(istBalanceAfterVaultOpen, user1IST);
-
- const activeVaultsAfter = await agops.vaults('list', '--from', USER1ADDR);
- t.log(currentVaults, activeVaultsAfter);
- t.true(
- activeVaultsAfter.length > currentVaults.length,
- `vaults count should increase, ${activeVaultsAfter.length}, ${currentVaults.length}`,
- );
-};
-
-const triggerAuction = async t => {
- await pushPrices(5.2, 'ATOM', oraclesByBrand);
-
- const atomOut = await getPriceQuote('ATOM');
- t.is(atomOut, '+5200000');
-};
-
-const checkAuctionVat = async t => {
- const details = await getDetailsMatchingVats('auctioneer');
- // This query matches both the auction and its governor, so double the count
- t.true(Object.keys(details).length > 2);
-};
-
-const verifyVaultPriceUpdate = async t => {
- const quote = await getVaultPrices(0);
-
- t.true(quote.value[0].amountIn.brand.includes(' ATOM '));
- t.is(quote.value[0].amountOut.value, '+5200000');
-};
-
-// test.serial() isn't guaranteed to run tests in order, so we run the intended tests here
-test('liquidation post upgrade', async t => {
- t.log('starting upgrade vaults test');
- await checkPriceFeedVatsUpdated(t);
-
- t.log('check new price quotes');
- await checkNewQuotes(t);
-
- t.log('create a new Bid for the auction');
- await createNewBid(t);
-
- t.log('open a marginal vault');
- await openMarginalVault(t);
-
- t.log('trigger Auction');
- await triggerAuction(t);
-
- t.log('make new auction');
- await checkAuctionVat(t);
-
- t.log('vault price updated');
- await verifyVaultPriceUpdate(t);
-});
diff --git a/a3p-integration/proposals/a:upgrade-next/use.sh b/a3p-integration/proposals/a:upgrade-next/use.sh
deleted file mode 100755
index dff35e765b1..00000000000
--- a/a3p-integration/proposals/a:upgrade-next/use.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-# Place here any actions that should happen after the upgrade has executed. The
-# actions are executed in the upgraded chain software and the effects are
-# persisted in the generated image for the upgrade, so they can be used in
-# later steps, such as the "test" step, or further proposal layers.
-
-./upgradeVaults.js
diff --git a/a3p-integration/proposals/b:enable-orchestration/.gitignore b/a3p-integration/proposals/b:enable-orchestration/.gitignore
deleted file mode 100644
index 46b91c10fac..00000000000
--- a/a3p-integration/proposals/b:enable-orchestration/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/restart-valueVow
-/start-valueVow
-/submission
diff --git a/a3p-integration/proposals/b:enable-orchestration/README.md b/a3p-integration/proposals/b:enable-orchestration/README.md
deleted file mode 100644
index 55519c81c97..00000000000
--- a/a3p-integration/proposals/b:enable-orchestration/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# CoreEvalProposal to enable orchestration features
-
-The `submission` for this proposal is automatically generated during `yarn build`
-in [a3p-integration](../..) using the code in agoric-sdk through
-[build-all-submissions.sh](../../scripts/build-all-submissions.sh) and
-[build-submission.sh](../../scripts/build-submission.sh).
diff --git a/a3p-integration/proposals/b:enable-orchestration/initial.test.js b/a3p-integration/proposals/b:enable-orchestration/initial.test.js
deleted file mode 100644
index 0a9d50e72f7..00000000000
--- a/a3p-integration/proposals/b:enable-orchestration/initial.test.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import test from 'ava';
-
-import { agd, getVatDetails } from '@agoric/synthetic-chain';
-
-const vats = {
- network: { incarnation: 0 },
- ibc: { incarnation: 0 },
- localchain: { incarnation: 0 },
- orchestration: { incarnation: 0 },
- transfer: { incarnation: 0 },
- walletFactory: { incarnation: 4 },
- zoe: { incarnation: 2 },
-};
-
-test(`vat details`, async t => {
- await null;
- for (const [vatName, expected] of Object.entries(vats)) {
- const actual = await getVatDetails(vatName);
- t.like(actual, expected, `${vatName} details mismatch`);
- }
-});
-
-const queryData = path =>
- agd
- .query('vstorage', 'data', '--output', 'json', path)
- .then(res => JSON.parse(JSON.parse(JSON.parse(res.value).values[0]).body));
-
-test('chain info', async t => {
- const chain = await queryData('published.agoricNames.chain.cosmoshub');
-
- console.log('chain.cosmoshub', chain);
- t.like(chain, { chainId: 'cosmoshub-4' });
-});
-
-test('chain connection', async t => {
- const connection = await queryData(
- 'published.agoricNames.chainConnection.cosmoshub-4_juno-1',
- );
- t.like(connection, { transferChannel: { portId: 'transfer' } });
-});
diff --git a/a3p-integration/proposals/b:enable-orchestration/package.json b/a3p-integration/proposals/b:enable-orchestration/package.json
deleted file mode 100644
index f0e9f51e5bc..00000000000
--- a/a3p-integration/proposals/b:enable-orchestration/package.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "agoricProposal": {
- "type": "/agoric.swingset.CoreEvalProposal",
- "source": "subdir",
- "sdk-generate": [
- "smart-wallet/build-wallet-factory2-upgrade.js",
- "testing/start-valueVow.js start-valueVow",
- "testing/restart-valueVow.js restart-valueVow",
- "vats/init-orchestration.js"
- ]
- },
- "type": "module",
- "license": "Apache-2.0",
- "dependencies": {
- "@agoric/internal": "0.3.3-dev-5676146.0",
- "@agoric/synthetic-chain": "^0.1.0",
- "@cosmjs/stargate": "^0.32.3",
- "@cosmjs/tendermint-rpc": "^0.32.3",
- "@endo/errors": "^1.2.2",
- "@endo/far": "^1.0.4",
- "@endo/init": "^1.0.4",
- "agoric": "0.21.2-dev-5676146.0",
- "ava": "^5.3.1",
- "execa": "^8.0.1",
- "node-fetch": "^3.3.2"
- },
- "ava": {
- "concurrency": 1,
- "serial": true,
- "files": [
- "!submission"
- ]
- },
- "packageManager": "yarn@4.2.2"
-}
diff --git a/a3p-integration/proposals/b:enable-orchestration/test.sh b/a3p-integration/proposals/b:enable-orchestration/test.sh
deleted file mode 100755
index 31b0b27bf56..00000000000
--- a/a3p-integration/proposals/b:enable-orchestration/test.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-# Place here any test that should be executed using the executed proposal.
-# The effects of this step are not persisted in further proposal layers.
-
-GLOBIGNORE=initial.test.js
-
-# test the state right after upgrade
-yarn ava initial.test.js
-
-# test more, in ways that change system state
-yarn ava ./*.test.js
diff --git a/a3p-integration/proposals/b:enable-orchestration/yarn.lock b/a3p-integration/proposals/b:enable-orchestration/yarn.lock
deleted file mode 100644
index b9507c7f0fd..00000000000
--- a/a3p-integration/proposals/b:enable-orchestration/yarn.lock
+++ /dev/null
@@ -1,5365 +0,0 @@
-# This file is generated by running "yarn install" inside your project.
-# Manual changes might be lost - proceed with caution!
-
-__metadata:
- version: 8
- cacheKey: 10c0
-
-"@agoric/access-token@npm:0.4.22-dev-5676146.0+5676146":
- version: 0.4.22-dev-5676146.0
- resolution: "@agoric/access-token@npm:0.4.22-dev-5676146.0"
- dependencies:
- n-readlines: "npm:^1.0.0"
- proper-lockfile: "npm:^4.1.2"
- tmp: "npm:^0.2.1"
- checksum: 10c0/c1fe4f9f1eaf2e4334ec190099f03d2ccff024e0b06693784230ccac6fbe7a98ebce63f365fade828b9c02c8967239e92c8fa0592d2661086e3b31eecd46e3b0
- languageName: node
- linkType: hard
-
-"@agoric/assert@npm:0.6.1-dev-5676146.0+5676146":
- version: 0.6.1-dev-5676146.0
- resolution: "@agoric/assert@npm:0.6.1-dev-5676146.0"
- checksum: 10c0/3391d53d64f4ca74ae5a87b623dc7489a20d91f45716723c33e393cfe6536fb1553344b72d24ac966f49b83d56906140c263778968ff513dfcdbb30e1be68091
- languageName: node
- linkType: hard
-
-"@agoric/babel-generator@npm:^7.17.6":
- version: 7.17.6
- resolution: "@agoric/babel-generator@npm:7.17.6"
- dependencies:
- "@babel/types": "npm:^7.17.0"
- jsesc: "npm:^2.5.1"
- source-map: "npm:^0.5.0"
- checksum: 10c0/59db151ae737bd9b1f21c1589df4c7da9cbf484de5b5cc8352052825c2d977283d975303f55acb54d0210c176cb405da263073ceba1d3a6db65c6e21cc6e663f
- languageName: node
- linkType: hard
-
-"@agoric/base-zone@npm:0.1.1-dev-5676146.0+5676146":
- version: 0.1.1-dev-5676146.0
- resolution: "@agoric/base-zone@npm:0.1.1-dev-5676146.0"
- dependencies:
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@endo/common": "npm:^1.1.0"
- "@endo/exo": "npm:^1.2.1"
- "@endo/far": "npm:^1.0.4"
- "@endo/pass-style": "npm:^1.2.0"
- "@endo/patterns": "npm:^1.2.0"
- checksum: 10c0/b3dfa47af7cf4a686244e2a31243394b44756f127a7612f5d50c77b1a91f777514386c305866705b46219d2d1e0df2b8d5bff9e08f82275043bb0c198c0601e4
- languageName: node
- linkType: hard
-
-"@agoric/cache@npm:0.3.3-dev-5676146.0+5676146":
- version: 0.3.3-dev-5676146.0
- resolution: "@agoric/cache@npm:0.3.3-dev-5676146.0"
- dependencies:
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/notifier": "npm:0.6.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@endo/far": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- checksum: 10c0/b2967955f99d3cfe9b30700373275290183a5b6284703b6bbfff98246342bd7ff995addc48e31a8b2c52c9330c1aed5566f9e73fc0ae5b753478c961d7cdf258
- languageName: node
- linkType: hard
-
-"@agoric/casting@npm:0.4.3-dev-5676146.0+5676146":
- version: 0.4.3-dev-5676146.0
- resolution: "@agoric/casting@npm:0.4.3-dev-5676146.0"
- dependencies:
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/notifier": "npm:0.6.3-dev-5676146.0+5676146"
- "@agoric/spawner": "npm:0.6.9-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@cosmjs/encoding": "npm:^0.32.3"
- "@cosmjs/proto-signing": "npm:^0.32.3"
- "@cosmjs/stargate": "npm:^0.32.3"
- "@cosmjs/tendermint-rpc": "npm:^0.32.3"
- "@endo/far": "npm:^1.0.4"
- "@endo/init": "npm:^1.0.4"
- "@endo/lockdown": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/promise-kit": "npm:^1.0.4"
- node-fetch: "npm:^2.6.0"
- checksum: 10c0/548c929c6535aea1d0a8e2cbc7fc3ec57d04dd8fd5b6e62ee565b674f8a87efe82536091e182a71a985244c0459e19b0195fc81b80a22c480859c37a69815367
- languageName: node
- linkType: hard
-
-"@agoric/cosmic-proto@npm:0.4.1-dev-5676146.0+5676146":
- version: 0.4.1-dev-5676146.0
- resolution: "@agoric/cosmic-proto@npm:0.4.1-dev-5676146.0"
- dependencies:
- "@cosmjs/amino": "npm:^0.32.3"
- "@cosmjs/proto-signing": "npm:^0.32.3"
- "@cosmjs/stargate": "npm:^0.32.3"
- "@cosmjs/tendermint-rpc": "npm:^0.32.3"
- "@endo/init": "npm:^1.0.3"
- axios: "npm:^1.6.7"
- checksum: 10c0/dc5a39feebce9209a393c37f6bfe6be550600718b2c841e13750a92d3a734d5ed718beb3d7532829c2da5e0344cf96b82f8d779dfc30d4b2c266d89902e2f4b8
- languageName: node
- linkType: hard
-
-"@agoric/ertp@npm:0.16.3-dev-5676146.0+5676146":
- version: 0.16.3-dev-5676146.0
- resolution: "@agoric/ertp@npm:0.16.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/notifier": "npm:0.6.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@agoric/zone": "npm:0.2.3-dev-5676146.0+5676146"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/far": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- checksum: 10c0/6a3ef33e6b1052253346a651f6f193dbda9551a2ed3f36f63af0b9da4d27ed80bdf63251f97cc631105c923ac23440ef456198f1b15b56b6aba86ec1a590b6f6
- languageName: node
- linkType: hard
-
-"@agoric/governance@npm:0.10.4-dev-5676146.0+5676146":
- version: 0.10.4-dev-5676146.0
- resolution: "@agoric/governance@npm:0.10.4-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/ertp": "npm:0.16.3-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/network": "npm:0.1.1-dev-5676146.0+5676146"
- "@agoric/notifier": "npm:0.6.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/time": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@agoric/zoe": "npm:0.26.3-dev-5676146.0+5676146"
- "@endo/bundle-source": "npm:^3.1.0"
- "@endo/captp": "npm:^4.0.4"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/far": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/promise-kit": "npm:^1.0.4"
- import-meta-resolve: "npm:^2.2.1"
- checksum: 10c0/64a8a0579fde6dd60630175e5d1bd0a370532c993700049352f2cc83dbfde6cac90b1671acf625afadcc3449a8f4872d1dacc194f8724281b5ac82e6c1b887d1
- languageName: node
- linkType: hard
-
-"@agoric/inter-protocol@npm:0.16.2-dev-5676146.0+5676146":
- version: 0.16.2-dev-5676146.0
- resolution: "@agoric/inter-protocol@npm:0.16.2-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/ertp": "npm:0.16.3-dev-5676146.0+5676146"
- "@agoric/governance": "npm:0.10.4-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/notifier": "npm:0.6.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/time": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@agoric/vats": "npm:0.15.2-dev-5676146.0+5676146"
- "@agoric/zoe": "npm:0.26.3-dev-5676146.0+5676146"
- "@endo/captp": "npm:^4.0.4"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/far": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/promise-kit": "npm:^1.0.4"
- jessie.js: "npm:^0.3.2"
- checksum: 10c0/6216bb903dc4b292f6b24fdc6121cd3540ebdd402f4c81dded60b00bbf2f8130c25a2565ccb80ffc68dbc2b625d0459df3215cbf69585ed84f101a5d53351e4c
- languageName: node
- linkType: hard
-
-"@agoric/internal@npm:0.3.3-dev-5676146.0, @agoric/internal@npm:0.3.3-dev-5676146.0+5676146":
- version: 0.3.3-dev-5676146.0
- resolution: "@agoric/internal@npm:0.3.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/base-zone": "npm:0.1.1-dev-5676146.0+5676146"
- "@endo/common": "npm:^1.1.0"
- "@endo/far": "npm:^1.0.4"
- "@endo/init": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- "@endo/stream": "npm:^1.1.0"
- anylogger: "npm:^0.21.0"
- jessie.js: "npm:^0.3.2"
- checksum: 10c0/cd2a81ff39790a1b333621b3815f0791b70d0822f201d491175e46602697c80814f1fb87a610167e541a9ad431a771cd7348afe24517a15c45d1591d3d494bc2
- languageName: node
- linkType: hard
-
-"@agoric/kmarshal@npm:0.1.1-dev-5676146.0+5676146":
- version: 0.1.1-dev-5676146.0
- resolution: "@agoric/kmarshal@npm:0.1.1-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@endo/far": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- checksum: 10c0/6acd0de1ad1cb2b4bd6065f13394222476a713be169dd7979a26934f223bcac2222d9e1560327f31417a774501e82703dce3c0cae0a327eae955e2072e8587d7
- languageName: node
- linkType: hard
-
-"@agoric/network@npm:0.1.1-dev-5676146.0+5676146":
- version: 0.1.1-dev-5676146.0
- resolution: "@agoric/network@npm:0.1.1-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@endo/base64": "npm:^1.0.2"
- "@endo/far": "npm:^1.0.4"
- "@endo/patterns": "npm:^1.1.0"
- "@endo/promise-kit": "npm:^1.0.4"
- checksum: 10c0/92207ef3889c53526490de4d62b93788dfb009fb70809b473a50993adc0bc8fbbd2be8da43db78a51b5df9af19d7cbe24aab55c958daf4bdcb86ae1e6e55af95
- languageName: node
- linkType: hard
-
-"@agoric/notifier@npm:0.6.3-dev-5676146.0+5676146":
- version: 0.6.3-dev-5676146.0
- resolution: "@agoric/notifier@npm:0.6.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@endo/far": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- checksum: 10c0/5357e05ff60d962189658e9476307f5c3a8fd4f6cf82d30dd4526050c5f747f33eafeb8cdb25753c61d91e1390a4c8408424fd6d15ecb103add72e5113b0c4a1
- languageName: node
- linkType: hard
-
-"@agoric/smart-wallet@npm:0.5.4-dev-5676146.0+5676146":
- version: 0.5.4-dev-5676146.0
- resolution: "@agoric/smart-wallet@npm:0.5.4-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/casting": "npm:0.4.3-dev-5676146.0+5676146"
- "@agoric/ertp": "npm:0.16.3-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/notifier": "npm:0.6.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@agoric/vats": "npm:0.15.2-dev-5676146.0+5676146"
- "@agoric/zoe": "npm:0.26.3-dev-5676146.0+5676146"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/far": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/promise-kit": "npm:^1.0.4"
- checksum: 10c0/cc46165846a0d0b3f7290ec4f5fe60030f3272ee7278bd49274634daee5000d96222e2ed3e72f724943100101cee4d2f760e0bf2d5c08620b89930d3fbed5715
- languageName: node
- linkType: hard
-
-"@agoric/spawner@npm:0.6.9-dev-5676146.0+5676146":
- version: 0.6.9-dev-5676146.0
- resolution: "@agoric/spawner@npm:0.6.9-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/import-bundle": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- checksum: 10c0/4f605a59a2da5fef37faf8923ebeb237e789f65f678a192c926bb1ccb3ead49eecb75b9120971da9cc4d046de0503087af38814e69811e9d6bfa7d1559b0c510
- languageName: node
- linkType: hard
-
-"@agoric/store@npm:0.9.3-dev-5676146.0+5676146":
- version: 0.9.3-dev-5676146.0
- resolution: "@agoric/store@npm:0.9.3-dev-5676146.0"
- dependencies:
- "@endo/exo": "npm:^1.2.1"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/pass-style": "npm:^1.2.0"
- "@endo/patterns": "npm:^1.2.0"
- checksum: 10c0/675e73bbcac024c456b658583ec3fd14a50f69fea5fc07aadf30e593978e5cadbc82d365b13976967b5509614a7adf0adad4e84712f7e0b6c13f2a2a93c9ea63
- languageName: node
- linkType: hard
-
-"@agoric/swing-store@npm:0.9.2-dev-5676146.0+5676146":
- version: 0.9.2-dev-5676146.0
- resolution: "@agoric/swing-store@npm:0.9.2-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@endo/base64": "npm:^1.0.2"
- "@endo/bundle-source": "npm:^3.1.0"
- "@endo/check-bundle": "npm:^1.0.4"
- "@endo/nat": "npm:^5.0.4"
- better-sqlite3: "npm:^9.1.1"
- checksum: 10c0/4f18b4051bc41fb153da4b750144db727f9b59e8fd18196eea1427d12028b47ebf8448b14c47708a2347ed2a4c1ed887fdcf2c0048b5ab4e84869cd17e3dc935
- languageName: node
- linkType: hard
-
-"@agoric/swingset-liveslots@npm:0.10.3-dev-5676146.0+5676146":
- version: 0.10.3-dev-5676146.0
- resolution: "@agoric/swingset-liveslots@npm:0.10.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@endo/env-options": "npm:^1.1.1"
- "@endo/errors": "npm:^1.1.0"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/exo": "npm:^1.2.1"
- "@endo/far": "npm:^1.0.4"
- "@endo/init": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/pass-style": "npm:^1.2.0"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- checksum: 10c0/17ff4c6b94992d5532b748b4b20a95d273f8eb9ee7345552b95050de90563f5f2b03416ff60b9ca3ce07564bb4f3aa993fbf7710f6b24dc88d902b701a8b6a91
- languageName: node
- linkType: hard
-
-"@agoric/swingset-vat@npm:0.32.3-dev-5676146.0+5676146":
- version: 0.32.3-dev-5676146.0
- resolution: "@agoric/swingset-vat@npm:0.32.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/kmarshal": "npm:0.1.1-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/swing-store": "npm:0.9.2-dev-5676146.0+5676146"
- "@agoric/swingset-liveslots": "npm:0.10.3-dev-5676146.0+5676146"
- "@agoric/swingset-xsnap-supervisor": "npm:0.10.3-dev-5676146.0+5676146"
- "@agoric/time": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@agoric/xsnap": "npm:0.14.3-dev-5676146.0+5676146"
- "@agoric/xsnap-lockdown": "npm:0.14.1-dev-5676146.0+5676146"
- "@endo/base64": "npm:^1.0.2"
- "@endo/bundle-source": "npm:^3.1.0"
- "@endo/captp": "npm:^4.0.4"
- "@endo/check-bundle": "npm:^1.0.4"
- "@endo/compartment-mapper": "npm:^1.1.2"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/far": "npm:^1.0.4"
- "@endo/import-bundle": "npm:^1.0.4"
- "@endo/init": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- "@endo/ses-ava": "npm:^1.1.2"
- "@endo/stream": "npm:^1.1.0"
- "@endo/zip": "npm:^1.0.2"
- ansi-styles: "npm:^6.2.1"
- anylogger: "npm:^0.21.0"
- better-sqlite3: "npm:^9.1.1"
- import-meta-resolve: "npm:^2.2.1"
- microtime: "npm:^3.1.0"
- semver: "npm:^6.3.0"
- tmp: "npm:^0.2.1"
- yargs-parser: "npm:^21.1.1"
- peerDependencies:
- ava: ^5.3.0
- bin:
- vat: bin/vat
- checksum: 10c0/5eaa97f9e9a71bf20c590d44693c97e12bfbf42e2ce15991d48e3393ff1f9561b8e7717fa63dabc3c0d720795e8922452485003e86b68e307d90bd6aea4c79b0
- languageName: node
- linkType: hard
-
-"@agoric/swingset-xsnap-supervisor@npm:0.10.3-dev-5676146.0+5676146":
- version: 0.10.3-dev-5676146.0
- resolution: "@agoric/swingset-xsnap-supervisor@npm:0.10.3-dev-5676146.0"
- checksum: 10c0/495c847ccb69bcfb338e27a2b423ec480e303c52c51e0496aaeea820d17af100c59f2d45e540517c8eba4aea9645ef6c3e200ad3834d46087b4a21671791e077
- languageName: node
- linkType: hard
-
-"@agoric/synthetic-chain@npm:^0.1.0":
- version: 0.1.0
- resolution: "@agoric/synthetic-chain@npm:0.1.0"
- dependencies:
- "@endo/zip": "npm:^1.0.1"
- better-sqlite3: "npm:^9.4.0"
- chalk: "npm:^5.3.0"
- execa: "npm:^8.0.1"
- bin:
- synthetic-chain: dist/cli/cli.js
- checksum: 10c0/8305293d085cde9cbf94670134216e06337c5624c45faf5dfebb86762042abe7b4340cf3205e671dfce54e888bd4e9b3428400756833fa06f2bbb21b44668c44
- languageName: node
- linkType: hard
-
-"@agoric/time@npm:0.3.3-dev-5676146.0+5676146":
- version: 0.3.3-dev-5676146.0
- resolution: "@agoric/time@npm:0.3.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@endo/nat": "npm:^5.0.4"
- "@endo/patterns": "npm:^1.2.0"
- checksum: 10c0/a221f90a327ffaf9eccc6943b1f59b97b200df3a9932b9da7aee484f938e919302069b056182035d6681ebb3b70759841bcf221549f91f172f89848372efe30a
- languageName: node
- linkType: hard
-
-"@agoric/vat-data@npm:0.5.3-dev-5676146.0+5676146":
- version: 0.5.3-dev-5676146.0
- resolution: "@agoric/vat-data@npm:0.5.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/base-zone": "npm:0.1.1-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/swingset-liveslots": "npm:0.10.3-dev-5676146.0+5676146"
- "@agoric/vow": "npm:0.1.1-dev-5676146.0+5676146"
- checksum: 10c0/2c08e571cf1ab9af2dc1214c1d7fb9b73446ed9ddaca3a10db2b90160138c07728a0d37cfc9748a37dd424a2945da706bfecc152b2b87fbb59e81bdafaba0e77
- languageName: node
- linkType: hard
-
-"@agoric/vats@npm:0.15.2-dev-5676146.0+5676146":
- version: 0.15.2-dev-5676146.0
- resolution: "@agoric/vats@npm:0.15.2-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/ertp": "npm:0.16.3-dev-5676146.0+5676146"
- "@agoric/governance": "npm:0.10.4-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/network": "npm:0.1.1-dev-5676146.0+5676146"
- "@agoric/notifier": "npm:0.6.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/swingset-vat": "npm:0.32.3-dev-5676146.0+5676146"
- "@agoric/time": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@agoric/zoe": "npm:0.26.3-dev-5676146.0+5676146"
- "@agoric/zone": "npm:0.2.3-dev-5676146.0+5676146"
- "@endo/far": "npm:^1.0.4"
- "@endo/import-bundle": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- import-meta-resolve: "npm:^2.2.1"
- jessie.js: "npm:^0.3.2"
- checksum: 10c0/ac5117f609b112bf8902488d4769c3f6670cc3402cbe8e75db1c8f227f25e4334b5b447d4fa29cfe674e6d3b93554cdfd3d5858dff6c5b48f89b6e24af636da4
- languageName: node
- linkType: hard
-
-"@agoric/vow@npm:0.1.1-dev-5676146.0+5676146":
- version: 0.1.1-dev-5676146.0
- resolution: "@agoric/vow@npm:0.1.1-dev-5676146.0"
- dependencies:
- "@agoric/base-zone": "npm:0.1.1-dev-5676146.0+5676146"
- "@endo/env-options": "npm:^1.1.1"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/pass-style": "npm:^1.2.0"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- checksum: 10c0/e0aa219b31e962b784bf4c48a2108b032aecf60c7cf05393e305c0279abee887a81879ca6999eb56cbaedebc656d7d575715ba5c470dd624f62304624475de60
- languageName: node
- linkType: hard
-
-"@agoric/xsnap-lockdown@npm:0.14.1-dev-5676146.0+5676146":
- version: 0.14.1-dev-5676146.0
- resolution: "@agoric/xsnap-lockdown@npm:0.14.1-dev-5676146.0"
- checksum: 10c0/8faa700ff6049b9cd29109c42e2ef3b228f18e265a5908e987af4ee32127e9b6451b7299538ec8fa50514c359f2b0b9a60beb6a5d2e126928def1e5232a3d919
- languageName: node
- linkType: hard
-
-"@agoric/xsnap@npm:0.14.3-dev-5676146.0+5676146":
- version: 0.14.3-dev-5676146.0
- resolution: "@agoric/xsnap@npm:0.14.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/xsnap-lockdown": "npm:0.14.1-dev-5676146.0+5676146"
- "@endo/bundle-source": "npm:^3.1.0"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/init": "npm:^1.0.4"
- "@endo/netstring": "npm:^1.0.4"
- "@endo/promise-kit": "npm:^1.0.4"
- "@endo/stream": "npm:^1.1.0"
- "@endo/stream-node": "npm:^1.0.4"
- glob: "npm:^7.1.6"
- tmp: "npm:^0.2.1"
- bin:
- ava-xs: src/ava-xs.js
- xsrepl: src/xsrepl
- checksum: 10c0/0f5461b8c5cafa94388720cdcbd5b9fc65e0f2416d9084e3e90b60728cf050fcd95c009a67fda284cee2471058814ba504e655e0a3de82cbbc36e03c24e9fc50
- languageName: node
- linkType: hard
-
-"@agoric/zoe@npm:0.26.3-dev-5676146.0+5676146":
- version: 0.26.3-dev-5676146.0
- resolution: "@agoric/zoe@npm:0.26.3-dev-5676146.0"
- dependencies:
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/base-zone": "npm:0.1.1-dev-5676146.0+5676146"
- "@agoric/ertp": "npm:0.16.3-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/notifier": "npm:0.6.3-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/swingset-liveslots": "npm:0.10.3-dev-5676146.0+5676146"
- "@agoric/swingset-vat": "npm:0.32.3-dev-5676146.0+5676146"
- "@agoric/time": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@agoric/zone": "npm:0.2.3-dev-5676146.0+5676146"
- "@endo/bundle-source": "npm:^3.1.0"
- "@endo/captp": "npm:^4.0.4"
- "@endo/common": "npm:^1.1.0"
- "@endo/eventual-send": "npm:^1.1.2"
- "@endo/exo": "npm:^1.2.1"
- "@endo/far": "npm:^1.0.4"
- "@endo/import-bundle": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- yargs-parser: "npm:^21.1.1"
- checksum: 10c0/4db929e776483dd41c0453d322fe93d27d35826ab98e31e257314e41f2eb6c86eb2a1da09761790bbc5f2bfa41a348ef5c84534044b6d1de576eca1ecea31a82
- languageName: node
- linkType: hard
-
-"@agoric/zone@npm:0.2.3-dev-5676146.0+5676146":
- version: 0.2.3-dev-5676146.0
- resolution: "@agoric/zone@npm:0.2.3-dev-5676146.0"
- dependencies:
- "@agoric/base-zone": "npm:0.1.1-dev-5676146.0+5676146"
- "@agoric/vat-data": "npm:0.5.3-dev-5676146.0+5676146"
- "@endo/far": "npm:^1.0.4"
- "@endo/pass-style": "npm:^1.2.0"
- checksum: 10c0/82a7f1c741bb1c6bfca6398686e71b47135ee584f794dbbfc01ecdb37aea37a2607d857532caefd5c61a03f90a3fb7ac02374c189d4510b759209276f631a8d6
- languageName: node
- linkType: hard
-
-"@babel/code-frame@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/code-frame@npm:7.24.7"
- dependencies:
- "@babel/highlight": "npm:^7.24.7"
- picocolors: "npm:^1.0.0"
- checksum: 10c0/ab0af539473a9f5aeaac7047e377cb4f4edd255a81d84a76058595f8540784cc3fbe8acf73f1e073981104562490aabfb23008cd66dc677a456a4ed5390fdde6
- languageName: node
- linkType: hard
-
-"@babel/generator@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/generator@npm:7.24.7"
- dependencies:
- "@babel/types": "npm:^7.24.7"
- "@jridgewell/gen-mapping": "npm:^0.3.5"
- "@jridgewell/trace-mapping": "npm:^0.3.25"
- jsesc: "npm:^2.5.1"
- checksum: 10c0/06b1f3350baf527a3309e50ffd7065f7aee04dd06e1e7db794ddfde7fe9d81f28df64edd587173f8f9295496a7ddb74b9a185d4bf4de7bb619e6d4ec45c8fd35
- languageName: node
- linkType: hard
-
-"@babel/helper-environment-visitor@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/helper-environment-visitor@npm:7.24.7"
- dependencies:
- "@babel/types": "npm:^7.24.7"
- checksum: 10c0/36ece78882b5960e2d26abf13cf15ff5689bf7c325b10a2895a74a499e712de0d305f8d78bb382dd3c05cfba7e47ec98fe28aab5674243e0625cd38438dd0b2d
- languageName: node
- linkType: hard
-
-"@babel/helper-function-name@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/helper-function-name@npm:7.24.7"
- dependencies:
- "@babel/template": "npm:^7.24.7"
- "@babel/types": "npm:^7.24.7"
- checksum: 10c0/e5e41e6cf86bd0f8bf272cbb6e7c5ee0f3e9660414174435a46653efba4f2479ce03ce04abff2aa2ef9359cf057c79c06cb7b134a565ad9c0e8a50dcdc3b43c4
- languageName: node
- linkType: hard
-
-"@babel/helper-hoist-variables@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/helper-hoist-variables@npm:7.24.7"
- dependencies:
- "@babel/types": "npm:^7.24.7"
- checksum: 10c0/19ee37563bbd1219f9d98991ad0e9abef77803ee5945fd85aa7aa62a67c69efca9a801696a1b58dda27f211e878b3327789e6fd2a6f6c725ccefe36774b5ce95
- languageName: node
- linkType: hard
-
-"@babel/helper-split-export-declaration@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/helper-split-export-declaration@npm:7.24.7"
- dependencies:
- "@babel/types": "npm:^7.24.7"
- checksum: 10c0/0254577d7086bf09b01bbde98f731d4fcf4b7c3fa9634fdb87929801307c1f6202a1352e3faa5492450fa8da4420542d44de604daf540704ff349594a78184f6
- languageName: node
- linkType: hard
-
-"@babel/helper-string-parser@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/helper-string-parser@npm:7.24.7"
- checksum: 10c0/47840c7004e735f3dc93939c77b099bb41a64bf3dda0cae62f60e6f74a5ff80b63e9b7cf77b5ec25a324516381fc994e1f62f922533236a8e3a6af57decb5e1e
- languageName: node
- linkType: hard
-
-"@babel/helper-validator-identifier@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/helper-validator-identifier@npm:7.24.7"
- checksum: 10c0/87ad608694c9477814093ed5b5c080c2e06d44cb1924ae8320474a74415241223cc2a725eea2640dd783ff1e3390e5f95eede978bc540e870053152e58f1d651
- languageName: node
- linkType: hard
-
-"@babel/highlight@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/highlight@npm:7.24.7"
- dependencies:
- "@babel/helper-validator-identifier": "npm:^7.24.7"
- chalk: "npm:^2.4.2"
- js-tokens: "npm:^4.0.0"
- picocolors: "npm:^1.0.0"
- checksum: 10c0/674334c571d2bb9d1c89bdd87566383f59231e16bcdcf5bb7835babdf03c9ae585ca0887a7b25bdf78f303984af028df52831c7989fecebb5101cc132da9393a
- languageName: node
- linkType: hard
-
-"@babel/parser@npm:^7.23.6, @babel/parser@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/parser@npm:7.24.7"
- bin:
- parser: ./bin/babel-parser.js
- checksum: 10c0/8b244756872185a1c6f14b979b3535e682ff08cb5a2a5fd97cc36c017c7ef431ba76439e95e419d43000c5b07720495b00cf29a7f0d9a483643d08802b58819b
- languageName: node
- linkType: hard
-
-"@babel/template@npm:^7.24.7":
- version: 7.24.7
- resolution: "@babel/template@npm:7.24.7"
- dependencies:
- "@babel/code-frame": "npm:^7.24.7"
- "@babel/parser": "npm:^7.24.7"
- "@babel/types": "npm:^7.24.7"
- checksum: 10c0/95b0b3ee80fcef685b7f4426f5713a855ea2cd5ac4da829b213f8fb5afe48a2a14683c2ea04d446dbc7f711c33c5cd4a965ef34dcbe5bc387c9e966b67877ae3
- languageName: node
- linkType: hard
-
-"@babel/traverse@npm:^7.23.6":
- version: 7.24.7
- resolution: "@babel/traverse@npm:7.24.7"
- dependencies:
- "@babel/code-frame": "npm:^7.24.7"
- "@babel/generator": "npm:^7.24.7"
- "@babel/helper-environment-visitor": "npm:^7.24.7"
- "@babel/helper-function-name": "npm:^7.24.7"
- "@babel/helper-hoist-variables": "npm:^7.24.7"
- "@babel/helper-split-export-declaration": "npm:^7.24.7"
- "@babel/parser": "npm:^7.24.7"
- "@babel/types": "npm:^7.24.7"
- debug: "npm:^4.3.1"
- globals: "npm:^11.1.0"
- checksum: 10c0/a5135e589c3f1972b8877805f50a084a04865ccb1d68e5e1f3b94a8841b3485da4142e33413d8fd76bc0e6444531d3adf1f59f359c11ffac452b743d835068ab
- languageName: node
- linkType: hard
-
-"@babel/types@npm:^7.17.0, @babel/types@npm:^7.24.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.8.3":
- version: 7.24.7
- resolution: "@babel/types@npm:7.24.7"
- dependencies:
- "@babel/helper-string-parser": "npm:^7.24.7"
- "@babel/helper-validator-identifier": "npm:^7.24.7"
- to-fast-properties: "npm:^2.0.0"
- checksum: 10c0/d9ecbfc3eb2b05fb1e6eeea546836ac30d990f395ef3fe3f75ced777a222c3cfc4489492f72e0ce3d9a5a28860a1ce5f81e66b88cf5088909068b3ff4fab72c1
- languageName: node
- linkType: hard
-
-"@colors/colors@npm:1.6.0":
- version: 1.6.0
- resolution: "@colors/colors@npm:1.6.0"
- checksum: 10c0/9328a0778a5b0db243af54455b79a69e3fb21122d6c15ef9e9fcc94881d8d17352d8b2b2590f9bdd46fac5c2d6c1636dcfc14358a20c70e22daf89e1a759b629
- languageName: node
- linkType: hard
-
-"@confio/ics23@npm:^0.6.8":
- version: 0.6.8
- resolution: "@confio/ics23@npm:0.6.8"
- dependencies:
- "@noble/hashes": "npm:^1.0.0"
- protobufjs: "npm:^6.8.8"
- checksum: 10c0/2f3f5032cd6a34c9b2fbd64bbf7e1cdec75ca71f348a770f7b5474b5027b12202bfbcd404eca931efddb5901f769af035a87cb8bddbf3f23d7e5d93c9d3d7f6f
- languageName: node
- linkType: hard
-
-"@confio/relayer@npm:^0.11.3":
- version: 0.11.3
- resolution: "@confio/relayer@npm:0.11.3"
- dependencies:
- "@cosmjs/cosmwasm-stargate": "npm:^0.32.1"
- "@cosmjs/crypto": "npm:^0.32.1"
- "@cosmjs/encoding": "npm:^0.32.1"
- "@cosmjs/faucet-client": "npm:^0.32.1"
- "@cosmjs/math": "npm:^0.32.1"
- "@cosmjs/proto-signing": "npm:^0.32.1"
- "@cosmjs/stargate": "npm:^0.32.1"
- "@cosmjs/stream": "npm:^0.32.1"
- "@cosmjs/tendermint-rpc": "npm:^0.32.1"
- "@cosmjs/utils": "npm:^0.32.1"
- ajv: "npm:7.1.1"
- axios: "npm:^1.6.7"
- commander: "npm:7.1.0"
- cosmjs-types: "npm:^0.9.0"
- fast-safe-stringify: "npm:2.0.4"
- js-yaml: "npm:4.0.0"
- lodash: "npm:4.17.21"
- prom-client: "npm:13.1.0"
- table: "npm:^6.7.1"
- triple-beam: "npm:1.3.0"
- winston: "npm:3.3.3"
- bin:
- ibc-relayer: build/binary/ibc-relayer/index.js
- ibc-setup: build/binary/ibc-setup/index.js
- checksum: 10c0/f6519a21a7e2b7d79835558305bbac6f6712b90f0e10f2c156ae74583ca170da0b97ec456272c25a2ffdcbe0343ad425e67886b792f2aed1f5303e34b93edf40
- languageName: node
- linkType: hard
-
-"@cosmjs/amino@npm:^0.32.3, @cosmjs/amino@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/amino@npm:0.32.4"
- dependencies:
- "@cosmjs/crypto": "npm:^0.32.4"
- "@cosmjs/encoding": "npm:^0.32.4"
- "@cosmjs/math": "npm:^0.32.4"
- "@cosmjs/utils": "npm:^0.32.4"
- checksum: 10c0/cd8e215b0406f5c7b73ab0a21106d06b6f76b1da12f1ab7b612884e1dd8bc626966dc67d4e7580090ade131546cbec70000f854e6596935299d054b788929a7e
- languageName: node
- linkType: hard
-
-"@cosmjs/cosmwasm-stargate@npm:^0.32.1":
- version: 0.32.4
- resolution: "@cosmjs/cosmwasm-stargate@npm:0.32.4"
- dependencies:
- "@cosmjs/amino": "npm:^0.32.4"
- "@cosmjs/crypto": "npm:^0.32.4"
- "@cosmjs/encoding": "npm:^0.32.4"
- "@cosmjs/math": "npm:^0.32.4"
- "@cosmjs/proto-signing": "npm:^0.32.4"
- "@cosmjs/stargate": "npm:^0.32.4"
- "@cosmjs/tendermint-rpc": "npm:^0.32.4"
- "@cosmjs/utils": "npm:^0.32.4"
- cosmjs-types: "npm:^0.9.0"
- pako: "npm:^2.0.2"
- checksum: 10c0/f7e285c51ef8b1098a9ea5ca2546a1e226b4fa0a990d95faa6f3b752f3638b6c55f36a56b6f4b11f0a66fd61e3ae8772921d8e99418218df0b2205efe1c82f37
- languageName: node
- linkType: hard
-
-"@cosmjs/crypto@npm:^0.32.1, @cosmjs/crypto@npm:^0.32.3, @cosmjs/crypto@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/crypto@npm:0.32.4"
- dependencies:
- "@cosmjs/encoding": "npm:^0.32.4"
- "@cosmjs/math": "npm:^0.32.4"
- "@cosmjs/utils": "npm:^0.32.4"
- "@noble/hashes": "npm:^1"
- bn.js: "npm:^5.2.0"
- elliptic: "npm:^6.5.4"
- libsodium-wrappers-sumo: "npm:^0.7.11"
- checksum: 10c0/94e742285eb8c7c5393055ba0635f10c06bf87710e953aedc71e3edc2b8e21a12a0d9b5e8eff37e326765f57c9eb3c7fd358f24f639efad4f1a6624eb8189534
- languageName: node
- linkType: hard
-
-"@cosmjs/encoding@npm:^0.32.1, @cosmjs/encoding@npm:^0.32.3, @cosmjs/encoding@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/encoding@npm:0.32.4"
- dependencies:
- base64-js: "npm:^1.3.0"
- bech32: "npm:^1.1.4"
- readonly-date: "npm:^1.0.0"
- checksum: 10c0/4a30d5ae1a2d1247d44bda46101ce208c7666d8801ca9a33de94edc35cc22460c16b4834ec84d5a65ffef5e2a4b58605e0a0a056c46bc0a042979ec84acf20cd
- languageName: node
- linkType: hard
-
-"@cosmjs/faucet-client@npm:^0.32.1":
- version: 0.32.4
- resolution: "@cosmjs/faucet-client@npm:0.32.4"
- dependencies:
- axios: "npm:^1.6.0"
- checksum: 10c0/1651cb370eb5fa2b12b6f94e06d1dc9a6306e34cad3fc87d9263d8b8a225d500449e10a9f6e326534f65261778208dab7fada6a70efb63195589ad08f58e1008
- languageName: node
- linkType: hard
-
-"@cosmjs/json-rpc@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/json-rpc@npm:0.32.4"
- dependencies:
- "@cosmjs/stream": "npm:^0.32.4"
- xstream: "npm:^11.14.0"
- checksum: 10c0/b3ebd240f4fb21260e284d2e503ecc61bac898842187ab717f0efb9a5f21272f161f267cc145629caeb9735f80946844384e2bd410275a4744147a44518c0fa0
- languageName: node
- linkType: hard
-
-"@cosmjs/math@npm:^0.32.1, @cosmjs/math@npm:^0.32.3, @cosmjs/math@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/math@npm:0.32.4"
- dependencies:
- bn.js: "npm:^5.2.0"
- checksum: 10c0/91e47015be5634d27d71d14c5a05899fb4992b69db02cab1558376dedf8254f96d5e24f097c5601804ae18ed33c7c25d023653ac2bf9d20250fd3e5637f6b101
- languageName: node
- linkType: hard
-
-"@cosmjs/proto-signing@npm:^0.32.1, @cosmjs/proto-signing@npm:^0.32.3, @cosmjs/proto-signing@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/proto-signing@npm:0.32.4"
- dependencies:
- "@cosmjs/amino": "npm:^0.32.4"
- "@cosmjs/crypto": "npm:^0.32.4"
- "@cosmjs/encoding": "npm:^0.32.4"
- "@cosmjs/math": "npm:^0.32.4"
- "@cosmjs/utils": "npm:^0.32.4"
- cosmjs-types: "npm:^0.9.0"
- checksum: 10c0/6915059d2e6dbe1abda4a747c3b1abd47a9eff4f8cb2cf9a5545f939b656b4a15bbde2bfc1364357f9b2a081a066280c3b469f6d13dd5fc51b429b0f90a54913
- languageName: node
- linkType: hard
-
-"@cosmjs/socket@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/socket@npm:0.32.4"
- dependencies:
- "@cosmjs/stream": "npm:^0.32.4"
- isomorphic-ws: "npm:^4.0.1"
- ws: "npm:^7"
- xstream: "npm:^11.14.0"
- checksum: 10c0/2d94c1fb39016bea3c7c145f4565c8a0fed20c805ac569ea604cd3646c15147b82b8db18a4e3c832d6ae0c3dd14363d4db3d91bcacac922679efba164ed49386
- languageName: node
- linkType: hard
-
-"@cosmjs/stargate@npm:^0.32.1, @cosmjs/stargate@npm:^0.32.3, @cosmjs/stargate@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/stargate@npm:0.32.4"
- dependencies:
- "@confio/ics23": "npm:^0.6.8"
- "@cosmjs/amino": "npm:^0.32.4"
- "@cosmjs/encoding": "npm:^0.32.4"
- "@cosmjs/math": "npm:^0.32.4"
- "@cosmjs/proto-signing": "npm:^0.32.4"
- "@cosmjs/stream": "npm:^0.32.4"
- "@cosmjs/tendermint-rpc": "npm:^0.32.4"
- "@cosmjs/utils": "npm:^0.32.4"
- cosmjs-types: "npm:^0.9.0"
- xstream: "npm:^11.14.0"
- checksum: 10c0/c30a3519516aaa7eae58ba827c80fcf74c7fe7a9d3aa5cc8138c3a2768f5f241f59c2f5cec27e9037b4df12b1c6605b4fac9eadb4de97bd84edddc3a80a02e24
- languageName: node
- linkType: hard
-
-"@cosmjs/stream@npm:^0.32.1, @cosmjs/stream@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/stream@npm:0.32.4"
- dependencies:
- xstream: "npm:^11.14.0"
- checksum: 10c0/c677c53f9101c2a36fa03a475d92dea2fa69c475f896751b5e18a5d07087eeecbf6bca2e62a8940003da53fa235a9b2dd78c8257bf19c3f96e3f69fa8d5f183d
- languageName: node
- linkType: hard
-
-"@cosmjs/tendermint-rpc@npm:^0.32.1, @cosmjs/tendermint-rpc@npm:^0.32.3, @cosmjs/tendermint-rpc@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/tendermint-rpc@npm:0.32.4"
- dependencies:
- "@cosmjs/crypto": "npm:^0.32.4"
- "@cosmjs/encoding": "npm:^0.32.4"
- "@cosmjs/json-rpc": "npm:^0.32.4"
- "@cosmjs/math": "npm:^0.32.4"
- "@cosmjs/socket": "npm:^0.32.4"
- "@cosmjs/stream": "npm:^0.32.4"
- "@cosmjs/utils": "npm:^0.32.4"
- axios: "npm:^1.6.0"
- readonly-date: "npm:^1.0.0"
- xstream: "npm:^11.14.0"
- checksum: 10c0/5fae7afcdf98cc7dd36922aa1586254cc8c202cf8fe66804e61d793d31dcff816f40d33f7a0eb72c1b9226c7c361d4848e4ff12d0489f6fa66f47f0c86ae18dd
- languageName: node
- linkType: hard
-
-"@cosmjs/utils@npm:^0.32.1, @cosmjs/utils@npm:^0.32.4":
- version: 0.32.4
- resolution: "@cosmjs/utils@npm:0.32.4"
- checksum: 10c0/d5ff8b235094be1150853a715116049f73eb5cdfeea8ce8e22ecccc61ec99792db457404d4307782b1a2f935dcf438f5c485beabfcfbc1dc5df26eb6e6da9062
- languageName: node
- linkType: hard
-
-"@dabh/diagnostics@npm:^2.0.2":
- version: 2.0.3
- resolution: "@dabh/diagnostics@npm:2.0.3"
- dependencies:
- colorspace: "npm:1.1.x"
- enabled: "npm:2.0.x"
- kuler: "npm:^2.0.0"
- checksum: 10c0/a5133df8492802465ed01f2f0a5784585241a1030c362d54a602ed1839816d6c93d71dde05cf2ddb4fd0796238c19774406bd62fa2564b637907b495f52425fe
- languageName: node
- linkType: hard
-
-"@endo/base64@npm:^1.0.2, @endo/base64@npm:^1.0.5":
- version: 1.0.5
- resolution: "@endo/base64@npm:1.0.5"
- checksum: 10c0/4a47a45b9025cf48542708fddc66314a135a31a1121262690c341f09f58fb6a37b21694461dd0bdc2d24c5b6417da7c42ab336033c38a67f0a4834aa7141d650
- languageName: node
- linkType: hard
-
-"@endo/bundle-source@npm:^3.1.0":
- version: 3.2.3
- resolution: "@endo/bundle-source@npm:3.2.3"
- dependencies:
- "@endo/base64": "npm:^1.0.5"
- "@endo/compartment-mapper": "npm:^1.1.5"
- "@endo/evasive-transform": "npm:^1.1.2"
- "@endo/init": "npm:^1.1.2"
- "@endo/promise-kit": "npm:^1.1.2"
- "@endo/where": "npm:^1.0.5"
- "@rollup/plugin-commonjs": "npm:^19.0.0"
- "@rollup/plugin-node-resolve": "npm:^13.0.0"
- acorn: "npm:^8.2.4"
- rollup: "npm:^2.79.1"
- bin:
- bundle-source: src/tool.js
- checksum: 10c0/6f35953edbb3fe9f2b18d69495c1d04ce5e94bc37ca41662dd424388d42b361e246b7f9759cbf70ad8373c917657f373f9aa5dc14366158e29981994fa7b3fe7
- languageName: node
- linkType: hard
-
-"@endo/captp@npm:^4.0.4":
- version: 4.2.0
- resolution: "@endo/captp@npm:4.2.0"
- dependencies:
- "@endo/errors": "npm:^1.2.2"
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/marshal": "npm:^1.5.0"
- "@endo/nat": "npm:^5.0.7"
- "@endo/promise-kit": "npm:^1.1.2"
- checksum: 10c0/968721cc0da15f58d5fadaef4de9194a77f7091d3889970beaa0a27b7546825cc8e1e26ec8636d04ce0232a63f19a9a05a04b6a68a35125a27e22544177f7d50
- languageName: node
- linkType: hard
-
-"@endo/check-bundle@npm:^1.0.4":
- version: 1.0.7
- resolution: "@endo/check-bundle@npm:1.0.7"
- dependencies:
- "@endo/base64": "npm:^1.0.5"
- "@endo/compartment-mapper": "npm:^1.1.5"
- "@endo/errors": "npm:^1.2.2"
- checksum: 10c0/824e476f79e40cdfd459f0e5352a7fd2e57014790cb03d234a3bed1862586513f965fac3f68cb657e4a1091c6e5392029927286eb681a498f705ae70f6413e34
- languageName: node
- linkType: hard
-
-"@endo/cjs-module-analyzer@npm:^1.0.5":
- version: 1.0.5
- resolution: "@endo/cjs-module-analyzer@npm:1.0.5"
- checksum: 10c0/a9d0eb444f01b9d690624b88828eece23fb994c52712f980b098a6117c9c2520aef514c271db83fd7b944ba362e8aa0629e3f27819e11727ce4435a1c3b82d5f
- languageName: node
- linkType: hard
-
-"@endo/common@npm:^1.1.0, @endo/common@npm:^1.2.2":
- version: 1.2.2
- resolution: "@endo/common@npm:1.2.2"
- dependencies:
- "@endo/errors": "npm:^1.2.2"
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/promise-kit": "npm:^1.1.2"
- checksum: 10c0/04a516c12be5146a2b15a31842e8f13a090efb19e674b018c45241ce1c13a9e2480f23df2240105fc6819dc596bac9d2e4746b6a5798b6e7a0b7fc019336e58e
- languageName: node
- linkType: hard
-
-"@endo/compartment-mapper@npm:^1.1.2, @endo/compartment-mapper@npm:^1.1.5":
- version: 1.1.5
- resolution: "@endo/compartment-mapper@npm:1.1.5"
- dependencies:
- "@endo/cjs-module-analyzer": "npm:^1.0.5"
- "@endo/static-module-record": "npm:^1.1.2"
- "@endo/zip": "npm:^1.0.5"
- ses: "npm:^1.5.0"
- checksum: 10c0/7f06ef852265dd29acde4f41fc749bf29a47ce4d5b1a7977c3d9a979ac3fdfb5de6a02bd86c736d136fd3e2005294bddc578fdb4fe5b0877e558722693ea0b01
- languageName: node
- linkType: hard
-
-"@endo/env-options@npm:^1.1.1, @endo/env-options@npm:^1.1.4":
- version: 1.1.4
- resolution: "@endo/env-options@npm:1.1.4"
- checksum: 10c0/8816c8fe1332a6f3366e7e4849b000d757fcd181eac011ed8363ccc4e66dfa2f2d975f8d5cbfb3844f3e327c5391e77ee7e234a59a21744c74c945f683b56df1
- languageName: node
- linkType: hard
-
-"@endo/errors@npm:^1.1.0, @endo/errors@npm:^1.2.2":
- version: 1.2.2
- resolution: "@endo/errors@npm:1.2.2"
- dependencies:
- ses: "npm:^1.5.0"
- checksum: 10c0/d90baaf803b17130b83fbc562e253504a6a05e4843d63536e74578503f6bd937fdba3464c4d8eeb9df16b795639cd9c4aad143520525f9e54aa3e91dc5184c17
- languageName: node
- linkType: hard
-
-"@endo/evasive-transform@npm:^1.1.2":
- version: 1.1.2
- resolution: "@endo/evasive-transform@npm:1.1.2"
- dependencies:
- "@agoric/babel-generator": "npm:^7.17.6"
- "@babel/parser": "npm:^7.23.6"
- "@babel/traverse": "npm:^7.23.6"
- source-map: "npm:0.7.4"
- checksum: 10c0/5a5a503ea144e63844d266a0b1713c10cdaf18e2390b3f67c69e57a6f20de1ad299abf55dca85c941ea95a8360ae9afa3d86ee72be2377699a62bc57adccb914
- languageName: node
- linkType: hard
-
-"@endo/eventual-send@npm:^1.1.2, @endo/eventual-send@npm:^1.2.2":
- version: 1.2.2
- resolution: "@endo/eventual-send@npm:1.2.2"
- dependencies:
- "@endo/env-options": "npm:^1.1.4"
- checksum: 10c0/d19fcee64b7113e5ff7fc4886d47bc722c4edd49a107f0952760567a4dd31cabd14abd788cc2c0c9d4b907e2c737944a389fd0ab5b0917809ef47a1df6803642
- languageName: node
- linkType: hard
-
-"@endo/exo@npm:^1.2.1":
- version: 1.5.0
- resolution: "@endo/exo@npm:1.5.0"
- dependencies:
- "@endo/common": "npm:^1.2.2"
- "@endo/env-options": "npm:^1.1.4"
- "@endo/errors": "npm:^1.2.2"
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/far": "npm:^1.1.2"
- "@endo/pass-style": "npm:^1.4.0"
- "@endo/patterns": "npm:^1.4.0"
- checksum: 10c0/75cebb6771b5e8822fa1b3bf9e8875ed41a60b8d5c6545bee781c115909b71c4e24508c2f3e6465be365470b4c29ea256c4e94482a7dd4ebeaa5c83f0ede0f3a
- languageName: node
- linkType: hard
-
-"@endo/far@npm:^1.0.0, @endo/far@npm:^1.0.4, @endo/far@npm:^1.1.2":
- version: 1.1.2
- resolution: "@endo/far@npm:1.1.2"
- dependencies:
- "@endo/errors": "npm:^1.2.2"
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/pass-style": "npm:^1.4.0"
- checksum: 10c0/11a0fa1a1b8d20e9c467f276710756ca81dd88810cd300d5646f462ca4c097616371017c9f59ce9f05ef8dc2a27e7d28185c23b40da69b6bdf77818e2eb457ea
- languageName: node
- linkType: hard
-
-"@endo/import-bundle@npm:^1.0.4":
- version: 1.1.2
- resolution: "@endo/import-bundle@npm:1.1.2"
- dependencies:
- "@endo/base64": "npm:^1.0.5"
- "@endo/compartment-mapper": "npm:^1.1.5"
- "@endo/errors": "npm:^1.2.2"
- "@endo/where": "npm:^1.0.5"
- ses: "npm:^1.5.0"
- checksum: 10c0/751aae63b03232061531bcd6a93c82a936f9aa200494e650f197145c9ed47fa1f01803f2b9b7d2e54388d3de79217ac87f8c0dcb9c84cc26d9999a9f1516e0d7
- languageName: node
- linkType: hard
-
-"@endo/init@npm:^1.0.3, @endo/init@npm:^1.0.4, @endo/init@npm:^1.1.2":
- version: 1.1.2
- resolution: "@endo/init@npm:1.1.2"
- dependencies:
- "@endo/base64": "npm:^1.0.5"
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/lockdown": "npm:^1.0.7"
- "@endo/promise-kit": "npm:^1.1.2"
- checksum: 10c0/804c3dfce9880e2424e7a3cee84b82c447b03ce8eb6f6050087c0423420bb7b4f37d1a8655004453f351b80d182054e0329edc0451f213380042f8ce8aa6e83d
- languageName: node
- linkType: hard
-
-"@endo/lockdown@npm:^1.0.4, @endo/lockdown@npm:^1.0.7":
- version: 1.0.7
- resolution: "@endo/lockdown@npm:1.0.7"
- dependencies:
- ses: "npm:^1.5.0"
- checksum: 10c0/a9d8ed2c3feff80741abac0c27f8a2ab9e0d46456b5b3c1d3edcaf81b498c5449b43aaf8ee01b1517452b8be548a1156c172d105469e847b01398df42a428a1b
- languageName: node
- linkType: hard
-
-"@endo/marshal@npm:^1.3.0, @endo/marshal@npm:^1.5.0":
- version: 1.5.0
- resolution: "@endo/marshal@npm:1.5.0"
- dependencies:
- "@endo/common": "npm:^1.2.2"
- "@endo/errors": "npm:^1.2.2"
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/nat": "npm:^5.0.7"
- "@endo/pass-style": "npm:^1.4.0"
- "@endo/promise-kit": "npm:^1.1.2"
- checksum: 10c0/1de746affa338e40da61d4a3fecb138724f58bf54a05060efc0996798c4fb2ca508923ac8815c8611741ec6207169517cfb4580dfd24d18e4d144ed412678047
- languageName: node
- linkType: hard
-
-"@endo/nat@npm:^5.0.4, @endo/nat@npm:^5.0.7":
- version: 5.0.7
- resolution: "@endo/nat@npm:5.0.7"
- checksum: 10c0/ee7d659a958fa0157767a0aa8a9425c99fe358754d3d1c93f6be169d5d92409427a88d5593da923614b087ad9faf717065ad58c3b4793dfb4049ce59b5bce63a
- languageName: node
- linkType: hard
-
-"@endo/netstring@npm:^1.0.4":
- version: 1.0.7
- resolution: "@endo/netstring@npm:1.0.7"
- dependencies:
- "@endo/init": "npm:^1.1.2"
- "@endo/promise-kit": "npm:^1.1.2"
- "@endo/stream": "npm:^1.2.2"
- ses: "npm:^1.5.0"
- checksum: 10c0/dd26f84d748bde731a186a433bdc5c2e8f51ca3793b108e0405e4b524709a69d9869a8466b6d703915b6a041156e237cf0f5c8430d5c29de6ca80b8aeb6bfb09
- languageName: node
- linkType: hard
-
-"@endo/pass-style@npm:^1.2.0, @endo/pass-style@npm:^1.4.0":
- version: 1.4.0
- resolution: "@endo/pass-style@npm:1.4.0"
- dependencies:
- "@endo/env-options": "npm:^1.1.4"
- "@endo/errors": "npm:^1.2.2"
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/promise-kit": "npm:^1.1.2"
- "@fast-check/ava": "npm:^1.1.5"
- checksum: 10c0/28ef4b4293dbae98b17ba8165dddf80edec4a1b7f94664b09adfb5fcd5927f2a4aa0679081b94876c997d4df559a192ef4ec5e8a9444fe671966488f6e098b50
- languageName: node
- linkType: hard
-
-"@endo/patterns@npm:^1.1.0, @endo/patterns@npm:^1.2.0, @endo/patterns@npm:^1.4.0":
- version: 1.4.0
- resolution: "@endo/patterns@npm:1.4.0"
- dependencies:
- "@endo/common": "npm:^1.2.2"
- "@endo/errors": "npm:^1.2.2"
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/marshal": "npm:^1.5.0"
- "@endo/promise-kit": "npm:^1.1.2"
- checksum: 10c0/c53cc422f3b09bac8b80a7fc406ffd70100ce3e455dd562ebbb0740b4b39cbe3e042d18d43dd48ebdcb4340b77a9ee90c13bc5179634e9ae091a6558fc2a06fc
- languageName: node
- linkType: hard
-
-"@endo/promise-kit@npm:^1.0.4, @endo/promise-kit@npm:^1.1.2":
- version: 1.1.2
- resolution: "@endo/promise-kit@npm:1.1.2"
- dependencies:
- ses: "npm:^1.5.0"
- checksum: 10c0/12bf81d5b3efd77f75c95d4d287a9b46f9f69adc9cb25586d5a25e1d01a5392fe2e268adf5e3f61ef77187f134ffeab9182deb1b9f35598fb14c9a89b38e3a88
- languageName: node
- linkType: hard
-
-"@endo/ses-ava@npm:^1.1.2":
- version: 1.2.2
- resolution: "@endo/ses-ava@npm:1.2.2"
- dependencies:
- "@endo/env-options": "npm:^1.1.4"
- "@endo/init": "npm:^1.1.2"
- ses: "npm:^1.5.0"
- peerDependencies:
- ava: ^5.3.0 || ^6.1.2
- checksum: 10c0/62b3747df53d34b986b75d6fd1c25f566448a4e62730afbaa9c4c8e27a7703c267cc6fb233a5e8deb45a68abfa2add048a4b5d4f55fd9790d7b7f0520ab384c4
- languageName: node
- linkType: hard
-
-"@endo/static-module-record@npm:^1.1.2":
- version: 1.1.2
- resolution: "@endo/static-module-record@npm:1.1.2"
- dependencies:
- "@agoric/babel-generator": "npm:^7.17.6"
- "@babel/parser": "npm:^7.23.6"
- "@babel/traverse": "npm:^7.23.6"
- "@babel/types": "npm:^7.24.0"
- ses: "npm:^1.5.0"
- checksum: 10c0/62809d0bf92721329e0838c0e8278d9ecd376dce36d7fd4b446443e2bad11d15ee7ae1aa79e68acf1498954874014cd71ac26f547cbd9b8aeb904c3cfe4e4e84
- languageName: node
- linkType: hard
-
-"@endo/stream-node@npm:^1.0.4":
- version: 1.1.2
- resolution: "@endo/stream-node@npm:1.1.2"
- dependencies:
- "@endo/errors": "npm:^1.2.2"
- "@endo/init": "npm:^1.1.2"
- "@endo/stream": "npm:^1.2.2"
- ses: "npm:^1.5.0"
- checksum: 10c0/0c6d3bc991c4cc66c612291663321fd2d2967a8ad894056f9708a3961e5ba1939e818815d6da3970a885b3a2acebd10792c8d2604d879c4529a38cfc02ca1cb0
- languageName: node
- linkType: hard
-
-"@endo/stream@npm:^1.1.0, @endo/stream@npm:^1.2.2":
- version: 1.2.2
- resolution: "@endo/stream@npm:1.2.2"
- dependencies:
- "@endo/eventual-send": "npm:^1.2.2"
- "@endo/promise-kit": "npm:^1.1.2"
- ses: "npm:^1.5.0"
- checksum: 10c0/3cc98b2c25aabd79a8005e958b981e5f652fdc8969589f0b67449678abfcdd780b57f0ce96710f6016058b740402c4fc23ddf6e0be7ca683226dcf978094d875
- languageName: node
- linkType: hard
-
-"@endo/where@npm:^1.0.5":
- version: 1.0.5
- resolution: "@endo/where@npm:1.0.5"
- checksum: 10c0/bff49d4a5c68df24abbe60642afed049a224150803da171b3af51b9e372e9bc4ea741a175221ae1bc574f5e68f4b1782c53028a83f397061f0ab4d442bf5a518
- languageName: node
- linkType: hard
-
-"@endo/zip@npm:^1.0.1":
- version: 1.0.1
- resolution: "@endo/zip@npm:1.0.1"
- checksum: 10c0/1074bdc10287f4c94b3423e130da88f9c6ba09c999483c1164b3eed061350a060d2dbe377cfa3b8d4a86b3f1c3aed5cbf0cdd78ee2bf2cb9b837caa2ebbf712f
- languageName: node
- linkType: hard
-
-"@endo/zip@npm:^1.0.2, @endo/zip@npm:^1.0.5":
- version: 1.0.5
- resolution: "@endo/zip@npm:1.0.5"
- checksum: 10c0/6d03178b66f36b1d39894a84760155219d68ffee975af6381869fc313dc1647464ec40da7a4b50c465a5485ff9f03066ffa0e74f254faa99b46a9fea8852d962
- languageName: node
- linkType: hard
-
-"@fast-check/ava@npm:^1.1.5":
- version: 1.2.1
- resolution: "@fast-check/ava@npm:1.2.1"
- dependencies:
- fast-check: "npm:^3.0.0"
- peerDependencies:
- ava: ^4 || ^5 || ^6
- checksum: 10c0/3800098fd7e8098102544a2f7a595351d063a7ebaeca18ed4901df5ec2679da2330ba8c0db2c820721d4cbb3e23d817ba22fec6d058957930e229f44fa71a684
- languageName: node
- linkType: hard
-
-"@iarna/toml@npm:^2.2.3":
- version: 2.2.5
- resolution: "@iarna/toml@npm:2.2.5"
- checksum: 10c0/d095381ad4554aca233b7cf5a91f243ef619e5e15efd3157bc640feac320545450d14b394aebbf6f02a2047437ced778ae598d5879a995441ab7b6c0b2c2f201
- languageName: node
- linkType: hard
-
-"@isaacs/cliui@npm:^8.0.2":
- version: 8.0.2
- resolution: "@isaacs/cliui@npm:8.0.2"
- dependencies:
- string-width: "npm:^5.1.2"
- string-width-cjs: "npm:string-width@^4.2.0"
- strip-ansi: "npm:^7.0.1"
- strip-ansi-cjs: "npm:strip-ansi@^6.0.1"
- wrap-ansi: "npm:^8.1.0"
- wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0"
- checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e
- languageName: node
- linkType: hard
-
-"@jridgewell/gen-mapping@npm:^0.3.5":
- version: 0.3.5
- resolution: "@jridgewell/gen-mapping@npm:0.3.5"
- dependencies:
- "@jridgewell/set-array": "npm:^1.2.1"
- "@jridgewell/sourcemap-codec": "npm:^1.4.10"
- "@jridgewell/trace-mapping": "npm:^0.3.24"
- checksum: 10c0/1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb
- languageName: node
- linkType: hard
-
-"@jridgewell/resolve-uri@npm:^3.1.0":
- version: 3.1.2
- resolution: "@jridgewell/resolve-uri@npm:3.1.2"
- checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e
- languageName: node
- linkType: hard
-
-"@jridgewell/set-array@npm:^1.2.1":
- version: 1.2.1
- resolution: "@jridgewell/set-array@npm:1.2.1"
- checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4
- languageName: node
- linkType: hard
-
-"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14":
- version: 1.4.15
- resolution: "@jridgewell/sourcemap-codec@npm:1.4.15"
- checksum: 10c0/0c6b5ae663087558039052a626d2d7ed5208da36cfd707dcc5cea4a07cfc918248403dcb5989a8f7afaf245ce0573b7cc6fd94c4a30453bd10e44d9363940ba5
- languageName: node
- linkType: hard
-
-"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
- version: 0.3.25
- resolution: "@jridgewell/trace-mapping@npm:0.3.25"
- dependencies:
- "@jridgewell/resolve-uri": "npm:^3.1.0"
- "@jridgewell/sourcemap-codec": "npm:^1.4.14"
- checksum: 10c0/3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4
- languageName: node
- linkType: hard
-
-"@noble/hashes@npm:^1, @noble/hashes@npm:^1.0.0":
- version: 1.4.0
- resolution: "@noble/hashes@npm:1.4.0"
- checksum: 10c0/8c3f005ee72e7b8f9cff756dfae1241485187254e3f743873e22073d63906863df5d4f13d441b7530ea614b7a093f0d889309f28b59850f33b66cb26a779a4a5
- languageName: node
- linkType: hard
-
-"@nodelib/fs.scandir@npm:2.1.5":
- version: 2.1.5
- resolution: "@nodelib/fs.scandir@npm:2.1.5"
- dependencies:
- "@nodelib/fs.stat": "npm:2.0.5"
- run-parallel: "npm:^1.1.9"
- checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb
- languageName: node
- linkType: hard
-
-"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2":
- version: 2.0.5
- resolution: "@nodelib/fs.stat@npm:2.0.5"
- checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d
- languageName: node
- linkType: hard
-
-"@nodelib/fs.walk@npm:^1.2.3":
- version: 1.2.8
- resolution: "@nodelib/fs.walk@npm:1.2.8"
- dependencies:
- "@nodelib/fs.scandir": "npm:2.1.5"
- fastq: "npm:^1.6.0"
- checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1
- languageName: node
- linkType: hard
-
-"@npmcli/agent@npm:^2.0.0":
- version: 2.2.0
- resolution: "@npmcli/agent@npm:2.2.0"
- dependencies:
- agent-base: "npm:^7.1.0"
- http-proxy-agent: "npm:^7.0.0"
- https-proxy-agent: "npm:^7.0.1"
- lru-cache: "npm:^10.0.1"
- socks-proxy-agent: "npm:^8.0.1"
- checksum: 10c0/7b89590598476dda88e79c473766b67c682aae6e0ab0213491daa6083dcc0c171f86b3868f5506f22c09aa5ea69ad7dfb78f4bf39a8dca375d89a42f408645b3
- languageName: node
- linkType: hard
-
-"@npmcli/fs@npm:^3.1.0":
- version: 3.1.0
- resolution: "@npmcli/fs@npm:3.1.0"
- dependencies:
- semver: "npm:^7.3.5"
- checksum: 10c0/162b4a0b8705cd6f5c2470b851d1dc6cd228c86d2170e1769d738c1fbb69a87160901411c3c035331e9e99db72f1f1099a8b734bf1637cc32b9a5be1660e4e1e
- languageName: node
- linkType: hard
-
-"@pkgjs/parseargs@npm:^0.11.0":
- version: 0.11.0
- resolution: "@pkgjs/parseargs@npm:0.11.0"
- checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd
- languageName: node
- linkType: hard
-
-"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2":
- version: 1.1.2
- resolution: "@protobufjs/aspromise@npm:1.1.2"
- checksum: 10c0/a83343a468ff5b5ec6bff36fd788a64c839e48a07ff9f4f813564f58caf44d011cd6504ed2147bf34835bd7a7dd2107052af755961c6b098fd8902b4f6500d0f
- languageName: node
- linkType: hard
-
-"@protobufjs/base64@npm:^1.1.2":
- version: 1.1.2
- resolution: "@protobufjs/base64@npm:1.1.2"
- checksum: 10c0/eec925e681081af190b8ee231f9bad3101e189abbc182ff279da6b531e7dbd2a56f1f306f37a80b1be9e00aa2d271690d08dcc5f326f71c9eed8546675c8caf6
- languageName: node
- linkType: hard
-
-"@protobufjs/codegen@npm:^2.0.4":
- version: 2.0.4
- resolution: "@protobufjs/codegen@npm:2.0.4"
- checksum: 10c0/26ae337c5659e41f091606d16465bbcc1df1f37cc1ed462438b1f67be0c1e28dfb2ca9f294f39100c52161aef82edf758c95d6d75650a1ddf31f7ddee1440b43
- languageName: node
- linkType: hard
-
-"@protobufjs/eventemitter@npm:^1.1.0":
- version: 1.1.0
- resolution: "@protobufjs/eventemitter@npm:1.1.0"
- checksum: 10c0/1eb0a75180e5206d1033e4138212a8c7089a3d418c6dfa5a6ce42e593a4ae2e5892c4ef7421f38092badba4040ea6a45f0928869989411001d8c1018ea9a6e70
- languageName: node
- linkType: hard
-
-"@protobufjs/fetch@npm:^1.1.0":
- version: 1.1.0
- resolution: "@protobufjs/fetch@npm:1.1.0"
- dependencies:
- "@protobufjs/aspromise": "npm:^1.1.1"
- "@protobufjs/inquire": "npm:^1.1.0"
- checksum: 10c0/cda6a3dc2d50a182c5865b160f72077aac197046600091dbb005dd0a66db9cce3c5eaed6d470ac8ed49d7bcbeef6ee5f0bc288db5ff9a70cbd003e5909065233
- languageName: node
- linkType: hard
-
-"@protobufjs/float@npm:^1.0.2":
- version: 1.0.2
- resolution: "@protobufjs/float@npm:1.0.2"
- checksum: 10c0/18f2bdede76ffcf0170708af15c9c9db6259b771e6b84c51b06df34a9c339dbbeec267d14ce0bddd20acc142b1d980d983d31434398df7f98eb0c94a0eb79069
- languageName: node
- linkType: hard
-
-"@protobufjs/inquire@npm:^1.1.0":
- version: 1.1.0
- resolution: "@protobufjs/inquire@npm:1.1.0"
- checksum: 10c0/64372482efcba1fb4d166a2664a6395fa978b557803857c9c03500e0ac1013eb4b1aacc9ed851dd5fc22f81583670b4f4431bae186f3373fedcfde863ef5921a
- languageName: node
- linkType: hard
-
-"@protobufjs/path@npm:^1.1.2":
- version: 1.1.2
- resolution: "@protobufjs/path@npm:1.1.2"
- checksum: 10c0/cece0a938e7f5dfd2fa03f8c14f2f1cf8b0d6e13ac7326ff4c96ea311effd5fb7ae0bba754fbf505312af2e38500250c90e68506b97c02360a43793d88a0d8b4
- languageName: node
- linkType: hard
-
-"@protobufjs/pool@npm:^1.1.0":
- version: 1.1.0
- resolution: "@protobufjs/pool@npm:1.1.0"
- checksum: 10c0/eda2718b7f222ac6e6ad36f758a92ef90d26526026a19f4f17f668f45e0306a5bd734def3f48f51f8134ae0978b6262a5c517c08b115a551756d1a3aadfcf038
- languageName: node
- linkType: hard
-
-"@protobufjs/utf8@npm:^1.1.0":
- version: 1.1.0
- resolution: "@protobufjs/utf8@npm:1.1.0"
- checksum: 10c0/a3fe31fe3fa29aa3349e2e04ee13dc170cc6af7c23d92ad49e3eeaf79b9766264544d3da824dba93b7855bd6a2982fb40032ef40693da98a136d835752beb487
- languageName: node
- linkType: hard
-
-"@rollup/plugin-commonjs@npm:^19.0.0":
- version: 19.0.2
- resolution: "@rollup/plugin-commonjs@npm:19.0.2"
- dependencies:
- "@rollup/pluginutils": "npm:^3.1.0"
- commondir: "npm:^1.0.1"
- estree-walker: "npm:^2.0.1"
- glob: "npm:^7.1.6"
- is-reference: "npm:^1.2.1"
- magic-string: "npm:^0.25.7"
- resolve: "npm:^1.17.0"
- peerDependencies:
- rollup: ^2.38.3
- checksum: 10c0/9adccf77ad835cbe565da4385212f1e54c3e0dca2be174b5c2cfe89cfaeb240f42c7673e97e49b21b7c66ed901cc1c711552b6727f60b43a953ce996eb2868a7
- languageName: node
- linkType: hard
-
-"@rollup/plugin-node-resolve@npm:^13.0.0":
- version: 13.3.0
- resolution: "@rollup/plugin-node-resolve@npm:13.3.0"
- dependencies:
- "@rollup/pluginutils": "npm:^3.1.0"
- "@types/resolve": "npm:1.17.1"
- deepmerge: "npm:^4.2.2"
- is-builtin-module: "npm:^3.1.0"
- is-module: "npm:^1.0.0"
- resolve: "npm:^1.19.0"
- peerDependencies:
- rollup: ^2.42.0
- checksum: 10c0/6caa32a8304a20f1c9953111b25e9543f4de7d254958d81ce0158ad909e4493946bc2060c4ace23d9748b560ebc84c920ee7bc1b7d50dbf8ba852ef13c91af58
- languageName: node
- linkType: hard
-
-"@rollup/pluginutils@npm:^3.1.0":
- version: 3.1.0
- resolution: "@rollup/pluginutils@npm:3.1.0"
- dependencies:
- "@types/estree": "npm:0.0.39"
- estree-walker: "npm:^1.0.1"
- picomatch: "npm:^2.2.2"
- peerDependencies:
- rollup: ^1.20.0||^2.0.0
- checksum: 10c0/7151753160d15ba2b259461a6c25b3932150994ea52dba8fd3144f634c7647c2e56733d986e2c15de67c4d96a9ee7d6278efa6d2e626a7169898fd64adc0f90c
- languageName: node
- linkType: hard
-
-"@types/estree@npm:*":
- version: 1.0.5
- resolution: "@types/estree@npm:1.0.5"
- checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d
- languageName: node
- linkType: hard
-
-"@types/estree@npm:0.0.39":
- version: 0.0.39
- resolution: "@types/estree@npm:0.0.39"
- checksum: 10c0/f0af6c95ac1988c4827964bd9d3b51d24da442e2188943f6dfcb1e1559103d5d024d564b2e9d3f84c53714a02a0a7435c7441138eb63d9af5de4dfc66cdc0d92
- languageName: node
- linkType: hard
-
-"@types/long@npm:^4.0.1":
- version: 4.0.2
- resolution: "@types/long@npm:4.0.2"
- checksum: 10c0/42ec66ade1f72ff9d143c5a519a65efc7c1c77be7b1ac5455c530ae9acd87baba065542f8847522af2e3ace2cc999f3ad464ef86e6b7352eece34daf88f8c924
- languageName: node
- linkType: hard
-
-"@types/node@npm:*, @types/node@npm:>=13.7.0":
- version: 20.14.9
- resolution: "@types/node@npm:20.14.9"
- dependencies:
- undici-types: "npm:~5.26.4"
- checksum: 10c0/911ffa444dc032897f4a23ed580c67903bd38ea1c5ec99b1d00fa10b83537a3adddef8e1f29710cbdd8e556a61407ed008e06537d834e48caf449ce59f87d387
- languageName: node
- linkType: hard
-
-"@types/resolve@npm:1.17.1":
- version: 1.17.1
- resolution: "@types/resolve@npm:1.17.1"
- dependencies:
- "@types/node": "npm:*"
- checksum: 10c0/6eeb9c27d99bf4b393bf168d43208f63e78cefca5644662a0bdb2bdbf8352386f4f3aca66add138fc41bce5f66fd48a0de430a1473f11b612fbed0375ae78031
- languageName: node
- linkType: hard
-
-"@types/triple-beam@npm:^1.3.2":
- version: 1.3.5
- resolution: "@types/triple-beam@npm:1.3.5"
- checksum: 10c0/d5d7f25da612f6d79266f4f1bb9c1ef8f1684e9f60abab251e1261170631062b656ba26ff22631f2760caeafd372abc41e64867cde27fba54fafb73a35b9056a
- languageName: node
- linkType: hard
-
-"abbrev@npm:^2.0.0":
- version: 2.0.0
- resolution: "abbrev@npm:2.0.0"
- checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372
- languageName: node
- linkType: hard
-
-"acorn-walk@npm:^8.2.0":
- version: 8.3.2
- resolution: "acorn-walk@npm:8.3.2"
- checksum: 10c0/7e2a8dad5480df7f872569b9dccff2f3da7e65f5353686b1d6032ab9f4ddf6e3a2cb83a9b52cf50b1497fd522154dda92f0abf7153290cc79cd14721ff121e52
- languageName: node
- linkType: hard
-
-"acorn@npm:^8.2.4":
- version: 8.12.0
- resolution: "acorn@npm:8.12.0"
- bin:
- acorn: bin/acorn
- checksum: 10c0/a19f9dead009d3b430fa3c253710b47778cdaace15b316de6de93a68c355507bc1072a9956372b6c990cbeeb167d4a929249d0faeb8ae4bb6911d68d53299549
- languageName: node
- linkType: hard
-
-"acorn@npm:^8.8.2":
- version: 8.11.3
- resolution: "acorn@npm:8.11.3"
- bin:
- acorn: bin/acorn
- checksum: 10c0/3ff155f8812e4a746fee8ecff1f227d527c4c45655bb1fad6347c3cb58e46190598217551b1500f18542d2bbe5c87120cb6927f5a074a59166fbdd9468f0a299
- languageName: node
- linkType: hard
-
-"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0":
- version: 7.1.0
- resolution: "agent-base@npm:7.1.0"
- dependencies:
- debug: "npm:^4.3.4"
- checksum: 10c0/fc974ab57ffdd8421a2bc339644d312a9cca320c20c3393c9d8b1fd91731b9bbabdb985df5fc860f5b79d81c3e350daa3fcb31c5c07c0bb385aafc817df004ce
- languageName: node
- linkType: hard
-
-"aggregate-error@npm:^3.0.0":
- version: 3.1.0
- resolution: "aggregate-error@npm:3.1.0"
- dependencies:
- clean-stack: "npm:^2.0.0"
- indent-string: "npm:^4.0.0"
- checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039
- languageName: node
- linkType: hard
-
-"aggregate-error@npm:^4.0.0":
- version: 4.0.1
- resolution: "aggregate-error@npm:4.0.1"
- dependencies:
- clean-stack: "npm:^4.0.0"
- indent-string: "npm:^5.0.0"
- checksum: 10c0/75fd739f5c4c60a667cce35ccaf0edf135e147ef0be9a029cab75de14ac9421779b15339d562e58d25b233ea0ef2bbd4c916f149fdbcb73c2b9a62209e611343
- languageName: node
- linkType: hard
-
-"agoric@npm:0.21.2-dev-5676146.0":
- version: 0.21.2-dev-5676146.0
- resolution: "agoric@npm:0.21.2-dev-5676146.0"
- dependencies:
- "@agoric/access-token": "npm:0.4.22-dev-5676146.0+5676146"
- "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
- "@agoric/cache": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/casting": "npm:0.4.3-dev-5676146.0+5676146"
- "@agoric/cosmic-proto": "npm:0.4.1-dev-5676146.0+5676146"
- "@agoric/ertp": "npm:0.16.3-dev-5676146.0+5676146"
- "@agoric/governance": "npm:0.10.4-dev-5676146.0+5676146"
- "@agoric/inter-protocol": "npm:0.16.2-dev-5676146.0+5676146"
- "@agoric/internal": "npm:0.3.3-dev-5676146.0+5676146"
- "@agoric/network": "npm:0.1.1-dev-5676146.0+5676146"
- "@agoric/smart-wallet": "npm:0.5.4-dev-5676146.0+5676146"
- "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
- "@agoric/swingset-vat": "npm:0.32.3-dev-5676146.0+5676146"
- "@agoric/vats": "npm:0.15.2-dev-5676146.0+5676146"
- "@agoric/zoe": "npm:0.26.3-dev-5676146.0+5676146"
- "@agoric/zone": "npm:0.2.3-dev-5676146.0+5676146"
- "@confio/relayer": "npm:^0.11.3"
- "@cosmjs/crypto": "npm:^0.32.3"
- "@cosmjs/encoding": "npm:^0.32.3"
- "@cosmjs/math": "npm:^0.32.3"
- "@cosmjs/proto-signing": "npm:^0.32.3"
- "@cosmjs/stargate": "npm:^0.32.3"
- "@endo/bundle-source": "npm:^3.1.0"
- "@endo/captp": "npm:^4.0.4"
- "@endo/compartment-mapper": "npm:^1.1.2"
- "@endo/env-options": "npm:^1.1.1"
- "@endo/far": "npm:^1.0.4"
- "@endo/init": "npm:^1.0.4"
- "@endo/marshal": "npm:^1.3.0"
- "@endo/nat": "npm:^5.0.4"
- "@endo/patterns": "npm:^1.2.0"
- "@endo/promise-kit": "npm:^1.0.4"
- "@iarna/toml": "npm:^2.2.3"
- anylogger: "npm:^0.21.0"
- chalk: "npm:^5.2.0"
- commander: "npm:^11.1.0"
- deterministic-json: "npm:^1.0.5"
- esm: "github:agoric-labs/esm#Agoric-built"
- inquirer: "npm:^8.2.2"
- opener: "npm:^1.5.2"
- tmp: "npm:^0.2.1"
- ws: "npm:^7.2.0"
- bin:
- agops: src/bin-agops.js
- agoric: src/entrypoint.js
- checksum: 10c0/abcea0bfd4594c2841d3e69ed6c78bedd5a4c573efa9ebcb34730e87ea445ab283e06a7dff2a0f44834faae3bb4dfc0153a2bd34cfd859064208cd7bfb92a19b
- languageName: node
- linkType: hard
-
-"ajv@npm:7.1.1":
- version: 7.1.1
- resolution: "ajv@npm:7.1.1"
- dependencies:
- fast-deep-equal: "npm:^3.1.1"
- json-schema-traverse: "npm:^1.0.0"
- require-from-string: "npm:^2.0.2"
- uri-js: "npm:^4.2.2"
- checksum: 10c0/328a86011a67dc10eff41e3e2ef412f88f5de546ad2288c8a3d2a563c203dd4dd479660c07f99fd9499e36c723afee212704b25f5599815991409528fd638329
- languageName: node
- linkType: hard
-
-"ajv@npm:^8.0.1":
- version: 8.16.0
- resolution: "ajv@npm:8.16.0"
- dependencies:
- fast-deep-equal: "npm:^3.1.3"
- json-schema-traverse: "npm:^1.0.0"
- require-from-string: "npm:^2.0.2"
- uri-js: "npm:^4.4.1"
- checksum: 10c0/6fc38aa8fd4fbfaa7096ac049e48c0cb440db36b76fef2d7d5b7d92b102735670d055d412d19176c08c9d48eaa9d06661b67e59f04943dc71ab1551e0484f88c
- languageName: node
- linkType: hard
-
-"ansi-escapes@npm:^4.2.1":
- version: 4.3.2
- resolution: "ansi-escapes@npm:4.3.2"
- dependencies:
- type-fest: "npm:^0.21.3"
- checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50
- languageName: node
- linkType: hard
-
-"ansi-regex@npm:^5.0.1":
- version: 5.0.1
- resolution: "ansi-regex@npm:5.0.1"
- checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737
- languageName: node
- linkType: hard
-
-"ansi-regex@npm:^6.0.1":
- version: 6.0.1
- resolution: "ansi-regex@npm:6.0.1"
- checksum: 10c0/cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08
- languageName: node
- linkType: hard
-
-"ansi-styles@npm:^3.2.1":
- version: 3.2.1
- resolution: "ansi-styles@npm:3.2.1"
- dependencies:
- color-convert: "npm:^1.9.0"
- checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b
- languageName: node
- linkType: hard
-
-"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0":
- version: 4.3.0
- resolution: "ansi-styles@npm:4.3.0"
- dependencies:
- color-convert: "npm:^2.0.1"
- checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041
- languageName: node
- linkType: hard
-
-"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1":
- version: 6.2.1
- resolution: "ansi-styles@npm:6.2.1"
- checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c
- languageName: node
- linkType: hard
-
-"anylogger@npm:^0.21.0":
- version: 0.21.0
- resolution: "anylogger@npm:0.21.0"
- checksum: 10c0/1ca7fcf5bc2b78d1e1d9b8c8cc7ce50b5c6cc67a8da5a28c9c975b7b46fff255a04abab02de38a5139190c9d8b34b3d6c59af6724521b077f7d7dfbad9b47a9c
- languageName: node
- linkType: hard
-
-"anymatch@npm:~3.1.2":
- version: 3.1.3
- resolution: "anymatch@npm:3.1.3"
- dependencies:
- normalize-path: "npm:^3.0.0"
- picomatch: "npm:^2.0.4"
- checksum: 10c0/57b06ae984bc32a0d22592c87384cd88fe4511b1dd7581497831c56d41939c8a001b28e7b853e1450f2bf61992dfcaa8ae2d0d161a0a90c4fb631ef07098fbac
- languageName: node
- linkType: hard
-
-"argparse@npm:^1.0.7":
- version: 1.0.10
- resolution: "argparse@npm:1.0.10"
- dependencies:
- sprintf-js: "npm:~1.0.2"
- checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de
- languageName: node
- linkType: hard
-
-"argparse@npm:^2.0.1":
- version: 2.0.1
- resolution: "argparse@npm:2.0.1"
- checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e
- languageName: node
- linkType: hard
-
-"array-find-index@npm:^1.0.1":
- version: 1.0.2
- resolution: "array-find-index@npm:1.0.2"
- checksum: 10c0/86b9485c74ddd324feab807e10a6de3f9c1683856267236fac4bb4d4667ada6463e106db3f6c540ae6b720e0442b590ec701d13676df4c6af30ebf4da09b4f57
- languageName: node
- linkType: hard
-
-"arrgv@npm:^1.0.2":
- version: 1.0.2
- resolution: "arrgv@npm:1.0.2"
- checksum: 10c0/7e6e782e6b749923ac7cbc4048ef6fe0844c4a59bfc8932fcd4c44566ba25eed46501f94dd7cf3c7297da88f3f599ca056bfb77d0c2484aebc92f04239f69124
- languageName: node
- linkType: hard
-
-"arrify@npm:^3.0.0":
- version: 3.0.0
- resolution: "arrify@npm:3.0.0"
- checksum: 10c0/2e26601b8486f29780f1f70f7ac05a226755814c2a3ab42e196748f650af1dc310cd575a11dd4b9841c70fd7460b2dd2b8fe6fb7a3375878e2660706efafa58e
- languageName: node
- linkType: hard
-
-"astral-regex@npm:^2.0.0":
- version: 2.0.0
- resolution: "astral-regex@npm:2.0.0"
- checksum: 10c0/f63d439cc383db1b9c5c6080d1e240bd14dae745f15d11ec5da863e182bbeca70df6c8191cffef5deba0b566ef98834610a68be79ac6379c95eeb26e1b310e25
- languageName: node
- linkType: hard
-
-"async@npm:^3.1.0":
- version: 3.2.5
- resolution: "async@npm:3.2.5"
- checksum: 10c0/1408287b26c6db67d45cb346e34892cee555b8b59e6c68e6f8c3e495cad5ca13b4f218180e871f3c2ca30df4ab52693b66f2f6ff43644760cab0b2198bda79c1
- languageName: node
- linkType: hard
-
-"asynckit@npm:^0.4.0":
- version: 0.4.0
- resolution: "asynckit@npm:0.4.0"
- checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d
- languageName: node
- linkType: hard
-
-"ava@npm:^5.3.1":
- version: 5.3.1
- resolution: "ava@npm:5.3.1"
- dependencies:
- acorn: "npm:^8.8.2"
- acorn-walk: "npm:^8.2.0"
- ansi-styles: "npm:^6.2.1"
- arrgv: "npm:^1.0.2"
- arrify: "npm:^3.0.0"
- callsites: "npm:^4.0.0"
- cbor: "npm:^8.1.0"
- chalk: "npm:^5.2.0"
- chokidar: "npm:^3.5.3"
- chunkd: "npm:^2.0.1"
- ci-info: "npm:^3.8.0"
- ci-parallel-vars: "npm:^1.0.1"
- clean-yaml-object: "npm:^0.1.0"
- cli-truncate: "npm:^3.1.0"
- code-excerpt: "npm:^4.0.0"
- common-path-prefix: "npm:^3.0.0"
- concordance: "npm:^5.0.4"
- currently-unhandled: "npm:^0.4.1"
- debug: "npm:^4.3.4"
- emittery: "npm:^1.0.1"
- figures: "npm:^5.0.0"
- globby: "npm:^13.1.4"
- ignore-by-default: "npm:^2.1.0"
- indent-string: "npm:^5.0.0"
- is-error: "npm:^2.2.2"
- is-plain-object: "npm:^5.0.0"
- is-promise: "npm:^4.0.0"
- matcher: "npm:^5.0.0"
- mem: "npm:^9.0.2"
- ms: "npm:^2.1.3"
- p-event: "npm:^5.0.1"
- p-map: "npm:^5.5.0"
- picomatch: "npm:^2.3.1"
- pkg-conf: "npm:^4.0.0"
- plur: "npm:^5.1.0"
- pretty-ms: "npm:^8.0.0"
- resolve-cwd: "npm:^3.0.0"
- stack-utils: "npm:^2.0.6"
- strip-ansi: "npm:^7.0.1"
- supertap: "npm:^3.0.1"
- temp-dir: "npm:^3.0.0"
- write-file-atomic: "npm:^5.0.1"
- yargs: "npm:^17.7.2"
- peerDependencies:
- "@ava/typescript": "*"
- peerDependenciesMeta:
- "@ava/typescript":
- optional: true
- bin:
- ava: entrypoints/cli.mjs
- checksum: 10c0/262cbdb9e8c3ce7177be91b92ba521e9d5aef577dcc8095cc591f86baaa291b91c88925928f5d26832c4d1b381a6ae99f2e8804077c592d0d32322c1212605cc
- languageName: node
- linkType: hard
-
-"axios@npm:^1.6.0, axios@npm:^1.6.7":
- version: 1.7.2
- resolution: "axios@npm:1.7.2"
- dependencies:
- follow-redirects: "npm:^1.15.6"
- form-data: "npm:^4.0.0"
- proxy-from-env: "npm:^1.1.0"
- checksum: 10c0/cbd47ce380fe045313364e740bb03b936420b8b5558c7ea36a4563db1258c658f05e40feb5ddd41f6633fdd96d37ac2a76f884dad599c5b0224b4c451b3fa7ae
- languageName: node
- linkType: hard
-
-"balanced-match@npm:^1.0.0":
- version: 1.0.2
- resolution: "balanced-match@npm:1.0.2"
- checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee
- languageName: node
- linkType: hard
-
-"base64-js@npm:^1.3.0, base64-js@npm:^1.3.1":
- version: 1.5.1
- resolution: "base64-js@npm:1.5.1"
- checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf
- languageName: node
- linkType: hard
-
-"bech32@npm:^1.1.4":
- version: 1.1.4
- resolution: "bech32@npm:1.1.4"
- checksum: 10c0/5f62ca47b8df99ace9c0e0d8deb36a919d91bf40066700aaa9920a45f86bb10eb56d537d559416fd8703aa0fb60dddb642e58f049701e7291df678b2033e5ee5
- languageName: node
- linkType: hard
-
-"better-sqlite3@npm:^9.1.1":
- version: 9.6.0
- resolution: "better-sqlite3@npm:9.6.0"
- dependencies:
- bindings: "npm:^1.5.0"
- node-gyp: "npm:latest"
- prebuild-install: "npm:^7.1.1"
- checksum: 10c0/8db9b38f414e26a56d4c40fc16e94a253118491dae0e2c054338a9e470f1a883c7eb4cb330f2f5737db30f704d4f2e697c59071ca04e03364ee9fe04375aa9c8
- languageName: node
- linkType: hard
-
-"better-sqlite3@npm:^9.4.0":
- version: 9.4.0
- resolution: "better-sqlite3@npm:9.4.0"
- dependencies:
- bindings: "npm:^1.5.0"
- node-gyp: "npm:latest"
- prebuild-install: "npm:^7.1.1"
- checksum: 10c0/42b2edfa46d62763514b87122245a3513a5ff20f05fef4fb49fec33f3de0a51a29025596178f57c634b8013f16bbdf8169a308fb3e3b8d126d715788d72d1e74
- languageName: node
- linkType: hard
-
-"binary-extensions@npm:^2.0.0":
- version: 2.2.0
- resolution: "binary-extensions@npm:2.2.0"
- checksum: 10c0/d73d8b897238a2d3ffa5f59c0241870043aa7471335e89ea5e1ff48edb7c2d0bb471517a3e4c5c3f4c043615caa2717b5f80a5e61e07503d51dc85cb848e665d
- languageName: node
- linkType: hard
-
-"bindings@npm:^1.5.0":
- version: 1.5.0
- resolution: "bindings@npm:1.5.0"
- dependencies:
- file-uri-to-path: "npm:1.0.0"
- checksum: 10c0/3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba
- languageName: node
- linkType: hard
-
-"bintrees@npm:1.0.2":
- version: 1.0.2
- resolution: "bintrees@npm:1.0.2"
- checksum: 10c0/132944b20c93c1a8f97bf8aa25980a76c6eb4291b7f2df2dbcd01cb5b417c287d3ee0847c7260c9f05f3d5a4233aaa03dec95114e97f308abe9cc3f72bed4a44
- languageName: node
- linkType: hard
-
-"bl@npm:^4.0.3, bl@npm:^4.1.0":
- version: 4.1.0
- resolution: "bl@npm:4.1.0"
- dependencies:
- buffer: "npm:^5.5.0"
- inherits: "npm:^2.0.4"
- readable-stream: "npm:^3.4.0"
- checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f
- languageName: node
- linkType: hard
-
-"blueimp-md5@npm:^2.10.0":
- version: 2.19.0
- resolution: "blueimp-md5@npm:2.19.0"
- checksum: 10c0/85d04343537dd99a288c62450341dcce7380d3454c81f8e5a971ddd80307d6f9ef51b5b92ad7d48aaaa92fd6d3a1f6b2f4fada068faae646887f7bfabc17a346
- languageName: node
- linkType: hard
-
-"bn.js@npm:^4.11.9":
- version: 4.12.0
- resolution: "bn.js@npm:4.12.0"
- checksum: 10c0/9736aaa317421b6b3ed038ff3d4491935a01419ac2d83ddcfebc5717385295fcfcf0c57311d90fe49926d0abbd7a9dbefdd8861e6129939177f7e67ebc645b21
- languageName: node
- linkType: hard
-
-"bn.js@npm:^5.2.0":
- version: 5.2.1
- resolution: "bn.js@npm:5.2.1"
- checksum: 10c0/bed3d8bd34ec89dbcf9f20f88bd7d4a49c160fda3b561c7bb227501f974d3e435a48fb9b61bc3de304acab9215a3bda0803f7017ffb4d0016a0c3a740a283caa
- languageName: node
- linkType: hard
-
-"brace-expansion@npm:^1.1.7":
- version: 1.1.11
- resolution: "brace-expansion@npm:1.1.11"
- dependencies:
- balanced-match: "npm:^1.0.0"
- concat-map: "npm:0.0.1"
- checksum: 10c0/695a56cd058096a7cb71fb09d9d6a7070113c7be516699ed361317aca2ec169f618e28b8af352e02ab4233fb54eb0168460a40dc320bab0034b36ab59aaad668
- languageName: node
- linkType: hard
-
-"brace-expansion@npm:^2.0.1":
- version: 2.0.1
- resolution: "brace-expansion@npm:2.0.1"
- dependencies:
- balanced-match: "npm:^1.0.0"
- checksum: 10c0/b358f2fe060e2d7a87aa015979ecea07f3c37d4018f8d6deb5bd4c229ad3a0384fe6029bb76cd8be63c81e516ee52d1a0673edbe2023d53a5191732ae3c3e49f
- languageName: node
- linkType: hard
-
-"braces@npm:^3.0.2, braces@npm:~3.0.2":
- version: 3.0.2
- resolution: "braces@npm:3.0.2"
- dependencies:
- fill-range: "npm:^7.0.1"
- checksum: 10c0/321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381
- languageName: node
- linkType: hard
-
-"brorand@npm:^1.1.0":
- version: 1.1.0
- resolution: "brorand@npm:1.1.0"
- checksum: 10c0/6f366d7c4990f82c366e3878492ba9a372a73163c09871e80d82fb4ae0d23f9f8924cb8a662330308206e6b3b76ba1d528b4601c9ef73c2166b440b2ea3b7571
- languageName: node
- linkType: hard
-
-"buffer@npm:^5.5.0":
- version: 5.7.1
- resolution: "buffer@npm:5.7.1"
- dependencies:
- base64-js: "npm:^1.3.1"
- ieee754: "npm:^1.1.13"
- checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e
- languageName: node
- linkType: hard
-
-"builtin-modules@npm:^3.3.0":
- version: 3.3.0
- resolution: "builtin-modules@npm:3.3.0"
- checksum: 10c0/2cb3448b4f7306dc853632a4fcddc95e8d4e4b9868c139400027b71938fc6806d4ff44007deffb362ac85724bd40c2c6452fb6a0aa4531650eeddb98d8e5ee8a
- languageName: node
- linkType: hard
-
-"cacache@npm:^18.0.0":
- version: 18.0.2
- resolution: "cacache@npm:18.0.2"
- dependencies:
- "@npmcli/fs": "npm:^3.1.0"
- fs-minipass: "npm:^3.0.0"
- glob: "npm:^10.2.2"
- lru-cache: "npm:^10.0.1"
- minipass: "npm:^7.0.3"
- minipass-collect: "npm:^2.0.1"
- minipass-flush: "npm:^1.0.5"
- minipass-pipeline: "npm:^1.2.4"
- p-map: "npm:^4.0.0"
- ssri: "npm:^10.0.0"
- tar: "npm:^6.1.11"
- unique-filename: "npm:^3.0.0"
- checksum: 10c0/7992665305cc251a984f4fdbab1449d50e88c635bc43bf2785530c61d239c61b349e5734461baa461caaee65f040ab14e2d58e694f479c0810cffd181ba5eabc
- languageName: node
- linkType: hard
-
-"call-bind@npm:^1.0.5":
- version: 1.0.7
- resolution: "call-bind@npm:1.0.7"
- dependencies:
- es-define-property: "npm:^1.0.0"
- es-errors: "npm:^1.3.0"
- function-bind: "npm:^1.1.2"
- get-intrinsic: "npm:^1.2.4"
- set-function-length: "npm:^1.2.1"
- checksum: 10c0/a3ded2e423b8e2a265983dba81c27e125b48eefb2655e7dfab6be597088da3d47c47976c24bc51b8fd9af1061f8f87b4ab78a314f3c77784b2ae2ba535ad8b8d
- languageName: node
- linkType: hard
-
-"callsites@npm:^4.0.0":
- version: 4.1.0
- resolution: "callsites@npm:4.1.0"
- checksum: 10c0/91700844127a6dcd4792d231a12dd8e9ec10525eb9962180a8558417d7e3f443e52a4f14746ad2838eaf14f79431ee1539d13bd188da280f720a06a91bd1157a
- languageName: node
- linkType: hard
-
-"cbor@npm:^8.1.0":
- version: 8.1.0
- resolution: "cbor@npm:8.1.0"
- dependencies:
- nofilter: "npm:^3.1.0"
- checksum: 10c0/a836e2e7ea0efb1b9c4e5a4be906c57113d730cc42293a34072e0164ed110bb8ac035dc7dca2e3ebb641bd4b37e00fdbbf09c951aa864b3d4888a6ed8c6243f7
- languageName: node
- linkType: hard
-
-"chalk@npm:^2.4.2":
- version: 2.4.2
- resolution: "chalk@npm:2.4.2"
- dependencies:
- ansi-styles: "npm:^3.2.1"
- escape-string-regexp: "npm:^1.0.5"
- supports-color: "npm:^5.3.0"
- checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073
- languageName: node
- linkType: hard
-
-"chalk@npm:^4.1.0, chalk@npm:^4.1.1":
- version: 4.1.2
- resolution: "chalk@npm:4.1.2"
- dependencies:
- ansi-styles: "npm:^4.1.0"
- supports-color: "npm:^7.1.0"
- checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880
- languageName: node
- linkType: hard
-
-"chalk@npm:^5.2.0, chalk@npm:^5.3.0":
- version: 5.3.0
- resolution: "chalk@npm:5.3.0"
- checksum: 10c0/8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09
- languageName: node
- linkType: hard
-
-"chardet@npm:^0.7.0":
- version: 0.7.0
- resolution: "chardet@npm:0.7.0"
- checksum: 10c0/96e4731b9ec8050cbb56ab684e8c48d6c33f7826b755802d14e3ebfdc51c57afeece3ea39bc6b09acc359e4363525388b915e16640c1378053820f5e70d0f27d
- languageName: node
- linkType: hard
-
-"chokidar@npm:^3.5.3":
- version: 3.5.3
- resolution: "chokidar@npm:3.5.3"
- dependencies:
- anymatch: "npm:~3.1.2"
- braces: "npm:~3.0.2"
- fsevents: "npm:~2.3.2"
- glob-parent: "npm:~5.1.2"
- is-binary-path: "npm:~2.1.0"
- is-glob: "npm:~4.0.1"
- normalize-path: "npm:~3.0.0"
- readdirp: "npm:~3.6.0"
- dependenciesMeta:
- fsevents:
- optional: true
- checksum: 10c0/1076953093e0707c882a92c66c0f56ba6187831aa51bb4de878c1fec59ae611a3bf02898f190efec8e77a086b8df61c2b2a3ea324642a0558bdf8ee6c5dc9ca1
- languageName: node
- linkType: hard
-
-"chownr@npm:^1.1.1":
- version: 1.1.4
- resolution: "chownr@npm:1.1.4"
- checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db
- languageName: node
- linkType: hard
-
-"chownr@npm:^2.0.0":
- version: 2.0.0
- resolution: "chownr@npm:2.0.0"
- checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6
- languageName: node
- linkType: hard
-
-"chunkd@npm:^2.0.1":
- version: 2.0.1
- resolution: "chunkd@npm:2.0.1"
- checksum: 10c0/4e0c5aac6048ecedfa4cd0a5f6c4f010c70a7b7645aeca7bfeb47cb0733c3463054f0ced3f2667b2e0e67edd75d68a8e05481b01115ba3f8a952a93026254504
- languageName: node
- linkType: hard
-
-"ci-info@npm:^3.8.0":
- version: 3.9.0
- resolution: "ci-info@npm:3.9.0"
- checksum: 10c0/6f0109e36e111684291d46123d491bc4e7b7a1934c3a20dea28cba89f1d4a03acd892f5f6a81ed3855c38647e285a150e3c9ba062e38943bef57fee6c1554c3a
- languageName: node
- linkType: hard
-
-"ci-parallel-vars@npm:^1.0.1":
- version: 1.0.1
- resolution: "ci-parallel-vars@npm:1.0.1"
- checksum: 10c0/80952f699cbbc146092b077b4f3e28d085620eb4e6be37f069b4dbb3db0ee70e8eec3beef4ebe70ff60631e9fc743b9d0869678489f167442cac08b260e5ac08
- languageName: node
- linkType: hard
-
-"clean-stack@npm:^2.0.0":
- version: 2.2.0
- resolution: "clean-stack@npm:2.2.0"
- checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1
- languageName: node
- linkType: hard
-
-"clean-stack@npm:^4.0.0":
- version: 4.2.0
- resolution: "clean-stack@npm:4.2.0"
- dependencies:
- escape-string-regexp: "npm:5.0.0"
- checksum: 10c0/2bdf981a0fef0a23c14255df693b30eb9ae27eedf212470d8c400a0c0b6fb82fbf1ff8c5216ccd5721e3670b700389c886b1dce5070776dc9fbcc040957758c0
- languageName: node
- linkType: hard
-
-"clean-yaml-object@npm:^0.1.0":
- version: 0.1.0
- resolution: "clean-yaml-object@npm:0.1.0"
- checksum: 10c0/a6505310590038afb9f0adc7f17a4c66787719c94d23f8491267ea4d9c405cdd378bd576ae1926169b6d997d4c59a8b86516bf4d16ba228280cf615598c58e05
- languageName: node
- linkType: hard
-
-"cli-cursor@npm:^3.1.0":
- version: 3.1.0
- resolution: "cli-cursor@npm:3.1.0"
- dependencies:
- restore-cursor: "npm:^3.1.0"
- checksum: 10c0/92a2f98ff9037d09be3dfe1f0d749664797fb674bf388375a2207a1203b69d41847abf16434203e0089212479e47a358b13a0222ab9fccfe8e2644a7ccebd111
- languageName: node
- linkType: hard
-
-"cli-spinners@npm:^2.5.0":
- version: 2.9.2
- resolution: "cli-spinners@npm:2.9.2"
- checksum: 10c0/907a1c227ddf0d7a101e7ab8b300affc742ead4b4ebe920a5bf1bc6d45dce2958fcd195eb28fa25275062fe6fa9b109b93b63bc8033396ed3bcb50297008b3a3
- languageName: node
- linkType: hard
-
-"cli-truncate@npm:^3.1.0":
- version: 3.1.0
- resolution: "cli-truncate@npm:3.1.0"
- dependencies:
- slice-ansi: "npm:^5.0.0"
- string-width: "npm:^5.0.0"
- checksum: 10c0/a19088878409ec0e5dc2659a5166929629d93cfba6d68afc9cde2282fd4c751af5b555bf197047e31c87c574396348d011b7aa806fec29c4139ea4f7f00b324c
- languageName: node
- linkType: hard
-
-"cli-width@npm:^3.0.0":
- version: 3.0.0
- resolution: "cli-width@npm:3.0.0"
- checksum: 10c0/125a62810e59a2564268c80fdff56c23159a7690c003e34aeb2e68497dccff26911998ff49c33916fcfdf71e824322cc3953e3f7b48b27267c7a062c81348a9a
- languageName: node
- linkType: hard
-
-"cliui@npm:^8.0.1":
- version: 8.0.1
- resolution: "cliui@npm:8.0.1"
- dependencies:
- string-width: "npm:^4.2.0"
- strip-ansi: "npm:^6.0.1"
- wrap-ansi: "npm:^7.0.0"
- checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5
- languageName: node
- linkType: hard
-
-"clone@npm:^1.0.2":
- version: 1.0.4
- resolution: "clone@npm:1.0.4"
- checksum: 10c0/2176952b3649293473999a95d7bebfc9dc96410f6cbd3d2595cf12fd401f63a4bf41a7adbfd3ab2ff09ed60cb9870c58c6acdd18b87767366fabfc163700f13b
- languageName: node
- linkType: hard
-
-"code-excerpt@npm:^4.0.0":
- version: 4.0.0
- resolution: "code-excerpt@npm:4.0.0"
- dependencies:
- convert-to-spaces: "npm:^2.0.1"
- checksum: 10c0/b6c5a06e039cecd2ab6a0e10ee0831de8362107d1f298ca3558b5f9004cb8e0260b02dd6c07f57b9a0e346c76864d2873311ee1989809fdeb05bd5fbbadde773
- languageName: node
- linkType: hard
-
-"color-convert@npm:^1.9.0, color-convert@npm:^1.9.3":
- version: 1.9.3
- resolution: "color-convert@npm:1.9.3"
- dependencies:
- color-name: "npm:1.1.3"
- checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c
- languageName: node
- linkType: hard
-
-"color-convert@npm:^2.0.1":
- version: 2.0.1
- resolution: "color-convert@npm:2.0.1"
- dependencies:
- color-name: "npm:~1.1.4"
- checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7
- languageName: node
- linkType: hard
-
-"color-name@npm:1.1.3":
- version: 1.1.3
- resolution: "color-name@npm:1.1.3"
- checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6
- languageName: node
- linkType: hard
-
-"color-name@npm:^1.0.0, color-name@npm:~1.1.4":
- version: 1.1.4
- resolution: "color-name@npm:1.1.4"
- checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95
- languageName: node
- linkType: hard
-
-"color-string@npm:^1.6.0":
- version: 1.9.1
- resolution: "color-string@npm:1.9.1"
- dependencies:
- color-name: "npm:^1.0.0"
- simple-swizzle: "npm:^0.2.2"
- checksum: 10c0/b0bfd74c03b1f837f543898b512f5ea353f71630ccdd0d66f83028d1f0924a7d4272deb278b9aef376cacf1289b522ac3fb175e99895283645a2dc3a33af2404
- languageName: node
- linkType: hard
-
-"color@npm:^3.1.3":
- version: 3.2.1
- resolution: "color@npm:3.2.1"
- dependencies:
- color-convert: "npm:^1.9.3"
- color-string: "npm:^1.6.0"
- checksum: 10c0/39345d55825884c32a88b95127d417a2c24681d8b57069413596d9fcbb721459ef9d9ec24ce3e65527b5373ce171b73e38dbcd9c830a52a6487e7f37bf00e83c
- languageName: node
- linkType: hard
-
-"colorspace@npm:1.1.x":
- version: 1.1.4
- resolution: "colorspace@npm:1.1.4"
- dependencies:
- color: "npm:^3.1.3"
- text-hex: "npm:1.0.x"
- checksum: 10c0/af5f91ff7f8e146b96e439ac20ed79b197210193bde721b47380a75b21751d90fa56390c773bb67c0aedd34ff85091883a437ab56861c779bd507d639ba7e123
- languageName: node
- linkType: hard
-
-"combined-stream@npm:^1.0.8":
- version: 1.0.8
- resolution: "combined-stream@npm:1.0.8"
- dependencies:
- delayed-stream: "npm:~1.0.0"
- checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5
- languageName: node
- linkType: hard
-
-"commander@npm:7.1.0":
- version: 7.1.0
- resolution: "commander@npm:7.1.0"
- checksum: 10c0/1c114cc2e0c7c980068d7f2472f3fc9129ea5d6f2f0a8699671afe5a44a51d5707a6c73daff1aaa919424284dea9fca4017307d30647935a1116518699d54c9d
- languageName: node
- linkType: hard
-
-"commander@npm:^11.1.0":
- version: 11.1.0
- resolution: "commander@npm:11.1.0"
- checksum: 10c0/13cc6ac875e48780250f723fb81c1c1178d35c5decb1abb1b628b3177af08a8554e76b2c0f29de72d69eef7c864d12613272a71fabef8047922bc622ab75a179
- languageName: node
- linkType: hard
-
-"common-path-prefix@npm:^3.0.0":
- version: 3.0.0
- resolution: "common-path-prefix@npm:3.0.0"
- checksum: 10c0/c4a74294e1b1570f4a8ab435285d185a03976c323caa16359053e749db4fde44e3e6586c29cd051100335e11895767cbbd27ea389108e327d62f38daf4548fdb
- languageName: node
- linkType: hard
-
-"commondir@npm:^1.0.1":
- version: 1.0.1
- resolution: "commondir@npm:1.0.1"
- checksum: 10c0/33a124960e471c25ee19280c9ce31ccc19574b566dc514fe4f4ca4c34fa8b0b57cf437671f5de380e11353ea9426213fca17687dd2ef03134fea2dbc53809fd6
- languageName: node
- linkType: hard
-
-"concat-map@npm:0.0.1":
- version: 0.0.1
- resolution: "concat-map@npm:0.0.1"
- checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f
- languageName: node
- linkType: hard
-
-"concordance@npm:^5.0.4":
- version: 5.0.4
- resolution: "concordance@npm:5.0.4"
- dependencies:
- date-time: "npm:^3.1.0"
- esutils: "npm:^2.0.3"
- fast-diff: "npm:^1.2.0"
- js-string-escape: "npm:^1.0.1"
- lodash: "npm:^4.17.15"
- md5-hex: "npm:^3.0.1"
- semver: "npm:^7.3.2"
- well-known-symbols: "npm:^2.0.0"
- checksum: 10c0/59b440f330df3a7c9aa148ba588b3e99aed86acab225b4f01ffcea34ace4cf11f817e31153254e8f38ed48508998dad40b9106951a743c334d751f7ab21afb8a
- languageName: node
- linkType: hard
-
-"convert-to-spaces@npm:^2.0.1":
- version: 2.0.1
- resolution: "convert-to-spaces@npm:2.0.1"
- checksum: 10c0/d90aa0e3b6a27f9d5265a8d32def3c5c855b3e823a9db1f26d772f8146d6b91020a2fdfd905ce8048a73fad3aaf836fef8188c67602c374405e2ae8396c4ac46
- languageName: node
- linkType: hard
-
-"cosmjs-types@npm:^0.9.0":
- version: 0.9.0
- resolution: "cosmjs-types@npm:0.9.0"
- checksum: 10c0/bc20f4293fb34629d7c5f96bafe533987f753df957ff68eb078d0128ae5a418320cb945024441769a07bb9bc5dde9d22b972fd40d485933e5706ea191c43727b
- languageName: node
- linkType: hard
-
-"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3":
- version: 7.0.3
- resolution: "cross-spawn@npm:7.0.3"
- dependencies:
- path-key: "npm:^3.1.0"
- shebang-command: "npm:^2.0.0"
- which: "npm:^2.0.1"
- checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750
- languageName: node
- linkType: hard
-
-"currently-unhandled@npm:^0.4.1":
- version: 0.4.1
- resolution: "currently-unhandled@npm:0.4.1"
- dependencies:
- array-find-index: "npm:^1.0.1"
- checksum: 10c0/32d197689ec32f035910202c1abb0dc6424dce01d7b51779c685119b380d98535c110ffff67a262fc7e367612a7dfd30d3d3055f9a6634b5a9dd1302de7ef11c
- languageName: node
- linkType: hard
-
-"data-uri-to-buffer@npm:^4.0.0":
- version: 4.0.1
- resolution: "data-uri-to-buffer@npm:4.0.1"
- checksum: 10c0/20a6b93107597530d71d4cb285acee17f66bcdfc03fd81040921a81252f19db27588d87fc8fc69e1950c55cfb0bf8ae40d0e5e21d907230813eb5d5a7f9eb45b
- languageName: node
- linkType: hard
-
-"date-time@npm:^3.1.0":
- version: 3.1.0
- resolution: "date-time@npm:3.1.0"
- dependencies:
- time-zone: "npm:^1.0.0"
- checksum: 10c0/aa3e2e930d74b0b9e90f69de7a16d3376e30f21f1f4ce9a2311d8fec32d760e776efea752dafad0ce188187265235229013036202be053fc2d7979813bfb6ded
- languageName: node
- linkType: hard
-
-"debug@npm:4, debug@npm:^4.3.4":
- version: 4.3.4
- resolution: "debug@npm:4.3.4"
- dependencies:
- ms: "npm:2.1.2"
- peerDependenciesMeta:
- supports-color:
- optional: true
- checksum: 10c0/cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736
- languageName: node
- linkType: hard
-
-"debug@npm:^4.3.1":
- version: 4.3.5
- resolution: "debug@npm:4.3.5"
- dependencies:
- ms: "npm:2.1.2"
- peerDependenciesMeta:
- supports-color:
- optional: true
- checksum: 10c0/082c375a2bdc4f4469c99f325ff458adad62a3fc2c482d59923c260cb08152f34e2659f72b3767db8bb2f21ca81a60a42d1019605a412132d7b9f59363a005cc
- languageName: node
- linkType: hard
-
-"decompress-response@npm:^6.0.0":
- version: 6.0.0
- resolution: "decompress-response@npm:6.0.0"
- dependencies:
- mimic-response: "npm:^3.1.0"
- checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e
- languageName: node
- linkType: hard
-
-"deep-extend@npm:^0.6.0":
- version: 0.6.0
- resolution: "deep-extend@npm:0.6.0"
- checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566
- languageName: node
- linkType: hard
-
-"deepmerge@npm:^4.2.2":
- version: 4.3.1
- resolution: "deepmerge@npm:4.3.1"
- checksum: 10c0/e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044
- languageName: node
- linkType: hard
-
-"defaults@npm:^1.0.3":
- version: 1.0.4
- resolution: "defaults@npm:1.0.4"
- dependencies:
- clone: "npm:^1.0.2"
- checksum: 10c0/9cfbe498f5c8ed733775db62dfd585780387d93c17477949e1670bfcfb9346e0281ce8c4bf9f4ac1fc0f9b851113bd6dc9e41182ea1644ccd97de639fa13c35a
- languageName: node
- linkType: hard
-
-"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4":
- version: 1.1.4
- resolution: "define-data-property@npm:1.1.4"
- dependencies:
- es-define-property: "npm:^1.0.0"
- es-errors: "npm:^1.3.0"
- gopd: "npm:^1.0.1"
- checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37
- languageName: node
- linkType: hard
-
-"define-properties@npm:^1.2.1":
- version: 1.2.1
- resolution: "define-properties@npm:1.2.1"
- dependencies:
- define-data-property: "npm:^1.0.1"
- has-property-descriptors: "npm:^1.0.0"
- object-keys: "npm:^1.1.1"
- checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3
- languageName: node
- linkType: hard
-
-"delayed-stream@npm:~1.0.0":
- version: 1.0.0
- resolution: "delayed-stream@npm:1.0.0"
- checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19
- languageName: node
- linkType: hard
-
-"detect-libc@npm:^2.0.0":
- version: 2.0.2
- resolution: "detect-libc@npm:2.0.2"
- checksum: 10c0/a9f4ffcd2701525c589617d98afe5a5d0676c8ea82bcc4ed6f3747241b79f781d36437c59a5e855254c864d36a3e9f8276568b6b531c28d6e53b093a15703f11
- languageName: node
- linkType: hard
-
-"deterministic-json@npm:^1.0.5":
- version: 1.0.5
- resolution: "deterministic-json@npm:1.0.5"
- dependencies:
- json-stable-stringify: "npm:^1.0.1"
- checksum: 10c0/e29679601cd3b05c73665529dcd0132b48797fd7dfbac6793238a479e82b5f3905114316fbb316332da58b4497e35df9aea77b41ff92fd74fe298a6f31b93d40
- languageName: node
- linkType: hard
-
-"dir-glob@npm:^3.0.1":
- version: 3.0.1
- resolution: "dir-glob@npm:3.0.1"
- dependencies:
- path-type: "npm:^4.0.0"
- checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c
- languageName: node
- linkType: hard
-
-"eastasianwidth@npm:^0.2.0":
- version: 0.2.0
- resolution: "eastasianwidth@npm:0.2.0"
- checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39
- languageName: node
- linkType: hard
-
-"elliptic@npm:^6.5.4":
- version: 6.5.5
- resolution: "elliptic@npm:6.5.5"
- dependencies:
- bn.js: "npm:^4.11.9"
- brorand: "npm:^1.1.0"
- hash.js: "npm:^1.0.0"
- hmac-drbg: "npm:^1.0.1"
- inherits: "npm:^2.0.4"
- minimalistic-assert: "npm:^1.0.1"
- minimalistic-crypto-utils: "npm:^1.0.1"
- checksum: 10c0/3e591e93783a1b66f234ebf5bd3a8a9a8e063a75073a35a671e03e3b25253b6e33ac121f7efe9b8808890fffb17b40596cc19d01e6e8d1fa13b9a56ff65597c8
- languageName: node
- linkType: hard
-
-"emittery@npm:^1.0.1":
- version: 1.0.2
- resolution: "emittery@npm:1.0.2"
- checksum: 10c0/7f26cdb3044dc25689b44e81d4486b404dcec93faaec71f09b8ead8bd0e089a58a26e4605bac2894c8985d5cc48c0f359f943da098944e9fdc3a04bb6bec6299
- languageName: node
- linkType: hard
-
-"emoji-regex@npm:^8.0.0":
- version: 8.0.0
- resolution: "emoji-regex@npm:8.0.0"
- checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010
- languageName: node
- linkType: hard
-
-"emoji-regex@npm:^9.2.2":
- version: 9.2.2
- resolution: "emoji-regex@npm:9.2.2"
- checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639
- languageName: node
- linkType: hard
-
-"enabled@npm:2.0.x":
- version: 2.0.0
- resolution: "enabled@npm:2.0.0"
- checksum: 10c0/3b2c2af9bc7f8b9e291610f2dde4a75cf6ee52a68f4dd585482fbdf9a55d65388940e024e56d40bb03e05ef6671f5f53021fa8b72a20e954d7066ec28166713f
- languageName: node
- linkType: hard
-
-"encoding@npm:^0.1.13":
- version: 0.1.13
- resolution: "encoding@npm:0.1.13"
- dependencies:
- iconv-lite: "npm:^0.6.2"
- checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039
- languageName: node
- linkType: hard
-
-"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1":
- version: 1.4.4
- resolution: "end-of-stream@npm:1.4.4"
- dependencies:
- once: "npm:^1.4.0"
- checksum: 10c0/870b423afb2d54bb8d243c63e07c170409d41e20b47eeef0727547aea5740bd6717aca45597a9f2745525667a6b804c1e7bede41f856818faee5806dd9ff3975
- languageName: node
- linkType: hard
-
-"env-paths@npm:^2.2.0":
- version: 2.2.1
- resolution: "env-paths@npm:2.2.1"
- checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4
- languageName: node
- linkType: hard
-
-"err-code@npm:^2.0.2":
- version: 2.0.3
- resolution: "err-code@npm:2.0.3"
- checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66
- languageName: node
- linkType: hard
-
-"es-define-property@npm:^1.0.0":
- version: 1.0.0
- resolution: "es-define-property@npm:1.0.0"
- dependencies:
- get-intrinsic: "npm:^1.2.4"
- checksum: 10c0/6bf3191feb7ea2ebda48b577f69bdfac7a2b3c9bcf97307f55fd6ef1bbca0b49f0c219a935aca506c993d8c5d8bddd937766cb760cd5e5a1071351f2df9f9aa4
- languageName: node
- linkType: hard
-
-"es-errors@npm:^1.3.0":
- version: 1.3.0
- resolution: "es-errors@npm:1.3.0"
- checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85
- languageName: node
- linkType: hard
-
-"escalade@npm:^3.1.1":
- version: 3.1.1
- resolution: "escalade@npm:3.1.1"
- checksum: 10c0/afd02e6ca91ffa813e1108b5e7756566173d6bc0d1eb951cb44d6b21702ec17c1cf116cfe75d4a2b02e05acb0b808a7a9387d0d1ca5cf9c04ad03a8445c3e46d
- languageName: node
- linkType: hard
-
-"escape-string-regexp@npm:5.0.0, escape-string-regexp@npm:^5.0.0":
- version: 5.0.0
- resolution: "escape-string-regexp@npm:5.0.0"
- checksum: 10c0/6366f474c6f37a802800a435232395e04e9885919873e382b157ab7e8f0feb8fed71497f84a6f6a81a49aab41815522f5839112bd38026d203aea0c91622df95
- languageName: node
- linkType: hard
-
-"escape-string-regexp@npm:^1.0.5":
- version: 1.0.5
- resolution: "escape-string-regexp@npm:1.0.5"
- checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371
- languageName: node
- linkType: hard
-
-"escape-string-regexp@npm:^2.0.0":
- version: 2.0.0
- resolution: "escape-string-regexp@npm:2.0.0"
- checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507
- languageName: node
- linkType: hard
-
-"esm@github:agoric-labs/esm#Agoric-built":
- version: 3.2.25
- resolution: "esm@https://github.com/agoric-labs/esm.git#commit=3603726ad4636b2f865f463188fcaade6375638e"
- checksum: 10c0/fc1e112a3a681e7b4152d4f5c76dd5aa9e30496d2020490ffa0fb61aaf57d1e12dae0c1074fdd2e0f08949ab2df7e00e750262356781f072e4119955ee10b754
- languageName: node
- linkType: hard
-
-"esprima@npm:^4.0.0":
- version: 4.0.1
- resolution: "esprima@npm:4.0.1"
- bin:
- esparse: ./bin/esparse.js
- esvalidate: ./bin/esvalidate.js
- checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3
- languageName: node
- linkType: hard
-
-"estree-walker@npm:^1.0.1":
- version: 1.0.1
- resolution: "estree-walker@npm:1.0.1"
- checksum: 10c0/fa9e5f8c1bbe8d01e314c0f03067b64a4f22d4c58410fc5237060d0c15b81e58c23921c41acc60abbdab490f1fdfcbd6408ede2d03ca704454272e0244d61a55
- languageName: node
- linkType: hard
-
-"estree-walker@npm:^2.0.1":
- version: 2.0.2
- resolution: "estree-walker@npm:2.0.2"
- checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af
- languageName: node
- linkType: hard
-
-"esutils@npm:^2.0.3":
- version: 2.0.3
- resolution: "esutils@npm:2.0.3"
- checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7
- languageName: node
- linkType: hard
-
-"execa@npm:^8.0.1":
- version: 8.0.1
- resolution: "execa@npm:8.0.1"
- dependencies:
- cross-spawn: "npm:^7.0.3"
- get-stream: "npm:^8.0.1"
- human-signals: "npm:^5.0.0"
- is-stream: "npm:^3.0.0"
- merge-stream: "npm:^2.0.0"
- npm-run-path: "npm:^5.1.0"
- onetime: "npm:^6.0.0"
- signal-exit: "npm:^4.1.0"
- strip-final-newline: "npm:^3.0.0"
- checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af
- languageName: node
- linkType: hard
-
-"expand-template@npm:^2.0.3":
- version: 2.0.3
- resolution: "expand-template@npm:2.0.3"
- checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51
- languageName: node
- linkType: hard
-
-"exponential-backoff@npm:^3.1.1":
- version: 3.1.1
- resolution: "exponential-backoff@npm:3.1.1"
- checksum: 10c0/160456d2d647e6019640bd07111634d8c353038d9fa40176afb7cd49b0548bdae83b56d05e907c2cce2300b81cae35d800ef92fefb9d0208e190fa3b7d6bb579
- languageName: node
- linkType: hard
-
-"external-editor@npm:^3.0.3":
- version: 3.1.0
- resolution: "external-editor@npm:3.1.0"
- dependencies:
- chardet: "npm:^0.7.0"
- iconv-lite: "npm:^0.4.24"
- tmp: "npm:^0.0.33"
- checksum: 10c0/c98f1ba3efdfa3c561db4447ff366a6adb5c1e2581462522c56a18bf90dfe4da382f9cd1feee3e330108c3595a854b218272539f311ba1b3298f841eb0fbf339
- languageName: node
- linkType: hard
-
-"fast-check@npm:^3.0.0":
- version: 3.19.0
- resolution: "fast-check@npm:3.19.0"
- dependencies:
- pure-rand: "npm:^6.1.0"
- checksum: 10c0/5a15484d380fb5a3e94ec951c97e59b940ac4f2e1f3f7a05578d67851e5cb5283121bcf08c57e3238bc85899ce691b47ab477a6dd481a6f520e2e7ab4952d1ee
- languageName: node
- linkType: hard
-
-"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
- version: 3.1.3
- resolution: "fast-deep-equal@npm:3.1.3"
- checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0
- languageName: node
- linkType: hard
-
-"fast-diff@npm:^1.2.0":
- version: 1.3.0
- resolution: "fast-diff@npm:1.3.0"
- checksum: 10c0/5c19af237edb5d5effda008c891a18a585f74bf12953be57923f17a3a4d0979565fc64dbc73b9e20926b9d895f5b690c618cbb969af0cf022e3222471220ad29
- languageName: node
- linkType: hard
-
-"fast-glob@npm:^3.3.0":
- version: 3.3.2
- resolution: "fast-glob@npm:3.3.2"
- dependencies:
- "@nodelib/fs.stat": "npm:^2.0.2"
- "@nodelib/fs.walk": "npm:^1.2.3"
- glob-parent: "npm:^5.1.2"
- merge2: "npm:^1.3.0"
- micromatch: "npm:^4.0.4"
- checksum: 10c0/42baad7b9cd40b63e42039132bde27ca2cb3a4950d0a0f9abe4639ea1aa9d3e3b40f98b1fe31cbc0cc17b664c9ea7447d911a152fa34ec5b72977b125a6fc845
- languageName: node
- linkType: hard
-
-"fast-safe-stringify@npm:2.0.4":
- version: 2.0.4
- resolution: "fast-safe-stringify@npm:2.0.4"
- checksum: 10c0/5e4fbafe8b8c4a1681c2ab259ed8ce6672fc209683a141876f020c36a2cbec73bfe25c417c269f439797020996d04ed2d7c4c6b2c5cf393d6febbf7f4d8a5f53
- languageName: node
- linkType: hard
-
-"fastq@npm:^1.6.0":
- version: 1.17.0
- resolution: "fastq@npm:1.17.0"
- dependencies:
- reusify: "npm:^1.0.4"
- checksum: 10c0/0a90ed46ccd6a858a32e297bd35f4249ba6544899b905d08f33a6ba36459041639161fa15bc85a38afa98dd44fb2fa2969419a879721a1395d3e24668a7732c7
- languageName: node
- linkType: hard
-
-"fecha@npm:^4.2.0":
- version: 4.2.3
- resolution: "fecha@npm:4.2.3"
- checksum: 10c0/0e895965959cf6a22bb7b00f0bf546f2783836310f510ddf63f463e1518d4c96dec61ab33fdfd8e79a71b4856a7c865478ce2ee8498d560fe125947703c9b1cf
- languageName: node
- linkType: hard
-
-"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4":
- version: 3.2.0
- resolution: "fetch-blob@npm:3.2.0"
- dependencies:
- node-domexception: "npm:^1.0.0"
- web-streams-polyfill: "npm:^3.0.3"
- checksum: 10c0/60054bf47bfa10fb0ba6cb7742acec2f37c1f56344f79a70bb8b1c48d77675927c720ff3191fa546410a0442c998d27ab05e9144c32d530d8a52fbe68f843b69
- languageName: node
- linkType: hard
-
-"figures@npm:^3.0.0":
- version: 3.2.0
- resolution: "figures@npm:3.2.0"
- dependencies:
- escape-string-regexp: "npm:^1.0.5"
- checksum: 10c0/9c421646ede432829a50bc4e55c7a4eb4bcb7cc07b5bab2f471ef1ab9a344595bbebb6c5c21470093fbb730cd81bbca119624c40473a125293f656f49cb47629
- languageName: node
- linkType: hard
-
-"figures@npm:^5.0.0":
- version: 5.0.0
- resolution: "figures@npm:5.0.0"
- dependencies:
- escape-string-regexp: "npm:^5.0.0"
- is-unicode-supported: "npm:^1.2.0"
- checksum: 10c0/ce0f17d4ea8b0fc429c5207c343534a2f5284ecfb22aa08607da7dc84ed9e1cf754f5b97760e8dcb98d3c9d1a1e4d3d578fe3b5b99c426f05d0f06c7ba618e16
- languageName: node
- linkType: hard
-
-"file-uri-to-path@npm:1.0.0":
- version: 1.0.0
- resolution: "file-uri-to-path@npm:1.0.0"
- checksum: 10c0/3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519
- languageName: node
- linkType: hard
-
-"fill-range@npm:^7.0.1":
- version: 7.0.1
- resolution: "fill-range@npm:7.0.1"
- dependencies:
- to-regex-range: "npm:^5.0.1"
- checksum: 10c0/7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f
- languageName: node
- linkType: hard
-
-"find-up@npm:^6.0.0":
- version: 6.3.0
- resolution: "find-up@npm:6.3.0"
- dependencies:
- locate-path: "npm:^7.1.0"
- path-exists: "npm:^5.0.0"
- checksum: 10c0/07e0314362d316b2b13f7f11ea4692d5191e718ca3f7264110127520f3347996349bf9e16805abae3e196805814bc66ef4bff2b8904dc4a6476085fc9b0eba07
- languageName: node
- linkType: hard
-
-"fn.name@npm:1.x.x":
- version: 1.1.0
- resolution: "fn.name@npm:1.1.0"
- checksum: 10c0/8ad62aa2d4f0b2a76d09dba36cfec61c540c13a0fd72e5d94164e430f987a7ce6a743112bbeb14877c810ef500d1f73d7f56e76d029d2e3413f20d79e3460a9a
- languageName: node
- linkType: hard
-
-"follow-redirects@npm:^1.15.6":
- version: 1.15.6
- resolution: "follow-redirects@npm:1.15.6"
- peerDependenciesMeta:
- debug:
- optional: true
- checksum: 10c0/9ff767f0d7be6aa6870c82ac79cf0368cd73e01bbc00e9eb1c2a16fbb198ec105e3c9b6628bb98e9f3ac66fe29a957b9645bcb9a490bb7aa0d35f908b6b85071
- languageName: node
- linkType: hard
-
-"foreground-child@npm:^3.1.0":
- version: 3.1.1
- resolution: "foreground-child@npm:3.1.1"
- dependencies:
- cross-spawn: "npm:^7.0.0"
- signal-exit: "npm:^4.0.1"
- checksum: 10c0/9700a0285628abaeb37007c9a4d92bd49f67210f09067638774338e146c8e9c825c5c877f072b2f75f41dc6a2d0be8664f79ffc03f6576649f54a84fb9b47de0
- languageName: node
- linkType: hard
-
-"form-data@npm:^4.0.0":
- version: 4.0.0
- resolution: "form-data@npm:4.0.0"
- dependencies:
- asynckit: "npm:^0.4.0"
- combined-stream: "npm:^1.0.8"
- mime-types: "npm:^2.1.12"
- checksum: 10c0/cb6f3ac49180be03ff07ba3ff125f9eba2ff0b277fb33c7fc47569fc5e616882c5b1c69b9904c4c4187e97dd0419dd03b134174756f296dec62041e6527e2c6e
- languageName: node
- linkType: hard
-
-"formdata-polyfill@npm:^4.0.10":
- version: 4.0.10
- resolution: "formdata-polyfill@npm:4.0.10"
- dependencies:
- fetch-blob: "npm:^3.1.2"
- checksum: 10c0/5392ec484f9ce0d5e0d52fb5a78e7486637d516179b0eb84d81389d7eccf9ca2f663079da56f761355c0a65792810e3b345dc24db9a8bbbcf24ef3c8c88570c6
- languageName: node
- linkType: hard
-
-"fs-constants@npm:^1.0.0":
- version: 1.0.0
- resolution: "fs-constants@npm:1.0.0"
- checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8
- languageName: node
- linkType: hard
-
-"fs-minipass@npm:^2.0.0":
- version: 2.1.0
- resolution: "fs-minipass@npm:2.1.0"
- dependencies:
- minipass: "npm:^3.0.0"
- checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004
- languageName: node
- linkType: hard
-
-"fs-minipass@npm:^3.0.0":
- version: 3.0.3
- resolution: "fs-minipass@npm:3.0.3"
- dependencies:
- minipass: "npm:^7.0.3"
- checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94
- languageName: node
- linkType: hard
-
-"fs.realpath@npm:^1.0.0":
- version: 1.0.0
- resolution: "fs.realpath@npm:1.0.0"
- checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948
- languageName: node
- linkType: hard
-
-"fsevents@npm:~2.3.2":
- version: 2.3.3
- resolution: "fsevents@npm:2.3.3"
- dependencies:
- node-gyp: "npm:latest"
- checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60
- conditions: os=darwin
- languageName: node
- linkType: hard
-
-"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin":
- version: 2.3.3
- resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"
- dependencies:
- node-gyp: "npm:latest"
- conditions: os=darwin
- languageName: node
- linkType: hard
-
-"function-bind@npm:^1.1.2":
- version: 1.1.2
- resolution: "function-bind@npm:1.1.2"
- checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5
- languageName: node
- linkType: hard
-
-"get-caller-file@npm:^2.0.5":
- version: 2.0.5
- resolution: "get-caller-file@npm:2.0.5"
- checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde
- languageName: node
- linkType: hard
-
-"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.4":
- version: 1.2.4
- resolution: "get-intrinsic@npm:1.2.4"
- dependencies:
- es-errors: "npm:^1.3.0"
- function-bind: "npm:^1.1.2"
- has-proto: "npm:^1.0.1"
- has-symbols: "npm:^1.0.3"
- hasown: "npm:^2.0.0"
- checksum: 10c0/0a9b82c16696ed6da5e39b1267104475c47e3a9bdbe8b509dfe1710946e38a87be70d759f4bb3cda042d76a41ef47fe769660f3b7c0d1f68750299344ffb15b7
- languageName: node
- linkType: hard
-
-"get-stream@npm:^8.0.1":
- version: 8.0.1
- resolution: "get-stream@npm:8.0.1"
- checksum: 10c0/5c2181e98202b9dae0bb4a849979291043e5892eb40312b47f0c22b9414fc9b28a3b6063d2375705eb24abc41ecf97894d9a51f64ff021511b504477b27b4290
- languageName: node
- linkType: hard
-
-"github-from-package@npm:0.0.0":
- version: 0.0.0
- resolution: "github-from-package@npm:0.0.0"
- checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12
- languageName: node
- linkType: hard
-
-"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
- version: 5.1.2
- resolution: "glob-parent@npm:5.1.2"
- dependencies:
- is-glob: "npm:^4.0.1"
- checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee
- languageName: node
- linkType: hard
-
-"glob@npm:^10.2.2, glob@npm:^10.3.10":
- version: 10.3.10
- resolution: "glob@npm:10.3.10"
- dependencies:
- foreground-child: "npm:^3.1.0"
- jackspeak: "npm:^2.3.5"
- minimatch: "npm:^9.0.1"
- minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0"
- path-scurry: "npm:^1.10.1"
- bin:
- glob: dist/esm/bin.mjs
- checksum: 10c0/13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d
- languageName: node
- linkType: hard
-
-"glob@npm:^7.1.6":
- version: 7.2.3
- resolution: "glob@npm:7.2.3"
- dependencies:
- fs.realpath: "npm:^1.0.0"
- inflight: "npm:^1.0.4"
- inherits: "npm:2"
- minimatch: "npm:^3.1.1"
- once: "npm:^1.3.0"
- path-is-absolute: "npm:^1.0.0"
- checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe
- languageName: node
- linkType: hard
-
-"globals@npm:^11.1.0":
- version: 11.12.0
- resolution: "globals@npm:11.12.0"
- checksum: 10c0/758f9f258e7b19226bd8d4af5d3b0dcf7038780fb23d82e6f98932c44e239f884847f1766e8fa9cc5635ccb3204f7fa7314d4408dd4002a5e8ea827b4018f0a1
- languageName: node
- linkType: hard
-
-"globalthis@npm:^1.0.1":
- version: 1.0.4
- resolution: "globalthis@npm:1.0.4"
- dependencies:
- define-properties: "npm:^1.2.1"
- gopd: "npm:^1.0.1"
- checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846
- languageName: node
- linkType: hard
-
-"globby@npm:^13.1.4":
- version: 13.2.2
- resolution: "globby@npm:13.2.2"
- dependencies:
- dir-glob: "npm:^3.0.1"
- fast-glob: "npm:^3.3.0"
- ignore: "npm:^5.2.4"
- merge2: "npm:^1.4.1"
- slash: "npm:^4.0.0"
- checksum: 10c0/a8d7cc7cbe5e1b2d0f81d467bbc5bc2eac35f74eaded3a6c85fc26d7acc8e6de22d396159db8a2fc340b8a342e74cac58de8f4aee74146d3d146921a76062664
- languageName: node
- linkType: hard
-
-"gopd@npm:^1.0.1":
- version: 1.0.1
- resolution: "gopd@npm:1.0.1"
- dependencies:
- get-intrinsic: "npm:^1.1.3"
- checksum: 10c0/505c05487f7944c552cee72087bf1567debb470d4355b1335f2c262d218ebbff805cd3715448fe29b4b380bae6912561d0467233e4165830efd28da241418c63
- languageName: node
- linkType: hard
-
-"graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6":
- version: 4.2.11
- resolution: "graceful-fs@npm:4.2.11"
- checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2
- languageName: node
- linkType: hard
-
-"has-flag@npm:^3.0.0":
- version: 3.0.0
- resolution: "has-flag@npm:3.0.0"
- checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473
- languageName: node
- linkType: hard
-
-"has-flag@npm:^4.0.0":
- version: 4.0.0
- resolution: "has-flag@npm:4.0.0"
- checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1
- languageName: node
- linkType: hard
-
-"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2":
- version: 1.0.2
- resolution: "has-property-descriptors@npm:1.0.2"
- dependencies:
- es-define-property: "npm:^1.0.0"
- checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236
- languageName: node
- linkType: hard
-
-"has-proto@npm:^1.0.1":
- version: 1.0.3
- resolution: "has-proto@npm:1.0.3"
- checksum: 10c0/35a6989f81e9f8022c2f4027f8b48a552de714938765d019dbea6bb547bd49ce5010a3c7c32ec6ddac6e48fc546166a3583b128f5a7add8b058a6d8b4afec205
- languageName: node
- linkType: hard
-
-"has-symbols@npm:^1.0.3":
- version: 1.0.3
- resolution: "has-symbols@npm:1.0.3"
- checksum: 10c0/e6922b4345a3f37069cdfe8600febbca791c94988c01af3394d86ca3360b4b93928bbf395859158f88099cb10b19d98e3bbab7c9ff2c1bd09cf665ee90afa2c3
- languageName: node
- linkType: hard
-
-"hash.js@npm:^1.0.0, hash.js@npm:^1.0.3":
- version: 1.1.7
- resolution: "hash.js@npm:1.1.7"
- dependencies:
- inherits: "npm:^2.0.3"
- minimalistic-assert: "npm:^1.0.1"
- checksum: 10c0/41ada59494eac5332cfc1ce6b7ebdd7b88a3864a6d6b08a3ea8ef261332ed60f37f10877e0c825aaa4bddebf164fbffa618286aeeec5296675e2671cbfa746c4
- languageName: node
- linkType: hard
-
-"hasown@npm:^2.0.0, hasown@npm:^2.0.2":
- version: 2.0.2
- resolution: "hasown@npm:2.0.2"
- dependencies:
- function-bind: "npm:^1.1.2"
- checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9
- languageName: node
- linkType: hard
-
-"hmac-drbg@npm:^1.0.1":
- version: 1.0.1
- resolution: "hmac-drbg@npm:1.0.1"
- dependencies:
- hash.js: "npm:^1.0.3"
- minimalistic-assert: "npm:^1.0.0"
- minimalistic-crypto-utils: "npm:^1.0.1"
- checksum: 10c0/f3d9ba31b40257a573f162176ac5930109816036c59a09f901eb2ffd7e5e705c6832bedfff507957125f2086a0ab8f853c0df225642a88bf1fcaea945f20600d
- languageName: node
- linkType: hard
-
-"http-cache-semantics@npm:^4.1.1":
- version: 4.1.1
- resolution: "http-cache-semantics@npm:4.1.1"
- checksum: 10c0/ce1319b8a382eb3cbb4a37c19f6bfe14e5bb5be3d09079e885e8c513ab2d3cd9214902f8a31c9dc4e37022633ceabfc2d697405deeaf1b8f3552bb4ed996fdfc
- languageName: node
- linkType: hard
-
-"http-proxy-agent@npm:^7.0.0":
- version: 7.0.0
- resolution: "http-proxy-agent@npm:7.0.0"
- dependencies:
- agent-base: "npm:^7.1.0"
- debug: "npm:^4.3.4"
- checksum: 10c0/a11574ff39436cee3c7bc67f259444097b09474605846ddd8edf0bf4ad8644be8533db1aa463426e376865047d05dc22755e638632819317c0c2f1b2196657c8
- languageName: node
- linkType: hard
-
-"https-proxy-agent@npm:^7.0.1":
- version: 7.0.2
- resolution: "https-proxy-agent@npm:7.0.2"
- dependencies:
- agent-base: "npm:^7.0.2"
- debug: "npm:4"
- checksum: 10c0/7735eb90073db087e7e79312e3d97c8c04baf7ea7ca7b013382b6a45abbaa61b281041a98f4e13c8c80d88f843785bcc84ba189165b4b4087b1e3496ba656d77
- languageName: node
- linkType: hard
-
-"human-signals@npm:^5.0.0":
- version: 5.0.0
- resolution: "human-signals@npm:5.0.0"
- checksum: 10c0/5a9359073fe17a8b58e5a085e9a39a950366d9f00217c4ff5878bd312e09d80f460536ea6a3f260b5943a01fe55c158d1cea3fc7bee3d0520aeef04f6d915c82
- languageName: node
- linkType: hard
-
-"iconv-lite@npm:^0.4.24":
- version: 0.4.24
- resolution: "iconv-lite@npm:0.4.24"
- dependencies:
- safer-buffer: "npm:>= 2.1.2 < 3"
- checksum: 10c0/c6886a24cc00f2a059767440ec1bc00d334a89f250db8e0f7feb4961c8727118457e27c495ba94d082e51d3baca378726cd110aaf7ded8b9bbfd6a44760cf1d4
- languageName: node
- linkType: hard
-
-"iconv-lite@npm:^0.6.2":
- version: 0.6.3
- resolution: "iconv-lite@npm:0.6.3"
- dependencies:
- safer-buffer: "npm:>= 2.1.2 < 3.0.0"
- checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1
- languageName: node
- linkType: hard
-
-"ieee754@npm:^1.1.13":
- version: 1.2.1
- resolution: "ieee754@npm:1.2.1"
- checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb
- languageName: node
- linkType: hard
-
-"ignore-by-default@npm:^2.1.0":
- version: 2.1.0
- resolution: "ignore-by-default@npm:2.1.0"
- checksum: 10c0/3a6040dac25ed9da39dee73bf1634fdd1e15b0eb7cf52a6bdec81c310565782d8811c104ce40acb3d690d61c5fc38a91c78e6baee830a8a2232424dbc6b66981
- languageName: node
- linkType: hard
-
-"ignore@npm:^5.2.4":
- version: 5.3.0
- resolution: "ignore@npm:5.3.0"
- checksum: 10c0/dc06bea5c23aae65d0725a957a0638b57e235ae4568dda51ca142053ed2c352de7e3bc93a69b2b32ac31966a1952e9a93c5ef2e2ab7c6b06aef9808f6b55b571
- languageName: node
- linkType: hard
-
-"import-meta-resolve@npm:^2.2.1":
- version: 2.2.2
- resolution: "import-meta-resolve@npm:2.2.2"
- checksum: 10c0/80873aebf0d2a66e824e278fb6cbb16a6660f86df49b367404e5de80928720ecb44f643243b46dc5c5fae506abb666ef54d6f281b45ee0f1034951acb2261eb5
- languageName: node
- linkType: hard
-
-"imurmurhash@npm:^0.1.4":
- version: 0.1.4
- resolution: "imurmurhash@npm:0.1.4"
- checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6
- languageName: node
- linkType: hard
-
-"indent-string@npm:^4.0.0":
- version: 4.0.0
- resolution: "indent-string@npm:4.0.0"
- checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f
- languageName: node
- linkType: hard
-
-"indent-string@npm:^5.0.0":
- version: 5.0.0
- resolution: "indent-string@npm:5.0.0"
- checksum: 10c0/8ee77b57d92e71745e133f6f444d6fa3ed503ad0e1bcd7e80c8da08b42375c07117128d670589725ed07b1978065803fa86318c309ba45415b7fe13e7f170220
- languageName: node
- linkType: hard
-
-"inflight@npm:^1.0.4":
- version: 1.0.6
- resolution: "inflight@npm:1.0.6"
- dependencies:
- once: "npm:^1.3.0"
- wrappy: "npm:1"
- checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2
- languageName: node
- linkType: hard
-
-"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4":
- version: 2.0.4
- resolution: "inherits@npm:2.0.4"
- checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2
- languageName: node
- linkType: hard
-
-"ini@npm:~1.3.0":
- version: 1.3.8
- resolution: "ini@npm:1.3.8"
- checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a
- languageName: node
- linkType: hard
-
-"inquirer@npm:^8.2.2":
- version: 8.2.6
- resolution: "inquirer@npm:8.2.6"
- dependencies:
- ansi-escapes: "npm:^4.2.1"
- chalk: "npm:^4.1.1"
- cli-cursor: "npm:^3.1.0"
- cli-width: "npm:^3.0.0"
- external-editor: "npm:^3.0.3"
- figures: "npm:^3.0.0"
- lodash: "npm:^4.17.21"
- mute-stream: "npm:0.0.8"
- ora: "npm:^5.4.1"
- run-async: "npm:^2.4.0"
- rxjs: "npm:^7.5.5"
- string-width: "npm:^4.1.0"
- strip-ansi: "npm:^6.0.0"
- through: "npm:^2.3.6"
- wrap-ansi: "npm:^6.0.1"
- checksum: 10c0/eb5724de1778265323f3a68c80acfa899378cb43c24cdcb58661386500e5696b6b0b6c700e046b7aa767fe7b4823c6f04e6ddc268173e3f84116112529016296
- languageName: node
- linkType: hard
-
-"ip@npm:^2.0.0":
- version: 2.0.0
- resolution: "ip@npm:2.0.0"
- checksum: 10c0/8d186cc5585f57372847ae29b6eba258c68862055e18a75cc4933327232cb5c107f89800ce29715d542eef2c254fbb68b382e780a7414f9ee7caf60b7a473958
- languageName: node
- linkType: hard
-
-"irregular-plurals@npm:^3.3.0":
- version: 3.5.0
- resolution: "irregular-plurals@npm:3.5.0"
- checksum: 10c0/7c033bbe7325e5a6e0a26949cc6863b6ce273403d4cd5b93bd99b33fecb6605b0884097c4259c23ed0c52c2133bf7d1cdcdd7a0630e8c325161fe269b3447918
- languageName: node
- linkType: hard
-
-"is-arrayish@npm:^0.3.1":
- version: 0.3.2
- resolution: "is-arrayish@npm:0.3.2"
- checksum: 10c0/f59b43dc1d129edb6f0e282595e56477f98c40278a2acdc8b0a5c57097c9eff8fe55470493df5775478cf32a4dc8eaf6d3a749f07ceee5bc263a78b2434f6a54
- languageName: node
- linkType: hard
-
-"is-binary-path@npm:~2.1.0":
- version: 2.1.0
- resolution: "is-binary-path@npm:2.1.0"
- dependencies:
- binary-extensions: "npm:^2.0.0"
- checksum: 10c0/a16eaee59ae2b315ba36fad5c5dcaf8e49c3e27318f8ab8fa3cdb8772bf559c8d1ba750a589c2ccb096113bb64497084361a25960899cb6172a6925ab6123d38
- languageName: node
- linkType: hard
-
-"is-builtin-module@npm:^3.1.0":
- version: 3.2.1
- resolution: "is-builtin-module@npm:3.2.1"
- dependencies:
- builtin-modules: "npm:^3.3.0"
- checksum: 10c0/5a66937a03f3b18803381518f0ef679752ac18cdb7dd53b5e23ee8df8d440558737bd8dcc04d2aae555909d2ecb4a81b5c0d334d119402584b61e6a003e31af1
- languageName: node
- linkType: hard
-
-"is-core-module@npm:^2.13.0":
- version: 2.14.0
- resolution: "is-core-module@npm:2.14.0"
- dependencies:
- hasown: "npm:^2.0.2"
- checksum: 10c0/ae8dbc82bd20426558bc8d20ce290ce301c1cfd6ae4446266d10cacff4c63c67ab16440ade1d72ced9ec41c569fbacbcee01e293782ce568527c4cdf35936e4c
- languageName: node
- linkType: hard
-
-"is-error@npm:^2.2.2":
- version: 2.2.2
- resolution: "is-error@npm:2.2.2"
- checksum: 10c0/475d3463968bf16e94485555d7cb7a879ed68685e08d365a3370972e626054f1846ebbb3934403091e06682445568601fe919e41646096e5007952d0c1f4fd9b
- languageName: node
- linkType: hard
-
-"is-extglob@npm:^2.1.1":
- version: 2.1.1
- resolution: "is-extglob@npm:2.1.1"
- checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912
- languageName: node
- linkType: hard
-
-"is-fullwidth-code-point@npm:^3.0.0":
- version: 3.0.0
- resolution: "is-fullwidth-code-point@npm:3.0.0"
- checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc
- languageName: node
- linkType: hard
-
-"is-fullwidth-code-point@npm:^4.0.0":
- version: 4.0.0
- resolution: "is-fullwidth-code-point@npm:4.0.0"
- checksum: 10c0/df2a717e813567db0f659c306d61f2f804d480752526886954a2a3e2246c7745fd07a52b5fecf2b68caf0a6c79dcdace6166fdf29cc76ed9975cc334f0a018b8
- languageName: node
- linkType: hard
-
-"is-glob@npm:^4.0.1, is-glob@npm:~4.0.1":
- version: 4.0.3
- resolution: "is-glob@npm:4.0.3"
- dependencies:
- is-extglob: "npm:^2.1.1"
- checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a
- languageName: node
- linkType: hard
-
-"is-interactive@npm:^1.0.0":
- version: 1.0.0
- resolution: "is-interactive@npm:1.0.0"
- checksum: 10c0/dd47904dbf286cd20aa58c5192161be1a67138485b9836d5a70433b21a45442e9611b8498b8ab1f839fc962c7620667a50535fdfb4a6bc7989b8858645c06b4d
- languageName: node
- linkType: hard
-
-"is-lambda@npm:^1.0.1":
- version: 1.0.1
- resolution: "is-lambda@npm:1.0.1"
- checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d
- languageName: node
- linkType: hard
-
-"is-module@npm:^1.0.0":
- version: 1.0.0
- resolution: "is-module@npm:1.0.0"
- checksum: 10c0/795a3914bcae7c26a1c23a1e5574c42eac13429625045737bf3e324ce865c0601d61aee7a5afbca1bee8cb300c7d9647e7dc98860c9bdbc3b7fdc51d8ac0bffc
- languageName: node
- linkType: hard
-
-"is-number@npm:^7.0.0":
- version: 7.0.0
- resolution: "is-number@npm:7.0.0"
- checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811
- languageName: node
- linkType: hard
-
-"is-plain-object@npm:^5.0.0":
- version: 5.0.0
- resolution: "is-plain-object@npm:5.0.0"
- checksum: 10c0/893e42bad832aae3511c71fd61c0bf61aa3a6d853061c62a307261842727d0d25f761ce9379f7ba7226d6179db2a3157efa918e7fe26360f3bf0842d9f28942c
- languageName: node
- linkType: hard
-
-"is-promise@npm:^4.0.0":
- version: 4.0.0
- resolution: "is-promise@npm:4.0.0"
- checksum: 10c0/ebd5c672d73db781ab33ccb155fb9969d6028e37414d609b115cc534654c91ccd061821d5b987eefaa97cf4c62f0b909bb2f04db88306de26e91bfe8ddc01503
- languageName: node
- linkType: hard
-
-"is-reference@npm:^1.2.1":
- version: 1.2.1
- resolution: "is-reference@npm:1.2.1"
- dependencies:
- "@types/estree": "npm:*"
- checksum: 10c0/7dc819fc8de7790264a0a5d531164f9f5b9ef5aa1cd05f35322d14db39c8a2ec78fd5d4bf57f9789f3ddd2b3abeea7728432b759636157a42db12a9e8c3b549b
- languageName: node
- linkType: hard
-
-"is-stream@npm:^2.0.0":
- version: 2.0.1
- resolution: "is-stream@npm:2.0.1"
- checksum: 10c0/7c284241313fc6efc329b8d7f08e16c0efeb6baab1b4cd0ba579eb78e5af1aa5da11e68559896a2067cd6c526bd29241dda4eb1225e627d5aa1a89a76d4635a5
- languageName: node
- linkType: hard
-
-"is-stream@npm:^3.0.0":
- version: 3.0.0
- resolution: "is-stream@npm:3.0.0"
- checksum: 10c0/eb2f7127af02ee9aa2a0237b730e47ac2de0d4e76a4a905a50a11557f2339df5765eaea4ceb8029f1efa978586abe776908720bfcb1900c20c6ec5145f6f29d8
- languageName: node
- linkType: hard
-
-"is-unicode-supported@npm:^0.1.0":
- version: 0.1.0
- resolution: "is-unicode-supported@npm:0.1.0"
- checksum: 10c0/00cbe3455c3756be68d2542c416cab888aebd5012781d6819749fefb15162ff23e38501fe681b3d751c73e8ff561ac09a5293eba6f58fdf0178462ce6dcb3453
- languageName: node
- linkType: hard
-
-"is-unicode-supported@npm:^1.2.0":
- version: 1.3.0
- resolution: "is-unicode-supported@npm:1.3.0"
- checksum: 10c0/b8674ea95d869f6faabddc6a484767207058b91aea0250803cbf1221345cb0c56f466d4ecea375dc77f6633d248d33c47bd296fb8f4cdba0b4edba8917e83d8a
- languageName: node
- linkType: hard
-
-"isarray@npm:^2.0.5":
- version: 2.0.5
- resolution: "isarray@npm:2.0.5"
- checksum: 10c0/4199f14a7a13da2177c66c31080008b7124331956f47bca57dd0b6ea9f11687aa25e565a2c7a2b519bc86988d10398e3049a1f5df13c9f6b7664154690ae79fd
- languageName: node
- linkType: hard
-
-"isexe@npm:^2.0.0":
- version: 2.0.0
- resolution: "isexe@npm:2.0.0"
- checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d
- languageName: node
- linkType: hard
-
-"isexe@npm:^3.1.1":
- version: 3.1.1
- resolution: "isexe@npm:3.1.1"
- checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7
- languageName: node
- linkType: hard
-
-"isomorphic-ws@npm:^4.0.1":
- version: 4.0.1
- resolution: "isomorphic-ws@npm:4.0.1"
- peerDependencies:
- ws: "*"
- checksum: 10c0/7cb90dc2f0eb409825558982fb15d7c1d757a88595efbab879592f9d2b63820d6bbfb5571ab8abe36c715946e165a413a99f6aafd9f40ab1f514d73487bc9996
- languageName: node
- linkType: hard
-
-"jackspeak@npm:^2.3.5":
- version: 2.3.6
- resolution: "jackspeak@npm:2.3.6"
- dependencies:
- "@isaacs/cliui": "npm:^8.0.2"
- "@pkgjs/parseargs": "npm:^0.11.0"
- dependenciesMeta:
- "@pkgjs/parseargs":
- optional: true
- checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111
- languageName: node
- linkType: hard
-
-"jessie.js@npm:^0.3.2":
- version: 0.3.4
- resolution: "jessie.js@npm:0.3.4"
- dependencies:
- "@endo/far": "npm:^1.0.0"
- checksum: 10c0/853ab3f8a0e30df11742882f5e11479d1303033a5a203a247d8ffbf4c6f3f3d4bcbefa53084ae4632e6ab106e348f23dc988280486cbeaaf5d16487fa3d40e96
- languageName: node
- linkType: hard
-
-"js-string-escape@npm:^1.0.1":
- version: 1.0.1
- resolution: "js-string-escape@npm:1.0.1"
- checksum: 10c0/2c33b9ff1ba6b84681c51ca0997e7d5a1639813c95d5b61cb7ad47e55cc28fa4a0b1935c3d218710d8e6bcee5d0cd8c44755231e3a4e45fc604534d9595a3628
- languageName: node
- linkType: hard
-
-"js-tokens@npm:^4.0.0":
- version: 4.0.0
- resolution: "js-tokens@npm:4.0.0"
- checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed
- languageName: node
- linkType: hard
-
-"js-yaml@npm:4.0.0":
- version: 4.0.0
- resolution: "js-yaml@npm:4.0.0"
- dependencies:
- argparse: "npm:^2.0.1"
- bin:
- js-yaml: bin/js-yaml.js
- checksum: 10c0/ef8489b87d9796b45df9f0bf3eefbb343b5063e39a9911d7b8ddbd4518cafaf73b49150d1f5865f54ee68719642ff0ab86110b9a332ff88bb05cd3bcf3039de1
- languageName: node
- linkType: hard
-
-"js-yaml@npm:^3.14.1":
- version: 3.14.1
- resolution: "js-yaml@npm:3.14.1"
- dependencies:
- argparse: "npm:^1.0.7"
- esprima: "npm:^4.0.0"
- bin:
- js-yaml: bin/js-yaml.js
- checksum: 10c0/6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b
- languageName: node
- linkType: hard
-
-"jsesc@npm:^2.5.1":
- version: 2.5.2
- resolution: "jsesc@npm:2.5.2"
- bin:
- jsesc: bin/jsesc
- checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88
- languageName: node
- linkType: hard
-
-"json-schema-traverse@npm:^1.0.0":
- version: 1.0.0
- resolution: "json-schema-traverse@npm:1.0.0"
- checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6
- languageName: node
- linkType: hard
-
-"json-stable-stringify@npm:^1.0.1":
- version: 1.1.1
- resolution: "json-stable-stringify@npm:1.1.1"
- dependencies:
- call-bind: "npm:^1.0.5"
- isarray: "npm:^2.0.5"
- jsonify: "npm:^0.0.1"
- object-keys: "npm:^1.1.1"
- checksum: 10c0/3801e3eeccbd030afb970f54bea690a079cfea7d9ed206a1b17ca9367f4b7772c764bf77a48f03e56b50e5f7ee7d11c52339fe20d8d7ccead003e4ca69e4cfde
- languageName: node
- linkType: hard
-
-"jsonify@npm:^0.0.1":
- version: 0.0.1
- resolution: "jsonify@npm:0.0.1"
- checksum: 10c0/7f5499cdd59a0967ed35bda48b7cec43d850bbc8fb955cdd3a1717bb0efadbe300724d5646de765bb7a99fc1c3ab06eb80d93503c6faaf99b4ff50a3326692f6
- languageName: node
- linkType: hard
-
-"kuler@npm:^2.0.0":
- version: 2.0.0
- resolution: "kuler@npm:2.0.0"
- checksum: 10c0/0a4e99d92ca373f8f74d1dc37931909c4d0d82aebc94cf2ba265771160fc12c8df34eaaac80805efbda367e2795cb1f1dd4c3d404b6b1cf38aec94035b503d2d
- languageName: node
- linkType: hard
-
-"libsodium-sumo@npm:^0.7.13":
- version: 0.7.13
- resolution: "libsodium-sumo@npm:0.7.13"
- checksum: 10c0/8159205cc36cc4bdf46ee097e5f998d5cac7d11612be7406a8396ca3ee31560871ac17daa69e47ff0e8407eeae9f49313912ea95dbc8715875301b004c28ef5b
- languageName: node
- linkType: hard
-
-"libsodium-wrappers-sumo@npm:^0.7.11":
- version: 0.7.13
- resolution: "libsodium-wrappers-sumo@npm:0.7.13"
- dependencies:
- libsodium-sumo: "npm:^0.7.13"
- checksum: 10c0/51a151d0f73418632dcf9cf0184b14d8eb6e16b9a3f01a652c7401c6d1bf8ead4f5ce40a4f00bd4754c5719a7a5fb71d6125691896aeb7a9c1abcfe4b73afc02
- languageName: node
- linkType: hard
-
-"load-json-file@npm:^7.0.0":
- version: 7.0.1
- resolution: "load-json-file@npm:7.0.1"
- checksum: 10c0/7117459608a0b6329c7f78e6e1f541b3162dd901c29dd5af721fec8b270177d2e3d7999c971f344fff04daac368d052732e2c7146014bc84d15e0b636975e19a
- languageName: node
- linkType: hard
-
-"locate-path@npm:^7.1.0":
- version: 7.2.0
- resolution: "locate-path@npm:7.2.0"
- dependencies:
- p-locate: "npm:^6.0.0"
- checksum: 10c0/139e8a7fe11cfbd7f20db03923cacfa5db9e14fa14887ea121345597472b4a63c1a42a8a5187defeeff6acf98fd568da7382aa39682d38f0af27433953a97751
- languageName: node
- linkType: hard
-
-"lodash.truncate@npm:^4.4.2":
- version: 4.4.2
- resolution: "lodash.truncate@npm:4.4.2"
- checksum: 10c0/4e870d54e8a6c86c8687e057cec4069d2e941446ccab7f40b4d9555fa5872d917d0b6aa73bece7765500a3123f1723bcdba9ae881b679ef120bba9e1a0b0ed70
- languageName: node
- linkType: hard
-
-"lodash@npm:4.17.21, lodash@npm:^4.17.15, lodash@npm:^4.17.21":
- version: 4.17.21
- resolution: "lodash@npm:4.17.21"
- checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c
- languageName: node
- linkType: hard
-
-"log-symbols@npm:^4.1.0":
- version: 4.1.0
- resolution: "log-symbols@npm:4.1.0"
- dependencies:
- chalk: "npm:^4.1.0"
- is-unicode-supported: "npm:^0.1.0"
- checksum: 10c0/67f445a9ffa76db1989d0fa98586e5bc2fd5247260dafb8ad93d9f0ccd5896d53fb830b0e54dade5ad838b9de2006c826831a3c528913093af20dff8bd24aca6
- languageName: node
- linkType: hard
-
-"logform@npm:^2.2.0, logform@npm:^2.3.2":
- version: 2.6.0
- resolution: "logform@npm:2.6.0"
- dependencies:
- "@colors/colors": "npm:1.6.0"
- "@types/triple-beam": "npm:^1.3.2"
- fecha: "npm:^4.2.0"
- ms: "npm:^2.1.1"
- safe-stable-stringify: "npm:^2.3.1"
- triple-beam: "npm:^1.3.0"
- checksum: 10c0/6e02f8617a03155b2fce451bacf777a2c01da16d32c4c745b3ec85be6c3f2602f2a4953a8bd096441cb4c42c447b52318541d6b6bc335dce903cb9ad77a1749f
- languageName: node
- linkType: hard
-
-"long@npm:^4.0.0":
- version: 4.0.0
- resolution: "long@npm:4.0.0"
- checksum: 10c0/50a6417d15b06104dbe4e3d4a667c39b137f130a9108ea8752b352a4cfae047531a3ac351c181792f3f8768fe17cca6b0f406674a541a86fb638aaac560d83ed
- languageName: node
- linkType: hard
-
-"lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0":
- version: 10.2.0
- resolution: "lru-cache@npm:10.2.0"
- checksum: 10c0/c9847612aa2daaef102d30542a8d6d9b2c2bb36581c1bf0dc3ebf5e5f3352c772a749e604afae2e46873b930a9e9523743faac4e5b937c576ab29196774712ee
- languageName: node
- linkType: hard
-
-"lru-cache@npm:^6.0.0":
- version: 6.0.0
- resolution: "lru-cache@npm:6.0.0"
- dependencies:
- yallist: "npm:^4.0.0"
- checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9
- languageName: node
- linkType: hard
-
-"magic-string@npm:^0.25.7":
- version: 0.25.9
- resolution: "magic-string@npm:0.25.9"
- dependencies:
- sourcemap-codec: "npm:^1.4.8"
- checksum: 10c0/37f5e01a7e8b19a072091f0b45ff127cda676232d373ce2c551a162dd4053c575ec048b9cbb4587a1f03adb6c5d0fd0dd49e8ab070cd2c83a4992b2182d9cb56
- languageName: node
- linkType: hard
-
-"make-fetch-happen@npm:^13.0.0":
- version: 13.0.0
- resolution: "make-fetch-happen@npm:13.0.0"
- dependencies:
- "@npmcli/agent": "npm:^2.0.0"
- cacache: "npm:^18.0.0"
- http-cache-semantics: "npm:^4.1.1"
- is-lambda: "npm:^1.0.1"
- minipass: "npm:^7.0.2"
- minipass-fetch: "npm:^3.0.0"
- minipass-flush: "npm:^1.0.5"
- minipass-pipeline: "npm:^1.2.4"
- negotiator: "npm:^0.6.3"
- promise-retry: "npm:^2.0.1"
- ssri: "npm:^10.0.0"
- checksum: 10c0/43b9f6dcbc6fe8b8604cb6396957c3698857a15ba4dbc38284f7f0e61f248300585ef1eb8cc62df54e9c724af977e45b5cdfd88320ef7f53e45070ed3488da55
- languageName: node
- linkType: hard
-
-"map-age-cleaner@npm:^0.1.3":
- version: 0.1.3
- resolution: "map-age-cleaner@npm:0.1.3"
- dependencies:
- p-defer: "npm:^1.0.0"
- checksum: 10c0/7495236c7b0950956c144fd8b4bc6399d4e78072a8840a4232fe1c4faccbb5eb5d842e5c0a56a60afc36d723f315c1c672325ca03c1b328650f7fcc478f385fd
- languageName: node
- linkType: hard
-
-"matcher@npm:^5.0.0":
- version: 5.0.0
- resolution: "matcher@npm:5.0.0"
- dependencies:
- escape-string-regexp: "npm:^5.0.0"
- checksum: 10c0/eda5471fc9d5b7264d63c81727824adc3585ddb5cfdc5fce5a9b7c86f946ff181610735d330b1c37a84811df872d1290bf4e9401d2be2a414204343701144b18
- languageName: node
- linkType: hard
-
-"md5-hex@npm:^3.0.1":
- version: 3.0.1
- resolution: "md5-hex@npm:3.0.1"
- dependencies:
- blueimp-md5: "npm:^2.10.0"
- checksum: 10c0/ee2b4d8da16b527b3a3fe4d7a96720f43afd07b46a82d49421208b5a126235fb75cfb30b80d4029514772c8844273f940bddfbf4155c787f968f3be4060d01e4
- languageName: node
- linkType: hard
-
-"mem@npm:^9.0.2":
- version: 9.0.2
- resolution: "mem@npm:9.0.2"
- dependencies:
- map-age-cleaner: "npm:^0.1.3"
- mimic-fn: "npm:^4.0.0"
- checksum: 10c0/c2c56141399e520d8f0e50186bb7e4b49300b33984dc919682f3f13e53dec0e6608fbd327d5ae99494f45061a3a05a8ee04ccba6dcf795c3c215b5aa906eb41f
- languageName: node
- linkType: hard
-
-"merge-stream@npm:^2.0.0":
- version: 2.0.0
- resolution: "merge-stream@npm:2.0.0"
- checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5
- languageName: node
- linkType: hard
-
-"merge2@npm:^1.3.0, merge2@npm:^1.4.1":
- version: 1.4.1
- resolution: "merge2@npm:1.4.1"
- checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb
- languageName: node
- linkType: hard
-
-"micromatch@npm:^4.0.4":
- version: 4.0.5
- resolution: "micromatch@npm:4.0.5"
- dependencies:
- braces: "npm:^3.0.2"
- picomatch: "npm:^2.3.1"
- checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff
- languageName: node
- linkType: hard
-
-"microtime@npm:^3.1.0":
- version: 3.1.1
- resolution: "microtime@npm:3.1.1"
- dependencies:
- node-addon-api: "npm:^5.0.0"
- node-gyp: "npm:latest"
- node-gyp-build: "npm:^4.4.0"
- checksum: 10c0/02512993de914c6f71424d3b8b28ce53de44ba5895b904a213420fd4fc86a084c1d08ec0876ac60cdae6427022766e1b9b86d9b3442bf408701120bd61455e26
- languageName: node
- linkType: hard
-
-"mime-db@npm:1.52.0":
- version: 1.52.0
- resolution: "mime-db@npm:1.52.0"
- checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa
- languageName: node
- linkType: hard
-
-"mime-types@npm:^2.1.12":
- version: 2.1.35
- resolution: "mime-types@npm:2.1.35"
- dependencies:
- mime-db: "npm:1.52.0"
- checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2
- languageName: node
- linkType: hard
-
-"mimic-fn@npm:^2.1.0":
- version: 2.1.0
- resolution: "mimic-fn@npm:2.1.0"
- checksum: 10c0/b26f5479d7ec6cc2bce275a08f146cf78f5e7b661b18114e2506dd91ec7ec47e7a25bf4360e5438094db0560bcc868079fb3b1fb3892b833c1ecbf63f80c95a4
- languageName: node
- linkType: hard
-
-"mimic-fn@npm:^4.0.0":
- version: 4.0.0
- resolution: "mimic-fn@npm:4.0.0"
- checksum: 10c0/de9cc32be9996fd941e512248338e43407f63f6d497abe8441fa33447d922e927de54d4cc3c1a3c6d652857acd770389d5a3823f311a744132760ce2be15ccbf
- languageName: node
- linkType: hard
-
-"mimic-response@npm:^3.1.0":
- version: 3.1.0
- resolution: "mimic-response@npm:3.1.0"
- checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362
- languageName: node
- linkType: hard
-
-"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1":
- version: 1.0.1
- resolution: "minimalistic-assert@npm:1.0.1"
- checksum: 10c0/96730e5601cd31457f81a296f521eb56036e6f69133c0b18c13fe941109d53ad23a4204d946a0d638d7f3099482a0cec8c9bb6d642604612ce43ee536be3dddd
- languageName: node
- linkType: hard
-
-"minimalistic-crypto-utils@npm:^1.0.1":
- version: 1.0.1
- resolution: "minimalistic-crypto-utils@npm:1.0.1"
- checksum: 10c0/790ecec8c5c73973a4fbf2c663d911033e8494d5fb0960a4500634766ab05d6107d20af896ca2132e7031741f19888154d44b2408ada0852446705441383e9f8
- languageName: node
- linkType: hard
-
-"minimatch@npm:^3.1.1":
- version: 3.1.2
- resolution: "minimatch@npm:3.1.2"
- dependencies:
- brace-expansion: "npm:^1.1.7"
- checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311
- languageName: node
- linkType: hard
-
-"minimatch@npm:^9.0.1":
- version: 9.0.3
- resolution: "minimatch@npm:9.0.3"
- dependencies:
- brace-expansion: "npm:^2.0.1"
- checksum: 10c0/85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac
- languageName: node
- linkType: hard
-
-"minimist@npm:^1.2.0, minimist@npm:^1.2.3":
- version: 1.2.8
- resolution: "minimist@npm:1.2.8"
- checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6
- languageName: node
- linkType: hard
-
-"minipass-collect@npm:^2.0.1":
- version: 2.0.1
- resolution: "minipass-collect@npm:2.0.1"
- dependencies:
- minipass: "npm:^7.0.3"
- checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e
- languageName: node
- linkType: hard
-
-"minipass-fetch@npm:^3.0.0":
- version: 3.0.4
- resolution: "minipass-fetch@npm:3.0.4"
- dependencies:
- encoding: "npm:^0.1.13"
- minipass: "npm:^7.0.3"
- minipass-sized: "npm:^1.0.3"
- minizlib: "npm:^2.1.2"
- dependenciesMeta:
- encoding:
- optional: true
- checksum: 10c0/1b63c1f3313e88eeac4689f1b71c9f086598db9a189400e3ee960c32ed89e06737fa23976c9305c2d57464fb3fcdc12749d3378805c9d6176f5569b0d0ee8a75
- languageName: node
- linkType: hard
-
-"minipass-flush@npm:^1.0.5":
- version: 1.0.5
- resolution: "minipass-flush@npm:1.0.5"
- dependencies:
- minipass: "npm:^3.0.0"
- checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd
- languageName: node
- linkType: hard
-
-"minipass-pipeline@npm:^1.2.4":
- version: 1.2.4
- resolution: "minipass-pipeline@npm:1.2.4"
- dependencies:
- minipass: "npm:^3.0.0"
- checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2
- languageName: node
- linkType: hard
-
-"minipass-sized@npm:^1.0.3":
- version: 1.0.3
- resolution: "minipass-sized@npm:1.0.3"
- dependencies:
- minipass: "npm:^3.0.0"
- checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb
- languageName: node
- linkType: hard
-
-"minipass@npm:^3.0.0":
- version: 3.3.6
- resolution: "minipass@npm:3.3.6"
- dependencies:
- yallist: "npm:^4.0.0"
- checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c
- languageName: node
- linkType: hard
-
-"minipass@npm:^5.0.0":
- version: 5.0.0
- resolution: "minipass@npm:5.0.0"
- checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462
- languageName: node
- linkType: hard
-
-"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3":
- version: 7.0.4
- resolution: "minipass@npm:7.0.4"
- checksum: 10c0/6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5
- languageName: node
- linkType: hard
-
-"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2":
- version: 2.1.2
- resolution: "minizlib@npm:2.1.2"
- dependencies:
- minipass: "npm:^3.0.0"
- yallist: "npm:^4.0.0"
- checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78
- languageName: node
- linkType: hard
-
-"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3":
- version: 0.5.3
- resolution: "mkdirp-classic@npm:0.5.3"
- checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168
- languageName: node
- linkType: hard
-
-"mkdirp@npm:^1.0.3":
- version: 1.0.4
- resolution: "mkdirp@npm:1.0.4"
- bin:
- mkdirp: bin/cmd.js
- checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf
- languageName: node
- linkType: hard
-
-"ms@npm:2.1.2":
- version: 2.1.2
- resolution: "ms@npm:2.1.2"
- checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc
- languageName: node
- linkType: hard
-
-"ms@npm:^2.1.1, ms@npm:^2.1.3":
- version: 2.1.3
- resolution: "ms@npm:2.1.3"
- checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
- languageName: node
- linkType: hard
-
-"mute-stream@npm:0.0.8":
- version: 0.0.8
- resolution: "mute-stream@npm:0.0.8"
- checksum: 10c0/18d06d92e5d6d45e2b63c0e1b8f25376af71748ac36f53c059baa8b76ffac31c5ab225480494e7d35d30215ecdb18fed26ec23cafcd2f7733f2f14406bcd19e2
- languageName: node
- linkType: hard
-
-"n-readlines@npm:^1.0.0":
- version: 1.0.3
- resolution: "n-readlines@npm:1.0.3"
- checksum: 10c0/436c27ac071409314093da35dc3a4c5198c94fb10ad12b1c4d2b3e44bdb634da0a7a8ab0c107c1f4815788cbf5e0c7c180e3037ba3d974f34637cab363a95a74
- languageName: node
- linkType: hard
-
-"napi-build-utils@npm:^1.0.1":
- version: 1.0.2
- resolution: "napi-build-utils@npm:1.0.2"
- checksum: 10c0/37fd2cd0ff2ad20073ce78d83fd718a740d568b225924e753ae51cb69d68f330c80544d487e5e5bd18e28702ed2ca469c2424ad948becd1862c1b0209542b2e9
- languageName: node
- linkType: hard
-
-"negotiator@npm:^0.6.3":
- version: 0.6.3
- resolution: "negotiator@npm:0.6.3"
- checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2
- languageName: node
- linkType: hard
-
-"node-abi@npm:^3.3.0":
- version: 3.54.0
- resolution: "node-abi@npm:3.54.0"
- dependencies:
- semver: "npm:^7.3.5"
- checksum: 10c0/9ebbb21e6951aa51e831549ed62b68dc56bcc10f6b21ffd04195a16a6abf5ddfc48b6ae5e3334720fe4459cafde5ec8103025902efff5599d0539f8656fc694e
- languageName: node
- linkType: hard
-
-"node-addon-api@npm:^5.0.0":
- version: 5.1.0
- resolution: "node-addon-api@npm:5.1.0"
- dependencies:
- node-gyp: "npm:latest"
- checksum: 10c0/0eb269786124ba6fad9df8007a149e03c199b3e5a3038125dfb3e747c2d5113d406a4e33f4de1ea600aa2339be1f137d55eba1a73ee34e5fff06c52a5c296d1d
- languageName: node
- linkType: hard
-
-"node-domexception@npm:^1.0.0":
- version: 1.0.0
- resolution: "node-domexception@npm:1.0.0"
- checksum: 10c0/5e5d63cda29856402df9472335af4bb13875e1927ad3be861dc5ebde38917aecbf9ae337923777af52a48c426b70148815e890a5d72760f1b4d758cc671b1a2b
- languageName: node
- linkType: hard
-
-"node-fetch@npm:^2.6.0":
- version: 2.7.0
- resolution: "node-fetch@npm:2.7.0"
- dependencies:
- whatwg-url: "npm:^5.0.0"
- peerDependencies:
- encoding: ^0.1.0
- peerDependenciesMeta:
- encoding:
- optional: true
- checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8
- languageName: node
- linkType: hard
-
-"node-fetch@npm:^3.3.2":
- version: 3.3.2
- resolution: "node-fetch@npm:3.3.2"
- dependencies:
- data-uri-to-buffer: "npm:^4.0.0"
- fetch-blob: "npm:^3.1.4"
- formdata-polyfill: "npm:^4.0.10"
- checksum: 10c0/f3d5e56190562221398c9f5750198b34cf6113aa304e34ee97c94fd300ec578b25b2c2906edba922050fce983338fde0d5d34fcb0fc3336ade5bd0e429ad7538
- languageName: node
- linkType: hard
-
-"node-gyp-build@npm:^4.4.0":
- version: 4.8.1
- resolution: "node-gyp-build@npm:4.8.1"
- bin:
- node-gyp-build: bin.js
- node-gyp-build-optional: optional.js
- node-gyp-build-test: build-test.js
- checksum: 10c0/e36ca3d2adf2b9cca316695d7687207c19ac6ed326d6d7c68d7112cebe0de4f82d6733dff139132539fcc01cf5761f6c9082a21864ab9172edf84282bc849ce7
- languageName: node
- linkType: hard
-
-"node-gyp@npm:latest":
- version: 10.0.1
- resolution: "node-gyp@npm:10.0.1"
- dependencies:
- env-paths: "npm:^2.2.0"
- exponential-backoff: "npm:^3.1.1"
- glob: "npm:^10.3.10"
- graceful-fs: "npm:^4.2.6"
- make-fetch-happen: "npm:^13.0.0"
- nopt: "npm:^7.0.0"
- proc-log: "npm:^3.0.0"
- semver: "npm:^7.3.5"
- tar: "npm:^6.1.2"
- which: "npm:^4.0.0"
- bin:
- node-gyp: bin/node-gyp.js
- checksum: 10c0/abddfff7d873312e4ed4a5fb75ce893a5c4fb69e7fcb1dfa71c28a6b92a7f1ef6b62790dffb39181b5a82728ba8f2f32d229cf8cbe66769fe02cea7db4a555aa
- languageName: node
- linkType: hard
-
-"nofilter@npm:^3.1.0":
- version: 3.1.0
- resolution: "nofilter@npm:3.1.0"
- checksum: 10c0/92459f3864a067b347032263f0b536223cbfc98153913b5dce350cb39c8470bc1813366e41993f22c33cc6400c0f392aa324a4b51e24c22040635c1cdb046499
- languageName: node
- linkType: hard
-
-"nopt@npm:^7.0.0":
- version: 7.2.0
- resolution: "nopt@npm:7.2.0"
- dependencies:
- abbrev: "npm:^2.0.0"
- bin:
- nopt: bin/nopt.js
- checksum: 10c0/9bd7198df6f16eb29ff16892c77bcf7f0cc41f9fb5c26280ac0def2cf8cf319f3b821b3af83eba0e74c85807cc430a16efe0db58fe6ae1f41e69519f585b6aff
- languageName: node
- linkType: hard
-
-"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
- version: 3.0.0
- resolution: "normalize-path@npm:3.0.0"
- checksum: 10c0/e008c8142bcc335b5e38cf0d63cfd39d6cf2d97480af9abdbe9a439221fd4d749763bab492a8ee708ce7a194bb00c9da6d0a115018672310850489137b3da046
- languageName: node
- linkType: hard
-
-"npm-run-path@npm:^5.1.0":
- version: 5.2.0
- resolution: "npm-run-path@npm:5.2.0"
- dependencies:
- path-key: "npm:^4.0.0"
- checksum: 10c0/7963c1f98e42afebe9524a08b0881477ec145aab34f6018842a315422b25ad40e015bdee709b697571e5efda2ecfa2640ee917d92674e4de1166fa3532a211b1
- languageName: node
- linkType: hard
-
-"object-keys@npm:^1.1.1":
- version: 1.1.1
- resolution: "object-keys@npm:1.1.1"
- checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d
- languageName: node
- linkType: hard
-
-"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
- version: 1.4.0
- resolution: "once@npm:1.4.0"
- dependencies:
- wrappy: "npm:1"
- checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0
- languageName: node
- linkType: hard
-
-"one-time@npm:^1.0.0":
- version: 1.0.0
- resolution: "one-time@npm:1.0.0"
- dependencies:
- fn.name: "npm:1.x.x"
- checksum: 10c0/6e4887b331edbb954f4e915831cbec0a7b9956c36f4feb5f6de98c448ac02ff881fd8d9b55a6b1b55030af184c6b648f340a76eb211812f4ad8c9b4b8692fdaa
- languageName: node
- linkType: hard
-
-"onetime@npm:^5.1.0":
- version: 5.1.2
- resolution: "onetime@npm:5.1.2"
- dependencies:
- mimic-fn: "npm:^2.1.0"
- checksum: 10c0/ffcef6fbb2692c3c40749f31ea2e22677a876daea92959b8a80b521d95cca7a668c884d8b2045d1d8ee7d56796aa405c405462af112a1477594cc63531baeb8f
- languageName: node
- linkType: hard
-
-"onetime@npm:^6.0.0":
- version: 6.0.0
- resolution: "onetime@npm:6.0.0"
- dependencies:
- mimic-fn: "npm:^4.0.0"
- checksum: 10c0/4eef7c6abfef697dd4479345a4100c382d73c149d2d56170a54a07418c50816937ad09500e1ed1e79d235989d073a9bade8557122aee24f0576ecde0f392bb6c
- languageName: node
- linkType: hard
-
-"opener@npm:^1.5.2":
- version: 1.5.2
- resolution: "opener@npm:1.5.2"
- bin:
- opener: bin/opener-bin.js
- checksum: 10c0/dd56256ab0cf796585617bc28e06e058adf09211781e70b264c76a1dbe16e90f868c974e5bf5309c93469157c7d14b89c35dc53fe7293b0e40b4d2f92073bc79
- languageName: node
- linkType: hard
-
-"ora@npm:^5.4.1":
- version: 5.4.1
- resolution: "ora@npm:5.4.1"
- dependencies:
- bl: "npm:^4.1.0"
- chalk: "npm:^4.1.0"
- cli-cursor: "npm:^3.1.0"
- cli-spinners: "npm:^2.5.0"
- is-interactive: "npm:^1.0.0"
- is-unicode-supported: "npm:^0.1.0"
- log-symbols: "npm:^4.1.0"
- strip-ansi: "npm:^6.0.0"
- wcwidth: "npm:^1.0.1"
- checksum: 10c0/10ff14aace236d0e2f044193362b22edce4784add08b779eccc8f8ef97195cae1248db8ec1ec5f5ff076f91acbe573f5f42a98c19b78dba8c54eefff983cae85
- languageName: node
- linkType: hard
-
-"os-tmpdir@npm:~1.0.2":
- version: 1.0.2
- resolution: "os-tmpdir@npm:1.0.2"
- checksum: 10c0/f438450224f8e2687605a8dd318f0db694b6293c5d835ae509a69e97c8de38b6994645337e5577f5001115470414638978cc49da1cdcc25106dad8738dc69990
- languageName: node
- linkType: hard
-
-"p-defer@npm:^1.0.0":
- version: 1.0.0
- resolution: "p-defer@npm:1.0.0"
- checksum: 10c0/ed603c3790e74b061ac2cb07eb6e65802cf58dce0fbee646c113a7b71edb711101329ad38f99e462bd2e343a74f6e9366b496a35f1d766c187084d3109900487
- languageName: node
- linkType: hard
-
-"p-event@npm:^5.0.1":
- version: 5.0.1
- resolution: "p-event@npm:5.0.1"
- dependencies:
- p-timeout: "npm:^5.0.2"
- checksum: 10c0/2317171489537f316661fa863f3bb711b2ceb89182937238422cec10223cbb958c432d6c26a238446a622d788187bdd295b1d8ecedbe2e467e045930d60202b0
- languageName: node
- linkType: hard
-
-"p-limit@npm:^4.0.0":
- version: 4.0.0
- resolution: "p-limit@npm:4.0.0"
- dependencies:
- yocto-queue: "npm:^1.0.0"
- checksum: 10c0/a56af34a77f8df2ff61ddfb29431044557fcbcb7642d5a3233143ebba805fc7306ac1d448de724352861cb99de934bc9ab74f0d16fe6a5460bdbdf938de875ad
- languageName: node
- linkType: hard
-
-"p-locate@npm:^6.0.0":
- version: 6.0.0
- resolution: "p-locate@npm:6.0.0"
- dependencies:
- p-limit: "npm:^4.0.0"
- checksum: 10c0/d72fa2f41adce59c198270aa4d3c832536c87a1806e0f69dffb7c1a7ca998fb053915ca833d90f166a8c082d3859eabfed95f01698a3214c20df6bb8de046312
- languageName: node
- linkType: hard
-
-"p-map@npm:^4.0.0":
- version: 4.0.0
- resolution: "p-map@npm:4.0.0"
- dependencies:
- aggregate-error: "npm:^3.0.0"
- checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75
- languageName: node
- linkType: hard
-
-"p-map@npm:^5.5.0":
- version: 5.5.0
- resolution: "p-map@npm:5.5.0"
- dependencies:
- aggregate-error: "npm:^4.0.0"
- checksum: 10c0/410bce846b1e3db6bb2ccab6248372ecf4e635fc2b31331c8f56478e73fec9e146e8b4547585e635703160a3d252a6a65b8f855834aebc2c3408eb5789630cc4
- languageName: node
- linkType: hard
-
-"p-timeout@npm:^5.0.2":
- version: 5.1.0
- resolution: "p-timeout@npm:5.1.0"
- checksum: 10c0/1b026cf9d5878c64bec4341ca9cda8ec6b8b3aea8a57885ca0fe2b35753a20d767fb6f9d3aa41e1252f42bc95432c05ea33b6b18f271fb10bfb0789591850a41
- languageName: node
- linkType: hard
-
-"pako@npm:^2.0.2":
- version: 2.1.0
- resolution: "pako@npm:2.1.0"
- checksum: 10c0/8e8646581410654b50eb22a5dfd71159cae98145bd5086c9a7a816ec0370b5f72b4648d08674624b3870a521e6a3daffd6c2f7bc00fdefc7063c9d8232ff5116
- languageName: node
- linkType: hard
-
-"parse-ms@npm:^3.0.0":
- version: 3.0.0
- resolution: "parse-ms@npm:3.0.0"
- checksum: 10c0/056b4a32a9d3749f3f4cfffefb45c45540491deaa8e1d8ad43c2ddde7ba04edd076bd1b298f521238bb5fb084a9b2c4a2ebb78aefa651afbc4c2b0af4232fc54
- languageName: node
- linkType: hard
-
-"path-exists@npm:^5.0.0":
- version: 5.0.0
- resolution: "path-exists@npm:5.0.0"
- checksum: 10c0/b170f3060b31604cde93eefdb7392b89d832dfbc1bed717c9718cbe0f230c1669b7e75f87e19901da2250b84d092989a0f9e44d2ef41deb09aa3ad28e691a40a
- languageName: node
- linkType: hard
-
-"path-is-absolute@npm:^1.0.0":
- version: 1.0.1
- resolution: "path-is-absolute@npm:1.0.1"
- checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078
- languageName: node
- linkType: hard
-
-"path-key@npm:^3.1.0":
- version: 3.1.1
- resolution: "path-key@npm:3.1.1"
- checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c
- languageName: node
- linkType: hard
-
-"path-key@npm:^4.0.0":
- version: 4.0.0
- resolution: "path-key@npm:4.0.0"
- checksum: 10c0/794efeef32863a65ac312f3c0b0a99f921f3e827ff63afa5cb09a377e202c262b671f7b3832a4e64731003fa94af0263713962d317b9887bd1e0c48a342efba3
- languageName: node
- linkType: hard
-
-"path-parse@npm:^1.0.7":
- version: 1.0.7
- resolution: "path-parse@npm:1.0.7"
- checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1
- languageName: node
- linkType: hard
-
-"path-scurry@npm:^1.10.1":
- version: 1.10.1
- resolution: "path-scurry@npm:1.10.1"
- dependencies:
- lru-cache: "npm:^9.1.1 || ^10.0.0"
- minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0"
- checksum: 10c0/e5dc78a7348d25eec61ab166317e9e9c7b46818aa2c2b9006c507a6ff48c672d011292d9662527213e558f5652ce0afcc788663a061d8b59ab495681840c0c1e
- languageName: node
- linkType: hard
-
-"path-type@npm:^4.0.0":
- version: 4.0.0
- resolution: "path-type@npm:4.0.0"
- checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c
- languageName: node
- linkType: hard
-
-"picocolors@npm:^1.0.0":
- version: 1.0.1
- resolution: "picocolors@npm:1.0.1"
- checksum: 10c0/c63cdad2bf812ef0d66c8db29583802355d4ca67b9285d846f390cc15c2f6ccb94e8cb7eb6a6e97fc5990a6d3ad4ae42d86c84d3146e667c739a4234ed50d400
- languageName: node
- linkType: hard
-
-"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.3.1":
- version: 2.3.1
- resolution: "picomatch@npm:2.3.1"
- checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be
- languageName: node
- linkType: hard
-
-"pkg-conf@npm:^4.0.0":
- version: 4.0.0
- resolution: "pkg-conf@npm:4.0.0"
- dependencies:
- find-up: "npm:^6.0.0"
- load-json-file: "npm:^7.0.0"
- checksum: 10c0/27d027609f27228edcde121f6f707b4ba1f5488e95e98f2e58652ae4e99792081bd1de67d591f4a0f05b02c0b66d745591d49f82041cbc8d41e2238ef5d73eb4
- languageName: node
- linkType: hard
-
-"plur@npm:^5.1.0":
- version: 5.1.0
- resolution: "plur@npm:5.1.0"
- dependencies:
- irregular-plurals: "npm:^3.3.0"
- checksum: 10c0/26bb622b8545fcfd47bbf56fbcca66c08693708a232e403fa3589e00003c56c14231ac57c7588ca5db83ef4be1f61383402c4ea954000768f779f8aef6eb6da8
- languageName: node
- linkType: hard
-
-"prebuild-install@npm:^7.1.1":
- version: 7.1.1
- resolution: "prebuild-install@npm:7.1.1"
- dependencies:
- detect-libc: "npm:^2.0.0"
- expand-template: "npm:^2.0.3"
- github-from-package: "npm:0.0.0"
- minimist: "npm:^1.2.3"
- mkdirp-classic: "npm:^0.5.3"
- napi-build-utils: "npm:^1.0.1"
- node-abi: "npm:^3.3.0"
- pump: "npm:^3.0.0"
- rc: "npm:^1.2.7"
- simple-get: "npm:^4.0.0"
- tar-fs: "npm:^2.0.0"
- tunnel-agent: "npm:^0.6.0"
- bin:
- prebuild-install: bin.js
- checksum: 10c0/6dc70f36b0f4adcb2fe0ed38d874ab28b571fb1a9725d769e8ba3f64a15831e58462de09f3e6e64569bcc4a3e03b9328b56faa0d45fe10ae1574478814536c76
- languageName: node
- linkType: hard
-
-"pretty-ms@npm:^8.0.0":
- version: 8.0.0
- resolution: "pretty-ms@npm:8.0.0"
- dependencies:
- parse-ms: "npm:^3.0.0"
- checksum: 10c0/e960d633ecca45445cf5c6dffc0f5e4bef6744c92449ab0e8c6c704800675ab71e181c5e02ece5265e02137a33e313d3f3e355fbf8ea30b4b5b23de423329f8d
- languageName: node
- linkType: hard
-
-"proc-log@npm:^3.0.0":
- version: 3.0.0
- resolution: "proc-log@npm:3.0.0"
- checksum: 10c0/f66430e4ff947dbb996058f6fd22de2c66612ae1a89b097744e17fb18a4e8e7a86db99eda52ccf15e53f00b63f4ec0b0911581ff2aac0355b625c8eac509b0dc
- languageName: node
- linkType: hard
-
-"prom-client@npm:13.1.0":
- version: 13.1.0
- resolution: "prom-client@npm:13.1.0"
- dependencies:
- tdigest: "npm:^0.1.1"
- checksum: 10c0/0f117e044bdbc7e8fb3a926e16e0e76ff3fb308dbc98fdb084dfa16ad52a0b68cf6a79a31e907b1c4ac9009b1d50848e3e72fb36ed43893291148e1505844fc2
- languageName: node
- linkType: hard
-
-"promise-retry@npm:^2.0.1":
- version: 2.0.1
- resolution: "promise-retry@npm:2.0.1"
- dependencies:
- err-code: "npm:^2.0.2"
- retry: "npm:^0.12.0"
- checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96
- languageName: node
- linkType: hard
-
-"proper-lockfile@npm:^4.1.2":
- version: 4.1.2
- resolution: "proper-lockfile@npm:4.1.2"
- dependencies:
- graceful-fs: "npm:^4.2.4"
- retry: "npm:^0.12.0"
- signal-exit: "npm:^3.0.2"
- checksum: 10c0/2f265dbad15897a43110a02dae55105c04d356ec4ed560723dcb9f0d34bc4fb2f13f79bb930e7561be10278e2314db5aca2527d5d3dcbbdee5e6b331d1571f6d
- languageName: node
- linkType: hard
-
-"protobufjs@npm:^6.8.8":
- version: 6.11.4
- resolution: "protobufjs@npm:6.11.4"
- dependencies:
- "@protobufjs/aspromise": "npm:^1.1.2"
- "@protobufjs/base64": "npm:^1.1.2"
- "@protobufjs/codegen": "npm:^2.0.4"
- "@protobufjs/eventemitter": "npm:^1.1.0"
- "@protobufjs/fetch": "npm:^1.1.0"
- "@protobufjs/float": "npm:^1.0.2"
- "@protobufjs/inquire": "npm:^1.1.0"
- "@protobufjs/path": "npm:^1.1.2"
- "@protobufjs/pool": "npm:^1.1.0"
- "@protobufjs/utf8": "npm:^1.1.0"
- "@types/long": "npm:^4.0.1"
- "@types/node": "npm:>=13.7.0"
- long: "npm:^4.0.0"
- bin:
- pbjs: bin/pbjs
- pbts: bin/pbts
- checksum: 10c0/c244d7b9b6d3258193da5c0d1e558dfb47f208ae345e209f90ec45c9dca911b90fa17e937892a9a39a4136ab9886981aae9efdf6039f7baff4f7225f5eeb9812
- languageName: node
- linkType: hard
-
-"proxy-from-env@npm:^1.1.0":
- version: 1.1.0
- resolution: "proxy-from-env@npm:1.1.0"
- checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b
- languageName: node
- linkType: hard
-
-"pump@npm:^3.0.0":
- version: 3.0.0
- resolution: "pump@npm:3.0.0"
- dependencies:
- end-of-stream: "npm:^1.1.0"
- once: "npm:^1.3.1"
- checksum: 10c0/bbdeda4f747cdf47db97428f3a135728669e56a0ae5f354a9ac5b74556556f5446a46f720a8f14ca2ece5be9b4d5d23c346db02b555f46739934cc6c093a5478
- languageName: node
- linkType: hard
-
-"punycode@npm:^2.1.0":
- version: 2.3.1
- resolution: "punycode@npm:2.3.1"
- checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9
- languageName: node
- linkType: hard
-
-"pure-rand@npm:^6.1.0":
- version: 6.1.0
- resolution: "pure-rand@npm:6.1.0"
- checksum: 10c0/1abe217897bf74dcb3a0c9aba3555fe975023147b48db540aa2faf507aee91c03bf54f6aef0eb2bf59cc259a16d06b28eca37f0dc426d94f4692aeff02fb0e65
- languageName: node
- linkType: hard
-
-"queue-microtask@npm:^1.2.2":
- version: 1.2.3
- resolution: "queue-microtask@npm:1.2.3"
- checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102
- languageName: node
- linkType: hard
-
-"rc@npm:^1.2.7":
- version: 1.2.8
- resolution: "rc@npm:1.2.8"
- dependencies:
- deep-extend: "npm:^0.6.0"
- ini: "npm:~1.3.0"
- minimist: "npm:^1.2.0"
- strip-json-comments: "npm:~2.0.1"
- bin:
- rc: ./cli.js
- checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15
- languageName: node
- linkType: hard
-
-"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0":
- version: 3.6.2
- resolution: "readable-stream@npm:3.6.2"
- dependencies:
- inherits: "npm:^2.0.3"
- string_decoder: "npm:^1.1.1"
- util-deprecate: "npm:^1.0.1"
- checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7
- languageName: node
- linkType: hard
-
-"readdirp@npm:~3.6.0":
- version: 3.6.0
- resolution: "readdirp@npm:3.6.0"
- dependencies:
- picomatch: "npm:^2.2.1"
- checksum: 10c0/6fa848cf63d1b82ab4e985f4cf72bd55b7dcfd8e0a376905804e48c3634b7e749170940ba77b32804d5fe93b3cc521aa95a8d7e7d725f830da6d93f3669ce66b
- languageName: node
- linkType: hard
-
-"readonly-date@npm:^1.0.0":
- version: 1.0.0
- resolution: "readonly-date@npm:1.0.0"
- checksum: 10c0/7ab32bf19f6bfec102584a524fa79a289e6ede0bf20c80fd90ab309962e45b71d19dd0e3915dff6e81edf226f08fda65e890539b4aca74668921790b10471356
- languageName: node
- linkType: hard
-
-"require-directory@npm:^2.1.1":
- version: 2.1.1
- resolution: "require-directory@npm:2.1.1"
- checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99
- languageName: node
- linkType: hard
-
-"require-from-string@npm:^2.0.2":
- version: 2.0.2
- resolution: "require-from-string@npm:2.0.2"
- checksum: 10c0/aaa267e0c5b022fc5fd4eef49d8285086b15f2a1c54b28240fdf03599cbd9c26049fee3eab894f2e1f6ca65e513b030a7c264201e3f005601e80c49fb2937ce2
- languageName: node
- linkType: hard
-
-"resolve-cwd@npm:^3.0.0":
- version: 3.0.0
- resolution: "resolve-cwd@npm:3.0.0"
- dependencies:
- resolve-from: "npm:^5.0.0"
- checksum: 10c0/e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4
- languageName: node
- linkType: hard
-
-"resolve-from@npm:^5.0.0":
- version: 5.0.0
- resolution: "resolve-from@npm:5.0.0"
- checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2
- languageName: node
- linkType: hard
-
-"resolve@npm:^1.17.0, resolve@npm:^1.19.0":
- version: 1.22.8
- resolution: "resolve@npm:1.22.8"
- dependencies:
- is-core-module: "npm:^2.13.0"
- path-parse: "npm:^1.0.7"
- supports-preserve-symlinks-flag: "npm:^1.0.0"
- bin:
- resolve: bin/resolve
- checksum: 10c0/07e179f4375e1fd072cfb72ad66d78547f86e6196c4014b31cb0b8bb1db5f7ca871f922d08da0fbc05b94e9fd42206f819648fa3b5b873ebbc8e1dc68fec433a
- languageName: node
- linkType: hard
-
-"resolve@patch:resolve@npm%3A^1.17.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin":
- version: 1.22.8
- resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d"
- dependencies:
- is-core-module: "npm:^2.13.0"
- path-parse: "npm:^1.0.7"
- supports-preserve-symlinks-flag: "npm:^1.0.0"
- bin:
- resolve: bin/resolve
- checksum: 10c0/0446f024439cd2e50c6c8fa8ba77eaa8370b4180f401a96abf3d1ebc770ac51c1955e12764cde449fde3fff480a61f84388e3505ecdbab778f4bef5f8212c729
- languageName: node
- linkType: hard
-
-"restore-cursor@npm:^3.1.0":
- version: 3.1.0
- resolution: "restore-cursor@npm:3.1.0"
- dependencies:
- onetime: "npm:^5.1.0"
- signal-exit: "npm:^3.0.2"
- checksum: 10c0/8051a371d6aa67ff21625fa94e2357bd81ffdc96267f3fb0fc4aaf4534028343836548ef34c240ffa8c25b280ca35eb36be00b3cb2133fa4f51896d7e73c6b4f
- languageName: node
- linkType: hard
-
-"retry@npm:^0.12.0":
- version: 0.12.0
- resolution: "retry@npm:0.12.0"
- checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe
- languageName: node
- linkType: hard
-
-"reusify@npm:^1.0.4":
- version: 1.0.4
- resolution: "reusify@npm:1.0.4"
- checksum: 10c0/c19ef26e4e188f408922c46f7ff480d38e8dfc55d448310dfb518736b23ed2c4f547fb64a6ed5bdba92cd7e7ddc889d36ff78f794816d5e71498d645ef476107
- languageName: node
- linkType: hard
-
-"rollup@npm:^2.79.1":
- version: 2.79.1
- resolution: "rollup@npm:2.79.1"
- dependencies:
- fsevents: "npm:~2.3.2"
- dependenciesMeta:
- fsevents:
- optional: true
- bin:
- rollup: dist/bin/rollup
- checksum: 10c0/421418687f5dcd7324f4387f203c6bfc7118b7ace789e30f5da022471c43e037a76f5fd93837052754eeeae798a4fb266ac05ccee1e594406d912a59af98dde9
- languageName: node
- linkType: hard
-
-"root-workspace-0b6124@workspace:.":
- version: 0.0.0-use.local
- resolution: "root-workspace-0b6124@workspace:."
- dependencies:
- "@agoric/internal": "npm:0.3.3-dev-5676146.0"
- "@agoric/synthetic-chain": "npm:^0.1.0"
- "@cosmjs/stargate": "npm:^0.32.3"
- "@cosmjs/tendermint-rpc": "npm:^0.32.3"
- "@endo/errors": "npm:^1.2.2"
- "@endo/far": "npm:^1.0.4"
- "@endo/init": "npm:^1.0.4"
- agoric: "npm:0.21.2-dev-5676146.0"
- ava: "npm:^5.3.1"
- execa: "npm:^8.0.1"
- node-fetch: "npm:^3.3.2"
- languageName: unknown
- linkType: soft
-
-"run-async@npm:^2.4.0":
- version: 2.4.1
- resolution: "run-async@npm:2.4.1"
- checksum: 10c0/35a68c8f1d9664f6c7c2e153877ca1d6e4f886e5ca067c25cdd895a6891ff3a1466ee07c63d6a9be306e9619ff7d509494e6d9c129516a36b9fd82263d579ee1
- languageName: node
- linkType: hard
-
-"run-parallel@npm:^1.1.9":
- version: 1.2.0
- resolution: "run-parallel@npm:1.2.0"
- dependencies:
- queue-microtask: "npm:^1.2.2"
- checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39
- languageName: node
- linkType: hard
-
-"rxjs@npm:^7.5.5":
- version: 7.8.1
- resolution: "rxjs@npm:7.8.1"
- dependencies:
- tslib: "npm:^2.1.0"
- checksum: 10c0/3c49c1ecd66170b175c9cacf5cef67f8914dcbc7cd0162855538d365c83fea631167cacb644b3ce533b2ea0e9a4d0b12175186985f89d75abe73dbd8f7f06f68
- languageName: node
- linkType: hard
-
-"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0":
- version: 5.2.1
- resolution: "safe-buffer@npm:5.2.1"
- checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3
- languageName: node
- linkType: hard
-
-"safe-stable-stringify@npm:^2.3.1":
- version: 2.4.3
- resolution: "safe-stable-stringify@npm:2.4.3"
- checksum: 10c0/81dede06b8f2ae794efd868b1e281e3c9000e57b39801c6c162267eb9efda17bd7a9eafa7379e1f1cacd528d4ced7c80d7460ad26f62ada7c9e01dec61b2e768
- languageName: node
- linkType: hard
-
-"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0":
- version: 2.1.2
- resolution: "safer-buffer@npm:2.1.2"
- checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4
- languageName: node
- linkType: hard
-
-"semver@npm:^6.3.0":
- version: 6.3.1
- resolution: "semver@npm:6.3.1"
- bin:
- semver: bin/semver.js
- checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d
- languageName: node
- linkType: hard
-
-"semver@npm:^7.3.2, semver@npm:^7.3.5":
- version: 7.5.4
- resolution: "semver@npm:7.5.4"
- dependencies:
- lru-cache: "npm:^6.0.0"
- bin:
- semver: bin/semver.js
- checksum: 10c0/5160b06975a38b11c1ab55950cb5b8a23db78df88275d3d8a42ccf1f29e55112ac995b3a26a522c36e3b5f76b0445f1eef70d696b8c7862a2b4303d7b0e7609e
- languageName: node
- linkType: hard
-
-"serialize-error@npm:^7.0.1":
- version: 7.0.1
- resolution: "serialize-error@npm:7.0.1"
- dependencies:
- type-fest: "npm:^0.13.1"
- checksum: 10c0/7982937d578cd901276c8ab3e2c6ed8a4c174137730f1fb0402d005af209a0e84d04acc874e317c936724c7b5b26c7a96ff7e4b8d11a469f4924a4b0ea814c05
- languageName: node
- linkType: hard
-
-"ses@npm:^1.5.0":
- version: 1.5.0
- resolution: "ses@npm:1.5.0"
- dependencies:
- "@endo/env-options": "npm:^1.1.4"
- checksum: 10c0/bd5e230ff07abe84632ff212a5dce5163d979ab0ae657c4ac0ee2748aea9f587d83c75639d0058def62eae6dde55c0ae9652f33aecc5e0fe538c89ce54bffcdc
- languageName: node
- linkType: hard
-
-"set-function-length@npm:^1.2.1":
- version: 1.2.2
- resolution: "set-function-length@npm:1.2.2"
- dependencies:
- define-data-property: "npm:^1.1.4"
- es-errors: "npm:^1.3.0"
- function-bind: "npm:^1.1.2"
- get-intrinsic: "npm:^1.2.4"
- gopd: "npm:^1.0.1"
- has-property-descriptors: "npm:^1.0.2"
- checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c
- languageName: node
- linkType: hard
-
-"shebang-command@npm:^2.0.0":
- version: 2.0.0
- resolution: "shebang-command@npm:2.0.0"
- dependencies:
- shebang-regex: "npm:^3.0.0"
- checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e
- languageName: node
- linkType: hard
-
-"shebang-regex@npm:^3.0.0":
- version: 3.0.0
- resolution: "shebang-regex@npm:3.0.0"
- checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690
- languageName: node
- linkType: hard
-
-"signal-exit@npm:^3.0.2":
- version: 3.0.7
- resolution: "signal-exit@npm:3.0.7"
- checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912
- languageName: node
- linkType: hard
-
-"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0":
- version: 4.1.0
- resolution: "signal-exit@npm:4.1.0"
- checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83
- languageName: node
- linkType: hard
-
-"simple-concat@npm:^1.0.0":
- version: 1.0.1
- resolution: "simple-concat@npm:1.0.1"
- checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776
- languageName: node
- linkType: hard
-
-"simple-get@npm:^4.0.0":
- version: 4.0.1
- resolution: "simple-get@npm:4.0.1"
- dependencies:
- decompress-response: "npm:^6.0.0"
- once: "npm:^1.3.1"
- simple-concat: "npm:^1.0.0"
- checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0
- languageName: node
- linkType: hard
-
-"simple-swizzle@npm:^0.2.2":
- version: 0.2.2
- resolution: "simple-swizzle@npm:0.2.2"
- dependencies:
- is-arrayish: "npm:^0.3.1"
- checksum: 10c0/df5e4662a8c750bdba69af4e8263c5d96fe4cd0f9fe4bdfa3cbdeb45d2e869dff640beaaeb1ef0e99db4d8d2ec92f85508c269f50c972174851bc1ae5bd64308
- languageName: node
- linkType: hard
-
-"slash@npm:^4.0.0":
- version: 4.0.0
- resolution: "slash@npm:4.0.0"
- checksum: 10c0/b522ca75d80d107fd30d29df0549a7b2537c83c4c4ecd12cd7d4ea6c8aaca2ab17ada002e7a1d78a9d736a0261509f26ea5b489082ee443a3a810586ef8eff18
- languageName: node
- linkType: hard
-
-"slice-ansi@npm:^4.0.0":
- version: 4.0.0
- resolution: "slice-ansi@npm:4.0.0"
- dependencies:
- ansi-styles: "npm:^4.0.0"
- astral-regex: "npm:^2.0.0"
- is-fullwidth-code-point: "npm:^3.0.0"
- checksum: 10c0/6c25678db1270d4793e0327620f1e0f9f5bea4630123f51e9e399191bc52c87d6e6de53ed33538609e5eacbd1fab769fae00f3705d08d029f02102a540648918
- languageName: node
- linkType: hard
-
-"slice-ansi@npm:^5.0.0":
- version: 5.0.0
- resolution: "slice-ansi@npm:5.0.0"
- dependencies:
- ansi-styles: "npm:^6.0.0"
- is-fullwidth-code-point: "npm:^4.0.0"
- checksum: 10c0/2d4d40b2a9d5cf4e8caae3f698fe24ae31a4d778701724f578e984dcb485ec8c49f0c04dab59c401821e80fcdfe89cace9c66693b0244e40ec485d72e543914f
- languageName: node
- linkType: hard
-
-"smart-buffer@npm:^4.2.0":
- version: 4.2.0
- resolution: "smart-buffer@npm:4.2.0"
- checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539
- languageName: node
- linkType: hard
-
-"socks-proxy-agent@npm:^8.0.1":
- version: 8.0.2
- resolution: "socks-proxy-agent@npm:8.0.2"
- dependencies:
- agent-base: "npm:^7.0.2"
- debug: "npm:^4.3.4"
- socks: "npm:^2.7.1"
- checksum: 10c0/a842402fc9b8848a31367f2811ca3cd14c4106588b39a0901cd7a69029998adfc6456b0203617c18ed090542ad0c24ee4e9d4c75a0c4b75071e214227c177eb7
- languageName: node
- linkType: hard
-
-"socks@npm:^2.7.1":
- version: 2.7.1
- resolution: "socks@npm:2.7.1"
- dependencies:
- ip: "npm:^2.0.0"
- smart-buffer: "npm:^4.2.0"
- checksum: 10c0/43f69dbc9f34fc8220bc51c6eea1c39715ab3cfdb115d6e3285f6c7d1a603c5c75655668a5bbc11e3c7e2c99d60321fb8d7ab6f38cda6a215fadd0d6d0b52130
- languageName: node
- linkType: hard
-
-"source-map@npm:0.7.4":
- version: 0.7.4
- resolution: "source-map@npm:0.7.4"
- checksum: 10c0/dc0cf3768fe23c345ea8760487f8c97ef6fca8a73c83cd7c9bf2fde8bc2c34adb9c0824d6feb14bc4f9e37fb522e18af621543f1289038a66ac7586da29aa7dc
- languageName: node
- linkType: hard
-
-"source-map@npm:^0.5.0":
- version: 0.5.7
- resolution: "source-map@npm:0.5.7"
- checksum: 10c0/904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599
- languageName: node
- linkType: hard
-
-"sourcemap-codec@npm:^1.4.8":
- version: 1.4.8
- resolution: "sourcemap-codec@npm:1.4.8"
- checksum: 10c0/f099279fdaae070ff156df7414bbe39aad69cdd615454947ed3e19136bfdfcb4544952685ee73f56e17038f4578091e12b17b283ed8ac013882916594d95b9e6
- languageName: node
- linkType: hard
-
-"sprintf-js@npm:~1.0.2":
- version: 1.0.3
- resolution: "sprintf-js@npm:1.0.3"
- checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb
- languageName: node
- linkType: hard
-
-"ssri@npm:^10.0.0":
- version: 10.0.5
- resolution: "ssri@npm:10.0.5"
- dependencies:
- minipass: "npm:^7.0.3"
- checksum: 10c0/b091f2ae92474183c7ac5ed3f9811457e1df23df7a7e70c9476eaa9a0c4a0c8fc190fb45acefbf023ca9ee864dd6754237a697dc52a0fb182afe65d8e77443d8
- languageName: node
- linkType: hard
-
-"stack-trace@npm:0.0.x":
- version: 0.0.10
- resolution: "stack-trace@npm:0.0.10"
- checksum: 10c0/9ff3dabfad4049b635a85456f927a075c9d0c210e3ea336412d18220b2a86cbb9b13ec46d6c37b70a302a4ea4d49e30e5d4944dd60ae784073f1cde778ac8f4b
- languageName: node
- linkType: hard
-
-"stack-utils@npm:^2.0.6":
- version: 2.0.6
- resolution: "stack-utils@npm:2.0.6"
- dependencies:
- escape-string-regexp: "npm:^2.0.0"
- checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a
- languageName: node
- linkType: hard
-
-"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3":
- version: 4.2.3
- resolution: "string-width@npm:4.2.3"
- dependencies:
- emoji-regex: "npm:^8.0.0"
- is-fullwidth-code-point: "npm:^3.0.0"
- strip-ansi: "npm:^6.0.1"
- checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b
- languageName: node
- linkType: hard
-
-"string-width@npm:^5.0.0, string-width@npm:^5.0.1, string-width@npm:^5.1.2":
- version: 5.1.2
- resolution: "string-width@npm:5.1.2"
- dependencies:
- eastasianwidth: "npm:^0.2.0"
- emoji-regex: "npm:^9.2.2"
- strip-ansi: "npm:^7.0.1"
- checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca
- languageName: node
- linkType: hard
-
-"string_decoder@npm:^1.1.1":
- version: 1.3.0
- resolution: "string_decoder@npm:1.3.0"
- dependencies:
- safe-buffer: "npm:~5.2.0"
- checksum: 10c0/810614ddb030e271cd591935dcd5956b2410dd079d64ff92a1844d6b7588bf992b3e1b69b0f4d34a3e06e0bd73046ac646b5264c1987b20d0601f81ef35d731d
- languageName: node
- linkType: hard
-
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1":
- version: 6.0.1
- resolution: "strip-ansi@npm:6.0.1"
- dependencies:
- ansi-regex: "npm:^5.0.1"
- checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952
- languageName: node
- linkType: hard
-
-"strip-ansi@npm:^7.0.1":
- version: 7.1.0
- resolution: "strip-ansi@npm:7.1.0"
- dependencies:
- ansi-regex: "npm:^6.0.1"
- checksum: 10c0/a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4
- languageName: node
- linkType: hard
-
-"strip-final-newline@npm:^3.0.0":
- version: 3.0.0
- resolution: "strip-final-newline@npm:3.0.0"
- checksum: 10c0/a771a17901427bac6293fd416db7577e2bc1c34a19d38351e9d5478c3c415f523f391003b42ed475f27e33a78233035df183525395f731d3bfb8cdcbd4da08ce
- languageName: node
- linkType: hard
-
-"strip-json-comments@npm:~2.0.1":
- version: 2.0.1
- resolution: "strip-json-comments@npm:2.0.1"
- checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43
- languageName: node
- linkType: hard
-
-"supertap@npm:^3.0.1":
- version: 3.0.1
- resolution: "supertap@npm:3.0.1"
- dependencies:
- indent-string: "npm:^5.0.0"
- js-yaml: "npm:^3.14.1"
- serialize-error: "npm:^7.0.1"
- strip-ansi: "npm:^7.0.1"
- checksum: 10c0/8164674f2e280cab875f0fef5bb36c15553c13e29697ff92f4e0d6bc62149f0303a89eee47535413ed145ea72e14a24d065bab233059d48a499ec5ebb4566b0f
- languageName: node
- linkType: hard
-
-"supports-color@npm:^5.3.0":
- version: 5.5.0
- resolution: "supports-color@npm:5.5.0"
- dependencies:
- has-flag: "npm:^3.0.0"
- checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05
- languageName: node
- linkType: hard
-
-"supports-color@npm:^7.1.0":
- version: 7.2.0
- resolution: "supports-color@npm:7.2.0"
- dependencies:
- has-flag: "npm:^4.0.0"
- checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124
- languageName: node
- linkType: hard
-
-"supports-preserve-symlinks-flag@npm:^1.0.0":
- version: 1.0.0
- resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
- checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39
- languageName: node
- linkType: hard
-
-"symbol-observable@npm:^2.0.3":
- version: 2.0.3
- resolution: "symbol-observable@npm:2.0.3"
- checksum: 10c0/03fb8766b75bfa65a3c7d68ae1e51a13a5ff71b40d6d53b17a0c9c77b1685c20a3bfbf45547ab36214a079665c3f551e250798f6b2f83a2a40762d864ed87f78
- languageName: node
- linkType: hard
-
-"table@npm:^6.7.1":
- version: 6.8.2
- resolution: "table@npm:6.8.2"
- dependencies:
- ajv: "npm:^8.0.1"
- lodash.truncate: "npm:^4.4.2"
- slice-ansi: "npm:^4.0.0"
- string-width: "npm:^4.2.3"
- strip-ansi: "npm:^6.0.1"
- checksum: 10c0/f8b348af38ee34e419d8ce7306ba00671ce6f20e861ccff22555f491ba264e8416086063ce278a8d81abfa8d23b736ec2cca7ac4029b5472f63daa4b4688b803
- languageName: node
- linkType: hard
-
-"tar-fs@npm:^2.0.0":
- version: 2.1.1
- resolution: "tar-fs@npm:2.1.1"
- dependencies:
- chownr: "npm:^1.1.1"
- mkdirp-classic: "npm:^0.5.2"
- pump: "npm:^3.0.0"
- tar-stream: "npm:^2.1.4"
- checksum: 10c0/871d26a934bfb7beeae4c4d8a09689f530b565f79bd0cf489823ff0efa3705da01278160da10bb006d1a793fa0425cf316cec029b32a9159eacbeaff4965fb6d
- languageName: node
- linkType: hard
-
-"tar-stream@npm:^2.1.4":
- version: 2.2.0
- resolution: "tar-stream@npm:2.2.0"
- dependencies:
- bl: "npm:^4.0.3"
- end-of-stream: "npm:^1.4.1"
- fs-constants: "npm:^1.0.0"
- inherits: "npm:^2.0.3"
- readable-stream: "npm:^3.1.1"
- checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692
- languageName: node
- linkType: hard
-
-"tar@npm:^6.1.11, tar@npm:^6.1.2":
- version: 6.2.0
- resolution: "tar@npm:6.2.0"
- dependencies:
- chownr: "npm:^2.0.0"
- fs-minipass: "npm:^2.0.0"
- minipass: "npm:^5.0.0"
- minizlib: "npm:^2.1.1"
- mkdirp: "npm:^1.0.3"
- yallist: "npm:^4.0.0"
- checksum: 10c0/02ca064a1a6b4521fef88c07d389ac0936730091f8c02d30ea60d472e0378768e870769ab9e986d87807bfee5654359cf29ff4372746cc65e30cbddc352660d8
- languageName: node
- linkType: hard
-
-"tdigest@npm:^0.1.1":
- version: 0.1.2
- resolution: "tdigest@npm:0.1.2"
- dependencies:
- bintrees: "npm:1.0.2"
- checksum: 10c0/10187b8144b112fcdfd3a5e4e9068efa42c990b1e30cd0d4f35ee8f58f16d1b41bc587e668fa7a6f6ca31308961cbd06cd5d4a4ae1dc388335902ae04f7d57df
- languageName: node
- linkType: hard
-
-"temp-dir@npm:^3.0.0":
- version: 3.0.0
- resolution: "temp-dir@npm:3.0.0"
- checksum: 10c0/a86978a400984cd5f315b77ebf3fe53bb58c61f192278cafcb1f3fb32d584a21dc8e08b93171d7874b7cc972234d3455c467306cc1bfc4524b622e5ad3bfd671
- languageName: node
- linkType: hard
-
-"text-hex@npm:1.0.x":
- version: 1.0.0
- resolution: "text-hex@npm:1.0.0"
- checksum: 10c0/57d8d320d92c79d7c03ffb8339b825bb9637c2cbccf14304309f51d8950015c44464b6fd1b6820a3d4821241c68825634f09f5a2d9d501e84f7c6fd14376860d
- languageName: node
- linkType: hard
-
-"through@npm:^2.3.6":
- version: 2.3.8
- resolution: "through@npm:2.3.8"
- checksum: 10c0/4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc
- languageName: node
- linkType: hard
-
-"time-zone@npm:^1.0.0":
- version: 1.0.0
- resolution: "time-zone@npm:1.0.0"
- checksum: 10c0/d00ebd885039109011b6e2423ebbf225160927333c2ade6d833e9cc4676db20759f1f3855fafde00d1bd668c243a6aa68938ce71fe58aab0d514e820d59c1d81
- languageName: node
- linkType: hard
-
-"tmp@npm:^0.0.33":
- version: 0.0.33
- resolution: "tmp@npm:0.0.33"
- dependencies:
- os-tmpdir: "npm:~1.0.2"
- checksum: 10c0/69863947b8c29cabad43fe0ce65cec5bb4b481d15d4b4b21e036b060b3edbf3bc7a5541de1bacb437bb3f7c4538f669752627fdf9b4aaf034cebd172ba373408
- languageName: node
- linkType: hard
-
-"tmp@npm:^0.2.1":
- version: 0.2.3
- resolution: "tmp@npm:0.2.3"
- checksum: 10c0/3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125
- languageName: node
- linkType: hard
-
-"to-fast-properties@npm:^2.0.0":
- version: 2.0.0
- resolution: "to-fast-properties@npm:2.0.0"
- checksum: 10c0/b214d21dbfb4bce3452b6244b336806ffea9c05297148d32ebb428d5c43ce7545bdfc65a1ceb58c9ef4376a65c0cb2854d645f33961658b3e3b4f84910ddcdd7
- languageName: node
- linkType: hard
-
-"to-regex-range@npm:^5.0.1":
- version: 5.0.1
- resolution: "to-regex-range@npm:5.0.1"
- dependencies:
- is-number: "npm:^7.0.0"
- checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892
- languageName: node
- linkType: hard
-
-"tr46@npm:~0.0.3":
- version: 0.0.3
- resolution: "tr46@npm:0.0.3"
- checksum: 10c0/047cb209a6b60c742f05c9d3ace8fa510bff609995c129a37ace03476a9b12db4dbf975e74600830ef0796e18882b2381fb5fb1f6b4f96b832c374de3ab91a11
- languageName: node
- linkType: hard
-
-"triple-beam@npm:1.3.0":
- version: 1.3.0
- resolution: "triple-beam@npm:1.3.0"
- checksum: 10c0/a6da96495f25b6c04b3629df5161c7eb84760927943f16665fd8dcd3a643daadf73d69eee78306b4b68d606937f22f8703afe763bc8d3723632ffb1f3a798493
- languageName: node
- linkType: hard
-
-"triple-beam@npm:^1.3.0":
- version: 1.4.1
- resolution: "triple-beam@npm:1.4.1"
- checksum: 10c0/4bf1db71e14fe3ff1c3adbe3c302f1fdb553b74d7591a37323a7badb32dc8e9c290738996cbb64f8b10dc5a3833645b5d8c26221aaaaa12e50d1251c9aba2fea
- languageName: node
- linkType: hard
-
-"tslib@npm:^2.1.0":
- version: 2.6.3
- resolution: "tslib@npm:2.6.3"
- checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a
- languageName: node
- linkType: hard
-
-"tunnel-agent@npm:^0.6.0":
- version: 0.6.0
- resolution: "tunnel-agent@npm:0.6.0"
- dependencies:
- safe-buffer: "npm:^5.0.1"
- checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a
- languageName: node
- linkType: hard
-
-"type-fest@npm:^0.13.1":
- version: 0.13.1
- resolution: "type-fest@npm:0.13.1"
- checksum: 10c0/0c0fa07ae53d4e776cf4dac30d25ad799443e9eef9226f9fddbb69242db86b08584084a99885cfa5a9dfe4c063ebdc9aa7b69da348e735baede8d43f1aeae93b
- languageName: node
- linkType: hard
-
-"type-fest@npm:^0.21.3":
- version: 0.21.3
- resolution: "type-fest@npm:0.21.3"
- checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8
- languageName: node
- linkType: hard
-
-"undici-types@npm:~5.26.4":
- version: 5.26.5
- resolution: "undici-types@npm:5.26.5"
- checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501
- languageName: node
- linkType: hard
-
-"unique-filename@npm:^3.0.0":
- version: 3.0.0
- resolution: "unique-filename@npm:3.0.0"
- dependencies:
- unique-slug: "npm:^4.0.0"
- checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f
- languageName: node
- linkType: hard
-
-"unique-slug@npm:^4.0.0":
- version: 4.0.0
- resolution: "unique-slug@npm:4.0.0"
- dependencies:
- imurmurhash: "npm:^0.1.4"
- checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635
- languageName: node
- linkType: hard
-
-"uri-js@npm:^4.2.2, uri-js@npm:^4.4.1":
- version: 4.4.1
- resolution: "uri-js@npm:4.4.1"
- dependencies:
- punycode: "npm:^2.1.0"
- checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c
- languageName: node
- linkType: hard
-
-"util-deprecate@npm:^1.0.1":
- version: 1.0.2
- resolution: "util-deprecate@npm:1.0.2"
- checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942
- languageName: node
- linkType: hard
-
-"wcwidth@npm:^1.0.1":
- version: 1.0.1
- resolution: "wcwidth@npm:1.0.1"
- dependencies:
- defaults: "npm:^1.0.3"
- checksum: 10c0/5b61ca583a95e2dd85d7078400190efd452e05751a64accb8c06ce4db65d7e0b0cde9917d705e826a2e05cc2548f61efde115ffa374c3e436d04be45c889e5b4
- languageName: node
- linkType: hard
-
-"web-streams-polyfill@npm:^3.0.3":
- version: 3.3.3
- resolution: "web-streams-polyfill@npm:3.3.3"
- checksum: 10c0/64e855c47f6c8330b5436147db1c75cb7e7474d924166800e8e2aab5eb6c76aac4981a84261dd2982b3e754490900b99791c80ae1407a9fa0dcff74f82ea3a7f
- languageName: node
- linkType: hard
-
-"webidl-conversions@npm:^3.0.0":
- version: 3.0.1
- resolution: "webidl-conversions@npm:3.0.1"
- checksum: 10c0/5612d5f3e54760a797052eb4927f0ddc01383550f542ccd33d5238cfd65aeed392a45ad38364970d0a0f4fea32e1f4d231b3d8dac4a3bdd385e5cf802ae097db
- languageName: node
- linkType: hard
-
-"well-known-symbols@npm:^2.0.0":
- version: 2.0.0
- resolution: "well-known-symbols@npm:2.0.0"
- checksum: 10c0/cb6c12e98877e8952ec28d13ae6f4fdb54ae1cb49b16a728720276dadd76c930e6cb0e174af3a4620054dd2752546f842540122920c6e31410208abd4958ee6b
- languageName: node
- linkType: hard
-
-"whatwg-url@npm:^5.0.0":
- version: 5.0.0
- resolution: "whatwg-url@npm:5.0.0"
- dependencies:
- tr46: "npm:~0.0.3"
- webidl-conversions: "npm:^3.0.0"
- checksum: 10c0/1588bed84d10b72d5eec1d0faa0722ba1962f1821e7539c535558fb5398d223b0c50d8acab950b8c488b4ba69043fd833cc2697056b167d8ad46fac3995a55d5
- languageName: node
- linkType: hard
-
-"which@npm:^2.0.1":
- version: 2.0.2
- resolution: "which@npm:2.0.2"
- dependencies:
- isexe: "npm:^2.0.0"
- bin:
- node-which: ./bin/node-which
- checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f
- languageName: node
- linkType: hard
-
-"which@npm:^4.0.0":
- version: 4.0.0
- resolution: "which@npm:4.0.0"
- dependencies:
- isexe: "npm:^3.1.1"
- bin:
- node-which: bin/which.js
- checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a
- languageName: node
- linkType: hard
-
-"winston-transport@npm:^4.4.0":
- version: 4.7.0
- resolution: "winston-transport@npm:4.7.0"
- dependencies:
- logform: "npm:^2.3.2"
- readable-stream: "npm:^3.6.0"
- triple-beam: "npm:^1.3.0"
- checksum: 10c0/cd16f3d0ab56697f93c4899e0eb5f89690f291bb6cf309194819789326a7c7ed943ef00f0b2fab513b114d371314368bde1a7ae6252ad1516181a79f90199cd2
- languageName: node
- linkType: hard
-
-"winston@npm:3.3.3":
- version: 3.3.3
- resolution: "winston@npm:3.3.3"
- dependencies:
- "@dabh/diagnostics": "npm:^2.0.2"
- async: "npm:^3.1.0"
- is-stream: "npm:^2.0.0"
- logform: "npm:^2.2.0"
- one-time: "npm:^1.0.0"
- readable-stream: "npm:^3.4.0"
- stack-trace: "npm:0.0.x"
- triple-beam: "npm:^1.3.0"
- winston-transport: "npm:^4.4.0"
- checksum: 10c0/18205fa1e3ebb88dc910fbe5337e3c9d2dbd94310978adca5ab77444b854d5679dec0a70fed425e77cf93e237390c7670bb937f14c492b8415e594ab21540d3d
- languageName: node
- linkType: hard
-
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
- version: 7.0.0
- resolution: "wrap-ansi@npm:7.0.0"
- dependencies:
- ansi-styles: "npm:^4.0.0"
- string-width: "npm:^4.1.0"
- strip-ansi: "npm:^6.0.0"
- checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da
- languageName: node
- linkType: hard
-
-"wrap-ansi@npm:^6.0.1":
- version: 6.2.0
- resolution: "wrap-ansi@npm:6.2.0"
- dependencies:
- ansi-styles: "npm:^4.0.0"
- string-width: "npm:^4.1.0"
- strip-ansi: "npm:^6.0.0"
- checksum: 10c0/baad244e6e33335ea24e86e51868fe6823626e3a3c88d9a6674642afff1d34d9a154c917e74af8d845fd25d170c4ea9cf69a47133c3f3656e1252b3d462d9f6c
- languageName: node
- linkType: hard
-
-"wrap-ansi@npm:^8.1.0":
- version: 8.1.0
- resolution: "wrap-ansi@npm:8.1.0"
- dependencies:
- ansi-styles: "npm:^6.1.0"
- string-width: "npm:^5.0.1"
- strip-ansi: "npm:^7.0.1"
- checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60
- languageName: node
- linkType: hard
-
-"wrappy@npm:1":
- version: 1.0.2
- resolution: "wrappy@npm:1.0.2"
- checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0
- languageName: node
- linkType: hard
-
-"write-file-atomic@npm:^5.0.1":
- version: 5.0.1
- resolution: "write-file-atomic@npm:5.0.1"
- dependencies:
- imurmurhash: "npm:^0.1.4"
- signal-exit: "npm:^4.0.1"
- checksum: 10c0/e8c850a8e3e74eeadadb8ad23c9d9d63e4e792bd10f4836ed74189ef6e996763959f1249c5650e232f3c77c11169d239cbfc8342fc70f3fe401407d23810505d
- languageName: node
- linkType: hard
-
-"ws@npm:^7, ws@npm:^7.2.0":
- version: 7.5.10
- resolution: "ws@npm:7.5.10"
- peerDependencies:
- bufferutil: ^4.0.1
- utf-8-validate: ^5.0.2
- peerDependenciesMeta:
- bufferutil:
- optional: true
- utf-8-validate:
- optional: true
- checksum: 10c0/bd7d5f4aaf04fae7960c23dcb6c6375d525e00f795dd20b9385902bd008c40a94d3db3ce97d878acc7573df852056ca546328b27b39f47609f80fb22a0a9b61d
- languageName: node
- linkType: hard
-
-"xstream@npm:^11.14.0":
- version: 11.14.0
- resolution: "xstream@npm:11.14.0"
- dependencies:
- globalthis: "npm:^1.0.1"
- symbol-observable: "npm:^2.0.3"
- checksum: 10c0/7a28baedc64385dc17597d04c7130ec3135db298e66d6dcf33821eb1953d5ad1b83c5fa08f1ce4d36e75fd219f2e9ef81ee0721aa8d4ccf619acc1760ba37f71
- languageName: node
- linkType: hard
-
-"y18n@npm:^5.0.5":
- version: 5.0.8
- resolution: "y18n@npm:5.0.8"
- checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249
- languageName: node
- linkType: hard
-
-"yallist@npm:^4.0.0":
- version: 4.0.0
- resolution: "yallist@npm:4.0.0"
- checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a
- languageName: node
- linkType: hard
-
-"yargs-parser@npm:^21.1.1":
- version: 21.1.1
- resolution: "yargs-parser@npm:21.1.1"
- checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2
- languageName: node
- linkType: hard
-
-"yargs@npm:^17.7.2":
- version: 17.7.2
- resolution: "yargs@npm:17.7.2"
- dependencies:
- cliui: "npm:^8.0.1"
- escalade: "npm:^3.1.1"
- get-caller-file: "npm:^2.0.5"
- require-directory: "npm:^2.1.1"
- string-width: "npm:^4.2.3"
- y18n: "npm:^5.0.5"
- yargs-parser: "npm:^21.1.1"
- checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05
- languageName: node
- linkType: hard
-
-"yocto-queue@npm:^1.0.0":
- version: 1.0.0
- resolution: "yocto-queue@npm:1.0.0"
- checksum: 10c0/856117aa15cf5103d2a2fb173f0ab4acb12b4b4d0ed3ab249fdbbf612e55d1cadfd27a6110940e24746fb0a78cf640b522cc8bca76f30a3b00b66e90cf82abe0
- languageName: node
- linkType: hard
diff --git a/a3p-integration/proposals/c:stake-bld/.yarnrc.yml b/a3p-integration/proposals/c:stake-bld/.yarnrc.yml
deleted file mode 100644
index 3186f3f0795..00000000000
--- a/a3p-integration/proposals/c:stake-bld/.yarnrc.yml
+++ /dev/null
@@ -1 +0,0 @@
-nodeLinker: node-modules
diff --git a/a3p-integration/proposals/n:upgrade-next/.gitignore b/a3p-integration/proposals/n:upgrade-next/.gitignore
new file mode 100644
index 00000000000..da0da987d7b
--- /dev/null
+++ b/a3p-integration/proposals/n:upgrade-next/.gitignore
@@ -0,0 +1,6 @@
+# Generated Artifacts to Ignore in CI
+add-LEMONS/
+add-OLIVES/
+upgrade-bank/
+upgrade-provisionPool/
+upgrade-orch-core/
diff --git a/a3p-integration/proposals/a:upgrade-next/.yarnrc.yml b/a3p-integration/proposals/n:upgrade-next/.yarnrc.yml
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/.yarnrc.yml
rename to a3p-integration/proposals/n:upgrade-next/.yarnrc.yml
diff --git a/a3p-integration/proposals/n:upgrade-next/README.md b/a3p-integration/proposals/n:upgrade-next/README.md
new file mode 100644
index 00000000000..e4f2a2e1f16
--- /dev/null
+++ b/a3p-integration/proposals/n:upgrade-next/README.md
@@ -0,0 +1,14 @@
+# Proposal to upgrade the chain software
+
+The `UNRELEASED_A3P_INTEGRATION` software upgrade may include core proposals
+defined in its upgrade handler. See `CoreProposalSteps` in the
+`unreleasedUpgradeHandler` in
+[golang/cosmos/app/upgrade.go](../../../golang/cosmos/app/upgrade.go).
+
+This test proposal may also include `coreProposals` in its `upgradeInfo`, which
+are executed after those defined in that upgrade handler. See `agoricProposal`
+in [package.json](./package.json).
+
+The "binaries" property of `upgradeInfo` is now required since Cosmos SDK 0.46,
+however it cannot be computed for an unreleased upgrade. To disable the check,
+`releaseNotes` is set to `false`.
diff --git a/a3p-integration/proposals/a:upgrade-next/agd-tools.js b/a3p-integration/proposals/n:upgrade-next/agd-tools.js
similarity index 88%
rename from a3p-integration/proposals/a:upgrade-next/agd-tools.js
rename to a3p-integration/proposals/n:upgrade-next/agd-tools.js
index 67cc2d4880e..550668e110b 100644
--- a/a3p-integration/proposals/a:upgrade-next/agd-tools.js
+++ b/a3p-integration/proposals/n:upgrade-next/agd-tools.js
@@ -87,6 +87,31 @@ const addOraclesForBrand = (baseId, brandName) => {
return oraclesWithID;
};
+export const addPreexistingOracles = async (brandIn, oraclesByBrand) => {
+ await null;
+
+ const oraclesWithID = [];
+ for (let i = 0; i < ORACLE_ADDRESSES.length; i += 1) {
+ const oracleAddress = ORACLE_ADDRESSES[i];
+
+ const path = `published.wallet.${oracleAddress}.current`;
+ const wallet = await getQuoteBody(path);
+ const idToInvitation = wallet.offerToUsedInvitation.find(([k]) => {
+ return !isNaN(k[0]);
+ });
+ if (idToInvitation) {
+ oraclesWithID.push({
+ address: oracleAddress,
+ offerId: idToInvitation[0],
+ });
+ } else {
+ console.log('AGD addO skip', oraclesWithID);
+ }
+ }
+
+ oraclesByBrand.set(brandIn, oraclesWithID);
+};
+
/**
* Generate a consistent map of oracleIDs and brands that can be used to
* register oracles or to push prices. The baseID changes each time new
diff --git a/a3p-integration/proposals/n:upgrade-next/initial.test.js b/a3p-integration/proposals/n:upgrade-next/initial.test.js
new file mode 100644
index 00000000000..366e7a71a7c
--- /dev/null
+++ b/a3p-integration/proposals/n:upgrade-next/initial.test.js
@@ -0,0 +1,21 @@
+import test from 'ava';
+
+import { getVatDetails } from '@agoric/synthetic-chain';
+
+const vats = {
+ network: { incarnation: 1 },
+ ibc: { incarnation: 1 },
+ localchain: { incarnation: 1 },
+ orchestration: { incarnation: 0 },
+ transfer: { incarnation: 1 },
+ walletFactory: { incarnation: 4 },
+ zoe: { incarnation: 2 },
+};
+
+test(`vat details`, async t => {
+ const actual = {};
+ for await (const vatName of Object.keys(vats)) {
+ actual[vatName] = await getVatDetails(vatName);
+ }
+ t.like(actual, vats, `vat details are alike`);
+});
diff --git a/a3p-integration/proposals/a:upgrade-next/localchain.test.js b/a3p-integration/proposals/n:upgrade-next/localchain.test.js
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/localchain.test.js
rename to a3p-integration/proposals/n:upgrade-next/localchain.test.js
diff --git a/a3p-integration/proposals/a:upgrade-next/package.json b/a3p-integration/proposals/n:upgrade-next/package.json
similarity index 94%
rename from a3p-integration/proposals/a:upgrade-next/package.json
rename to a3p-integration/proposals/n:upgrade-next/package.json
index 06868e9bea8..c3bd2a7c3c1 100644
--- a/a3p-integration/proposals/a:upgrade-next/package.json
+++ b/a3p-integration/proposals/n:upgrade-next/package.json
@@ -7,7 +7,6 @@
"coreProposals": []
},
"sdk-generate": [
- "vats/probe-zcf-bundle.js probe-submission",
"vats/test-localchain.js localchaintest-submission",
"vats/upgrade-bank.js upgrade-bank",
"vats/upgrade-provisionPool.js upgrade-provisionPool",
diff --git a/a3p-integration/proposals/a:upgrade-next/prepare.sh b/a3p-integration/proposals/n:upgrade-next/prepare.sh
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/prepare.sh
rename to a3p-integration/proposals/n:upgrade-next/prepare.sh
diff --git a/a3p-integration/proposals/a:upgrade-next/priceFeed-follower-auction.test.js b/a3p-integration/proposals/n:upgrade-next/priceFeed-follower-auction.test.js
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/priceFeed-follower-auction.test.js
rename to a3p-integration/proposals/n:upgrade-next/priceFeed-follower-auction.test.js
diff --git a/a3p-integration/proposals/a:upgrade-next/provisionPool.test.js b/a3p-integration/proposals/n:upgrade-next/provisionPool.test.js
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/provisionPool.test.js
rename to a3p-integration/proposals/n:upgrade-next/provisionPool.test.js
diff --git a/a3p-integration/proposals/a:upgrade-next/synthetic-chain-excerpt.js b/a3p-integration/proposals/n:upgrade-next/synthetic-chain-excerpt.js
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/synthetic-chain-excerpt.js
rename to a3p-integration/proposals/n:upgrade-next/synthetic-chain-excerpt.js
diff --git a/a3p-integration/proposals/a:upgrade-next/test.sh b/a3p-integration/proposals/n:upgrade-next/test.sh
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/test.sh
rename to a3p-integration/proposals/n:upgrade-next/test.sh
diff --git a/a3p-integration/proposals/a:upgrade-next/tsconfig.json b/a3p-integration/proposals/n:upgrade-next/tsconfig.json
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/tsconfig.json
rename to a3p-integration/proposals/n:upgrade-next/tsconfig.json
diff --git a/a3p-integration/proposals/a:upgrade-next/vatDetails.js b/a3p-integration/proposals/n:upgrade-next/vatDetails.js
similarity index 96%
rename from a3p-integration/proposals/a:upgrade-next/vatDetails.js
rename to a3p-integration/proposals/n:upgrade-next/vatDetails.js
index ccf24608309..2cd4c2c949d 100644
--- a/a3p-integration/proposals/a:upgrade-next/vatDetails.js
+++ b/a3p-integration/proposals/n:upgrade-next/vatDetails.js
@@ -90,10 +90,11 @@ export const getDetailsMatchingVats = async vatName => {
const infos = [];
for (const vatID of vatIDs) {
const vatInfo = kStore.lookupVat(vatID);
+ const name = vatInfo.options().name;
const source = vatInfo.source();
// @ts-expect-error cast
const { incarnation } = vatInfo.currentSpan();
- infos.push({ vatName, vatID, incarnation, ...source });
+ infos.push({ vatName: name, vatID, incarnation, ...source });
}
return infos;
diff --git a/a3p-integration/proposals/a:upgrade-next/yarn.lock b/a3p-integration/proposals/n:upgrade-next/yarn.lock
similarity index 100%
rename from a3p-integration/proposals/a:upgrade-next/yarn.lock
rename to a3p-integration/proposals/n:upgrade-next/yarn.lock
diff --git a/a3p-integration/proposals/b:enable-orchestration/.yarnrc.yml b/a3p-integration/proposals/s:stake-bld/.yarnrc.yml
similarity index 100%
rename from a3p-integration/proposals/b:enable-orchestration/.yarnrc.yml
rename to a3p-integration/proposals/s:stake-bld/.yarnrc.yml
diff --git a/a3p-integration/proposals/c:stake-bld/README.md b/a3p-integration/proposals/s:stake-bld/README.md
similarity index 100%
rename from a3p-integration/proposals/c:stake-bld/README.md
rename to a3p-integration/proposals/s:stake-bld/README.md
diff --git a/a3p-integration/proposals/c:stake-bld/package.json b/a3p-integration/proposals/s:stake-bld/package.json
similarity index 92%
rename from a3p-integration/proposals/c:stake-bld/package.json
rename to a3p-integration/proposals/s:stake-bld/package.json
index 190e40882f6..888bc5736f4 100644
--- a/a3p-integration/proposals/c:stake-bld/package.json
+++ b/a3p-integration/proposals/s:stake-bld/package.json
@@ -18,8 +18,7 @@
"@endo/init": "^1.0.4",
"agoric": "0.21.2-dev-5676146.0",
"ava": "^5.3.1",
- "execa": "^8.0.1",
- "node-fetch": "^3.3.2"
+ "execa": "^8.0.1"
},
"ava": {
"concurrency": 1
diff --git a/a3p-integration/proposals/c:stake-bld/stakeBld.test.js b/a3p-integration/proposals/s:stake-bld/stakeBld.test.js
similarity index 100%
rename from a3p-integration/proposals/c:stake-bld/stakeBld.test.js
rename to a3p-integration/proposals/s:stake-bld/stakeBld.test.js
diff --git a/a3p-integration/proposals/b:enable-orchestration/test-lib/chain.js b/a3p-integration/proposals/s:stake-bld/test-lib/chain.js
similarity index 100%
rename from a3p-integration/proposals/b:enable-orchestration/test-lib/chain.js
rename to a3p-integration/proposals/s:stake-bld/test-lib/chain.js
diff --git a/a3p-integration/proposals/c:stake-bld/test-lib/index.js b/a3p-integration/proposals/s:stake-bld/test-lib/index.js
similarity index 90%
rename from a3p-integration/proposals/c:stake-bld/test-lib/index.js
rename to a3p-integration/proposals/s:stake-bld/test-lib/index.js
index 4e301fd9863..25e8a22265c 100644
--- a/a3p-integration/proposals/c:stake-bld/test-lib/index.js
+++ b/a3p-integration/proposals/s:stake-bld/test-lib/index.js
@@ -1,5 +1,4 @@
-/* global setTimeout */
-import fetch from 'node-fetch';
+/* eslint-env node */
import { execFileSync } from 'child_process';
import { makeWalletUtils } from './wallet.js';
diff --git a/a3p-integration/proposals/c:stake-bld/test-lib/rpc.js b/a3p-integration/proposals/s:stake-bld/test-lib/rpc.js
similarity index 100%
rename from a3p-integration/proposals/c:stake-bld/test-lib/rpc.js
rename to a3p-integration/proposals/s:stake-bld/test-lib/rpc.js
diff --git a/a3p-integration/proposals/b:enable-orchestration/test-lib/wallet.js b/a3p-integration/proposals/s:stake-bld/test-lib/wallet.js
similarity index 98%
rename from a3p-integration/proposals/b:enable-orchestration/test-lib/wallet.js
rename to a3p-integration/proposals/s:stake-bld/test-lib/wallet.js
index bb75e7b784d..5fbe9b70027 100644
--- a/a3p-integration/proposals/b:enable-orchestration/test-lib/wallet.js
+++ b/a3p-integration/proposals/s:stake-bld/test-lib/wallet.js
@@ -53,7 +53,7 @@ export const getCurrent = async (addr, { readLatestHead }) => {
await readLatestHead(`published.wallet.${addr}.current`)
);
if (current === undefined) {
- throw new Error(`undefined current node for ${addr}`);
+ throw Error(`undefined current node for ${addr}`);
}
// Repair a type misunderstanding seen in the wild.
diff --git a/a3p-integration/proposals/c:stake-bld/test.sh b/a3p-integration/proposals/s:stake-bld/test.sh
similarity index 100%
rename from a3p-integration/proposals/c:stake-bld/test.sh
rename to a3p-integration/proposals/s:stake-bld/test.sh
diff --git a/a3p-integration/proposals/c:stake-bld/yarn.lock b/a3p-integration/proposals/s:stake-bld/yarn.lock
similarity index 99%
rename from a3p-integration/proposals/c:stake-bld/yarn.lock
rename to a3p-integration/proposals/s:stake-bld/yarn.lock
index 46e7264cf6c..8c9004f426c 100644
--- a/a3p-integration/proposals/c:stake-bld/yarn.lock
+++ b/a3p-integration/proposals/s:stake-bld/yarn.lock
@@ -2394,13 +2394,6 @@ __metadata:
languageName: node
linkType: hard
-"data-uri-to-buffer@npm:^4.0.0":
- version: 4.0.1
- resolution: "data-uri-to-buffer@npm:4.0.1"
- checksum: 10c0/20a6b93107597530d71d4cb285acee17f66bcdfc03fd81040921a81252f19db27588d87fc8fc69e1950c55cfb0bf8ae40d0e5e21d907230813eb5d5a7f9eb45b
- languageName: node
- linkType: hard
-
"date-time@npm:^3.1.0":
version: 3.1.0
resolution: "date-time@npm:3.1.0"
@@ -2773,16 +2766,6 @@ __metadata:
languageName: node
linkType: hard
-"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4":
- version: 3.2.0
- resolution: "fetch-blob@npm:3.2.0"
- dependencies:
- node-domexception: "npm:^1.0.0"
- web-streams-polyfill: "npm:^3.0.3"
- checksum: 10c0/60054bf47bfa10fb0ba6cb7742acec2f37c1f56344f79a70bb8b1c48d77675927c720ff3191fa546410a0442c998d27ab05e9144c32d530d8a52fbe68f843b69
- languageName: node
- linkType: hard
-
"figures@npm:^3.0.0":
version: 3.2.0
resolution: "figures@npm:3.2.0"
@@ -2866,15 +2849,6 @@ __metadata:
languageName: node
linkType: hard
-"formdata-polyfill@npm:^4.0.10":
- version: 4.0.10
- resolution: "formdata-polyfill@npm:4.0.10"
- dependencies:
- fetch-blob: "npm:^3.1.2"
- checksum: 10c0/5392ec484f9ce0d5e0d52fb5a78e7486637d516179b0eb84d81389d7eccf9ca2f663079da56f761355c0a65792810e3b345dc24db9a8bbbcf24ef3c8c88570c6
- languageName: node
- linkType: hard
-
"fs-constants@npm:^1.0.0":
version: 1.0.0
resolution: "fs-constants@npm:1.0.0"
@@ -3989,13 +3963,6 @@ __metadata:
languageName: node
linkType: hard
-"node-domexception@npm:^1.0.0":
- version: 1.0.0
- resolution: "node-domexception@npm:1.0.0"
- checksum: 10c0/5e5d63cda29856402df9472335af4bb13875e1927ad3be861dc5ebde38917aecbf9ae337923777af52a48c426b70148815e890a5d72760f1b4d758cc671b1a2b
- languageName: node
- linkType: hard
-
"node-fetch@npm:^2.6.0":
version: 2.7.0
resolution: "node-fetch@npm:2.7.0"
@@ -4010,17 +3977,6 @@ __metadata:
languageName: node
linkType: hard
-"node-fetch@npm:^3.3.2":
- version: 3.3.2
- resolution: "node-fetch@npm:3.3.2"
- dependencies:
- data-uri-to-buffer: "npm:^4.0.0"
- fetch-blob: "npm:^3.1.4"
- formdata-polyfill: "npm:^4.0.10"
- checksum: 10c0/f3d5e56190562221398c9f5750198b34cf6113aa304e34ee97c94fd300ec578b25b2c2906edba922050fce983338fde0d5d34fcb0fc3336ade5bd0e429ad7538
- languageName: node
- linkType: hard
-
"node-gyp-build@npm:^4.4.0":
version: 4.8.0
resolution: "node-gyp-build@npm:4.8.0"
@@ -4592,7 +4548,6 @@ __metadata:
agoric: "npm:0.21.2-dev-5676146.0"
ava: "npm:^5.3.1"
execa: "npm:^8.0.1"
- node-fetch: "npm:^3.3.2"
languageName: unknown
linkType: soft
@@ -5207,13 +5162,6 @@ __metadata:
languageName: node
linkType: hard
-"web-streams-polyfill@npm:^3.0.3":
- version: 3.3.3
- resolution: "web-streams-polyfill@npm:3.3.3"
- checksum: 10c0/64e855c47f6c8330b5436147db1c75cb7e7474d924166800e8e2aab5eb6c76aac4981a84261dd2982b3e754490900b99791c80ae1407a9fa0dcff74f82ea3a7f
- languageName: node
- linkType: hard
-
"webidl-conversions@npm:^3.0.0":
version: 3.0.1
resolution: "webidl-conversions@npm:3.0.1"
diff --git a/a3p-integration/proposals/z:acceptance/.gitignore b/a3p-integration/proposals/z:acceptance/.gitignore
index 2e83a4c6d68..146ed010dc0 100644
--- a/a3p-integration/proposals/z:acceptance/.gitignore
+++ b/a3p-integration/proposals/z:acceptance/.gitignore
@@ -1 +1,3 @@
!*submission/
+restart-valueVow
+start-valueVow
diff --git a/a3p-integration/proposals/z:acceptance/lib/vaults.mts b/a3p-integration/proposals/z:acceptance/lib/vaults.mts
new file mode 100644
index 00000000000..4ce6697f1ee
--- /dev/null
+++ b/a3p-integration/proposals/z:acceptance/lib/vaults.mts
@@ -0,0 +1,209 @@
+/* eslint-disable @jessie.js/safe-await-separator */
+/* eslint-env node */
+
+import { strict as assert } from 'node:assert';
+
+import {
+ addUser,
+ agops,
+ agoric,
+ ATOM_DENOM,
+ executeOffer,
+ GOV1ADDR,
+ GOV2ADDR,
+ GOV3ADDR,
+ provisionSmartWallet,
+ waitForBlock,
+} from '@agoric/synthetic-chain';
+
+const govAccounts = [GOV1ADDR, GOV2ADDR, GOV3ADDR];
+
+export const ISTunit = 1_000_000n; // aka displayInfo: { decimalPlaces: 6 }
+
+// XXX likely longer than necessary
+const VOTING_WAIT_MS = 65 * 1000;
+
+const proposeNewAuctionParams = async (
+ address: string,
+ startFequency: any,
+ clockStep: any,
+ priceLockPeriod: any,
+) => {
+ const charterAcceptOfferId = await agops.ec(
+ 'find-continuing-id',
+ '--for',
+ `${'charter\\ member\\ invitation'}`,
+ '--from',
+ address,
+ );
+
+ return executeOffer(
+ address,
+ agops.auctioneer(
+ 'proposeParamChange',
+ '--charterAcceptOfferId',
+ charterAcceptOfferId,
+ '--start-frequency',
+ startFequency,
+ '--clock-step',
+ clockStep,
+ '--price-lock-period',
+ priceLockPeriod,
+ ),
+ );
+};
+
+const voteForNewParams = (accounts: string[], position: number) => {
+ console.log('ACTIONS voting for position', position, 'using', accounts);
+ return Promise.all(
+ accounts.map((account: string) =>
+ agops.ec('vote', '--forPosition', position, '--send-from', account),
+ ),
+ );
+};
+
+const paramChangeOfferGeneration = async (
+ previousOfferId: string,
+ voteDur: number,
+ debtLimit: number | bigint,
+) => {
+ const voteDurSec = BigInt(voteDur);
+ const debtLimitValue = BigInt(debtLimit) * ISTunit;
+ const toSec = (ms: number) => BigInt(Math.round(ms / 1000));
+
+ const id = `propose-${Date.now()}`;
+ const deadline = toSec(Date.now()) + voteDurSec;
+
+ const zip = (xs: any[], ys: { [x: string]: any }) =>
+ xs.map((x: any, i: string | number) => [x, ys[i]]);
+ const fromSmallCapsEntries = (txt: string) => {
+ const { body, slots } = JSON.parse(txt);
+ const theEntries = zip(JSON.parse(body.slice(1)), slots).map(
+ ([[name, ref], boardID]) => {
+ const iface = ref.replace(/^\$\d+\./, '');
+ return [name, { iface, boardID }];
+ },
+ );
+ return Object.fromEntries(theEntries);
+ };
+
+ const slots = [] as string[]; // XXX global mutable state
+ const smallCaps = {
+ Nat: (n: any) => `+${n}`,
+ // XXX mutates obj
+ ref: (obj: { ix: string; boardID: any; iface: any }) => {
+ if (obj.ix) return obj.ix;
+ const ix = slots.length;
+ slots.push(obj.boardID);
+ obj.ix = `$${ix}.Alleged: ${obj.iface}`;
+ return obj.ix;
+ },
+ };
+
+ const instance = fromSmallCapsEntries(
+ await agoric.follow('-lF', ':published.agoricNames.instance', '-o', 'text'),
+ );
+ assert(instance.VaultFactory);
+
+ const brand = fromSmallCapsEntries(
+ await agoric.follow('-lF', ':published.agoricNames.brand', '-o', 'text'),
+ );
+ assert(brand.IST);
+ assert(brand.ATOM);
+
+ const body = {
+ method: 'executeOffer',
+ offer: {
+ id,
+ invitationSpec: {
+ invitationMakerName: 'VoteOnParamChange',
+ previousOffer: previousOfferId,
+ source: 'continuing',
+ },
+ offerArgs: {
+ deadline: smallCaps.Nat(deadline),
+ instance: smallCaps.ref(instance.VaultFactory),
+ params: {
+ DebtLimit: {
+ brand: smallCaps.ref(brand.IST),
+ value: smallCaps.Nat(debtLimitValue),
+ },
+ },
+ path: {
+ paramPath: {
+ key: {
+ collateralBrand: smallCaps.ref(brand.ATOM),
+ },
+ },
+ },
+ },
+ proposal: {},
+ },
+ };
+
+ const capData = { body: `#${JSON.stringify(body)}`, slots };
+ return JSON.stringify(capData);
+};
+export const provisionWallet = async (user: string) => {
+ const userAddress = await addUser(user);
+
+ await provisionSmartWallet(
+ userAddress,
+ `20000000ubld,100000000${ATOM_DENOM}`,
+ );
+ await waitForBlock();
+};
+
+export const implementNewAuctionParams = async (
+ address: string,
+ oracles: { address: string; id: string }[],
+ startFequency: number,
+ clockStep: number,
+ priceLockPeriod: number,
+) => {
+ await waitForBlock(3);
+
+ await proposeNewAuctionParams(
+ address,
+ startFequency,
+ clockStep,
+ priceLockPeriod,
+ );
+
+ console.log('ACTIONS voting for new auction params');
+ await voteForNewParams(govAccounts, 0);
+
+ console.log('ACTIONS wait for the vote deadline to pass');
+ await new Promise(r => setTimeout(r, VOTING_WAIT_MS));
+};
+
+export const proposeNewDebtCeiling = async (
+ address: string,
+ debtLimit: number | bigint,
+) => {
+ const charterAcceptOfferId = await agops.ec(
+ 'find-continuing-id',
+ '--for',
+ `${'charter\\ member\\ invitation'}`,
+ '--from',
+ address,
+ );
+
+ return executeOffer(
+ address,
+ paramChangeOfferGeneration(charterAcceptOfferId, 30, debtLimit),
+ );
+};
+
+export const setDebtLimit = async (
+ address: string,
+ debtLimit: number | bigint,
+) => {
+ console.log('ACTIONS Setting debt limit');
+
+ await proposeNewDebtCeiling(address, debtLimit);
+ await voteForNewParams(govAccounts, 0);
+
+ console.log('ACTIONS wait for the vote to pass');
+ await new Promise(r => setTimeout(r, VOTING_WAIT_MS));
+};
diff --git a/a3p-integration/proposals/z:acceptance/package.json b/a3p-integration/proposals/z:acceptance/package.json
index 0891c85d62a..fde9a21fc4d 100644
--- a/a3p-integration/proposals/z:acceptance/package.json
+++ b/a3p-integration/proposals/z:acceptance/package.json
@@ -1,15 +1,28 @@
{
"agoricProposal": {
- "type": "/cosmos.params.v1beta1.ParameterChangeProposal"
+ "type": "/agoric.swingset.CoreEvalProposal",
+ "sdk-generate": [
+ "testing/start-valueVow.js start-valueVow",
+ "testing/restart-valueVow.js restart-valueVow"
+ ]
},
"type": "module",
"license": "Apache-2.0",
"dependencies": {
- "@agoric/synthetic-chain": "^0.1.0",
- "ava": "^6.1.2"
+ "@agoric/internal": "0.3.3-dev-5676146.0",
+ "@agoric/synthetic-chain": "^0.2.1",
+ "@endo/errors": "^1.2.2",
+ "@endo/far": "^1.1.5",
+ "@endo/init": "^1.1.4",
+ "ava": "^6.1.2",
+ "tsx": "^4.17.0"
+ },
+ "resolutions": {
+ "execa": "^9.3.1"
},
"ava": {
"concurrency": 1,
+ "serial": true,
"timeout": "2m",
"files": [
"!submission"
@@ -18,5 +31,8 @@
"scripts": {
"agops": "yarn --cwd /usr/src/agoric-sdk/ --silent agops"
},
- "packageManager": "yarn@4.2.2"
+ "packageManager": "yarn@4.2.2",
+ "devDependencies": {
+ "typescript": "^5.5.4"
+ }
}
diff --git a/a3p-integration/proposals/z:acceptance/scripts/test-vaults.mts b/a3p-integration/proposals/z:acceptance/scripts/test-vaults.mts
new file mode 100755
index 00000000000..7fdbcef510a
--- /dev/null
+++ b/a3p-integration/proposals/z:acceptance/scripts/test-vaults.mts
@@ -0,0 +1,55 @@
+#!/usr/bin/env tsx
+/* eslint-disable @jessie.js/safe-await-separator */
+
+import {
+ agoric,
+ GOV1ADDR,
+ GOV2ADDR,
+ newOfferId,
+} from '@agoric/synthetic-chain';
+import assert from 'node:assert/strict';
+import {
+ implementNewAuctionParams,
+ ISTunit,
+ provisionWallet,
+ setDebtLimit,
+} from '../lib/vaults.mjs';
+
+const START_FREQUENCY = 600; // StartFrequency: 600s (auction runs every 10m)
+const CLOCK_STEP = 20; // ClockStep: 20s (ensures auction completes in time)
+const PRICE_LOCK_PERIOD = 300;
+const oraclesAddresses = [GOV1ADDR, GOV2ADDR];
+
+const oracles = [] as { address: string; id: string }[];
+for (const oracle of oraclesAddresses) {
+ const offerId = await newOfferId();
+ oracles.push({ address: oracle, id: offerId });
+}
+
+console.log('Ensure user2 provisioned');
+await provisionWallet('user2');
+
+console.log('Ensure auction params have changed');
+await implementNewAuctionParams(
+ GOV1ADDR,
+ oracles,
+ START_FREQUENCY,
+ CLOCK_STEP,
+ PRICE_LOCK_PERIOD,
+);
+
+const govParams = await agoric.follow('-lF', ':published.auction.governance');
+assert.equal(govParams.current.ClockStep.value.relValue, CLOCK_STEP.toString());
+assert.equal(
+ govParams.current.StartFrequency.value.relValue,
+ START_FREQUENCY.toString(),
+);
+
+console.log('Ensure debt ceiling changes');
+const limit = 45_000_000n;
+await setDebtLimit(GOV1ADDR, limit);
+const params = await agoric.follow(
+ '-lF',
+ ':published.vaultFactory.managers.manager0.governance',
+);
+assert.equal(params.current.DebtLimit.value.value, String(limit * ISTunit));
diff --git a/a3p-integration/proposals/c:stake-bld/test-lib/chain.js b/a3p-integration/proposals/z:acceptance/test-lib/chain.js
similarity index 100%
rename from a3p-integration/proposals/c:stake-bld/test-lib/chain.js
rename to a3p-integration/proposals/z:acceptance/test-lib/chain.js
diff --git a/a3p-integration/proposals/b:enable-orchestration/test-lib/index.js b/a3p-integration/proposals/z:acceptance/test-lib/index.js
similarity index 90%
rename from a3p-integration/proposals/b:enable-orchestration/test-lib/index.js
rename to a3p-integration/proposals/z:acceptance/test-lib/index.js
index 4e301fd9863..0c6fffa980a 100644
--- a/a3p-integration/proposals/b:enable-orchestration/test-lib/index.js
+++ b/a3p-integration/proposals/z:acceptance/test-lib/index.js
@@ -1,5 +1,4 @@
-/* global setTimeout */
-import fetch from 'node-fetch';
+/* global fetch setTimeout */
import { execFileSync } from 'child_process';
import { makeWalletUtils } from './wallet.js';
diff --git a/a3p-integration/proposals/b:enable-orchestration/test-lib/rpc.js b/a3p-integration/proposals/z:acceptance/test-lib/rpc.js
similarity index 100%
rename from a3p-integration/proposals/b:enable-orchestration/test-lib/rpc.js
rename to a3p-integration/proposals/z:acceptance/test-lib/rpc.js
diff --git a/a3p-integration/proposals/c:stake-bld/test-lib/wallet.js b/a3p-integration/proposals/z:acceptance/test-lib/wallet.js
similarity index 98%
rename from a3p-integration/proposals/c:stake-bld/test-lib/wallet.js
rename to a3p-integration/proposals/z:acceptance/test-lib/wallet.js
index bb75e7b784d..5fbe9b70027 100644
--- a/a3p-integration/proposals/c:stake-bld/test-lib/wallet.js
+++ b/a3p-integration/proposals/z:acceptance/test-lib/wallet.js
@@ -53,7 +53,7 @@ export const getCurrent = async (addr, { readLatestHead }) => {
await readLatestHead(`published.wallet.${addr}.current`)
);
if (current === undefined) {
- throw new Error(`undefined current node for ${addr}`);
+ throw Error(`undefined current node for ${addr}`);
}
// Repair a type misunderstanding seen in the wild.
diff --git a/a3p-integration/proposals/z:acceptance/test.sh b/a3p-integration/proposals/z:acceptance/test.sh
index 7e4b0145a04..0eb07f8af7f 100755
--- a/a3p-integration/proposals/z:acceptance/test.sh
+++ b/a3p-integration/proposals/z:acceptance/test.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+set -ueo pipefail
# Place here any test that should be executed using the executed proposal.
# The effects of this step are not persisted in further proposal layers.
@@ -6,11 +7,18 @@
# test the state right after the previous proposals
yarn ava initial.test.js
-# test more, in ways that change system state
-GLOBIGNORE=initial.test.js
-yarn ava ./*.test.js
+# XXX some of these tests have path dependencies so no globs
+yarn ava core-eval.test.js
+npm install -g tsx
+scripts/test-vaults.mts
+
+echo ACCEPTANCE TESTING kread
./create-kread-item-test.sh
+echo ACCEPTANCE TESTING valueVow
+yarn ava valueVow.test.js
+
+echo ACCEPTANCE TESTING state sync
./state-sync-snapshots-test.sh
./genesis-test.sh
diff --git a/a3p-integration/proposals/z:acceptance/tsconfig.json b/a3p-integration/proposals/z:acceptance/tsconfig.json
index 02e3bea3c6d..795ebdd04fc 100644
--- a/a3p-integration/proposals/z:acceptance/tsconfig.json
+++ b/a3p-integration/proposals/z:acceptance/tsconfig.json
@@ -2,11 +2,14 @@
"compilerOptions": {
"noEmit": true,
"target": "esnext",
- "module": "esnext",
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
"allowJs": true,
"checkJs": true,
"strict": false,
"strictNullChecks": true,
- "noImplicitThis": true
+ "noImplicitThis": true,
+ // XXX synthetic-chain has some errors
+ "skipLibCheck": true,
}
}
diff --git a/a3p-integration/proposals/b:enable-orchestration/valueVow.test.js b/a3p-integration/proposals/z:acceptance/valueVow.test.js
similarity index 98%
rename from a3p-integration/proposals/b:enable-orchestration/valueVow.test.js
rename to a3p-integration/proposals/z:acceptance/valueVow.test.js
index 2d96393c24a..faec82e710a 100644
--- a/a3p-integration/proposals/b:enable-orchestration/valueVow.test.js
+++ b/a3p-integration/proposals/z:acceptance/valueVow.test.js
@@ -1,7 +1,7 @@
// @ts-check
import test from 'ava';
import { inspect } from 'node:util';
-import '@endo/init';
+import '@endo/init/debug.js';
import {
evalBundles,
diff --git a/a3p-integration/proposals/z:acceptance/yarn.lock b/a3p-integration/proposals/z:acceptance/yarn.lock
index 708f6030037..aaf12baa475 100644
--- a/a3p-integration/proposals/z:acceptance/yarn.lock
+++ b/a3p-integration/proposals/z:acceptance/yarn.lock
@@ -5,24 +5,413 @@ __metadata:
version: 8
cacheKey: 10c0
-"@agoric/synthetic-chain@npm:^0.1.0":
- version: 0.1.0
- resolution: "@agoric/synthetic-chain@npm:0.1.0"
+"@agoric/assert@npm:0.6.1-dev-5676146.0+5676146":
+ version: 0.6.1-dev-5676146.0
+ resolution: "@agoric/assert@npm:0.6.1-dev-5676146.0"
+ checksum: 10c0/3391d53d64f4ca74ae5a87b623dc7489a20d91f45716723c33e393cfe6536fb1553344b72d24ac966f49b83d56906140c263778968ff513dfcdbb30e1be68091
+ languageName: node
+ linkType: hard
+
+"@agoric/base-zone@npm:0.1.1-dev-5676146.0+5676146":
+ version: 0.1.1-dev-5676146.0
+ resolution: "@agoric/base-zone@npm:0.1.1-dev-5676146.0"
+ dependencies:
+ "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146"
+ "@endo/common": "npm:^1.1.0"
+ "@endo/exo": "npm:^1.2.1"
+ "@endo/far": "npm:^1.0.4"
+ "@endo/pass-style": "npm:^1.2.0"
+ "@endo/patterns": "npm:^1.2.0"
+ checksum: 10c0/b3dfa47af7cf4a686244e2a31243394b44756f127a7612f5d50c77b1a91f777514386c305866705b46219d2d1e0df2b8d5bff9e08f82275043bb0c198c0601e4
+ languageName: node
+ linkType: hard
+
+"@agoric/internal@npm:0.3.3-dev-5676146.0":
+ version: 0.3.3-dev-5676146.0
+ resolution: "@agoric/internal@npm:0.3.3-dev-5676146.0"
+ dependencies:
+ "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146"
+ "@agoric/base-zone": "npm:0.1.1-dev-5676146.0+5676146"
+ "@endo/common": "npm:^1.1.0"
+ "@endo/far": "npm:^1.0.4"
+ "@endo/init": "npm:^1.0.4"
+ "@endo/marshal": "npm:^1.3.0"
+ "@endo/patterns": "npm:^1.2.0"
+ "@endo/promise-kit": "npm:^1.0.4"
+ "@endo/stream": "npm:^1.1.0"
+ anylogger: "npm:^0.21.0"
+ jessie.js: "npm:^0.3.2"
+ checksum: 10c0/cd2a81ff39790a1b333621b3815f0791b70d0822f201d491175e46602697c80814f1fb87a610167e541a9ad431a771cd7348afe24517a15c45d1591d3d494bc2
+ languageName: node
+ linkType: hard
+
+"@agoric/store@npm:0.9.3-dev-5676146.0+5676146":
+ version: 0.9.3-dev-5676146.0
+ resolution: "@agoric/store@npm:0.9.3-dev-5676146.0"
dependencies:
- "@endo/zip": "npm:^1.0.1"
- better-sqlite3: "npm:^9.4.0"
+ "@endo/exo": "npm:^1.2.1"
+ "@endo/marshal": "npm:^1.3.0"
+ "@endo/pass-style": "npm:^1.2.0"
+ "@endo/patterns": "npm:^1.2.0"
+ checksum: 10c0/675e73bbcac024c456b658583ec3fd14a50f69fea5fc07aadf30e593978e5cadbc82d365b13976967b5509614a7adf0adad4e84712f7e0b6c13f2a2a93c9ea63
+ languageName: node
+ linkType: hard
+
+"@agoric/synthetic-chain@npm:^0.2.1":
+ version: 0.2.1
+ resolution: "@agoric/synthetic-chain@npm:0.2.1"
+ dependencies:
+ "@endo/zip": "npm:^1.0.6"
+ better-sqlite3: "npm:^9.6.0"
chalk: "npm:^5.3.0"
+ cosmjs-types: "npm:^0.9.0"
execa: "npm:^8.0.1"
bin:
synthetic-chain: dist/cli/cli.js
- checksum: 10c0/8305293d085cde9cbf94670134216e06337c5624c45faf5dfebb86762042abe7b4340cf3205e671dfce54e888bd4e9b3428400756833fa06f2bbb21b44668c44
+ checksum: 10c0/ca3bfe968d0f157b4fdad3cc7e234c0d38f2eb8cc55ce4cb0a82f02a5371ef49d534fec05be6ef769cb166d0da278fb3e900b5882d08410008c2bb5e7e719de3
languageName: node
linkType: hard
-"@endo/zip@npm:^1.0.1":
- version: 1.0.1
- resolution: "@endo/zip@npm:1.0.1"
- checksum: 10c0/1074bdc10287f4c94b3423e130da88f9c6ba09c999483c1164b3eed061350a060d2dbe377cfa3b8d4a86b3f1c3aed5cbf0cdd78ee2bf2cb9b837caa2ebbf712f
+"@endo/base64@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "@endo/base64@npm:1.0.7"
+ checksum: 10c0/aab10f433f8ea588ebd1786188b6660c0be3a743c119ef2df52ee23afd4ce3844b1d954028952569a747f6657287aeced875afe8e136ea8bff4ba146a60578bd
+ languageName: node
+ linkType: hard
+
+"@endo/common@npm:^1.1.0, @endo/common@npm:^1.2.5":
+ version: 1.2.5
+ resolution: "@endo/common@npm:1.2.5"
+ dependencies:
+ "@endo/errors": "npm:^1.2.5"
+ "@endo/eventual-send": "npm:^1.2.5"
+ "@endo/promise-kit": "npm:^1.1.5"
+ checksum: 10c0/104ca2febd87d05b97a77037cb0f281157082b722a39f3fbfca94e36984ad8bc8622e900aeba861d7ed6e6b5d103971599ec2b804eb236537576d498f9ab1fe5
+ languageName: node
+ linkType: hard
+
+"@endo/env-options@npm:^1.1.6":
+ version: 1.1.6
+ resolution: "@endo/env-options@npm:1.1.6"
+ checksum: 10c0/0001b1cba6954cccfa40104f819378f2f5c8babc89103213a8a5da4f8f94248c8389bfa06ec37cecae81edabe570428558399313d649c64ad7c90743f563dea2
+ languageName: node
+ linkType: hard
+
+"@endo/errors@npm:^1.2.2, @endo/errors@npm:^1.2.5":
+ version: 1.2.5
+ resolution: "@endo/errors@npm:1.2.5"
+ dependencies:
+ ses: "npm:^1.8.0"
+ checksum: 10c0/32eac3b332139ddec8a85a0013645482541e4f3cc0c484073dde430087f27bb683cde8b0a6e399c5b7f07af007c3b6aa589cf31935a8b8d69e5f869bf71a1662
+ languageName: node
+ linkType: hard
+
+"@endo/eventual-send@npm:^1.2.5":
+ version: 1.2.5
+ resolution: "@endo/eventual-send@npm:1.2.5"
+ dependencies:
+ "@endo/env-options": "npm:^1.1.6"
+ checksum: 10c0/7eaa30628582f768920659e4894b871c1056da4252b82b8ad70ed49a24c4559efb8d1655a6845984a0eae83d328179e4272b0917007a2f147dc8b15ecb0ecc52
+ languageName: node
+ linkType: hard
+
+"@endo/exo@npm:^1.2.1":
+ version: 1.5.3
+ resolution: "@endo/exo@npm:1.5.3"
+ dependencies:
+ "@endo/common": "npm:^1.2.5"
+ "@endo/env-options": "npm:^1.1.6"
+ "@endo/errors": "npm:^1.2.5"
+ "@endo/eventual-send": "npm:^1.2.5"
+ "@endo/far": "npm:^1.1.5"
+ "@endo/pass-style": "npm:^1.4.3"
+ "@endo/patterns": "npm:^1.4.3"
+ checksum: 10c0/5510bc442730910ce2470c6ebdb6c04208c033e452cd60c8684e1769039453ad5f47de31b00629be3c6bf4183bee4a421bace142144e92740b606c591a839c72
+ languageName: node
+ linkType: hard
+
+"@endo/far@npm:^1.0.0, @endo/far@npm:^1.0.4, @endo/far@npm:^1.1.5":
+ version: 1.1.5
+ resolution: "@endo/far@npm:1.1.5"
+ dependencies:
+ "@endo/errors": "npm:^1.2.5"
+ "@endo/eventual-send": "npm:^1.2.5"
+ "@endo/pass-style": "npm:^1.4.3"
+ checksum: 10c0/8c50a28323ab1078d0cb6fce1d7fc6da4884247d76585f37f960a2a7134fc7f293075effaae34b41801b7508a1f75d32304c19db0597709727853c4a87eb4999
+ languageName: node
+ linkType: hard
+
+"@endo/init@npm:^1.0.4, @endo/init@npm:^1.1.4":
+ version: 1.1.4
+ resolution: "@endo/init@npm:1.1.4"
+ dependencies:
+ "@endo/base64": "npm:^1.0.7"
+ "@endo/eventual-send": "npm:^1.2.5"
+ "@endo/lockdown": "npm:^1.0.10"
+ "@endo/promise-kit": "npm:^1.1.5"
+ checksum: 10c0/9e915b3b888b7a9f1d563d532ad180dea987253d71e79eda1fcda8d287391611bcca369f2d9b89c59b9f24b3adc548816954e8eaefa4f7402c68585245a686a5
+ languageName: node
+ linkType: hard
+
+"@endo/lockdown@npm:^1.0.10":
+ version: 1.0.10
+ resolution: "@endo/lockdown@npm:1.0.10"
+ dependencies:
+ ses: "npm:^1.8.0"
+ checksum: 10c0/94be0c1b14cacb2d8088dcc17998e901159a028c51170d78a8cc6a820ae76cabc7d2694f1a1956cb4eab70a8c9a0c8254d88ea4c3f3d9725b739aacf6db83d5b
+ languageName: node
+ linkType: hard
+
+"@endo/marshal@npm:^1.3.0, @endo/marshal@npm:^1.5.3":
+ version: 1.5.3
+ resolution: "@endo/marshal@npm:1.5.3"
+ dependencies:
+ "@endo/common": "npm:^1.2.5"
+ "@endo/errors": "npm:^1.2.5"
+ "@endo/eventual-send": "npm:^1.2.5"
+ "@endo/nat": "npm:^5.0.10"
+ "@endo/pass-style": "npm:^1.4.3"
+ "@endo/promise-kit": "npm:^1.1.5"
+ checksum: 10c0/05f4fceef7727971d3d2a1b8d87f4d9c6651772f9d231e2daa36c3ed0b0e13c3b8d26cb4828ecaadf4329bf77792a293507eadcff7a61df292d4e390936993d1
+ languageName: node
+ linkType: hard
+
+"@endo/nat@npm:^5.0.10":
+ version: 5.0.10
+ resolution: "@endo/nat@npm:5.0.10"
+ checksum: 10c0/7ad2aa2d216d517409c771aebb465aceb6ea8b88ec808c2dc030d7ffc7fe7d601d8401572f3866384a63ff2aa74209a22f29e1561e773d91d7ad2d81fa13fc7e
+ languageName: node
+ linkType: hard
+
+"@endo/pass-style@npm:^1.2.0, @endo/pass-style@npm:^1.4.3":
+ version: 1.4.3
+ resolution: "@endo/pass-style@npm:1.4.3"
+ dependencies:
+ "@endo/env-options": "npm:^1.1.6"
+ "@endo/errors": "npm:^1.2.5"
+ "@endo/eventual-send": "npm:^1.2.5"
+ "@endo/promise-kit": "npm:^1.1.5"
+ "@fast-check/ava": "npm:^1.1.5"
+ checksum: 10c0/f24c528b1219f5aa122f9a04e80459dec3e9664e7849019b172ad8354870b849b643c8dfc79104857827457d66b2bb09bade9b2c6ea717a97e613ecf6d53c1f9
+ languageName: node
+ linkType: hard
+
+"@endo/patterns@npm:^1.2.0, @endo/patterns@npm:^1.4.3":
+ version: 1.4.3
+ resolution: "@endo/patterns@npm:1.4.3"
+ dependencies:
+ "@endo/common": "npm:^1.2.5"
+ "@endo/errors": "npm:^1.2.5"
+ "@endo/eventual-send": "npm:^1.2.5"
+ "@endo/marshal": "npm:^1.5.3"
+ "@endo/promise-kit": "npm:^1.1.5"
+ checksum: 10c0/10aabc6459d1b5d26e8946ab1b88db23eda80231aa6a0b6c9835568eee1daf745d23c29fa7f202bf11859a7ae77d5f51071c3d863d34e259a62c382ec797bb03
+ languageName: node
+ linkType: hard
+
+"@endo/promise-kit@npm:^1.0.4, @endo/promise-kit@npm:^1.1.5":
+ version: 1.1.5
+ resolution: "@endo/promise-kit@npm:1.1.5"
+ dependencies:
+ ses: "npm:^1.8.0"
+ checksum: 10c0/3a9fb59546507dbbb8c83ada4de664ca4f6085ffcb56c9e3e07789e002e717454b1ee5ae1273549935a7e77ac42be7ae8ddca94ff6d4f16914210d31159ce1a4
+ languageName: node
+ linkType: hard
+
+"@endo/stream@npm:^1.1.0":
+ version: 1.2.5
+ resolution: "@endo/stream@npm:1.2.5"
+ dependencies:
+ "@endo/eventual-send": "npm:^1.2.5"
+ "@endo/promise-kit": "npm:^1.1.5"
+ ses: "npm:^1.8.0"
+ checksum: 10c0/625fd9b8b485149c269a01673b76b33fadd0702d76eb37f136c9f7558252e3d51cc9602b2880f1b43971a00f41e5d3e3d2b3a6ebef6f0253bb314d9a144a2cf5
+ languageName: node
+ linkType: hard
+
+"@endo/zip@npm:^1.0.6":
+ version: 1.0.7
+ resolution: "@endo/zip@npm:1.0.7"
+ checksum: 10c0/a1c0d155448ce877012b34c8fe8cd3a58de9eb807514c81cddeebb802ee8e552b27d8a9a40fab3f3e4c49e0cb7fea6902fa1dd12a23ff6f30b56161fc3edc1f8
+ languageName: node
+ linkType: hard
+
+"@esbuild/aix-ppc64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/aix-ppc64@npm:0.23.1"
+ conditions: os=aix & cpu=ppc64
+ languageName: node
+ linkType: hard
+
+"@esbuild/android-arm64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/android-arm64@npm:0.23.1"
+ conditions: os=android & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@esbuild/android-arm@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/android-arm@npm:0.23.1"
+ conditions: os=android & cpu=arm
+ languageName: node
+ linkType: hard
+
+"@esbuild/android-x64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/android-x64@npm:0.23.1"
+ conditions: os=android & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@esbuild/darwin-arm64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/darwin-arm64@npm:0.23.1"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@esbuild/darwin-x64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/darwin-x64@npm:0.23.1"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@esbuild/freebsd-arm64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/freebsd-arm64@npm:0.23.1"
+ conditions: os=freebsd & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@esbuild/freebsd-x64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/freebsd-x64@npm:0.23.1"
+ conditions: os=freebsd & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-arm64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-arm64@npm:0.23.1"
+ conditions: os=linux & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-arm@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-arm@npm:0.23.1"
+ conditions: os=linux & cpu=arm
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-ia32@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-ia32@npm:0.23.1"
+ conditions: os=linux & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-loong64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-loong64@npm:0.23.1"
+ conditions: os=linux & cpu=loong64
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-mips64el@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-mips64el@npm:0.23.1"
+ conditions: os=linux & cpu=mips64el
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-ppc64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-ppc64@npm:0.23.1"
+ conditions: os=linux & cpu=ppc64
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-riscv64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-riscv64@npm:0.23.1"
+ conditions: os=linux & cpu=riscv64
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-s390x@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-s390x@npm:0.23.1"
+ conditions: os=linux & cpu=s390x
+ languageName: node
+ linkType: hard
+
+"@esbuild/linux-x64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/linux-x64@npm:0.23.1"
+ conditions: os=linux & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@esbuild/netbsd-x64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/netbsd-x64@npm:0.23.1"
+ conditions: os=netbsd & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@esbuild/openbsd-arm64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/openbsd-arm64@npm:0.23.1"
+ conditions: os=openbsd & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@esbuild/openbsd-x64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/openbsd-x64@npm:0.23.1"
+ conditions: os=openbsd & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@esbuild/sunos-x64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/sunos-x64@npm:0.23.1"
+ conditions: os=sunos & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@esbuild/win32-arm64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/win32-arm64@npm:0.23.1"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@esbuild/win32-ia32@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/win32-ia32@npm:0.23.1"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@esbuild/win32-x64@npm:0.23.1":
+ version: 0.23.1
+ resolution: "@esbuild/win32-x64@npm:0.23.1"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@fast-check/ava@npm:^1.1.5":
+ version: 1.2.1
+ resolution: "@fast-check/ava@npm:1.2.1"
+ dependencies:
+ fast-check: "npm:^3.0.0"
+ peerDependencies:
+ ava: ^4 || ^5 || ^6
+ checksum: 10c0/3800098fd7e8098102544a2f7a595351d063a7ebaeca18ed4901df5ec2679da2330ba8c0db2c820721d4cbb3e23d817ba22fec6d058957930e229f44fa71a684
languageName: node
linkType: hard
@@ -125,6 +514,13 @@ __metadata:
languageName: node
linkType: hard
+"@sec-ant/readable-stream@npm:^0.4.1":
+ version: 0.4.1
+ resolution: "@sec-ant/readable-stream@npm:0.4.1"
+ checksum: 10c0/64e9e9cf161e848067a5bf60cdc04d18495dc28bb63a8d9f8993e4dd99b91ad34e4b563c85de17d91ffb177ec17a0664991d2e115f6543e73236a906068987af
+ languageName: node
+ linkType: hard
+
"@sindresorhus/merge-streams@npm:^2.1.0":
version: 2.3.0
resolution: "@sindresorhus/merge-streams@npm:2.3.0"
@@ -132,6 +528,13 @@ __metadata:
languageName: node
linkType: hard
+"@sindresorhus/merge-streams@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "@sindresorhus/merge-streams@npm:4.0.0"
+ checksum: 10c0/482ee543629aa1933b332f811a1ae805a213681ecdd98c042b1c1b89387df63e7812248bb4df3910b02b3cc5589d3d73e4393f30e197c9dde18046ccd471fc6b
+ languageName: node
+ linkType: hard
+
"@vercel/nft@npm:^0.26.2":
version: 0.26.4
resolution: "@vercel/nft@npm:0.26.4"
@@ -251,6 +654,13 @@ __metadata:
languageName: node
linkType: hard
+"anylogger@npm:^0.21.0":
+ version: 0.21.0
+ resolution: "anylogger@npm:0.21.0"
+ checksum: 10c0/1ca7fcf5bc2b78d1e1d9b8c8cc7ce50b5c6cc67a8da5a28c9c975b7b46fff255a04abab02de38a5139190c9d8b34b3d6c59af6724521b077f7d7dfbad9b47a9c
+ languageName: node
+ linkType: hard
+
"aproba@npm:^1.0.3 || ^2.0.0":
version: 2.0.0
resolution: "aproba@npm:2.0.0"
@@ -374,14 +784,14 @@ __metadata:
languageName: node
linkType: hard
-"better-sqlite3@npm:^9.4.0":
- version: 9.4.0
- resolution: "better-sqlite3@npm:9.4.0"
+"better-sqlite3@npm:^9.6.0":
+ version: 9.6.0
+ resolution: "better-sqlite3@npm:9.6.0"
dependencies:
bindings: "npm:^1.5.0"
node-gyp: "npm:latest"
prebuild-install: "npm:^7.1.1"
- checksum: 10c0/42b2edfa46d62763514b87122245a3513a5ff20f05fef4fb49fec33f3de0a51a29025596178f57c634b8013f16bbdf8169a308fb3e3b8d126d715788d72d1e74
+ checksum: 10c0/8db9b38f414e26a56d4c40fc16e94a253118491dae0e2c054338a9e470f1a883c7eb4cb330f2f5737db30f704d4f2e697c59071ca04e03364ee9fe04375aa9c8
languageName: node
linkType: hard
@@ -634,6 +1044,13 @@ __metadata:
languageName: node
linkType: hard
+"cosmjs-types@npm:^0.9.0":
+ version: 0.9.0
+ resolution: "cosmjs-types@npm:0.9.0"
+ checksum: 10c0/bc20f4293fb34629d7c5f96bafe533987f753df957ff68eb078d0128ae5a418320cb945024441769a07bb9bc5dde9d22b972fd40d485933e5706ea191c43727b
+ languageName: node
+ linkType: hard
+
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
@@ -772,6 +1189,89 @@ __metadata:
languageName: node
linkType: hard
+"esbuild@npm:~0.23.0":
+ version: 0.23.1
+ resolution: "esbuild@npm:0.23.1"
+ dependencies:
+ "@esbuild/aix-ppc64": "npm:0.23.1"
+ "@esbuild/android-arm": "npm:0.23.1"
+ "@esbuild/android-arm64": "npm:0.23.1"
+ "@esbuild/android-x64": "npm:0.23.1"
+ "@esbuild/darwin-arm64": "npm:0.23.1"
+ "@esbuild/darwin-x64": "npm:0.23.1"
+ "@esbuild/freebsd-arm64": "npm:0.23.1"
+ "@esbuild/freebsd-x64": "npm:0.23.1"
+ "@esbuild/linux-arm": "npm:0.23.1"
+ "@esbuild/linux-arm64": "npm:0.23.1"
+ "@esbuild/linux-ia32": "npm:0.23.1"
+ "@esbuild/linux-loong64": "npm:0.23.1"
+ "@esbuild/linux-mips64el": "npm:0.23.1"
+ "@esbuild/linux-ppc64": "npm:0.23.1"
+ "@esbuild/linux-riscv64": "npm:0.23.1"
+ "@esbuild/linux-s390x": "npm:0.23.1"
+ "@esbuild/linux-x64": "npm:0.23.1"
+ "@esbuild/netbsd-x64": "npm:0.23.1"
+ "@esbuild/openbsd-arm64": "npm:0.23.1"
+ "@esbuild/openbsd-x64": "npm:0.23.1"
+ "@esbuild/sunos-x64": "npm:0.23.1"
+ "@esbuild/win32-arm64": "npm:0.23.1"
+ "@esbuild/win32-ia32": "npm:0.23.1"
+ "@esbuild/win32-x64": "npm:0.23.1"
+ dependenciesMeta:
+ "@esbuild/aix-ppc64":
+ optional: true
+ "@esbuild/android-arm":
+ optional: true
+ "@esbuild/android-arm64":
+ optional: true
+ "@esbuild/android-x64":
+ optional: true
+ "@esbuild/darwin-arm64":
+ optional: true
+ "@esbuild/darwin-x64":
+ optional: true
+ "@esbuild/freebsd-arm64":
+ optional: true
+ "@esbuild/freebsd-x64":
+ optional: true
+ "@esbuild/linux-arm":
+ optional: true
+ "@esbuild/linux-arm64":
+ optional: true
+ "@esbuild/linux-ia32":
+ optional: true
+ "@esbuild/linux-loong64":
+ optional: true
+ "@esbuild/linux-mips64el":
+ optional: true
+ "@esbuild/linux-ppc64":
+ optional: true
+ "@esbuild/linux-riscv64":
+ optional: true
+ "@esbuild/linux-s390x":
+ optional: true
+ "@esbuild/linux-x64":
+ optional: true
+ "@esbuild/netbsd-x64":
+ optional: true
+ "@esbuild/openbsd-arm64":
+ optional: true
+ "@esbuild/openbsd-x64":
+ optional: true
+ "@esbuild/sunos-x64":
+ optional: true
+ "@esbuild/win32-arm64":
+ optional: true
+ "@esbuild/win32-ia32":
+ optional: true
+ "@esbuild/win32-x64":
+ optional: true
+ bin:
+ esbuild: bin/esbuild
+ checksum: 10c0/08c2ed1105cc3c5e3a24a771e35532fe6089dd24a39c10097899072cef4a99f20860e41e9294e000d86380f353b04d8c50af482483d7f69f5208481cce61eec7
+ languageName: node
+ linkType: hard
+
"escalade@npm:^3.1.1":
version: 3.1.1
resolution: "escalade@npm:3.1.1"
@@ -817,20 +1317,23 @@ __metadata:
languageName: node
linkType: hard
-"execa@npm:^8.0.1":
- version: 8.0.1
- resolution: "execa@npm:8.0.1"
+"execa@npm:^9.3.1":
+ version: 9.3.1
+ resolution: "execa@npm:9.3.1"
dependencies:
+ "@sindresorhus/merge-streams": "npm:^4.0.0"
cross-spawn: "npm:^7.0.3"
- get-stream: "npm:^8.0.1"
- human-signals: "npm:^5.0.0"
- is-stream: "npm:^3.0.0"
- merge-stream: "npm:^2.0.0"
- npm-run-path: "npm:^5.1.0"
- onetime: "npm:^6.0.0"
+ figures: "npm:^6.1.0"
+ get-stream: "npm:^9.0.0"
+ human-signals: "npm:^8.0.0"
+ is-plain-obj: "npm:^4.1.0"
+ is-stream: "npm:^4.0.1"
+ npm-run-path: "npm:^5.2.0"
+ pretty-ms: "npm:^9.0.0"
signal-exit: "npm:^4.1.0"
- strip-final-newline: "npm:^3.0.0"
- checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af
+ strip-final-newline: "npm:^4.0.0"
+ yoctocolors: "npm:^2.0.0"
+ checksum: 10c0/113979ff56575f6cb69fd021eb3894a674fb59b264f5e8c2b9b30e301629abc4f44cee881e680f9fb3b7d4956645df76a2d8c0006869dea985f96ec65f07b226
languageName: node
linkType: hard
@@ -848,6 +1351,15 @@ __metadata:
languageName: node
linkType: hard
+"fast-check@npm:^3.0.0":
+ version: 3.22.0
+ resolution: "fast-check@npm:3.22.0"
+ dependencies:
+ pure-rand: "npm:^6.1.0"
+ checksum: 10c0/15c70f83df655f9bdcec4f8ed7e3207a933bf6e22c220a4fafc7ea17a28a009bc5d0a85588689f5726e3514796745cb5b35e7295ce469ac286992548fd55cc1d
+ languageName: node
+ linkType: hard
+
"fast-diff@npm:^1.2.0":
version: 1.3.0
resolution: "fast-diff@npm:1.3.0"
@@ -877,7 +1389,7 @@ __metadata:
languageName: node
linkType: hard
-"figures@npm:^6.0.1":
+"figures@npm:^6.0.1, figures@npm:^6.1.0":
version: 6.1.0
resolution: "figures@npm:6.1.0"
dependencies:
@@ -951,6 +1463,25 @@ __metadata:
languageName: node
linkType: hard
+"fsevents@npm:~2.3.3":
+ version: 2.3.3
+ resolution: "fsevents@npm:2.3.3"
+ dependencies:
+ node-gyp: "npm:latest"
+ checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
+"fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin":
+ version: 2.3.3
+ resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"
+ dependencies:
+ node-gyp: "npm:latest"
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
"gauge@npm:^3.0.0":
version: 3.0.2
resolution: "gauge@npm:3.0.2"
@@ -982,10 +1513,22 @@ __metadata:
languageName: node
linkType: hard
-"get-stream@npm:^8.0.1":
- version: 8.0.1
- resolution: "get-stream@npm:8.0.1"
- checksum: 10c0/5c2181e98202b9dae0bb4a849979291043e5892eb40312b47f0c22b9414fc9b28a3b6063d2375705eb24abc41ecf97894d9a51f64ff021511b504477b27b4290
+"get-stream@npm:^9.0.0":
+ version: 9.0.1
+ resolution: "get-stream@npm:9.0.1"
+ dependencies:
+ "@sec-ant/readable-stream": "npm:^0.4.1"
+ is-stream: "npm:^4.0.1"
+ checksum: 10c0/d70e73857f2eea1826ac570c3a912757dcfbe8a718a033fa0c23e12ac8e7d633195b01710e0559af574cbb5af101009b42df7b6f6b29ceec8dbdf7291931b948
+ languageName: node
+ linkType: hard
+
+"get-tsconfig@npm:^4.7.5":
+ version: 4.7.6
+ resolution: "get-tsconfig@npm:4.7.6"
+ dependencies:
+ resolve-pkg-maps: "npm:^1.0.0"
+ checksum: 10c0/2240e1b13e996dfbb947d177f422f83d09d1f93c9ce16959ebb3c2bdf8bdf4f04f98eba043859172da1685f9c7071091f0acfa964ebbe4780394d83b7dc3f58a
languageName: node
linkType: hard
@@ -1099,10 +1642,10 @@ __metadata:
languageName: node
linkType: hard
-"human-signals@npm:^5.0.0":
- version: 5.0.0
- resolution: "human-signals@npm:5.0.0"
- checksum: 10c0/5a9359073fe17a8b58e5a085e9a39a950366d9f00217c4ff5878bd312e09d80f460536ea6a3f260b5943a01fe55c158d1cea3fc7bee3d0520aeef04f6d915c82
+"human-signals@npm:^8.0.0":
+ version: 8.0.0
+ resolution: "human-signals@npm:8.0.0"
+ checksum: 10c0/e4dac4f7d3eb791ed04129fc6a85bd454a9102d3e3b76c911d0db7057ebd60b2956b435b5b5712aec18960488ede3c21ef7c56e42cdd70760c0d84d3c05cd92e
languageName: node
linkType: hard
@@ -1239,6 +1782,13 @@ __metadata:
languageName: node
linkType: hard
+"is-plain-obj@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "is-plain-obj@npm:4.1.0"
+ checksum: 10c0/32130d651d71d9564dc88ba7e6fda0e91a1010a3694648e9f4f47bb6080438140696d3e3e15c741411d712e47ac9edc1a8a9de1fe76f3487b0d90be06ac9975e
+ languageName: node
+ linkType: hard
+
"is-plain-object@npm:^5.0.0":
version: 5.0.0
resolution: "is-plain-object@npm:5.0.0"
@@ -1253,10 +1803,10 @@ __metadata:
languageName: node
linkType: hard
-"is-stream@npm:^3.0.0":
- version: 3.0.0
- resolution: "is-stream@npm:3.0.0"
- checksum: 10c0/eb2f7127af02ee9aa2a0237b730e47ac2de0d4e76a4a905a50a11557f2339df5765eaea4ceb8029f1efa978586abe776908720bfcb1900c20c6ec5145f6f29d8
+"is-stream@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "is-stream@npm:4.0.1"
+ checksum: 10c0/2706c7f19b851327ba374687bc4a3940805e14ca496dc672b9629e744d143b1ad9c6f1b162dece81c7bfbc0f83b32b61ccc19ad2e05aad2dd7af347408f60c7f
languageName: node
linkType: hard
@@ -1294,6 +1844,15 @@ __metadata:
languageName: node
linkType: hard
+"jessie.js@npm:^0.3.2":
+ version: 0.3.4
+ resolution: "jessie.js@npm:0.3.4"
+ dependencies:
+ "@endo/far": "npm:^1.0.0"
+ checksum: 10c0/853ab3f8a0e30df11742882f5e11479d1303033a5a203a247d8ffbf4c6f3f3d4bcbefa53084ae4632e6ab106e348f23dc988280486cbeaaf5d16487fa3d40e96
+ languageName: node
+ linkType: hard
+
"js-string-escape@npm:^1.0.1":
version: 1.0.1
resolution: "js-string-escape@npm:1.0.1"
@@ -1398,13 +1957,6 @@ __metadata:
languageName: node
linkType: hard
-"merge-stream@npm:^2.0.0":
- version: 2.0.0
- resolution: "merge-stream@npm:2.0.0"
- checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5
- languageName: node
- linkType: hard
-
"merge2@npm:^1.3.0":
version: 1.4.1
resolution: "merge2@npm:1.4.1"
@@ -1422,13 +1974,6 @@ __metadata:
languageName: node
linkType: hard
-"mimic-fn@npm:^4.0.0":
- version: 4.0.0
- resolution: "mimic-fn@npm:4.0.0"
- checksum: 10c0/de9cc32be9996fd941e512248338e43407f63f6d497abe8441fa33447d922e927de54d4cc3c1a3c6d652857acd770389d5a3823f311a744132760ce2be15ccbf
- languageName: node
- linkType: hard
-
"mimic-function@npm:^5.0.0":
version: 5.0.1
resolution: "mimic-function@npm:5.0.1"
@@ -1679,12 +2224,12 @@ __metadata:
languageName: node
linkType: hard
-"npm-run-path@npm:^5.1.0":
- version: 5.1.0
- resolution: "npm-run-path@npm:5.1.0"
+"npm-run-path@npm:^5.2.0":
+ version: 5.3.0
+ resolution: "npm-run-path@npm:5.3.0"
dependencies:
path-key: "npm:^4.0.0"
- checksum: 10c0/ff6d77514489f47fa1c3b1311d09cd4b6d09a874cc1866260f9dea12cbaabda0436ed7f8c2ee44d147bf99a3af29307c6f63b0f83d242b0b6b0ab25dff2629e3
+ checksum: 10c0/124df74820c40c2eb9a8612a254ea1d557ddfab1581c3e751f825e3e366d9f00b0d76a3c94ecd8398e7f3eee193018622677e95816e8491f0797b21e30b2deba
languageName: node
linkType: hard
@@ -1716,15 +2261,6 @@ __metadata:
languageName: node
linkType: hard
-"onetime@npm:^6.0.0":
- version: 6.0.0
- resolution: "onetime@npm:6.0.0"
- dependencies:
- mimic-fn: "npm:^4.0.0"
- checksum: 10c0/4eef7c6abfef697dd4479345a4100c382d73c149d2d56170a54a07418c50816937ad09500e1ed1e79d235989d073a9bade8557122aee24f0576ecde0f392bb6c
- languageName: node
- linkType: hard
-
"p-map@npm:^4.0.0":
version: 4.0.0
resolution: "p-map@npm:4.0.0"
@@ -1877,6 +2413,13 @@ __metadata:
languageName: node
linkType: hard
+"pure-rand@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "pure-rand@npm:6.1.0"
+ checksum: 10c0/1abe217897bf74dcb3a0c9aba3555fe975023147b48db540aa2faf507aee91c03bf54f6aef0eb2bf59cc259a16d06b28eca37f0dc426d94f4692aeff02fb0e65
+ languageName: node
+ linkType: hard
+
"queue-microtask@npm:^1.2.2":
version: 1.2.3
resolution: "queue-microtask@npm:1.2.3"
@@ -1932,6 +2475,13 @@ __metadata:
languageName: node
linkType: hard
+"resolve-pkg-maps@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "resolve-pkg-maps@npm:1.0.0"
+ checksum: 10c0/fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab
+ languageName: node
+ linkType: hard
+
"retry@npm:^0.12.0":
version: 0.12.0
resolution: "retry@npm:0.12.0"
@@ -1961,8 +2511,14 @@ __metadata:
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
dependencies:
- "@agoric/synthetic-chain": "npm:^0.1.0"
+ "@agoric/internal": "npm:0.3.3-dev-5676146.0"
+ "@agoric/synthetic-chain": "npm:^0.2.1"
+ "@endo/errors": "npm:^1.2.2"
+ "@endo/far": "npm:^1.1.5"
+ "@endo/init": "npm:^1.1.4"
ava: "npm:^6.1.2"
+ tsx: "npm:^4.17.0"
+ typescript: "npm:^5.5.4"
languageName: unknown
linkType: soft
@@ -2018,6 +2574,15 @@ __metadata:
languageName: node
linkType: hard
+"ses@npm:^1.8.0":
+ version: 1.8.0
+ resolution: "ses@npm:1.8.0"
+ dependencies:
+ "@endo/env-options": "npm:^1.1.6"
+ checksum: 10c0/4b2114e586a547dd2a71477e0a42e8ea5d0ea9c3ff135d0dbfb63569eeda19c7152db76b82bcad12a2969d3f5fb09e5fa52e921b5a2831560e6876ca1f9ba207
+ languageName: node
+ linkType: hard
+
"set-blocking@npm:^2.0.0":
version: 2.0.0
resolution: "set-blocking@npm:2.0.0"
@@ -2203,10 +2768,10 @@ __metadata:
languageName: node
linkType: hard
-"strip-final-newline@npm:^3.0.0":
- version: 3.0.0
- resolution: "strip-final-newline@npm:3.0.0"
- checksum: 10c0/a771a17901427bac6293fd416db7577e2bc1c34a19d38351e9d5478c3c415f523f391003b42ed475f27e33a78233035df183525395f731d3bfb8cdcbd4da08ce
+"strip-final-newline@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "strip-final-newline@npm:4.0.0"
+ checksum: 10c0/b0cf2b62d597a1b0e3ebc42b88767f0a0d45601f89fd379a928a1812c8779440c81abba708082c946445af1d6b62d5f16e2a7cf4f30d9d6587b89425fae801ff
languageName: node
linkType: hard
@@ -2298,6 +2863,22 @@ __metadata:
languageName: node
linkType: hard
+"tsx@npm:^4.17.0":
+ version: 4.17.0
+ resolution: "tsx@npm:4.17.0"
+ dependencies:
+ esbuild: "npm:~0.23.0"
+ fsevents: "npm:~2.3.3"
+ get-tsconfig: "npm:^4.7.5"
+ dependenciesMeta:
+ fsevents:
+ optional: true
+ bin:
+ tsx: dist/cli.mjs
+ checksum: 10c0/ad720b81d6447c7695d24c27947fa1a2b6db9d2ef03216389edd6fa0006aa479bc0d8348a1ac9975a08edef4ce791ff5629a24d8dccbb0987f42e5407785cfa4
+ languageName: node
+ linkType: hard
+
"tunnel-agent@npm:^0.6.0":
version: 0.6.0
resolution: "tunnel-agent@npm:0.6.0"
@@ -2314,6 +2895,26 @@ __metadata:
languageName: node
linkType: hard
+"typescript@npm:^5.5.4":
+ version: 5.5.4
+ resolution: "typescript@npm:5.5.4"
+ bin:
+ tsc: bin/tsc
+ tsserver: bin/tsserver
+ checksum: 10c0/422be60f89e661eab29ac488c974b6cc0a660fb2228003b297c3d10c32c90f3bcffc1009b43876a082515a3c376b1eefcce823d6e78982e6878408b9a923199c
+ languageName: node
+ linkType: hard
+
+"typescript@patch:typescript@npm%3A^5.5.4#optional!builtin":
+ version: 5.5.4
+ resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin::version=5.5.4&hash=b45daf"
+ bin:
+ tsc: bin/tsc
+ tsserver: bin/tsserver
+ checksum: 10c0/10dd9881baba22763de859e8050d6cb6e2db854197495c6f1929b08d1eb2b2b00d0b5d9b0bcee8472f1c3f4a7ef6a5d7ebe0cfd703f853aa5ae465b8404bc1ba
+ languageName: node
+ linkType: hard
+
"unicorn-magic@npm:^0.1.0":
version: 0.1.0
resolution: "unicorn-magic@npm:0.1.0"
@@ -2475,3 +3076,10 @@ __metadata:
checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05
languageName: node
linkType: hard
+
+"yoctocolors@npm:^2.0.0":
+ version: 2.1.1
+ resolution: "yoctocolors@npm:2.1.1"
+ checksum: 10c0/85903f7fa96f1c70badee94789fade709f9d83dab2ec92753d612d84fcea6d34c772337a9f8914c6bed2f5fc03a428ac5d893e76fab636da5f1236ab725486d0
+ languageName: node
+ linkType: hard
diff --git a/a3p-integration/yarn.lock b/a3p-integration/yarn.lock
index c5c8e80616e..c5a6485757f 100644
--- a/a3p-integration/yarn.lock
+++ b/a3p-integration/yarn.lock
@@ -5,38 +5,25 @@ __metadata:
version: 8
cacheKey: 10c0
-"@agoric/synthetic-chain@npm:0.1.0":
- version: 0.1.0
- resolution: "@agoric/synthetic-chain@npm:0.1.0"
+"@agoric/synthetic-chain@npm:^0.3.0":
+ version: 0.3.0
+ resolution: "@agoric/synthetic-chain@npm:0.3.0"
dependencies:
- "@endo/zip": "npm:^1.0.1"
- better-sqlite3: "npm:^9.4.0"
+ "@endo/zip": "npm:^1.0.7"
+ better-sqlite3: "npm:^9.6.0"
chalk: "npm:^5.3.0"
- execa: "npm:^8.0.1"
+ cosmjs-types: "npm:^0.9.0"
+ execa: "npm:^9.3.1"
bin:
synthetic-chain: dist/cli/cli.js
- checksum: 10c0/8305293d085cde9cbf94670134216e06337c5624c45faf5dfebb86762042abe7b4340cf3205e671dfce54e888bd4e9b3428400756833fa06f2bbb21b44668c44
+ checksum: 10c0/17c6241bdc48b8a2a7608c9d4d7c0a0c76fb10d4ee44a31a1150104a792bcd1133f4b1a7e8ab26673a07450b3ceabccd9911999117568221b49221b6ee4306a1
languageName: node
linkType: hard
-"@agoric/synthetic-chain@patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch":
- version: 0.1.0
- resolution: "@agoric/synthetic-chain@patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch::version=0.1.0&hash=4a65eb"
- dependencies:
- "@endo/zip": "npm:^1.0.1"
- better-sqlite3: "npm:^9.4.0"
- chalk: "npm:^5.3.0"
- execa: "npm:^8.0.1"
- bin:
- synthetic-chain: dist/cli/cli.js
- checksum: 10c0/e974038161b1a9570912a02d9366c6680bc13ee3dfd0e49d06e5ce5e93dbcddf04d1d4cd453af0969bf29ccfe96ce3e141a214539722449add90b13f0785f1f7
- languageName: node
- linkType: hard
-
-"@endo/zip@npm:^1.0.1":
- version: 1.0.1
- resolution: "@endo/zip@npm:1.0.1"
- checksum: 10c0/1074bdc10287f4c94b3423e130da88f9c6ba09c999483c1164b3eed061350a060d2dbe377cfa3b8d4a86b3f1c3aed5cbf0cdd78ee2bf2cb9b837caa2ebbf712f
+"@endo/zip@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "@endo/zip@npm:1.0.7"
+ checksum: 10c0/a1c0d155448ce877012b34c8fe8cd3a58de9eb807514c81cddeebb802ee8e552b27d8a9a40fab3f3e4c49e0cb7fea6902fa1dd12a23ff6f30b56161fc3edc1f8
languageName: node
linkType: hard
@@ -83,6 +70,20 @@ __metadata:
languageName: node
linkType: hard
+"@sec-ant/readable-stream@npm:^0.4.1":
+ version: 0.4.1
+ resolution: "@sec-ant/readable-stream@npm:0.4.1"
+ checksum: 10c0/64e9e9cf161e848067a5bf60cdc04d18495dc28bb63a8d9f8993e4dd99b91ad34e4b563c85de17d91ffb177ec17a0664991d2e115f6543e73236a906068987af
+ languageName: node
+ linkType: hard
+
+"@sindresorhus/merge-streams@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "@sindresorhus/merge-streams@npm:4.0.0"
+ checksum: 10c0/482ee543629aa1933b332f811a1ae805a213681ecdd98c042b1c1b89387df63e7812248bb4df3910b02b3cc5589d3d73e4393f30e197c9dde18046ccd471fc6b
+ languageName: node
+ linkType: hard
+
"@types/better-sqlite3@npm:^7.6.9":
version: 7.6.9
resolution: "@types/better-sqlite3@npm:7.6.9"
@@ -171,14 +172,14 @@ __metadata:
languageName: node
linkType: hard
-"better-sqlite3@npm:^9.4.0":
- version: 9.4.0
- resolution: "better-sqlite3@npm:9.4.0"
+"better-sqlite3@npm:^9.6.0":
+ version: 9.6.0
+ resolution: "better-sqlite3@npm:9.6.0"
dependencies:
bindings: "npm:^1.5.0"
node-gyp: "npm:latest"
prebuild-install: "npm:^7.1.1"
- checksum: 10c0/42b2edfa46d62763514b87122245a3513a5ff20f05fef4fb49fec33f3de0a51a29025596178f57c634b8013f16bbdf8169a308fb3e3b8d126d715788d72d1e74
+ checksum: 10c0/8db9b38f414e26a56d4c40fc16e94a253118491dae0e2c054338a9e470f1a883c7eb4cb330f2f5737db30f704d4f2e697c59071ca04e03364ee9fe04375aa9c8
languageName: node
linkType: hard
@@ -285,6 +286,13 @@ __metadata:
languageName: node
linkType: hard
+"cosmjs-types@npm:^0.9.0":
+ version: 0.9.0
+ resolution: "cosmjs-types@npm:0.9.0"
+ checksum: 10c0/bc20f4293fb34629d7c5f96bafe533987f753df957ff68eb078d0128ae5a418320cb945024441769a07bb9bc5dde9d22b972fd40d485933e5706ea191c43727b
+ languageName: node
+ linkType: hard
+
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
@@ -384,20 +392,23 @@ __metadata:
languageName: node
linkType: hard
-"execa@npm:^8.0.1":
- version: 8.0.1
- resolution: "execa@npm:8.0.1"
+"execa@npm:^9.3.1":
+ version: 9.3.1
+ resolution: "execa@npm:9.3.1"
dependencies:
+ "@sindresorhus/merge-streams": "npm:^4.0.0"
cross-spawn: "npm:^7.0.3"
- get-stream: "npm:^8.0.1"
- human-signals: "npm:^5.0.0"
- is-stream: "npm:^3.0.0"
- merge-stream: "npm:^2.0.0"
- npm-run-path: "npm:^5.1.0"
- onetime: "npm:^6.0.0"
+ figures: "npm:^6.1.0"
+ get-stream: "npm:^9.0.0"
+ human-signals: "npm:^8.0.0"
+ is-plain-obj: "npm:^4.1.0"
+ is-stream: "npm:^4.0.1"
+ npm-run-path: "npm:^5.2.0"
+ pretty-ms: "npm:^9.0.0"
signal-exit: "npm:^4.1.0"
- strip-final-newline: "npm:^3.0.0"
- checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af
+ strip-final-newline: "npm:^4.0.0"
+ yoctocolors: "npm:^2.0.0"
+ checksum: 10c0/113979ff56575f6cb69fd021eb3894a674fb59b264f5e8c2b9b30e301629abc4f44cee881e680f9fb3b7d4956645df76a2d8c0006869dea985f96ec65f07b226
languageName: node
linkType: hard
@@ -415,6 +426,15 @@ __metadata:
languageName: node
linkType: hard
+"figures@npm:^6.1.0":
+ version: 6.1.0
+ resolution: "figures@npm:6.1.0"
+ dependencies:
+ is-unicode-supported: "npm:^2.0.0"
+ checksum: 10c0/9159df4264d62ef447a3931537de92f5012210cf5135c35c010df50a2169377581378149abfe1eb238bd6acbba1c0d547b1f18e0af6eee49e30363cedaffcfe4
+ languageName: node
+ linkType: hard
+
"file-uri-to-path@npm:1.0.0":
version: 1.0.0
resolution: "file-uri-to-path@npm:1.0.0"
@@ -457,10 +477,13 @@ __metadata:
languageName: node
linkType: hard
-"get-stream@npm:^8.0.1":
- version: 8.0.1
- resolution: "get-stream@npm:8.0.1"
- checksum: 10c0/5c2181e98202b9dae0bb4a849979291043e5892eb40312b47f0c22b9414fc9b28a3b6063d2375705eb24abc41ecf97894d9a51f64ff021511b504477b27b4290
+"get-stream@npm:^9.0.0":
+ version: 9.0.1
+ resolution: "get-stream@npm:9.0.1"
+ dependencies:
+ "@sec-ant/readable-stream": "npm:^0.4.1"
+ is-stream: "npm:^4.0.1"
+ checksum: 10c0/d70e73857f2eea1826ac570c3a912757dcfbe8a718a033fa0c23e12ac8e7d633195b01710e0559af574cbb5af101009b42df7b6f6b29ceec8dbdf7291931b948
languageName: node
linkType: hard
@@ -520,10 +543,10 @@ __metadata:
languageName: node
linkType: hard
-"human-signals@npm:^5.0.0":
- version: 5.0.0
- resolution: "human-signals@npm:5.0.0"
- checksum: 10c0/5a9359073fe17a8b58e5a085e9a39a950366d9f00217c4ff5878bd312e09d80f460536ea6a3f260b5943a01fe55c158d1cea3fc7bee3d0520aeef04f6d915c82
+"human-signals@npm:^8.0.0":
+ version: 8.0.0
+ resolution: "human-signals@npm:8.0.0"
+ checksum: 10c0/e4dac4f7d3eb791ed04129fc6a85bd454a9102d3e3b76c911d0db7057ebd60b2956b435b5b5712aec18960488ede3c21ef7c56e42cdd70760c0d84d3c05cd92e
languageName: node
linkType: hard
@@ -592,10 +615,24 @@ __metadata:
languageName: node
linkType: hard
-"is-stream@npm:^3.0.0":
- version: 3.0.0
- resolution: "is-stream@npm:3.0.0"
- checksum: 10c0/eb2f7127af02ee9aa2a0237b730e47ac2de0d4e76a4a905a50a11557f2339df5765eaea4ceb8029f1efa978586abe776908720bfcb1900c20c6ec5145f6f29d8
+"is-plain-obj@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "is-plain-obj@npm:4.1.0"
+ checksum: 10c0/32130d651d71d9564dc88ba7e6fda0e91a1010a3694648e9f4f47bb6080438140696d3e3e15c741411d712e47ac9edc1a8a9de1fe76f3487b0d90be06ac9975e
+ languageName: node
+ linkType: hard
+
+"is-stream@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "is-stream@npm:4.0.1"
+ checksum: 10c0/2706c7f19b851327ba374687bc4a3940805e14ca496dc672b9629e744d143b1ad9c6f1b162dece81c7bfbc0f83b32b61ccc19ad2e05aad2dd7af347408f60c7f
+ languageName: node
+ linkType: hard
+
+"is-unicode-supported@npm:^2.0.0":
+ version: 2.1.0
+ resolution: "is-unicode-supported@npm:2.1.0"
+ checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5
languageName: node
linkType: hard
@@ -661,20 +698,6 @@ __metadata:
languageName: node
linkType: hard
-"merge-stream@npm:^2.0.0":
- version: 2.0.0
- resolution: "merge-stream@npm:2.0.0"
- checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5
- languageName: node
- linkType: hard
-
-"mimic-fn@npm:^4.0.0":
- version: 4.0.0
- resolution: "mimic-fn@npm:4.0.0"
- checksum: 10c0/de9cc32be9996fd941e512248338e43407f63f6d497abe8441fa33447d922e927de54d4cc3c1a3c6d652857acd770389d5a3823f311a744132760ce2be15ccbf
- languageName: node
- linkType: hard
-
"mimic-response@npm:^3.1.0":
version: 3.1.0
resolution: "mimic-response@npm:3.1.0"
@@ -859,12 +882,12 @@ __metadata:
languageName: node
linkType: hard
-"npm-run-path@npm:^5.1.0":
- version: 5.2.0
- resolution: "npm-run-path@npm:5.2.0"
+"npm-run-path@npm:^5.2.0":
+ version: 5.3.0
+ resolution: "npm-run-path@npm:5.3.0"
dependencies:
path-key: "npm:^4.0.0"
- checksum: 10c0/7963c1f98e42afebe9524a08b0881477ec145aab34f6018842a315422b25ad40e015bdee709b697571e5efda2ecfa2640ee917d92674e4de1166fa3532a211b1
+ checksum: 10c0/124df74820c40c2eb9a8612a254ea1d557ddfab1581c3e751f825e3e366d9f00b0d76a3c94ecd8398e7f3eee193018622677e95816e8491f0797b21e30b2deba
languageName: node
linkType: hard
@@ -877,15 +900,6 @@ __metadata:
languageName: node
linkType: hard
-"onetime@npm:^6.0.0":
- version: 6.0.0
- resolution: "onetime@npm:6.0.0"
- dependencies:
- mimic-fn: "npm:^4.0.0"
- checksum: 10c0/4eef7c6abfef697dd4479345a4100c382d73c149d2d56170a54a07418c50816937ad09500e1ed1e79d235989d073a9bade8557122aee24f0576ecde0f392bb6c
- languageName: node
- linkType: hard
-
"p-map@npm:^4.0.0":
version: 4.0.0
resolution: "p-map@npm:4.0.0"
@@ -895,6 +909,13 @@ __metadata:
languageName: node
linkType: hard
+"parse-ms@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "parse-ms@npm:4.0.0"
+ checksum: 10c0/a7900f4f1ebac24cbf5e9708c16fb2fd482517fad353aecd7aefb8c2ba2f85ce017913ccb8925d231770404780df46244ea6fec598b3bde6490882358b4d2d16
+ languageName: node
+ linkType: hard
+
"path-key@npm:^3.1.0":
version: 3.1.1
resolution: "path-key@npm:3.1.1"
@@ -941,6 +962,15 @@ __metadata:
languageName: node
linkType: hard
+"pretty-ms@npm:^9.0.0":
+ version: 9.1.0
+ resolution: "pretty-ms@npm:9.1.0"
+ dependencies:
+ parse-ms: "npm:^4.0.0"
+ checksum: 10c0/fd111aad8800a04dfd654e6016da69bdaa6fc6a4c280f8e727cffd8b5960558e94942f1a94d4aa6e4d179561a0fbb0366a9ebe0ccefbbb0f8ff853b129cdefb9
+ languageName: node
+ linkType: hard
+
"proc-log@npm:^3.0.0":
version: 3.0.0
resolution: "proc-log@npm:3.0.0"
@@ -1004,7 +1034,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
dependencies:
- "@agoric/synthetic-chain": "patch:@agoric/synthetic-chain@npm%3A0.1.0#~/.yarn/patches/@agoric-synthetic-chain-npm-0.1.0-148de716a6.patch"
+ "@agoric/synthetic-chain": "npm:^0.3.0"
"@types/better-sqlite3": "npm:^7.6.9"
languageName: unknown
linkType: soft
@@ -1161,10 +1191,10 @@ __metadata:
languageName: node
linkType: hard
-"strip-final-newline@npm:^3.0.0":
- version: 3.0.0
- resolution: "strip-final-newline@npm:3.0.0"
- checksum: 10c0/a771a17901427bac6293fd416db7577e2bc1c34a19d38351e9d5478c3c415f523f391003b42ed475f27e33a78233035df183525395f731d3bfb8cdcbd4da08ce
+"strip-final-newline@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "strip-final-newline@npm:4.0.0"
+ checksum: 10c0/b0cf2b62d597a1b0e3ebc42b88767f0a0d45601f89fd379a928a1812c8779440c81abba708082c946445af1d6b62d5f16e2a7cf4f30d9d6587b89425fae801ff
languageName: node
linkType: hard
@@ -1312,3 +1342,10 @@ __metadata:
checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a
languageName: node
linkType: hard
+
+"yoctocolors@npm:^2.0.0":
+ version: 2.1.1
+ resolution: "yoctocolors@npm:2.1.1"
+ checksum: 10c0/85903f7fa96f1c70badee94789fade709f9d83dab2ec92753d612d84fcea6d34c772337a9f8914c6bed2f5fc03a428ac5d893e76fab636da5f1236ab725486d0
+ languageName: node
+ linkType: hard
diff --git a/depot.json b/depot.json
new file mode 100644
index 00000000000..6687457c334
--- /dev/null
+++ b/depot.json
@@ -0,0 +1 @@
+{"id":"0gtvlr9g8j"}
diff --git a/golang/cosmos/Makefile b/golang/cosmos/Makefile
index 0429668f13c..803d169aefd 100644
--- a/golang/cosmos/Makefile
+++ b/golang/cosmos/Makefile
@@ -61,10 +61,10 @@ node-compile-gyp:
npm run build:gyp; \
fi
-compile-agd: go-mod-cache
+compile-agd: go.sum
go build -v $(MOD_READONLY) $(BUILD_FLAGS) -buildmode=exe -o build/agd ./cmd/agd
-install-agd: go-mod-cache
+install-agd: go.sum
go install -v $(MOD_READONLY) $(BUILD_FLAGS) -buildmode=exe ./cmd/agd
# Only run from the package.json build:gyp script.
@@ -73,17 +73,18 @@ compile-gyp:
node-gyp configure build $(GYP_DEBUG) || { status=$$?; rm -f binding.gyp; exit $$status; }
rm -f binding.gyp
-compile-libdaemon: go-mod-cache
+compile-libdaemon: go.sum
go build -v $(MOD_READONLY) $(SHARED_BUILD_FLAGS) -buildmode=c-shared \
-o build/libagcosmosdaemon.so ./cmd/libdaemon/main.go
-go-mod-cache: go.sum
- @echo "--> Download go modules to local cache"
- @go mod download
-
go.sum: go.mod
- @echo "--> Ensure dependencies have not been modified"
+ @echo "--> Ensure dependencies have not been modified unless suppressed by SKIP_MOD_VERIFY ..."
+ifndef SKIP_MOD_VERIFY
GO111MODULE=on go mod verify
+endif
+ GO111MODULE=on go mod tidy
+ @echo "--> Download go modules to local cache"
+ go mod download
###############################################################################
### Protobuf ###
diff --git a/golang/cosmos/app/app.go b/golang/cosmos/app/app.go
index bb5dfc4e8bf..52eb932eaa0 100644
--- a/golang/cosmos/app/app.go
+++ b/golang/cosmos/app/app.go
@@ -214,6 +214,7 @@ var (
// capabilities aren't needed for testing.
type GaiaApp struct { // nolint: golint
*baseapp.BaseApp
+ resolvedConfig servertypes.AppOptions
legacyAmino *codec.LegacyAmino
appCodec codec.Codec
interfaceRegistry types.InterfaceRegistry
@@ -314,9 +315,18 @@ func NewGaiaApp(
}
func NewAgoricApp(
- sendToController vm.Sender, agdServer *vm.AgdServer,
- logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool,
- homePath string, invCheckPeriod uint, encodingConfig gaiaappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp),
+ sendToController vm.Sender,
+ agdServer *vm.AgdServer,
+ logger log.Logger,
+ db dbm.DB,
+ traceStore io.Writer,
+ loadLatest bool,
+ skipUpgradeHeights map[int64]bool,
+ homePath string,
+ invCheckPeriod uint,
+ encodingConfig gaiaappparams.EncodingConfig,
+ appOpts servertypes.AppOptions,
+ baseAppOptions ...func(*baseapp.BaseApp),
) *GaiaApp {
appCodec := encodingConfig.Marshaler
legacyAmino := encodingConfig.Amino
@@ -342,6 +352,7 @@ func NewAgoricApp(
app := &GaiaApp{
BaseApp: bApp,
AgdServer: agdServer,
+ resolvedConfig: appOpts,
legacyAmino: legacyAmino,
appCodec: appCodec,
interfaceRegistry: interfaceRegistry,
@@ -862,27 +873,26 @@ func NewAgoricApp(
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
- for name := range upgradeNamesOfThisVersion {
+ for _, name := range upgradeNamesOfThisVersion {
app.UpgradeKeeper.SetUpgradeHandler(
name,
unreleasedUpgradeHandler(app, name),
)
}
+ // At this point we don't have a way to read from the store, so we have to
+ // rely on data saved by the x/upgrade module in the previous software.
upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic(err)
}
- if upgradeNamesOfThisVersion[upgradeInfo.Name] && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
+ // Store migrations can only run once, so we use a notion of "primary upgrade
+ // name" to trigger them. Testnets may end up upgrading from one rc to
+ // another, which shouldn't re-run store upgrades.
+ if isPrimaryUpgradeName(upgradeInfo.Name) && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := storetypes.StoreUpgrades{
- Added: []string{
- packetforwardtypes.ModuleName, // Added PFM
- vlocalchain.ModuleName, // Agoric added vlocalchain
- vtransfer.ModuleName, // Agoric added vtransfer
- },
- Deleted: []string{
- "lien", // Agoric removed the lien module
- },
+ Added: []string{},
+ Deleted: []string{},
}
// configure store loader that checks if version == upgradeHeight and applies store upgrades
@@ -933,11 +943,12 @@ type upgradeDetails struct {
type cosmosInitAction struct {
vm.ActionHeader `actionType:"AG_COSMOS_INIT"`
- ChainID string `json:"chainID"`
- IsBootstrap bool `json:"isBootstrap"`
- UpgradeDetails *upgradeDetails `json:"upgradeDetails,omitempty"`
- Params swingset.Params `json:"params"`
- SupplyCoins sdk.Coins `json:"supplyCoins"`
+ ChainID string `json:"chainID"`
+ IsBootstrap bool `json:"isBootstrap"`
+ Params swingset.Params `json:"params"`
+ ResolvedConfig *swingset.SwingsetConfig `json:"resolvedConfig"`
+ SupplyCoins sdk.Coins `json:"supplyCoins"`
+ UpgradeDetails *upgradeDetails `json:"upgradeDetails,omitempty"`
// CAVEAT: Every property ending in "Port" is saved in chain-main.js/portNums
// with a key consisting of this name with the "Port" stripped.
StoragePort int `json:"storagePort"`
@@ -969,10 +980,15 @@ func (app *GaiaApp) initController(ctx sdk.Context, bootstrap bool) {
app.controllerInited = true
// Begin initializing the controller here.
+ swingsetConfig, err := swingset.SwingsetConfigFromViper(app.resolvedConfig)
+ if err != nil {
+ panic(err)
+ }
action := &cosmosInitAction{
ChainID: ctx.ChainID(),
IsBootstrap: bootstrap,
Params: app.SwingSetKeeper.GetParams(ctx),
+ ResolvedConfig: swingsetConfig,
SupplyCoins: sdk.NewCoins(app.BankKeeper.GetSupply(ctx, "uist")),
UpgradeDetails: app.upgradeDetails,
// See CAVEAT in cosmosInitAction.
diff --git a/golang/cosmos/app/upgrade.go b/golang/cosmos/app/upgrade.go
index 519083ddf4c..12cd6eb4a77 100644
--- a/golang/cosmos/app/upgrade.go
+++ b/golang/cosmos/app/upgrade.go
@@ -1,10 +1,7 @@
package gaia
import (
- "encoding/json"
"fmt"
- "strings"
- "text/template"
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
swingsetkeeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
@@ -13,146 +10,66 @@ import (
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
-var upgradeNamesOfThisVersion = map[string]bool{
- "UNRELEASED_BASIC": true, // no-frills
- "UNRELEASED_A3P_INTEGRATION": true,
- "UNRELEASED_main": true,
- "UNRELEASED_devnet": true,
+var upgradeNamesOfThisVersion = []string{
+ "UNRELEASED_BASIC", // no-frills
+ "UNRELEASED_A3P_INTEGRATION",
+ "UNRELEASED_main",
+ "UNRELEASED_devnet",
+ "UNRELEASED_REAPPLY",
}
-func isFirstTimeUpgradeOfThisVersion(app *GaiaApp, ctx sdk.Context) bool {
- for name := range upgradeNamesOfThisVersion {
- if app.UpgradeKeeper.GetDoneHeight(ctx, name) != 0 {
- return false
+// isUpgradeNameOfThisVersion returns whether the provided plan name is a
+// known upgrade name of this software version
+func isUpgradeNameOfThisVersion(name string) bool {
+ for _, upgradeName := range upgradeNamesOfThisVersion {
+ if upgradeName == name {
+ return true
}
}
- return true
+ return false
}
-// upgradePriceFeedCoreProposalSteps returns the core proposal steps for the
-// price feed upgrade and associated changes to scaledPriceAuthority and
-// vaultManager.
-func upgradePriceFeedCoreProposalSteps(upgradeName string) ([]vm.CoreProposalStep, error) {
- isThisUpgrade := func(expectedUpgradeName string) bool {
- if !upgradeNamesOfThisVersion[expectedUpgradeName] {
- panic(fmt.Errorf("invalid upgrade name: %s", expectedUpgradeName))
- }
- return upgradeName == expectedUpgradeName
- }
-
- t := template.Must(template.New("").Parse(`{
- "module": "@agoric/builders/scripts/vats/priceFeedSupport.js",
- "entrypoint": {{.entrypointJson}},
- "args": [{
- "AGORIC_INSTANCE_NAME": {{.instanceNameJson}},
- "ORACLE_ADDRESSES": {{.oracleAddressesJson}},
- "IN_BRAND_LOOKUP": {{.inBrandLookupJson}},
- "IN_BRAND_DECIMALS": 6,
- "OUT_BRAND_LOOKUP": ["agoricNames", "oracleBrand", "USD"],
- "OUT_BRAND_DECIMALS": 4
- }]
- }`))
-
- var oracleAddresses []string
-
- var entrypoint string
- switch {
- case isThisUpgrade("UNRELEASED_A3P_INTEGRATION"):
- entrypoint = "deprecatedPriceFeedProposalBuilder"
- case isThisUpgrade("UNRELEASED_main"):
- oracleAddresses = []string{
- "agoric144rrhh4m09mh7aaffhm6xy223ym76gve2x7y78", // DSRV
- "agoric19d6gnr9fyp6hev4tlrg87zjrzsd5gzr5qlfq2p", // Stakin
- "agoric19uscwxdac6cf6z7d5e26e0jm0lgwstc47cpll8", // 01node
- "agoric1krunjcqfrf7la48zrvdfeeqtls5r00ep68mzkr", // Simply Staking
- "agoric1n4fcxsnkxe4gj6e24naec99hzmc4pjfdccy5nj", // P2P
- }
- entrypoint = "strictPriceFeedProposalBuilder"
- case isThisUpgrade("UNRELEASED_devnet"):
- oracleAddresses = []string{
- "agoric1lw4e4aas9q84tq0q92j85rwjjjapf8dmnllnft", // DSRV
- "agoric1zj6vrrrjq4gsyr9lw7dplv4vyejg3p8j2urm82", // Stakin
- "agoric1ra0g6crtsy6r3qnpu7ruvm7qd4wjnznyzg5nu4", // 01node
- "agoric1qj07c7vfk3knqdral0sej7fa6eavkdn8vd8etf", // Simply Staking
- "agoric10vjkvkmpp9e356xeh6qqlhrny2htyzp8hf88fk", // P2P
- }
- entrypoint = "strictPriceFeedProposalBuilder"
-
- // No price feed upgrade for this version.
- case isThisUpgrade("UNRELEASED_BASIC"):
- }
-
- if entrypoint == "" {
- return []vm.CoreProposalStep{}, nil
- }
-
- entrypointJson, err := json.Marshal(entrypoint)
- if err != nil {
- return nil, err
+// validUpgradeName is an identity function that asserts the provided name
+// is an upgrade name of this software version. It can be used as a sort of
+// dynamic enum check.
+func validUpgradeName(name string) string {
+ if !isUpgradeNameOfThisVersion(name) {
+ panic(fmt.Errorf("invalid upgrade name: %s", name))
}
+ return name
+}
- var inBrandNames []string
- switch {
- case isThisUpgrade("UNRELEASED_A3P_INTEGRATION"), isThisUpgrade("UNRELEASED_main"):
- inBrandNames = []string{
- "ATOM",
- "stATOM",
- "stOSMO",
- "stTIA",
- "stkATOM",
- }
- case isThisUpgrade("UNRELEASED_devnet"):
- inBrandNames = []string{
- "ATOM",
- "stTIA",
- "stkATOM",
- }
+// isPrimaryUpgradeName returns wether the provided plan name is considered a
+// primary for the purpose of applying store migrations for the first upgrade
+// of this version.
+// It is expected that only primary plan names are used for non testing chains.
+func isPrimaryUpgradeName(name string) bool {
+ if name == "" {
+ // An empty upgrade name can happen if there are no upgrade in progress
+ return false
}
-
- oracleAddressesJson, err := json.Marshal(oracleAddresses)
- if err != nil {
- return nil, err
+ switch name {
+ case validUpgradeName("UNRELEASED_BASIC"),
+ validUpgradeName("UNRELEASED_A3P_INTEGRATION"),
+ validUpgradeName("UNRELEASED_main"),
+ validUpgradeName("UNRELEASED_devnet"):
+ return true
+ case validUpgradeName("UNRELEASED_REAPPLY"):
+ return false
+ default:
+ panic(fmt.Errorf("unexpected upgrade name %s", validUpgradeName(name)))
}
+}
- proposals := make(vm.CoreProposalStep, 0, len(inBrandNames))
- for _, inBrandName := range inBrandNames {
- instanceName := inBrandName + "-USD price feed"
- instanceNameJson, err := json.Marshal(instanceName)
- if err != nil {
- return nil, err
- }
- inBrandLookup := []string{"agoricNames", "oracleBrand", inBrandName}
- inBrandLookupJson, err := json.Marshal(inBrandLookup)
- if err != nil {
- return nil, err
- }
-
- var result strings.Builder
- err = t.Execute(&result, map[string]any{
- "entrypointJson": string(entrypointJson),
- "inBrandLookupJson": string(inBrandLookupJson),
- "instanceNameJson": string(instanceNameJson),
- "oracleAddressesJson": string(oracleAddressesJson),
- })
- if err != nil {
- return nil, err
- }
-
- jsonStr := result.String()
- jsonBz := []byte(jsonStr)
- if !json.Valid(jsonBz) {
- return nil, fmt.Errorf("invalid JSON: %s", jsonStr)
+// isFirstTimeUpgradeOfThisVersion looks up in the upgrade store whether no
+// upgrade plan name of this version have previously been applied.
+func isFirstTimeUpgradeOfThisVersion(app *GaiaApp, ctx sdk.Context) bool {
+ for _, name := range upgradeNamesOfThisVersion {
+ if app.UpgradeKeeper.GetDoneHeight(ctx, name) != 0 {
+ return false
}
- proposals = append(proposals, vm.ArbitraryCoreProposal{Json: jsonBz})
}
- return []vm.CoreProposalStep{
- // Add new vats for price feeds. The existing ones will be retired shortly.
- vm.CoreProposalStepForModules(proposals...),
- // Add new auction contract. The old one will be retired shortly.
- vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/add-auction.js"),
- // upgrade vaultFactory.
- vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/upgradeVaults.js"),
- }, nil
+ return true
}
// unreleasedUpgradeHandler performs standard upgrade actions plus custom actions for the unreleased upgrade.
@@ -165,28 +82,29 @@ func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Conte
// These CoreProposalSteps are not idempotent and should only be executed
// as part of the first upgrade using this handler on any given chain.
if isFirstTimeUpgradeOfThisVersion(app, ctx) {
+ // The storeUpgrades defined in app.go only execute for the primary upgrade name
+ // If we got here and this first upgrade of this version does not use the
+ // primary upgrade name, stores have not been initialized correctly.
+ if !isPrimaryUpgradeName(plan.Name) {
+ return module.VersionMap{}, fmt.Errorf("cannot run %s as first upgrade", plan.Name)
+ }
+
// Each CoreProposalStep runs sequentially, and can be constructed from
// one or more modules executing in parallel within the step.
CoreProposalSteps = []vm.CoreProposalStep{
- // Upgrade Zoe + ZCF
- vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/replace-zoe.js"),
- // Revive KREAd characters
- vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/revive-kread.js"),
-
- // upgrade the provisioning vat
- vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/replace-provisioning.js"),
- // Enable low-level Orchestration.
vm.CoreProposalStepForModules(
- "@agoric/builders/scripts/vats/init-network.js",
- "@agoric/builders/scripts/vats/init-localchain.js",
- "@agoric/builders/scripts/vats/init-transfer.js",
+ // Upgrade to new liveslots for repaired vow usage.
+ "@agoric/builders/scripts/vats/upgrade-orch-core.js",
+ ),
+ vm.CoreProposalStepForModules(
+ // Upgrade to new liveslots and support vows.
+ "@agoric/builders/scripts/smart-wallet/build-wallet-factory2-upgrade.js",
+ ),
+ vm.CoreProposalStepForModules(
+ // Create vat-orchestration.
+ "@agoric/builders/scripts/vats/init-orchestration.js",
),
}
- priceFeedSteps, err := upgradePriceFeedCoreProposalSteps(targetUpgrade)
- if err != nil {
- return nil, err
- }
- CoreProposalSteps = append(CoreProposalSteps, priceFeedSteps...)
}
app.upgradeDetails = &upgradeDetails{
diff --git a/golang/cosmos/daemon/cmd/root.go b/golang/cosmos/daemon/cmd/root.go
index 043b1b5edcf..367cea44c07 100644
--- a/golang/cosmos/daemon/cmd/root.go
+++ b/golang/cosmos/daemon/cmd/root.go
@@ -6,6 +6,7 @@ import (
"io"
"os"
"path/filepath"
+ "strings"
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
@@ -36,6 +37,7 @@ import (
gaia "github.com/Agoric/agoric-sdk/golang/cosmos/app"
"github.com/Agoric/agoric-sdk/golang/cosmos/app/params"
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
+ swingset "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset"
swingsetkeeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
)
@@ -43,6 +45,31 @@ var AppName = "agd"
var OnStartHook func(*vm.AgdServer, log.Logger, servertypes.AppOptions) error
var OnExportHook func(*vm.AgdServer, log.Logger, servertypes.AppOptions) error
+// CustomAppConfig extends the base config struct.
+type CustomAppConfig struct {
+ serverconfig.Config `mapstructure:",squash"`
+ // Swingset must be named as expected by swingset.DefaultConfigTemplate
+ // and must use a mapstructure key matching swingset.ConfigPrefix.
+ Swingset swingset.SwingsetConfig `mapstructure:"swingset"`
+}
+
+type cobraRunE func(cmd *cobra.Command, args []string) error
+
+func appendToPreRunE(cmd *cobra.Command, fn cobraRunE) {
+ preRunE := cmd.PreRunE
+ if preRunE == nil {
+ cmd.PreRunE = fn
+ return
+ }
+ composite := func(cmd *cobra.Command, args []string) error {
+ if err := preRunE(cmd, args); err != nil {
+ return err
+ }
+ return fn(cmd, args)
+ }
+ cmd.PreRunE = composite
+}
+
// NewRootCmd creates a new root command for simd. It is called once in the
// main function.
func NewRootCmd(sender vm.Sender) (*cobra.Command, params.EncodingConfig) {
@@ -99,24 +126,25 @@ func initTendermintConfig() *tmcfg.Config {
// initAppConfig helps to override default appConfig template and configs.
// return "", nil if no custom configuration is required for the application.
func initAppConfig() (string, interface{}) {
- // Allow us to overwrite the SDK's default server config.
srvCfg := serverconfig.DefaultConfig()
- // The SDK's default minimum gas price is set to "" (empty value) inside
- // app.toml. If left empty by validators, the node will halt on startup.
- // However, the chain developer can set a default app.toml value for their
- // validators here.
- //
- // In summary:
- // - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their
- // own app.toml config,
- // - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
- // own app.toml to override, or use this default value.
- //
- // FIXME: We may want to have Agoric set a min gas price in uist.
- // For now, we set it to zero so that validators don't have to worry about it.
+
+ // FIXME: We may want a non-zero min gas price.
+ // For now, we set it to zero to reduce friction (the default "" fails
+ // startup, forcing each validator to set their own value).
srvCfg.MinGasPrices = "0uist"
- return serverconfig.DefaultConfigTemplate, *srvCfg
+ customAppConfig := CustomAppConfig{
+ Config: *srvCfg,
+ Swingset: swingset.DefaultSwingsetConfig,
+ }
+
+ // Config TOML.
+ customAppTemplate := strings.Join([]string{
+ serverconfig.DefaultConfigTemplate,
+ swingset.DefaultConfigTemplate,
+ }, "")
+
+ return customAppTemplate, customAppConfig
}
func initRootCmd(sender vm.Sender, rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
@@ -144,10 +172,27 @@ func initRootCmd(sender vm.Sender, rootCmd *cobra.Command, encodingConfig params
snapshot.Cmd(ac.newSnapshotsApp),
)
- server.AddCommands(rootCmd, gaia.DefaultNodeHome, ac.newApp, ac.appExport, addModuleInitFlags)
+ server.AddCommands(rootCmd, gaia.DefaultNodeHome, ac.newApp, ac.appExport, addStartFlags)
for _, command := range rootCmd.Commands() {
switch command.Name() {
+ case "start":
+ var preRunE cobraRunE = func(cmd *cobra.Command, _ []string) error {
+ // Consume and validate config.
+ viper := server.GetServerContextFromCmd(cmd).Viper
+ baseConfig, err := serverconfig.GetConfig(viper)
+ if err != nil {
+ return err
+ }
+ if err = baseConfig.ValidateBasic(); err != nil {
+ return err
+ }
+ if _, err = swingset.SwingsetConfigFromViper(viper); err != nil {
+ return err
+ }
+ return nil
+ }
+ appendToPreRunE(command, preRunE)
case "export":
addAgoricVMFlags(command)
extendCosmosExportCommand(command)
@@ -197,7 +242,7 @@ func addAgoricVMFlags(cmd *cobra.Command) {
)
}
-func addModuleInitFlags(startCmd *cobra.Command) {
+func addStartFlags(startCmd *cobra.Command) {
addAgoricVMFlags(startCmd)
}
@@ -282,11 +327,12 @@ func (ac appCreator) newApp(
homePath := cast.ToString(appOpts.Get(flags.FlagHome))
- // Set a default value for FlagSwingStoreExportDir based on the homePath
+ // Set a default value for FlagSwingStoreExportDir based on homePath
// in case we need to InitGenesis with swing-store data
viper, ok := appOpts.(*viper.Viper)
- if ok && cast.ToString(appOpts.Get(gaia.FlagSwingStoreExportDir)) == "" {
- viper.Set(gaia.FlagSwingStoreExportDir, filepath.Join(homePath, "config", ExportedSwingStoreDirectoryName))
+ if ok && viper.GetString(gaia.FlagSwingStoreExportDir) == "" {
+ exportDir := filepath.Join(homePath, "config", ExportedSwingStoreDirectoryName)
+ viper.Set(gaia.FlagSwingStoreExportDir, exportDir)
}
return gaia.NewAgoricApp(
diff --git a/golang/cosmos/go.mod b/golang/cosmos/go.mod
index 1c55e96b032..f1c9174a507 100644
--- a/golang/cosmos/go.mod
+++ b/golang/cosmos/go.mod
@@ -17,6 +17,7 @@ require (
github.com/rakyll/statik v0.1.7
github.com/spf13/cast v1.5.0
github.com/spf13/cobra v1.7.0
+ github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.14.0
github.com/stretchr/testify v1.8.4
github.com/tendermint/tendermint v0.34.29
@@ -133,7 +134,6 @@ require (
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
diff --git a/golang/cosmos/package.json b/golang/cosmos/package.json
index 227a803a481..5b6e2b60146 100644
--- a/golang/cosmos/package.json
+++ b/golang/cosmos/package.json
@@ -9,7 +9,7 @@
"engines": {
"node": "^18.12 || ^20.9"
},
- "packageManager": "yarn@1.22.19",
+ "packageManager": "yarn@1.22.22",
"scripts": {
"test": "exit 0",
"build:all": "make",
diff --git a/golang/cosmos/util/util.go b/golang/cosmos/util/util.go
new file mode 100644
index 00000000000..c2d7533a078
--- /dev/null
+++ b/golang/cosmos/util/util.go
@@ -0,0 +1,21 @@
+package util
+
+import (
+ "github.com/spf13/viper"
+)
+
+func IndexOf[T comparable](a []T, x T) int {
+ for i, s := range a {
+ if s == x {
+ return i
+ }
+ }
+ return -1
+}
+
+func NewFileOnlyViper(v1 *viper.Viper) (*viper.Viper, error) {
+ v2 := viper.New()
+ v2.SetConfigFile(v1.ConfigFileUsed())
+ err := v2.ReadInConfig()
+ return v2, err
+}
diff --git a/golang/cosmos/x/swingset/config.go b/golang/cosmos/x/swingset/config.go
new file mode 100644
index 00000000000..4f2e25313c5
--- /dev/null
+++ b/golang/cosmos/x/swingset/config.go
@@ -0,0 +1,234 @@
+package swingset
+
+import (
+ "fmt"
+ "path/filepath"
+
+ "github.com/spf13/viper"
+
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
+ serverconfig "github.com/cosmos/cosmos-sdk/server/config"
+ servertypes "github.com/cosmos/cosmos-sdk/server/types"
+
+ "github.com/Agoric/agoric-sdk/golang/cosmos/util"
+)
+
+const (
+ ConfigPrefix = "swingset"
+ FlagSlogfile = ConfigPrefix + ".slogfile"
+ FlagVatSnapshotArchiveDir = ConfigPrefix + ".vat-snapshot-archive-dir"
+ FlagVatTranscriptArchiveDir = ConfigPrefix + ".vat-transcript-archive-dir"
+
+ SnapshotRetentionOptionDebug = "debug"
+ SnapshotRetentionOptionOperational = "operational"
+
+ TranscriptRetentionOptionArchival = "archival"
+ TranscriptRetentionOptionOperational = "operational"
+)
+
+var snapshotRetentionValues []string = []string{
+ SnapshotRetentionOptionDebug,
+ SnapshotRetentionOptionOperational,
+}
+
+var transcriptRetentionValues []string = []string{
+ TranscriptRetentionOptionArchival,
+ TranscriptRetentionOptionOperational,
+}
+
+// DefaultConfigTemplate defines a default TOML configuration section for the SwingSet VM.
+// Values are pulled from a "Swingset" property, in accord with CustomAppConfig from
+// ../../daemon/cmd/root.go.
+// See https://github.com/cosmos/cosmos-sdk/issues/20097 for auto-synchronization ideas.
+const DefaultConfigTemplate = `
+###############################################################################
+### SwingSet Configuration ###
+###############################################################################
+
+[swingset]
+# The path at which a SwingSet log "slog" file should be written.
+# If relative, it is interpreted against the application home directory
+# (e.g., ~/.agoric).
+# May be overridden by a SLOGFILE environment variable, which if relative is
+# interpreted against the working directory.
+slogfile = "{{ .Swingset.SlogFile }}"
+
+# The maximum number of vats that the SwingSet kernel will bring online. A lower number
+# requires less memory but may have a negative performance impact if vats need to
+# be frequently paged out to remain under this limit.
+max-vats-online = {{ .Swingset.MaxVatsOnline }}
+
+# Retention of vat snapshots, with values analogous to those of export
+# 'artifactMode' (cf.
+# https://github.com/Agoric/agoric-sdk/blob/master/packages/swing-store/docs/data-export.md#optional--historical-data ).
+# * "debug": keep all snapshots
+# * "operational": keep only the last snapshot
+vat-snapshot-retention = "{{ .Swingset.VatSnapshotRetention }}"
+
+# Retention of vat transcript spans, with values analogous to those of export
+# 'artifactMode' (cf.
+# https://github.com/Agoric/agoric-sdk/blob/master/packages/swing-store/docs/data-export.md#optional--historical-data ).
+# * "archival": keep all transcript spans
+# * "operational": keep only necessary transcript spans (i.e., since the
+# last snapshot of their vat)
+# * "default": determined by 'pruning' ("archival" if 'pruning' is "nothing",
+# otherwise "operational")
+vat-transcript-retention = "{{ .Swingset.VatTranscriptRetention }}"
+
+# Archival of gzipped vat snapshots.
+vat-snapshot-archive-dir = "{{ .Swingset.VatSnapshotArchiveDir }}"
+
+# Archival of historical (i.e., closed) vat transcript spans to gzipped files.
+vat-transcript-archive-dir = "{{ .Swingset.VatTranscriptArchiveDir }}"
+`
+
+// SwingsetConfig defines configuration for the SwingSet VM.
+// "mapstructure" tag data is used to direct reads from app.toml;
+// "json" tag data is used to populate init messages for the VM.
+// This should be kept in sync with SwingsetConfigShape in
+// ../../../../packages/cosmic-swingset/src/chain-main.js.
+// TODO: Consider extensions from docs/env.md.
+type SwingsetConfig struct {
+ // SlogFile is the path at which a SwingSet log "slog" file should be written.
+ // If relative, it is interpreted against the application home directory
+ SlogFile string `mapstructure:"slogfile" json:"slogfile,omitempty"`
+
+ // MaxVatsOnline is the maximum number of vats that the SwingSet kernel will have online
+ // at any given time.
+ MaxVatsOnline int `mapstructure:"max-vats-online" json:"maxVatsOnline,omitempty"`
+
+ // VatSnapshotRetention controls retention of vat snapshots,
+ // and has values analogous to those of export `artifactMode` (cf.
+ // ../../../../packages/swing-store/docs/data-export.md#optional--historical-data ).
+ // * "debug": keep all snapshots
+ // * "operational": keep only the last snapshot
+ VatSnapshotRetention string `mapstructure:"vat-snapshot-retention" json:"vatSnapshotRetention,omitempty"`
+
+ // VatTranscriptRetention controls retention of vat transcript spans,
+ // and has values analogous to those of export `artifactMode` (cf.
+ // ../../../../packages/swing-store/docs/data-export.md#optional--historical-data ).
+ // * "archival": keep all transcript spans
+ // * "operational": keep only necessary transcript spans (i.e., since the
+ // last snapshot of their vat)
+ // * "default": determined by `pruning` ("archival" if `pruning` is
+ // "nothing", otherwise "operational")
+ VatTranscriptRetention string `mapstructure:"vat-transcript-retention" json:"vatTranscriptRetention,omitempty"`
+
+ // VatSnapshotArchiveDir controls archival of gzipped vat snapshots.
+ VatSnapshotArchiveDir string `mapstructure:"vat-snapshot-archive-dir" json:"vatSnapshotArchiveDir,omitempty"`
+
+ // VatTranscriptArchiveDir controls archival of historical (i.e., closed) vat
+ // transcript spans to gzipped files.
+ VatTranscriptArchiveDir string `mapstructure:"vat-transcript-archive-dir" json:"vatTranscriptArchiveDir,omitempty"`
+}
+
+var DefaultSwingsetConfig = SwingsetConfig{
+ SlogFile: "",
+ MaxVatsOnline: 50,
+ VatSnapshotRetention: "operational",
+ VatTranscriptRetention: "default",
+}
+
+func SwingsetConfigFromViper(resolvedConfig servertypes.AppOptions) (*SwingsetConfig, error) {
+ v, ok := resolvedConfig.(*viper.Viper)
+ if !ok {
+ // Tolerate an apparently empty configuration such as
+ // cosmos/cosmos-sdk/simapp EmptyAppOptions, but otherwise require viper.
+ if resolvedConfig.Get(flags.FlagHome) != nil {
+ return nil, fmt.Errorf("expected an instance of viper!")
+ }
+ }
+ if v == nil {
+ return nil, nil
+ }
+ v.MustBindEnv(FlagSlogfile, "SLOGFILE")
+ // See CustomAppConfig in ../../daemon/cmd/root.go.
+ type ExtendedConfig struct {
+ serverconfig.Config `mapstructure:",squash"`
+ Swingset SwingsetConfig `mapstructure:"swingset"`
+ }
+ extendedConfig := ExtendedConfig{}
+ if err := v.Unmarshal(&extendedConfig); err != nil {
+ return nil, err
+ }
+ ssConfig := &extendedConfig.Swingset
+
+ // Validate vat snapshot retention only if non-empty (because otherwise it
+ // it will be omitted, leaving the VM to apply its own defaults).
+ if ssConfig.VatSnapshotRetention != "" {
+ if util.IndexOf(snapshotRetentionValues, ssConfig.VatSnapshotRetention) == -1 {
+ err := fmt.Errorf(
+ "value for vat-snapshot-retention must be in %q",
+ snapshotRetentionValues,
+ )
+ return nil, err
+ }
+ }
+
+ // Default/validate vat transcript retention.
+ if ssConfig.VatTranscriptRetention == "" || ssConfig.VatTranscriptRetention == "default" {
+ if extendedConfig.Pruning == pruningtypes.PruningOptionNothing {
+ ssConfig.VatTranscriptRetention = TranscriptRetentionOptionArchival
+ } else {
+ ssConfig.VatTranscriptRetention = TranscriptRetentionOptionOperational
+ }
+ }
+ if util.IndexOf(transcriptRetentionValues, ssConfig.VatTranscriptRetention) == -1 {
+ valuesCopy := append([]string{}, transcriptRetentionValues...)
+ err := fmt.Errorf(
+ "value for vat-transcript-retention must be in %q",
+ append(valuesCopy, "default"),
+ )
+ return nil, err
+ }
+
+ // Interpret relative paths from config files against the application home
+ // directory and from other sources (e.g. env vars) against the current
+ // working directory.
+ var fileOnlyViper *viper.Viper
+ resolvePath := func(path, configKey string) (string, error) {
+ if path == "" || filepath.IsAbs(path) {
+ return path, nil
+ }
+ if v.InConfig(configKey) {
+ if fileOnlyViper == nil {
+ var err error
+ fileOnlyViper, err = util.NewFileOnlyViper(v)
+ if err != nil {
+ return "", err
+ }
+ }
+ pathFromFile := fileOnlyViper.GetString(configKey)
+ if path == pathFromFile {
+ homePath := viper.GetString(flags.FlagHome)
+ if homePath == "" {
+ return "", fmt.Errorf("cannot resolve path against empty application home")
+ }
+ absHomePath, err := filepath.Abs(homePath)
+ return filepath.Join(absHomePath, path), err
+ }
+ }
+ return filepath.Abs(path)
+ }
+
+ resolvedSlogFile, err := resolvePath(ssConfig.SlogFile, FlagSlogfile)
+ if err != nil {
+ return nil, err
+ }
+ ssConfig.SlogFile = resolvedSlogFile
+
+ resolvedSnapshotDir, err := resolvePath(ssConfig.VatSnapshotArchiveDir, FlagVatSnapshotArchiveDir)
+ if err != nil {
+ return nil, err
+ }
+ ssConfig.VatSnapshotArchiveDir = resolvedSnapshotDir
+
+ resolvedTranscriptDir, err := resolvePath(ssConfig.VatTranscriptArchiveDir, FlagVatTranscriptArchiveDir)
+ if err != nil {
+ return nil, err
+ }
+ ssConfig.VatTranscriptArchiveDir = resolvedTranscriptDir
+
+ return ssConfig, nil
+}
diff --git a/golang/cosmos/x/vibc/types/ibc_module.go b/golang/cosmos/x/vibc/types/ibc_module.go
index b5abb322c0f..a240c2414ab 100644
--- a/golang/cosmos/x/vibc/types/ibc_module.go
+++ b/golang/cosmos/x/vibc/types/ibc_module.go
@@ -1,6 +1,8 @@
package types
import (
+ fmt "fmt"
+
sdkioerrors "cosmossdk.io/errors"
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
capability "github.com/cosmos/cosmos-sdk/x/capability/types"
@@ -221,7 +223,10 @@ func (im IBCModule) OnChanCloseInit(
}
err := im.impl.PushAction(ctx, event)
- return err
+ if err != nil {
+ return err
+ }
+ return fmt.Errorf("OnChanCloseInit can only be sent by the VM")
}
type ChannelCloseConfirmEvent struct {
diff --git a/golang/cosmos/x/vtransfer/ibc_middleware.go b/golang/cosmos/x/vtransfer/ibc_middleware.go
index 2264ae87e5b..b47c76c2a63 100644
--- a/golang/cosmos/x/vtransfer/ibc_middleware.go
+++ b/golang/cosmos/x/vtransfer/ibc_middleware.go
@@ -50,7 +50,7 @@ func NewIBCMiddleware(ibcModule porttypes.IBCModule, vtransferKeeper keeper.Keep
// wrapped IBCModule. They are not performed in the context of a packet, and so
// do not need to be intercepted.
-// OnChanCloseInit implements the IBCModule interface.
+// OnChanOpenInit implements the IBCModule interface.
func (im IBCMiddleware) OnChanOpenInit(
ctx sdk.Context,
order channeltypes.Order,
diff --git a/multichain-testing/Makefile b/multichain-testing/Makefile
index 52275118340..3fe90607fed 100644
--- a/multichain-testing/Makefile
+++ b/multichain-testing/Makefile
@@ -5,7 +5,7 @@ FILE = config.yaml
HELM_REPO = starship
HELM_CHART = devnet
-HELM_VERSION = v0.2.2
+HELM_VERSION = v0.2.10
###############################################################################
### All commands ###
@@ -61,7 +61,7 @@ setup-kind:
.PHONY: clean-kind
clean-kind:
- kind delete cluster --name $(KIND_CLUSTER)
+ -kind delete cluster --name $(KIND_CLUSTER)
###############################################################################
### Agoric Setup ###
@@ -91,3 +91,15 @@ provision-smart-wallet:
# view agoric swingset logs from slog file, until we can set `DEBUG=SwingSet:vat,SwingSet:ls`
tail-slog:
kubectl exec -i agoriclocal-genesis-0 -c validator -- tail -f slog.slog
+
+###############################################################################
+### Start All ###
+###############################################################################
+
+.PHONY: wait-for-pods
+wait-for-pods:
+ node_modules/.bin/tsx scripts/pod-readiness.ts
+
+.PHONY: start
+start: install wait-for-pods port-forward fund-provision-pool override-chain-registry
+
diff --git a/multichain-testing/README.md b/multichain-testing/README.md
index 48490edfde6..cb090092cde 100644
--- a/multichain-testing/README.md
+++ b/multichain-testing/README.md
@@ -2,10 +2,9 @@
End-to-end testing environment for fully simulated chains, powered by [Starship](https://docs.cosmology.zone/starship).
-
## Configuration
-The current commands will read from [`config.yaml`](./config.yaml) to build a multi-chain teting environment. Currently, the image includes `agoric`, `osmosis`, and `cosmos-hub` chains and a hermes relayer between each.
+The current commands will read from [`config.yaml`](./config.yaml) to build a multi-chain testing environment. Currently, the image includes `agoric`, `osmosis`, and `cosmoshub` chains and a hermes relayer between each.
The `agoric` software revision includes the vats necessary for building and testing orchestration applications:
- vat-network
@@ -16,9 +15,15 @@ The `agoric` software revision includes the vats necessary for building and test
## Initial Setup
-First, ensure you have Kubernetes available. See https://docs.cosmology.zone/starship/get-started/step-2.
+Install the relevant dependencies:
+
+```sh
+yarn install
+```
+
+Ensure you have Kubernetes available. See https://docs.cosmology.zone/starship/get-started/step-2.
-The following will install `kubectl`, `kind`, `helm`, and `yq` as needed.
+The following will install `kubectl`, `kind`, `helm`, and `yq` as needed:
```sh
make clean setup
@@ -26,19 +31,31 @@ make clean setup
## Getting Started
+You can start everything with a single command:
+
+```sh
+make start
+```
+
+This command will:
+1. Install the Helm chart and start the Starship service
+2. Wait for all pods to be ready
+3. Set up port forwarding
+4. Fund the provision pool
+5. Override the chain registry
+
+The process may take 7-12 minutes to complete. You'll see status updates as the pods come online.
+
+Alternatively, you can run the steps individually:
+
```sh
# install helm chart and start starship service
make install
# wait for all pods to spin up
-watch kubectl get pods
-```
+make wait-for-pods
-**Wait 10-12** minutes. It takes some time for the above to finish setting up. The watch command should show a table in which the STATUS of every pod is Running.
-
-
-```bash
-# expose ports on your local machine. useful for testing dapps
+# expose ports on your local machine (useful for testing dapps)
make port-forward
# set up Agoric testing environment
@@ -47,7 +64,7 @@ make fund-provision-pool override-chain-registry
If you get an error like "connection refused", you need to wait longer, until all the pods are Running.
-# Cleanup
+## Cleanup
```sh
# stop the containers and port-forwarding
@@ -57,10 +74,9 @@ make stop
make clean
```
-
## Logs
-You can use the following commmands to view logs:
+You can use the following commands to view logs:
```sh
# agoric slogfile
@@ -92,12 +108,12 @@ make fund-wallet COIN=20000000ubld ADDR=$ADDR
make provision-smart-wallet ADDR=$ADDR
```
-# Chain Registry
+## Chain Registry
These only work if you've done `make port-forward`.
-http://localhost:8081/chains/agoriclocal
-http://localhost:8081/chains/osmosislocal
-http://localhost:8081/chains/gaialocal
-http://localhost:8081/chains/agoriclocal/keys
-http://localhost:8081/ibc
+- http://localhost:8081/chains/agoriclocal
+- http://localhost:8081/chains/osmosislocal
+- http://localhost:8081/chains/gaialocal
+- http://localhost:8081/chains/agoriclocal/keys
+- http://localhost:8081/ibc
diff --git a/multichain-testing/config.yaml b/multichain-testing/config.yaml
index a82dbac5e8b..8bb75beeeb4 100644
--- a/multichain-testing/config.yaml
+++ b/multichain-testing/config.yaml
@@ -44,7 +44,9 @@ chains:
host_port: 'icqhost'
params:
host_enabled: true
- allow_queries: ['*']
+ allow_queries:
+ - /cosmos.bank.v1beta1.Query/Balance
+ - /cosmos.bank.v1beta1.Query/AllBalances
faucet:
enabled: true
type: starship
@@ -71,6 +73,7 @@ chains:
allow_messages: ['*']
faucet:
enabled: true
+ type: starship
ports:
rest: 1314
rpc: 26654
diff --git a/multichain-testing/package.json b/multichain-testing/package.json
index 7088cc34fb2..158a9a46829 100644
--- a/multichain-testing/package.json
+++ b/multichain-testing/package.json
@@ -36,13 +36,12 @@
"execa": "^9.2.0",
"fs-extra": "^11.2.0",
"patch-package": "^8.0.0",
- "starshipjs": "2.0.0",
+ "starshipjs": "2.4.0",
"tsimp": "^2.0.10",
"tsx": "^4.15.6",
"typescript": "^5.3.3"
},
"resolutions": {
- "node-fetch": "2.6.12",
"axios": "1.6.7"
},
"ava": {
diff --git a/multichain-testing/patches/starshipjs+2.0.0.patch b/multichain-testing/patches/starshipjs+2.0.0.patch
deleted file mode 100644
index d8c2ab9a825..00000000000
--- a/multichain-testing/patches/starshipjs+2.0.0.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-diff --git a/node_modules/starshipjs/hooks.js b/node_modules/starshipjs/hooks.js
-index fb3e3cf..6b6567b 100644
---- a/node_modules/starshipjs/hooks.js
-+++ b/node_modules/starshipjs/hooks.js
-@@ -14,7 +14,7 @@ const useRegistry = async (configFile) => {
- const registryUrl = `http://localhost:${config.registry.ports.rest}`;
- const urls = [];
- config.chains?.forEach((chain) => {
-- urls.push(`${registryUrl}/chains/${chain.name}`, `${registryUrl}/chains/${chain.name}/assets`);
-+ urls.push(`${registryUrl}/chains/${chain.id}`, `${registryUrl}/chains/${chain.id}/assets`);
- });
- config.relayers?.forEach((relayer) => {
- urls.push(`${registryUrl}/ibc/${relayer.chains[0]}/${relayer.chains[1]}`, `${registryUrl}/ibc/${relayer.chains[1]}/${relayer.chains[0]}`);
-@@ -35,10 +35,10 @@ const useChain = (chainName) => {
- const chainInfo = registry.getChainInfo(chainName);
- const chainID = chainInfo.chain.chain_id;
- const getRpcEndpoint = () => {
-- return `http://localhost:${config.chains.find((chain) => chain.name === chainID).ports.rpc}`;
-+ return `http://localhost:${config.chains.find((chain) => chain.id === chainID).ports.rpc}`;
- };
- const getRestEndpoint = () => {
-- return `http://localhost:${config.chains.find((chain) => chain.name === chainID).ports.rest}`;
-+ return `http://localhost:${config.chains.find((chain) => chain.id === chainID).ports.rest}`;
- };
- const getGenesisMnemonic = async () => {
- const url = `http://localhost:${config.registry.ports.rest}/chains/${chainID}/keys`;
-@@ -50,7 +50,7 @@ const useChain = (chainName) => {
- return chainInfo.fetcher.getChainAssetList(chainName).assets[0];
- };
- const creditFromFaucet = async (address, denom = null) => {
-- const faucetEndpoint = `http://localhost:${config.chains.find((chain) => chain.name === chainID).ports.faucet}/credit`;
-+ const faucetEndpoint = `http://localhost:${config.chains.find((chain) => chain.id === chainID).ports.faucet}/credit`;
- if (!denom) {
- denom = getCoin().base;
- }
diff --git a/multichain-testing/scripts/fetch-starship-chain-info.ts b/multichain-testing/scripts/fetch-starship-chain-info.ts
index f809e031e16..e660039cad2 100755
--- a/multichain-testing/scripts/fetch-starship-chain-info.ts
+++ b/multichain-testing/scripts/fetch-starship-chain-info.ts
@@ -1,6 +1,6 @@
#!/usr/bin/env tsx
+/* eslint-env node */
-import nodeFetch from 'node-fetch';
import fsp from 'node:fs/promises';
import prettier from 'prettier';
@@ -8,8 +8,6 @@ import { convertChainInfo } from '@agoric/orchestration/src/utils/registry.js';
import type { IBCInfo, Chains } from '@chain-registry/types';
-const fetch = nodeFetch.default;
-
/**
* Chain registry running in Starship
*
@@ -29,21 +27,6 @@ const ibc: {
data: IBCInfo[];
} = await fetch(`${BASE_URL}ibc`).then(r => r.json());
-// UNTIL https://github.com/cosmology-tech/starship/issues/494
-const backmap = {
- agoriclocal: 'agoric',
- osmosislocal: 'osmosis',
- gaialocal: 'cosmoshub',
-};
-for (const ibcInfo of ibc.data) {
- ibcInfo.chain_1.chain_name = backmap[ibcInfo.chain_1.chain_name];
- ibcInfo.chain_2.chain_name = backmap[ibcInfo.chain_2.chain_name];
- for (const c of ibcInfo.channels) {
- // @ts-expect-error XXX bad typedef
- c.tags.preferred = c.tags.perferred;
- }
-}
-
const chainInfo = await convertChainInfo({
chains,
ibcData: ibc.data,
diff --git a/multichain-testing/scripts/install.sh b/multichain-testing/scripts/install.sh
index faa8bac917e..930212af9e4 100644
--- a/multichain-testing/scripts/install.sh
+++ b/multichain-testing/scripts/install.sh
@@ -24,7 +24,7 @@ NAMESPACE=""
HELM_REPO="starship"
HELM_CHART="starship/devnet"
HELM_REPO_URL="https://cosmology-tech.github.io/starship/"
-HELM_CHART_VERSION="0.2.2"
+HELM_CHART_VERSION="0.2.8"
HELM_NAME="agoric-multichain-testing"
# check_helm function verifies the helm binary is installed
@@ -62,7 +62,6 @@ function set_helm_args() {
return 0
fi
for i in $(seq 0 $num_chains); do
- chain=$(yq -r ".chains[$i].name" ${CONFIGFILE})
scripts=$(yq -r ".chains[$i].scripts" ${CONFIGFILE})
if [[ "$scripts" == "null" ]]; then
return 0
@@ -114,7 +113,7 @@ while [ $# -gt 0 ]; do
DRY_RUN=1
shift # past argument
;;
- -* | --*)
+ -)
echo "Unknown option $1"
exit 1
;;
diff --git a/multichain-testing/scripts/pod-readiness.ts b/multichain-testing/scripts/pod-readiness.ts
new file mode 100644
index 00000000000..a5a583d6946
--- /dev/null
+++ b/multichain-testing/scripts/pod-readiness.ts
@@ -0,0 +1,36 @@
+import { execa } from 'execa';
+import { sleep } from '../tools/sleep.ts';
+
+const checkPodsReadiness = async (): Promise => {
+ const { stdout } = await execa('kubectl', ['get', 'pods']);
+ console.clear();
+ console.log('Current pod status:');
+ console.log(stdout);
+
+ const lines = stdout.split('\n').slice(1); // Skip the header line
+ return (
+ lines.length > 0 &&
+ lines.every(line => {
+ const [, ready] = line.split(/\s+/);
+ const [readyCount, totalCount] = ready.split('/');
+ return readyCount === totalCount;
+ })
+ );
+};
+
+const main = async () => {
+ console.log('Starting pod readiness check...');
+ for (;;) {
+ const allReady = await checkPodsReadiness();
+ if (allReady) {
+ console.log('All pods are ready!');
+ process.exit(0);
+ }
+ await sleep(2 * 1_000);
+ }
+};
+
+main().catch(error => {
+ console.error('An error occurred:', error);
+ process.exit(1);
+});
diff --git a/multichain-testing/scripts/update-config.sh b/multichain-testing/scripts/update-config.sh
index a350f60142c..7d8046d0eb7 100644
--- a/multichain-testing/scripts/update-config.sh
+++ b/multichain-testing/scripts/update-config.sh
@@ -16,17 +16,6 @@ sed -i -e 's/index_all_keys = false/index_all_keys = true/g' $CHAIN_DIR/config/c
sed -i -e 's/seeds = ".*"/seeds = ""/g' $CHAIN_DIR/config/config.toml
sed -i -e 's#cors_allowed_origins = \[\]#cors_allowed_origins = \["*"\]#g' $CHAIN_DIR/config/config.toml
-echo "Increase $(*_bytes) parameters for MsgInstallBundle"
-# See https://github.com/Agoric/agoric-sdk/blob/7b684a6268c999b082a326fdb22f63e4575bac4f/packages/agoric-cli/src/chain-config.js#L66
-RPC_MAX_BODY_BYTES=15000000
-MAX_HEADER_BYTES=$((RPC_MAX_BODY_BYTES / 10))
-MAX_TXS_BYTES=$((RPC_MAX_BODY_BYTES * 50))
-sed -i -e "s/max_body_bytes = .*/max_body_bytes = $RPC_MAX_BODY_BYTES/g" $CHAIN_DIR/config/config.toml
-sed -i -e "s/max_header_bytes = .*/max_header_bytes = $MAX_HEADER_BYTES/g" $CHAIN_DIR/config/config.toml
-sed -i -e "s/max_txs_bytes = .*/max_txs_bytes = $MAX_TXS_BYTES/g" $CHAIN_DIR/config/config.toml
-sed -i -e "s/max_tx_bytes = .*/max_tx_bytes = $RPC_MAX_BODY_BYTES/g" $CHAIN_DIR/config/config.toml
-sed -i -e "s/^rpc-max-body-bytes =.*/rpc-max-body-bytes = $RPC_MAX_BODY_BYTES/" $CHAIN_DIR/config/app.toml
-
echo "Update client.toml file"
sed -i -e 's#keyring-backend = "os"#keyring-backend = "test"#g' $CHAIN_DIR/config/client.toml
sed -i -e 's#output = "text"#output = "json"#g' $CHAIN_DIR/config/client.toml
diff --git a/multichain-testing/test/account-balance-queries.test.ts b/multichain-testing/test/account-balance-queries.test.ts
new file mode 100644
index 00000000000..05344da9f53
--- /dev/null
+++ b/multichain-testing/test/account-balance-queries.test.ts
@@ -0,0 +1,191 @@
+import anyTest from '@endo/ses-ava/prepare-endo.js';
+import type { TestFn } from 'ava';
+import type { CosmosChainInfo } from '@agoric/orchestration';
+import {
+ commonSetup,
+ SetupContextWithWallets,
+ chainConfig,
+} from './support.js';
+import { makeDoOffer } from '../tools/e2e-tools.js';
+import chainInfo from '../starship-chain-info.js';
+import { MAKE_ACCOUNT_AND_QUERY_BALANCE_TIMEOUT } from './config.js';
+
+const test = anyTest as TestFn;
+
+const accounts = ['osmosis', 'cosmoshub', 'agoric'];
+
+const contractName = 'queryFlows';
+const contractBuilder =
+ '../packages/builders/scripts/testing/start-query-flows.js';
+
+test.before(async t => {
+ const { deleteTestKeys, setupTestKeys, ...rest } = await commonSetup(t);
+ deleteTestKeys(accounts).catch();
+ const wallets = await setupTestKeys(accounts);
+ t.context = { ...rest, wallets, deleteTestKeys };
+ const { startContract } = rest;
+ await startContract(contractName, contractBuilder);
+});
+
+test.after(async t => {
+ const { deleteTestKeys } = t.context;
+ deleteTestKeys(accounts);
+});
+
+const queryAccountBalances = test.macro({
+ title: (_, chainName: string) => `Query Account Balances on ${chainName}`,
+ exec: async (t, chainName: string) => {
+ const config = chainConfig[chainName];
+ if (!config) return t.fail(`Unknown chain: ${chainName}`);
+ const {
+ wallets,
+ provisionSmartWallet,
+ vstorageClient,
+ retryUntilCondition,
+ } = t.context;
+
+ const agoricAddr = wallets[chainName];
+ const wdUser1 = await provisionSmartWallet(agoricAddr, {
+ BLD: 100n,
+ IST: 100n,
+ });
+ t.log(`provisioning agoric smart wallet for ${agoricAddr}`);
+
+ const doOffer = makeDoOffer(wdUser1);
+ t.log(`${chainName} makeAccountAndGetBalancesQuery offer`);
+ const offerId = `${chainName}-makeAccountAndGetBalancesQuery-${Date.now()}`;
+
+ await doOffer({
+ id: offerId,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: [contractName],
+ callPipe: [['makeAccountAndGetBalancesQueryInvitation']],
+ },
+ offerArgs: { chainName },
+ proposal: {},
+ });
+
+ const offerResult = await retryUntilCondition(
+ () => vstorageClient.queryData(`published.wallet.${agoricAddr}`),
+ ({ status }) => status.id === offerId && (status.result || status.error),
+ `${offerId} offer result is in vstorage`,
+ MAKE_ACCOUNT_AND_QUERY_BALANCE_TIMEOUT,
+ );
+ t.log('Account Balances Query Offer Result', offerResult);
+
+ const { icqEnabled } = (chainInfo as Record)[
+ chainName
+ ];
+ const expectValidResult = icqEnabled || chainName === 'agoric';
+ t.log(
+ `Expecting offer ${expectValidResult ? 'result' : 'error'} for ${chainName}`,
+ );
+
+ const {
+ status: { result, error },
+ } = offerResult;
+ if (expectValidResult) {
+ t.is(error, undefined, 'No error observed for supported chain');
+ const balances = JSON.parse(result);
+ t.truthy(balances, 'Result is parsed successfully');
+ t.true(Array.isArray(balances), 'Balances is an array');
+ t.is(balances.length, 0, 'Balances are empty');
+ } else {
+ t.truthy(error, 'Error observed for unsupported chain');
+ t.regex(
+ error,
+ /Queries not available for chain/i,
+ 'Correct error message for unsupported chain',
+ );
+ }
+ },
+});
+
+const queryAccountBalance = test.macro({
+ title: (_, chainName: string) => `Query Account Balance on ${chainName}`,
+ exec: async (t, chainName: string) => {
+ const config = chainConfig[chainName];
+ if (!config) return t.fail(`Unknown chain: ${chainName}`);
+ const {
+ wallets,
+ provisionSmartWallet,
+ vstorageClient,
+ retryUntilCondition,
+ useChain,
+ } = t.context;
+
+ const {
+ chainInfo: {
+ chain: { staking },
+ },
+ } = useChain(chainName);
+ const denom = staking?.staking_tokens?.[0].denom;
+ if (!denom) throw Error(`no denom for ${chainName}`);
+
+ const agoricAddr = wallets[chainName];
+ const wdUser1 = await provisionSmartWallet(agoricAddr, {
+ BLD: 100n,
+ IST: 100n,
+ });
+ t.log(`provisioning agoric smart wallet for ${agoricAddr}`);
+
+ const doOffer = makeDoOffer(wdUser1);
+ t.log(`${chainName} makeAccountAndGetBalanceQuery offer`);
+ const offerId = `${chainName}-makeAccountAndGetBalanceQuery-${Date.now()}`;
+
+ await doOffer({
+ id: offerId,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: [contractName],
+ callPipe: [['makeAccountAndGetBalanceQueryInvitation']],
+ },
+ offerArgs: { chainName, denom },
+ proposal: {},
+ });
+
+ const offerResult = await retryUntilCondition(
+ () => vstorageClient.queryData(`published.wallet.${agoricAddr}`),
+ ({ status }) => status.id === offerId && (status.result || status.error),
+ `${offerId} offer result is in vstorage`,
+ MAKE_ACCOUNT_AND_QUERY_BALANCE_TIMEOUT,
+ );
+ t.log('Account Balance Query Offer Result', offerResult);
+ const { icqEnabled } = (chainInfo as Record)[
+ chainName
+ ];
+
+ const expectValidResult = icqEnabled || chainName === 'agoric';
+ t.log(
+ `Expecting offer ${expectValidResult ? 'result' : 'error'} for ${chainName}`,
+ );
+
+ const {
+ status: { result, error },
+ } = offerResult;
+ if (expectValidResult) {
+ t.is(error, undefined, 'No error observed for supported chain');
+ const parsedBalance = JSON.parse(result);
+ t.truthy(parsedBalance, 'Result is parsed successfully');
+
+ t.truthy(parsedBalance, 'Balance object exists');
+ t.is(parsedBalance.denom, denom, 'Correct denom in balance');
+ t.is(parsedBalance.value, '[0n]', 'Balance amount is 0n');
+ } else {
+ t.truthy(error, 'Error observed for unsupported chain');
+ t.regex(
+ error,
+ /Queries not available for chain/i,
+ 'Correct error message for unsupported chain',
+ );
+ }
+ },
+});
+
+test.serial(queryAccountBalances, 'osmosis');
+test.serial(queryAccountBalances, 'cosmoshub');
+test.serial(queryAccountBalances, 'agoric');
+test.serial(queryAccountBalance, 'osmosis');
+test.serial(queryAccountBalance, 'cosmoshub');
+test.serial(queryAccountBalance, 'agoric');
diff --git a/multichain-testing/test/auto-stake-it.test.ts b/multichain-testing/test/auto-stake-it.test.ts
index 89dcead678d..5aee9d6fa15 100644
--- a/multichain-testing/test/auto-stake-it.test.ts
+++ b/multichain-testing/test/auto-stake-it.test.ts
@@ -1,16 +1,17 @@
+import type { CosmosChainInfo } from '@agoric/orchestration';
import anyTest from '@endo/ses-ava/prepare-endo.js';
import type { ExecutionContext, TestFn } from 'ava';
import { useChain } from 'starshipjs';
-import type { CosmosChainInfo, IBCConnectionInfo } from '@agoric/orchestration';
-import type { SetupContextWithWallets } from './support.js';
-import { chainConfig, commonSetup } from './support.js';
-import { makeQueryClient } from '../tools/query.js';
-import { makeDoOffer } from '../tools/e2e-tools.js';
import chainInfo from '../starship-chain-info.js';
+import { makeDoOffer } from '../tools/e2e-tools.js';
import {
createFundedWalletAndClient,
makeIBCTransferMsg,
} from '../tools/ibc-transfer.js';
+import { makeQueryClient } from '../tools/query.js';
+import type { SetupContextWithWallets } from './support.js';
+import { chainConfig, commonSetup } from './support.js';
+import { AUTO_STAKE_IT_DELEGATIONS_TIMEOUT } from './config.js';
const test = anyTest as TestFn;
@@ -25,15 +26,8 @@ test.before(async t => {
deleteTestKeys(accounts).catch();
const wallets = await setupTestKeys(accounts);
t.context = { ...rest, wallets, deleteTestKeys };
-
- t.log('bundle and install contract', contractName);
- await t.context.deployBuilder(contractBuilder);
- const vstorageClient = t.context.makeQueryTool();
- await t.context.retryUntilCondition(
- () => vstorageClient.queryData(`published.agoricNames.instance`),
- res => contractName in Object.fromEntries(res),
- `${contractName} instance is available`,
- );
+ const { startContract } = rest;
+ await startContract(contractName, contractBuilder);
});
test.after(async t => {
@@ -89,49 +83,26 @@ const makeFundAndTransfer = (t: ExecutionContext) => {
const autoStakeItScenario = test.macro({
title: (_, chainName: string) => `auto-stake-it on ${chainName}`,
exec: async (t, chainName: string) => {
+ // 1. setup
const {
wallets,
- makeQueryTool,
+ vstorageClient,
provisionSmartWallet,
retryUntilCondition,
} = t.context;
const fundAndTransfer = makeFundAndTransfer(t);
- // 1. Send initial tokens so denom is available (debatably necessary, but
- // allows us to trace the denom until we have ibc denoms in chainInfo)
- const agAdminAddr = wallets['agoricAdmin'];
- console.log('Sending tokens to', agAdminAddr, `from ${chainName}`);
- await fundAndTransfer(chainName, agAdminAddr);
-
// 2. Find 'stakingDenom' denom on agoric
- const agoricConns = chainInfo['agoric'].connections as Record<
- string,
- IBCConnectionInfo
- >;
const remoteChainInfo = (chainInfo as Record)[
chainName
];
- // const remoteChainId = remoteChainInfo.chain.chain_id;
- // const agoricToRemoteConn = agoricConns[remoteChainId];
- const { portId, channelId } =
- agoricConns[remoteChainInfo.chainId].transferChannel;
- const agoricQueryClient = makeQueryClient(
- useChain('agoric').getRestEndpoint(),
- );
const stakingDenom = remoteChainInfo?.stakingTokens?.[0].denom;
if (!stakingDenom) throw Error(`staking denom found for ${chainName}`);
- const { hash } = await retryUntilCondition(
- () =>
- agoricQueryClient.queryDenom(`/${portId}/${channelId}`, stakingDenom),
- denomTrace => !!denomTrace.hash,
- `local denom hash for ${stakingDenom} found`,
- );
- t.log(`found ibc denom hash for ${stakingDenom}:`, hash);
// 3. Find a remoteChain validator to delegate to
const remoteQueryClient = makeQueryClient(
- useChain(chainName).getRestEndpoint(),
+ await useChain(chainName).getRestEndpoint(),
);
const { validators } = await remoteQueryClient.queryValidators();
const validatorAddress = validators[0]?.operator_address;
@@ -168,13 +139,11 @@ const autoStakeItScenario = test.macro({
encoding: 'bech32',
chainId: remoteChainInfo.chainId,
},
- localDenom: `ibc/${hash}`,
},
proposal: {},
});
// FIXME https://github.com/Agoric/agoric-sdk/issues/9643
- const vstorageClient = makeQueryTool();
const currentWalletRecord = await retryUntilCondition(
() =>
vstorageClient.queryData(`published.wallet.${agoricUserAddr}.current`),
@@ -208,14 +177,11 @@ const autoStakeItScenario = test.macro({
await fundAndTransfer(chainName, lcaAddress, transferAmount);
// 7. verify the COA has active delegations
- if (chainName === 'cosmoshub') {
- // FIXME: delegations are not visible on cosmoshub
- return t.pass('skipping verifying delegations on cosmoshub');
- }
const { delegation_responses } = await retryUntilCondition(
() => remoteQueryClient.queryDelegations(icaAddress),
({ delegation_responses }) => !!delegation_responses.length,
- `delegations visible on ${chainName}`,
+ `auto-stake-it delegations visible on ${chainName}`,
+ AUTO_STAKE_IT_DELEGATIONS_TIMEOUT,
);
t.log('delegation balance', delegation_responses[0]?.balance);
t.like(
diff --git a/multichain-testing/test/basic-flows.test.ts b/multichain-testing/test/basic-flows.test.ts
index f6649e0100b..9d8d9f57e44 100644
--- a/multichain-testing/test/basic-flows.test.ts
+++ b/multichain-testing/test/basic-flows.test.ts
@@ -20,15 +20,8 @@ test.before(async t => {
deleteTestKeys(accounts).catch();
const wallets = await setupTestKeys(accounts);
t.context = { ...rest, wallets, deleteTestKeys };
-
- t.log('bundle and install contract', contractName);
- await t.context.deployBuilder(contractBuilder);
- const vstorageClient = t.context.makeQueryTool();
- await t.context.retryUntilCondition(
- () => vstorageClient.queryData(`published.agoricNames.instance`),
- res => contractName in Object.fromEntries(res),
- `${contractName} instance is available`,
- );
+ const { startContract } = rest;
+ await startContract(contractName, contractBuilder);
});
test.after(async t => {
@@ -45,12 +38,10 @@ const makeAccountScenario = test.macro({
const {
wallets,
provisionSmartWallet,
- makeQueryTool,
+ vstorageClient,
retryUntilCondition,
} = t.context;
- const vstorageClient = makeQueryTool();
-
const agoricAddr = wallets[chainName];
const wdUser1 = await provisionSmartWallet(agoricAddr, {
BLD: 100n,
diff --git a/multichain-testing/test/chain-queries.test.ts b/multichain-testing/test/chain-queries.test.ts
new file mode 100644
index 00000000000..70d5e73bbf4
--- /dev/null
+++ b/multichain-testing/test/chain-queries.test.ts
@@ -0,0 +1,300 @@
+import anyTest from '@endo/ses-ava/prepare-endo.js';
+import type { TestFn } from 'ava';
+import {
+ QueryBalanceRequest,
+ QueryBalanceResponse,
+ QueryAllBalancesRequest,
+ QueryAllBalancesResponse,
+} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js';
+import { toRequestQueryJson, typedJson } from '@agoric/cosmic-proto';
+import { decodeBase64 } from '@endo/base64';
+import {
+ commonSetup,
+ SetupContextWithWallets,
+ chainConfig,
+ FAUCET_POUR,
+} from './support.js';
+import { makeDoOffer } from '../tools/e2e-tools.js';
+import { createWallet } from '../tools/wallet.js';
+import { makeQueryClient } from '../tools/query.js';
+
+const test = anyTest as TestFn;
+
+const accounts = ['osmosis', 'cosmoshub', 'agoric'];
+
+const contractName = 'queryFlows';
+const contractBuilder =
+ '../packages/builders/scripts/testing/start-query-flows.js';
+
+test.before(async t => {
+ const { deleteTestKeys, setupTestKeys, ...rest } = await commonSetup(t);
+ deleteTestKeys(accounts).catch();
+ const wallets = await setupTestKeys(accounts);
+ t.context = { ...rest, wallets, deleteTestKeys };
+ const { startContract } = rest;
+ await startContract(contractName, contractBuilder);
+});
+
+test.after(async t => {
+ const { deleteTestKeys } = t.context;
+ deleteTestKeys(accounts);
+});
+
+const queryICQChain = test.macro({
+ title: (_, chainName: string) => `Send ICQ Query on ${chainName}`,
+ exec: async (t, chainName: string) => {
+ const config = chainConfig[chainName];
+ if (!config) return t.fail(`Unknown chain: ${chainName}`);
+ const {
+ wallets,
+ provisionSmartWallet,
+ vstorageClient,
+ retryUntilCondition,
+ useChain,
+ } = t.context;
+
+ const { creditFromFaucet, chainInfo, getRestEndpoint } =
+ useChain(chainName);
+ const { staking, bech32_prefix } = chainInfo.chain;
+ const denom = staking?.staking_tokens?.[0].denom;
+ if (!denom) throw Error(`no denom for ${chainName}`);
+
+ t.log(
+ 'Set up wallet with tokens so we have a wallet with balance to query',
+ );
+ const wallet = await createWallet(bech32_prefix);
+ const { address } = (await wallet.getAccounts())[0];
+ await creditFromFaucet(address);
+
+ const remoteQueryClient = makeQueryClient(await getRestEndpoint());
+ await retryUntilCondition(
+ () => remoteQueryClient.queryBalances(address),
+ ({ balances }) => Number(balances?.[0]?.amount) > 0,
+ `Faucet balances found for ${address}`,
+ );
+
+ const agoricAddr = wallets[chainName];
+ const wdUser1 = await provisionSmartWallet(agoricAddr, {
+ BLD: 100n,
+ IST: 100n,
+ });
+ t.log(`provisioning agoric smart wallet for ${agoricAddr}`);
+
+ const doOffer = makeDoOffer(wdUser1);
+ t.log(`${chainName} sendICQQuery offer`);
+ const offerId = `${chainName}-sendICQQuery-${Date.now()}`;
+
+ const balanceQuery = toRequestQueryJson(
+ QueryBalanceRequest.toProtoMsg({
+ address,
+ denom,
+ }),
+ );
+ const allBalanceQuery = toRequestQueryJson(
+ QueryAllBalancesRequest.toProtoMsg({
+ address,
+ }),
+ );
+
+ await doOffer({
+ id: offerId,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: [contractName],
+ callPipe: [['makeSendICQQueryInvitation']],
+ },
+ offerArgs: { chainName, msgs: [balanceQuery, allBalanceQuery] },
+ proposal: {},
+ });
+
+ const offerResult = await retryUntilCondition(
+ () => vstorageClient.queryData(`published.wallet.${agoricAddr}`),
+ ({ status }) => status.id === offerId && (status.result || status.error),
+ `${offerId} offer result is in vstorage`,
+ {
+ maxRetries: 15,
+ },
+ );
+ t.log('ICQ Query Offer Result', offerResult);
+ const {
+ status: { result, error },
+ } = offerResult;
+ t.is(error, undefined, 'No error observed');
+
+ const [balanceQueryResult, allBalanceQueryResult] = JSON.parse(result);
+
+ t.is(balanceQueryResult.code, 0, 'balance query was successful');
+ const balanceQueryResultDecoded = QueryBalanceResponse.decode(
+ decodeBase64(balanceQueryResult.key),
+ );
+ t.log('balanceQueryResult', balanceQueryResultDecoded);
+ t.deepEqual(balanceQueryResultDecoded, {
+ balance: {
+ amount: String(FAUCET_POUR),
+ denom,
+ },
+ });
+
+ t.is(allBalanceQueryResult.code, 0, 'allBalances query was successful');
+ const allBalanceQueryResultDecoded = QueryAllBalancesResponse.decode(
+ decodeBase64(allBalanceQueryResult.key),
+ );
+ t.log('allBalanceQueryResult', allBalanceQueryResultDecoded);
+ t.like(allBalanceQueryResultDecoded, {
+ balances: [
+ {
+ amount: String(FAUCET_POUR),
+ denom,
+ },
+ ],
+ });
+ },
+});
+
+const queryChainWithoutICQ = test.macro({
+ title: (_, chainName: string) =>
+ `Attempt Query on chain with ICQ ${chainName}`,
+ exec: async (t, chainName: string) => {
+ const config = chainConfig[chainName];
+ if (!config) return t.fail(`Unknown chain: ${chainName}`);
+ const {
+ wallets,
+ provisionSmartWallet,
+ vstorageClient,
+ retryUntilCondition,
+ useChain,
+ } = t.context;
+
+ const { chainInfo } = useChain(chainName);
+ const { staking, chain_id } = chainInfo.chain;
+ const denom = staking?.staking_tokens?.[0].denom;
+ if (!denom) throw Error(`no denom for ${chainName}`);
+
+ const agoricAddr = wallets[chainName];
+ const wdUser1 = await provisionSmartWallet(agoricAddr, {
+ BLD: 100n,
+ IST: 100n,
+ });
+ t.log(`provisioning agoric smart wallet for ${agoricAddr}`);
+
+ const doOffer = makeDoOffer(wdUser1);
+ t.log(`${chainName} sendICQQuery offer (unsupported)`);
+ const offerId = `${chainName}-sendICQQuery-${Date.now()}`;
+
+ const balanceQuery = toRequestQueryJson(
+ QueryBalanceRequest.toProtoMsg({
+ address: 'cosmos1234',
+ denom,
+ }),
+ );
+
+ await doOffer({
+ id: offerId,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: [contractName],
+ callPipe: [['makeSendICQQueryInvitation']],
+ },
+ offerArgs: { chainName, msgs: [balanceQuery] },
+ proposal: {},
+ });
+
+ const offerResult = await retryUntilCondition(
+ () => vstorageClient.queryData(`published.wallet.${agoricAddr}`),
+ ({ status }) => status.id === offerId && (status.result || status.error),
+ `${offerId} continuing invitation is in vstorage`,
+ {
+ maxRetries: 10,
+ },
+ );
+ t.is(
+ offerResult.status.error,
+ `Error: Queries not available for chain "${chain_id}"`,
+ 'Queries not available error returned',
+ );
+ },
+});
+
+test.serial('Send Local Query from chain object', async t => {
+ const { wallets, provisionSmartWallet, vstorageClient, retryUntilCondition } =
+ t.context;
+
+ const agoricAddr = wallets['agoric'];
+ const wdUser1 = await provisionSmartWallet(agoricAddr, {
+ BLD: 100n,
+ IST: 100n,
+ });
+ const expectedBalances = [
+ {
+ denom: 'ubld',
+ amount: '90000000', // 100n * (10n ** 6n) - smart wallet provision
+ },
+ {
+ denom: 'uist',
+ amount: '100250000', // 100n * (10n ** 6n) + smart wallet credit
+ },
+ ];
+ t.log(`provisioning agoric smart wallet for ${agoricAddr}`);
+
+ const doOffer = makeDoOffer(wdUser1);
+ t.log('sendLocalQuery offer');
+ const offerId = `agoric-sendLocalQuery-${Date.now()}`;
+
+ const allBalancesProto3JsonQuery = typedJson(
+ '/cosmos.bank.v1beta1.QueryAllBalancesRequest',
+ {
+ address: agoricAddr,
+ },
+ );
+ const balanceProto3JsonQuery = typedJson(
+ '/cosmos.bank.v1beta1.QueryBalanceRequest',
+ {
+ address: agoricAddr,
+ denom: 'ubld',
+ },
+ );
+
+ await doOffer({
+ id: offerId,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: [contractName],
+ callPipe: [['makeSendLocalQueryInvitation']],
+ },
+ offerArgs: {
+ msgs: [allBalancesProto3JsonQuery, balanceProto3JsonQuery],
+ },
+ proposal: {},
+ });
+
+ const offerResult = await retryUntilCondition(
+ () => vstorageClient.queryData(`published.wallet.${agoricAddr}`),
+ ({ status }) => status.id === offerId && (status.result || status.error),
+ `${offerId} continuing invitation is in vstorage`,
+ {
+ maxRetries: 10,
+ },
+ );
+
+ const parsedResults = JSON.parse(offerResult.status.result);
+ t.truthy(parsedResults[0].height, 'query height is returned');
+ t.is(parsedResults[0].error, '', 'error is empty');
+ t.like(
+ parsedResults[0].reply,
+ {
+ balances: expectedBalances,
+ },
+ 'QueryAllBalances result is returned',
+ );
+ t.deepEqual(
+ parsedResults[1].reply,
+ {
+ '@type': '/cosmos.bank.v1beta1.QueryBalanceResponse',
+ balance: expectedBalances[0],
+ },
+ 'QueryBalance result is returned',
+ );
+});
+
+test.serial(queryICQChain, 'osmosis');
+test.serial(queryChainWithoutICQ, 'cosmoshub');
diff --git a/multichain-testing/test/config.ts b/multichain-testing/test/config.ts
new file mode 100644
index 00000000000..975c0d25e34
--- /dev/null
+++ b/multichain-testing/test/config.ts
@@ -0,0 +1,43 @@
+import type { RetryOptions } from '../tools/sleep.js';
+
+/**
+ * Wait up to 90 seconds to ensure staking rewards are available.
+ *
+ * While we expect staking rewards to be available after a
+ * single block (~5-12 seconds for most chains), this provides additional
+ * padding after observed failures in CI
+ * (https://github.com/Agoric/agoric-sdk/issues/9934).
+ *
+ * A more robust approach might consider Distribution params and the
+ * {@link FAUCET_POUR} constant to determine how many blocks it should take for
+ * rewards to be available.
+ */
+export const STAKING_REWARDS_TIMEOUT: RetryOptions = {
+ retryIntervalMs: 5000,
+ maxRetries: 18,
+};
+
+/**
+ * Wait up to 2 minutes to ensure:
+ * - IBC Transfer from LocalAccount -> ICA Account Completes
+ * - Delegation from ICA Account (initiated from SwingSet) Completes
+ * - Delegations are visible via LCD (API Endpoint)
+ *
+ * Most of the time this finishes in <7 seconds, but other times it
+ * appears to take much longer.
+ */
+export const AUTO_STAKE_IT_DELEGATIONS_TIMEOUT: RetryOptions = {
+ retryIntervalMs: 5000,
+ maxRetries: 24,
+};
+
+/**
+ * Wait up to 2 minutes to ensure:
+ * - ICA Account is created
+ * - ICQ Connection is established (in some instances)
+ * - Query is executed (sometimes local, sometimes via ICQ)
+ */
+export const MAKE_ACCOUNT_AND_QUERY_BALANCE_TIMEOUT: RetryOptions = {
+ retryIntervalMs: 5000,
+ maxRetries: 24,
+};
diff --git a/multichain-testing/test/ica-channel-close.test.ts b/multichain-testing/test/ica-channel-close.test.ts
new file mode 100644
index 00000000000..d7bf8305ea9
--- /dev/null
+++ b/multichain-testing/test/ica-channel-close.test.ts
@@ -0,0 +1,376 @@
+import anyTest from '@endo/ses-ava/prepare-endo.js';
+import type { TestFn } from 'ava';
+import type { CosmosOrchestrationAccountStorageState } from '@agoric/orchestration/src/exos/cosmos-orchestration-account.js';
+import type { IdentifiedChannelSDKType } from '@agoric/cosmic-proto/ibc/core/channel/v1/channel.js';
+import type { IBCChannelID, IBCPortID } from '@agoric/vats';
+import { makeDoOffer } from '../tools/e2e-tools.js';
+import {
+ commonSetup,
+ SetupContextWithWallets,
+ chainConfig,
+} from './support.js';
+import { makeQueryClient } from '../tools/query.js';
+import { parseLocalAddress, parseRemoteAddress } from '../tools/address.js';
+import chainInfo from '../starship-chain-info.js';
+
+const test = anyTest as TestFn;
+
+const accounts = ['cosmoshub', 'osmosis'];
+
+const contractName = 'basicFlows';
+const contractBuilder =
+ '../packages/builders/scripts/orchestration/init-basic-flows.js';
+
+test.before(async t => {
+ const { deleteTestKeys, setupTestKeys, ...rest } = await commonSetup(t);
+ deleteTestKeys(accounts).catch();
+ const wallets = await setupTestKeys(accounts);
+ t.context = { ...rest, wallets, deleteTestKeys };
+ const { startContract } = rest;
+ await startContract(contractName, contractBuilder);
+});
+
+test.after(async t => {
+ const { deleteTestKeys } = t.context;
+ deleteTestKeys(accounts);
+});
+
+// XXX until https://github.com/Agoric/agoric-sdk/issues/9066,
+// where localAddr + remoteAddr are reliably published to vstorage,
+// us original port to determine new channelID. currently, vstorage
+// values won't be updated when the ICA channel is reopened.
+const findNewChannel = (
+ channels: IdentifiedChannelSDKType[],
+ { rPortID, lPortID }: { rPortID: IBCPortID; lPortID: IBCPortID },
+) =>
+ channels.find(
+ c =>
+ c.port_id === rPortID &&
+ c.counterparty.port_id === lPortID &&
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ c.state === 'STATE_OPEN',
+ );
+
+/** The account holder chooses to close their ICA account (channel) */
+const intentionalCloseAccountScenario = test.macro({
+ title: (_, chainName: string) => `Close and reopen account on ${chainName}`,
+ exec: async (t, chainName: string) => {
+ const config = chainConfig[chainName];
+ if (!config) return t.fail(`Unknown chain: ${chainName}`);
+
+ const {
+ wallets,
+ provisionSmartWallet,
+ vstorageClient,
+ retryUntilCondition,
+ useChain,
+ } = t.context;
+
+ const agoricAddr = wallets[chainName];
+ const wdUser1 = await provisionSmartWallet(agoricAddr, {
+ BLD: 100n,
+ IST: 100n,
+ });
+ t.log(`provisioning agoric smart wallet for ${agoricAddr}`);
+
+ const doOffer = makeDoOffer(wdUser1);
+ t.log(`${chainName} makeAccount offer`);
+ const offerId = `${chainName}-makeAccount-${Date.now()}`;
+
+ await doOffer({
+ id: offerId,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: [contractName],
+ callPipe: [['makeOrchAccountInvitation']],
+ },
+ offerArgs: { chainName },
+ proposal: {},
+ });
+ const currentWalletRecord = await retryUntilCondition(
+ () => vstorageClient.queryData(`published.wallet.${agoricAddr}.current`),
+ ({ offerToPublicSubscriberPaths }) =>
+ Object.fromEntries(offerToPublicSubscriberPaths)[offerId],
+ `${offerId} continuing invitation is in vstorage`,
+ );
+ const offerToPublicSubscriberMap = Object.fromEntries(
+ currentWalletRecord.offerToPublicSubscriberPaths,
+ );
+
+ const accountStoragePath = offerToPublicSubscriberMap[offerId]?.account;
+ t.assert(accountStoragePath, 'account storage path returned');
+ const address = accountStoragePath.split('.').pop();
+ t.log('Got address:', address);
+
+ const {
+ remoteAddress,
+ localAddress,
+ }: CosmosOrchestrationAccountStorageState =
+ await vstorageClient.queryData(accountStoragePath);
+ const { rPortID, rChannelID } = parseRemoteAddress(remoteAddress);
+
+ const remoteQueryClient = makeQueryClient(
+ await useChain(chainName).getRestEndpoint(),
+ );
+ const localQueryClient = makeQueryClient(
+ await useChain('agoric').getRestEndpoint(),
+ );
+
+ const { channel } = await retryUntilCondition(
+ () => remoteQueryClient.queryChannel(rPortID, rChannelID),
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ ({ channel }) => channel?.state === 'STATE_OPEN',
+ `ICA channel is open on Host - ${chainName}`,
+ );
+ t.log('Channel State Before', channel);
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ t.is(channel?.state, 'STATE_OPEN', 'channel is open');
+
+ const closeAccountOfferId = `${chainName}-deactivateAccount-${Date.now()}`;
+ await doOffer({
+ id: closeAccountOfferId,
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: offerId,
+ invitationMakerName: 'DeactivateAccount',
+ },
+ proposal: {},
+ });
+
+ const { channel: rChannelAfterClose } = await retryUntilCondition(
+ () => remoteQueryClient.queryChannel(rPortID, rChannelID),
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ ({ channel }) => channel?.state === 'STATE_CLOSED',
+ `ICA channel is closed on Host - ${chainName}`,
+ );
+ t.log('Remote Channel State After', rChannelAfterClose);
+ t.is(
+ rChannelAfterClose?.state,
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ 'STATE_CLOSED',
+ `channel is closed from host perspective - ${chainName}`,
+ );
+
+ const { lPortID, lChannelID } = parseLocalAddress(localAddress);
+ const { channel: lChannelAfterClose } = await retryUntilCondition(
+ () => localQueryClient.queryChannel(lPortID, lChannelID),
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ ({ channel }) => channel?.state === 'STATE_CLOSED',
+ `ICA channel is closed on Controller - ${chainName}`,
+ );
+ t.log('Local Channel State After', lChannelAfterClose);
+ if (!lChannelAfterClose?.state) throw Error('channel state is available');
+ t.is(
+ lChannelAfterClose.state,
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ 'STATE_CLOSED',
+ `channel is closed from controller perspective - ${chainName}`,
+ );
+
+ const reopenAccountOfferId = `${chainName}-reactivateAccount-${Date.now()}`;
+ await doOffer({
+ id: reopenAccountOfferId,
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: offerId,
+ invitationMakerName: 'ReactivateAccount',
+ },
+ proposal: {},
+ });
+
+ const { channels } = await retryUntilCondition(
+ () => remoteQueryClient.queryChannels(),
+ ({ channels }) => !!findNewChannel(channels, { rPortID, lPortID }),
+ `ICA channel is reopened on ${chainName} Host`,
+ );
+ const newChannel = findNewChannel(channels, { rPortID, lPortID });
+ t.log('New Channel after Reactivate', newChannel);
+ if (!newChannel) throw Error('Channel not found');
+ const newAddress = JSON.parse(newChannel.version).address;
+ t.is(newAddress, address, `same chain address is returned - ${chainName}`);
+ t.is(
+ newChannel.state,
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ 'STATE_OPEN',
+ `channel is open on ${chainName} Host`,
+ );
+ t.not(newChannel.channel_id, rChannelID, 'remote channel id changed');
+ t.not(
+ newChannel.counterparty.channel_id,
+ lChannelID,
+ 'local channel id changed',
+ );
+ },
+});
+
+/** Only application logic should be able to close an ICA channel; not channelCloseInit. */
+const channelCloseInitScenario = test.macro({
+ title: (_, chainName: string) =>
+ `Clients cannot initiate channelCloseInit on ${chainName}`,
+ exec: async (t, chainName: string) => {
+ const config = chainConfig[chainName];
+ if (!config) return t.fail(`Unknown chain: ${chainName}`);
+
+ const {
+ wallets,
+ provisionSmartWallet,
+ vstorageClient,
+ retryUntilCondition,
+ useChain,
+ hermes,
+ } = t.context;
+
+ // make an account so there's an ICA channel we can attempt to close
+ const agoricAddr = wallets[chainName];
+ const wdUser1 = await provisionSmartWallet(agoricAddr, {
+ BLD: 100n,
+ IST: 100n,
+ });
+ t.log(`provisioning agoric smart wallet for ${agoricAddr}`);
+ const doOffer = makeDoOffer(wdUser1);
+ t.log(`${chainName} makeAccount offer`);
+ const offerId = `${chainName}-makeAccount-${Date.now()}`;
+ await doOffer({
+ id: offerId,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: [contractName],
+ callPipe: [['makeOrchAccountInvitation']],
+ },
+ offerArgs: { chainName },
+ proposal: {},
+ });
+ const currentWalletRecord = await retryUntilCondition(
+ () => vstorageClient.queryData(`published.wallet.${agoricAddr}.current`),
+ ({ offerToPublicSubscriberPaths }) =>
+ Object.fromEntries(offerToPublicSubscriberPaths)[offerId],
+ `${offerId} continuing invitation is in vstorage`,
+ );
+ const offerToPublicSubscriberMap = Object.fromEntries(
+ currentWalletRecord.offerToPublicSubscriberPaths,
+ );
+
+ const accountStoragePath = offerToPublicSubscriberMap[offerId]?.account;
+ t.assert(accountStoragePath, 'account storage path returned');
+ const address = accountStoragePath.split('.').pop();
+ t.log('Got address:', address);
+
+ const {
+ remoteAddress,
+ localAddress,
+ }: CosmosOrchestrationAccountStorageState =
+ await vstorageClient.queryData(accountStoragePath);
+ const { rPortID, rChannelID, rConnectionID } =
+ parseRemoteAddress(remoteAddress);
+ const { lPortID, lChannelID, lConnectionID } =
+ parseLocalAddress(localAddress);
+
+ const dst = {
+ chainId: chainInfo['agoric'].chainId,
+ channelID: lChannelID,
+ portID: lPortID,
+ connectionID: lConnectionID,
+ };
+ const src = {
+ chainId: useChain(chainName).chainInfo.chain.chain_id,
+ channelID: rChannelID,
+ portID: rPortID,
+ connectionID: rConnectionID,
+ };
+ console.log(
+ `Initiating channelCloseInit for dst: ${JSON.stringify(dst)} src: ${JSON.stringify(src)}`,
+ );
+ t.throws(
+ () => hermes.channelCloseInit(chainName, dst, src),
+ { message: /Command failed/ },
+ 'hermes channelCloseInit failed from agoric side for ICA',
+ );
+ t.throws(
+ () => hermes.channelCloseInit(chainName, src, dst),
+ { message: /Command failed/ },
+ `hermes channelCloseInit failed from ${chainName} side for ICA`,
+ );
+
+ const remoteQueryClient = makeQueryClient(
+ await useChain(chainName).getRestEndpoint(),
+ );
+ const { channel } = await retryUntilCondition(
+ () => remoteQueryClient.queryChannel(rPortID, rChannelID),
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ ({ channel }) => channel?.state === 'STATE_OPEN',
+ 'Hermes closeChannelInit failed so ICA channel is still open',
+ );
+ t.log(channel);
+ t.is(
+ channel?.state,
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ 'STATE_OPEN',
+ 'ICA channel is still open',
+ );
+
+ {
+ const transferChannel = (
+ await remoteQueryClient.queryChannels()
+ ).channels.find(
+ x => x.port_id === 'transfer' && x.connection_hops[0] === rConnectionID,
+ );
+ if (!transferChannel) throw Error('Transfer channel not found.');
+
+ const dstTransferChannel = {
+ chainId: chainInfo['agoric'].chainId,
+ channelID: transferChannel.counterparty.channel_id as IBCChannelID,
+ portID: 'transfer',
+ connectionID: lConnectionID,
+ };
+ const srcTransferChannel = {
+ chainId: useChain(chainName).chainInfo.chain.chain_id,
+ channelID: transferChannel.channel_id as IBCChannelID,
+ portID: 'transfer',
+ connectionID: rConnectionID,
+ };
+ t.throws(
+ () =>
+ hermes.channelCloseInit(
+ chainName,
+ dstTransferChannel,
+ srcTransferChannel,
+ ),
+ { message: /Command failed/ },
+ 'hermes channelCloseInit failed from agoric side for transfer',
+ );
+ t.throws(
+ () =>
+ hermes.channelCloseInit(
+ chainName,
+ srcTransferChannel,
+ dstTransferChannel,
+ ),
+ { message: /Command failed/ },
+ `hermes channelCloseInit failed from ${chainName} side for transfer`,
+ );
+
+ const { channel } = await retryUntilCondition(
+ () =>
+ remoteQueryClient.queryChannel(
+ 'transfer',
+ transferChannel.channel_id,
+ ),
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ ({ channel }) => channel?.state === 'STATE_OPEN',
+ 'Hermes closeChannelInit failed so transfer channel is still open',
+ );
+ t.log(channel);
+ t.is(
+ channel?.state,
+ // @ts-expect-error ChannelSDKType.state is a string not a number
+ 'STATE_OPEN',
+ 'Transfer channel is still open',
+ );
+ }
+ },
+});
+
+test.serial(intentionalCloseAccountScenario, 'cosmoshub');
+test.serial(intentionalCloseAccountScenario, 'osmosis');
+test.serial(channelCloseInitScenario, 'cosmoshub');
+test.serial(channelCloseInitScenario, 'osmosis');
diff --git a/multichain-testing/test/send-anywhere.test.ts b/multichain-testing/test/send-anywhere.test.ts
new file mode 100644
index 00000000000..4eaf9e5711a
--- /dev/null
+++ b/multichain-testing/test/send-anywhere.test.ts
@@ -0,0 +1,130 @@
+import anyTest from '@endo/ses-ava/prepare-endo.js';
+import type { TestFn } from 'ava';
+import { makeDoOffer } from '../tools/e2e-tools.js';
+import {
+ commonSetup,
+ SetupContextWithWallets,
+ chainConfig,
+} from './support.js';
+import { createWallet } from '../tools/wallet.js';
+import { AmountMath } from '@agoric/ertp';
+import { makeQueryClient } from '../tools/query.js';
+import type { Amount } from '@agoric/ertp/src/types.js';
+
+const test = anyTest as TestFn;
+
+const accounts = ['osmosis1', 'osmosis2', 'cosmoshub1', 'cosmoshub2'];
+
+const contractName = 'sendAnywhere';
+const contractBuilder =
+ '../packages/builders/scripts/testing/start-send-anywhere.js';
+
+test.before(async t => {
+ const { deleteTestKeys, setupTestKeys, ...rest } = await commonSetup(t);
+ deleteTestKeys(accounts).catch();
+ const wallets = await setupTestKeys(accounts);
+ t.context = { ...rest, wallets, deleteTestKeys };
+ const { startContract } = rest;
+ await startContract(contractName, contractBuilder);
+});
+
+test.after(async t => {
+ const { deleteTestKeys } = t.context;
+ deleteTestKeys(accounts);
+});
+
+const sendAnywhereScenario = test.macro({
+ title: (_, chainName: string, acctIdx: number) =>
+ `send-anywhere ${chainName}${acctIdx}`,
+ exec: async (t, chainName: string, acctIdx: number) => {
+ const config = chainConfig[chainName];
+ if (!config) return t.fail(`Unknown chain: ${chainName}`);
+
+ const {
+ wallets,
+ provisionSmartWallet,
+ vstorageClient,
+ retryUntilCondition,
+ useChain,
+ } = t.context;
+
+ t.log('Create a receiving wallet for the send-anywhere transfer');
+ const chain = useChain(chainName).chain;
+
+ t.log('Create an agoric smart wallet to initiate send-anywhere transfer');
+ const agoricAddr = wallets[`${chainName}${acctIdx}`];
+ const wdUser1 = await provisionSmartWallet(agoricAddr, {
+ BLD: 100_000n,
+ IST: 100_000n,
+ });
+ t.log(`provisioning agoric smart wallet for ${agoricAddr}`);
+
+ const doOffer = makeDoOffer(wdUser1);
+
+ const brands = await vstorageClient.queryData(
+ 'published.agoricNames.brand',
+ );
+ const istBrand = Object.fromEntries(brands).IST;
+
+ const apiUrl = await useChain(chainName).getRestEndpoint();
+ const queryClient = makeQueryClient(apiUrl);
+ t.log(`Made ${chainName} query client`);
+
+ const doSendAnywhere = async (amount: Amount) => {
+ t.log(`Sending ${amount.value} ${amount.brand}.`);
+ const wallet = await createWallet(chain.bech32_prefix);
+ const receiver = {
+ chainId: chain.chain_id,
+ value: (await wallet.getAccounts())[0].address,
+ encoding: 'bech32',
+ };
+ t.log('Will send payment to:', receiver);
+ t.log(`${chainName} offer`);
+ const offerId = `${chainName}-makeSendInvitation-${Date.now()}`;
+ await doOffer({
+ id: offerId,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: [contractName],
+ callPipe: [['makeSendInvitation']],
+ },
+ offerArgs: { destAddr: receiver.value, chainName },
+ proposal: { give: { Send: amount } },
+ });
+
+ const { balances } = await retryUntilCondition(
+ () => queryClient.queryBalances(receiver.value),
+ ({ balances }) => 'amount' in balances[0],
+ `${receiver.value} ${amount.value} balance available from send-anywhere`,
+ );
+
+ t.log(`${receiver.value} Balances`, balances);
+ t.like(balances, [
+ {
+ // XXX consider verifying uist hash
+ amount: String(amount.value),
+ },
+ ]);
+ };
+
+ const makeRandomValue = (min: number, max: number) =>
+ BigInt(Math.floor(Math.random() * (max - min + 1)) + min);
+ // send 3 offers from each account. different values help distinguish
+ // one offer/result from another.
+ const offerAmounts = [
+ makeRandomValue(1, 33),
+ makeRandomValue(34, 66),
+ makeRandomValue(67, 100),
+ ];
+ console.log(`${agoricAddr} offer amounts:`, offerAmounts);
+
+ for (const value of offerAmounts) {
+ await doSendAnywhere(AmountMath.make(istBrand, value));
+ }
+ },
+});
+
+test.serial(sendAnywhereScenario, 'osmosis', 1);
+test.serial(sendAnywhereScenario, 'osmosis', 2);
+test.serial(sendAnywhereScenario, 'cosmoshub', 1);
+test.serial(sendAnywhereScenario, 'cosmoshub', 2);
diff --git a/multichain-testing/test/smart-wallet.test.ts b/multichain-testing/test/smart-wallet.test.ts
index ceaea0aa555..04fb0e20fd3 100644
--- a/multichain-testing/test/smart-wallet.test.ts
+++ b/multichain-testing/test/smart-wallet.test.ts
@@ -17,19 +17,19 @@ test.after(async t => {
});
test('provision smart wallet', async t => {
- const { wallets, provisionSmartWallet, makeQueryTool, useChain } = t.context;
+ const { wallets, provisionSmartWallet, vstorageClient, useChain } = t.context;
const wallet = await provisionSmartWallet(wallets.user1, { BLD: 100n });
t.log('wallet', wallet);
- const vstorageClient = makeQueryTool();
-
const walletCurrent = await vstorageClient.queryData(
`published.wallet.${wallets.user1}.current`,
);
t.like(walletCurrent, { liveOffers: [], offerToPublicSubscriberPaths: [] });
- const agQueryClient = makeQueryClient(useChain('agoric').getRestEndpoint());
+ const agQueryClient = makeQueryClient(
+ await useChain('agoric').getRestEndpoint(),
+ );
const { balances } = await agQueryClient.queryBalances(wallets.user1);
t.deepEqual(
balances,
diff --git a/multichain-testing/test/stake-ica.test.ts b/multichain-testing/test/stake-ica.test.ts
index 78f520e6045..f5fd41fd020 100644
--- a/multichain-testing/test/stake-ica.test.ts
+++ b/multichain-testing/test/stake-ica.test.ts
@@ -1,9 +1,14 @@
import anyTest from '@endo/ses-ava/prepare-endo.js';
import type { TestFn } from 'ava';
-import { commonSetup, SetupContextWithWallets } from './support.js';
+import {
+ commonSetup,
+ SetupContextWithWallets,
+ FAUCET_POUR,
+} from './support.js';
import { makeDoOffer } from '../tools/e2e-tools.js';
import { makeQueryClient } from '../tools/query.js';
import { sleep } from '../tools/sleep.js';
+import { STAKING_REWARDS_TIMEOUT } from './config.js';
const test = anyTest as TestFn;
@@ -18,8 +23,6 @@ test.before(async t => {
t.context = { ...rest, wallets, deleteTestKeys };
});
-const FAUCET_POUR = 10000000000n;
-
test.after(async t => {
const { deleteTestKeys } = t.context;
deleteTestKeys(accounts);
@@ -40,20 +43,13 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
const {
wallets,
provisionSmartWallet,
- makeQueryTool,
+ vstorageClient,
retryUntilCondition,
useChain,
- deployBuilder,
+ startContract,
} = t.context;
- t.log('bundle and install contract', scenario);
- await deployBuilder(scenario.builder);
- const vstorageClient = makeQueryTool();
- await retryUntilCondition(
- () => vstorageClient.queryData(`published.agoricNames.instance`),
- res => scenario.contractName in Object.fromEntries(res),
- `${scenario.contractName} instance is available`,
- );
+ await startContract(scenario.contractName, scenario.builder);
const wdUser1 = await provisionSmartWallet(wallets[scenario.wallet], {
BLD: 100n,
IST: 100n,
@@ -102,15 +98,8 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
`address for ${scenario.chain} is valid`,
);
- if (scenario.chain === 'cosmoshub') {
- // see https://github.com/cosmos/cosmjs/pull/1593 for upstream fix
- t.pass(
- `SKIP ${scenario.chain}. @cosmjs/faucet does not support ICA address length.`,
- );
- return;
- }
const { creditFromFaucet, getRestEndpoint } = useChain(scenario.chain);
- const queryClient = makeQueryClient(getRestEndpoint());
+ const queryClient = makeQueryClient(await getRestEndpoint());
t.log(`Requesting faucet funds for ${address}`);
// XXX fails intermittently until https://github.com/cosmology-tech/starship/issues/417
@@ -186,6 +175,7 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
return Number(total?.[0]?.amount) > 0;
},
`rewards available on ${scenario.chain}`,
+ STAKING_REWARDS_TIMEOUT,
);
t.log('reward:', total[0]);
t.log('WithrawReward offer from continuing inv');
@@ -210,7 +200,7 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
);
t.log('Balance after claiming rewards:', rewards);
- const SHARES = 50;
+ const TOKENS_TO_UNDELEGATE = 50n;
t.log('Undelegate offer from continuing inv');
const undelegateOfferId = `undelegate-${Date.now()}`;
await doOffer({
@@ -222,8 +212,11 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
invitationArgs: [
[
{
- validatorAddress,
- shares: String(SHARES),
+ validator: validatorChainAddress,
+ amount: {
+ denom: scenario.denom,
+ value: TOKENS_TO_UNDELEGATE,
+ },
},
],
],
@@ -239,7 +232,7 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
t.log('unbonding_responses:', unbonding_responses[0].entries);
t.is(
unbonding_responses[0].entries[0].balance,
- String(SHARES),
+ String(TOKENS_TO_UNDELEGATE),
'undelegating 50 shares in progress',
);
@@ -249,11 +242,13 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
t.log('Current Balance:', currentBalances[0]);
console.log('waiting for unbonding period');
+ // XXX reference `120000` from chain state + `maxClockSkew`
await sleep(120000);
const { balances: rewardsWithUndelegations } = await retryUntilCondition(
() => queryClient.queryBalances(address),
({ balances }) => {
- const expectedBalance = Number(currentBalances[0].amount) + SHARES;
+ const expectedBalance =
+ Number(currentBalances[0].amount) + Number(TOKENS_TO_UNDELEGATE);
return Number(balances?.[0]?.amount) >= expectedBalance;
},
'claimed rewards available',
diff --git a/multichain-testing/test/support.ts b/multichain-testing/test/support.ts
index d7caf44e9a4..2267b813436 100644
--- a/multichain-testing/test/support.ts
+++ b/multichain-testing/test/support.ts
@@ -9,6 +9,9 @@ import { makeGetFile, makeSetupRegistry } from '../tools/registry.js';
import { generateMnemonic } from '../tools/wallet.js';
import { makeRetryUntilCondition } from '../tools/sleep.js';
import { makeDeployBuilder } from '../tools/deploy.js';
+import { makeHermes } from '../tools/hermes-tools.js';
+
+export const FAUCET_POUR = 10_000n * 1_000_000n;
const setupRegistry = makeSetupRegistry(makeGetFile({ dirname, join }));
@@ -55,9 +58,48 @@ export const commonSetup = async (t: ExecutionContext) => {
const tools = await makeAgdTools(t.log, childProcess);
const keyring = await makeKeyring(tools);
const deployBuilder = makeDeployBuilder(tools, fse.readJSON, execa);
- const retryUntilCondition = makeRetryUntilCondition(t.log);
+ const retryUntilCondition = makeRetryUntilCondition({
+ log: t.log,
+ setTimeout: globalThis.setTimeout,
+ });
+ const hermes = makeHermes(childProcess);
- return { useChain, ...tools, ...keyring, retryUntilCondition, deployBuilder };
+ /**
+ * Starts a contract if instance not found. Takes care of installing
+ * bundles and voting on the CoreEval proposal.
+ *
+ * @param contractName name of the contract in agoricNames
+ * @param contractBuilder path to proposal builder
+ */
+ const startContract = async (
+ contractName: string,
+ contractBuilder: string,
+ ) => {
+ const { vstorageClient } = tools;
+ const instances = Object.fromEntries(
+ await vstorageClient.queryData(`published.agoricNames.instance`),
+ );
+ if (contractName in instances) {
+ return t.log('Contract found. Skipping installation...');
+ }
+ t.log('bundle and install contract', contractName);
+ await deployBuilder(contractBuilder);
+ await retryUntilCondition(
+ () => vstorageClient.queryData(`published.agoricNames.instance`),
+ res => contractName in Object.fromEntries(res),
+ `${contractName} instance is available`,
+ );
+ };
+
+ return {
+ useChain,
+ ...tools,
+ ...keyring,
+ retryUntilCondition,
+ deployBuilder,
+ hermes,
+ startContract,
+ };
};
export type SetupContext = Awaited>;
diff --git a/multichain-testing/test/tools/address.test.ts b/multichain-testing/test/tools/address.test.ts
new file mode 100644
index 00000000000..6579434ddf0
--- /dev/null
+++ b/multichain-testing/test/tools/address.test.ts
@@ -0,0 +1,31 @@
+import anyTest from '@endo/ses-ava/prepare-endo.js';
+import type { TestFn } from 'ava';
+import { parseRemoteAddress, parseLocalAddress } from '../../tools/address.js';
+
+const test = anyTest as TestFn>;
+
+test('parseRemoteAddress correctly parses a remote IBC address', t => {
+ const remoteAddress =
+ '/ibc-hop/connection-0/ibc-port/icahost/ordered/{"version":"ics27-1","controller_connection_id":"connection-0","host_connection_id":"connection-1","address":"cosmos1wrz3ltf3k6leg39t353qmj5xk5gfpf4wh5mtw7mqcrw2k2072j2sud9rhl","encoding":"proto3","tx_type":"sdk_multi_msg"}/ibc-channel/channel-2';
+
+ const result = parseRemoteAddress(remoteAddress);
+
+ t.deepEqual(result, {
+ rConnectionID: 'connection-1',
+ rPortID: 'icahost',
+ rChannelID: 'channel-2',
+ });
+});
+
+test('parseLocalAddress correctly parses a local IBC address', t => {
+ const localAddress =
+ '/ibc-port/icacontroller-3/ordered/{"version":"ics27-1","controller_connection_id":"connection-0","host_connection_id":"connection-1","address":"cosmos1wrz3ltf3k6leg39t353qmj5xk5gfpf4wh5mtw7mqcrw2k2072j2sud9rhl","encoding":"proto3","tx_type":"sdk_multi_msg"}/ibc-channel/channel-4';
+
+ const result = parseLocalAddress(localAddress);
+
+ t.deepEqual(result, {
+ lConnectionID: 'connection-0',
+ lPortID: 'icacontroller-3',
+ lChannelID: 'channel-4',
+ });
+});
diff --git a/multichain-testing/test/tools/wallet.test.ts b/multichain-testing/test/tools/wallet.test.ts
index 01c9119feec..bc76ab8b993 100644
--- a/multichain-testing/test/tools/wallet.test.ts
+++ b/multichain-testing/test/tools/wallet.test.ts
@@ -2,13 +2,12 @@ import anyTest from '@endo/ses-ava/prepare-endo.js';
import type { TestFn } from 'ava';
import { makeQueryClient } from '../../tools/query.js';
import { createWallet } from '../../tools/wallet.js';
-import { sleep } from '../../tools/sleep.js';
import { commonSetup } from '../support.js';
const test = anyTest as TestFn>;
const walletScenario = test.macro(async (t, scenario: string) => {
- const { useChain } = await commonSetup(t);
+ const { useChain, retryUntilCondition } = await commonSetup(t);
const prefix = useChain(scenario).chain.bech32_prefix;
const wallet = await createWallet(prefix);
@@ -16,7 +15,7 @@ const walletScenario = test.macro(async (t, scenario: string) => {
t.regex(addr, new RegExp(`^${prefix}1`));
t.log('Made temp wallet:', addr);
- const apiUrl = useChain(scenario).getRestEndpoint();
+ const apiUrl = await useChain(scenario).getRestEndpoint();
const queryClient = makeQueryClient(apiUrl);
t.log('Made query client');
@@ -30,9 +29,12 @@ const walletScenario = test.macro(async (t, scenario: string) => {
await creditFromFaucet(addr);
// XXX needed to avoid race condition between faucet POST and LCD Query
// see https://github.com/cosmology-tech/starship/issues/417
- await sleep(1000, t.log);
+ const { balances: updatedBalances } = await retryUntilCondition(
+ () => queryClient.queryBalances(addr),
+ ({ balances }) => !!balances.length,
+ `${scenario} balance available from faucet`,
+ );
- const { balances: updatedBalances } = await queryClient.queryBalances(addr);
const expectedDenom = scenario === 'osmosis' ? 'uosmo' : 'uatom';
t.like(updatedBalances, [{ denom: expectedDenom, amount: '10000000000' }]);
t.log('Updated balances:', updatedBalances);
diff --git a/multichain-testing/tools/address.ts b/multichain-testing/tools/address.ts
new file mode 100644
index 00000000000..4a5def93d09
--- /dev/null
+++ b/multichain-testing/tools/address.ts
@@ -0,0 +1,56 @@
+import type { IBCChannelID, IBCConnectionID, IBCPortID } from '@agoric/vats';
+import {
+ type LocalIbcAddress,
+ type RemoteIbcAddress,
+} from '@agoric/vats/tools/ibc-utils.js';
+
+// XXX consider moving to vats/tools/ibc-utils by updating current values or renaming as `NEGOTIATED_...`
+// These take those values and build off of them
+const REMOTE_ADDR_RE =
+ /^(?(?:\/ibc-hop\/[^/]+)*)\/ibc-port\/(?[^/]+)\/(?ordered|unordered)\/(?{[^}]+})\/ibc-channel\/(?[^/]+)$/;
+const LOCAL_ADDR_RE =
+ /^\/ibc-port\/(?[^/]+)\/(?ordered|unordered)\/(?{[^}]+})\/ibc-channel\/(?[^/]+)$/;
+
+export const parseRemoteAddress = (
+ address: RemoteIbcAddress,
+): {
+ rConnectionID: IBCConnectionID;
+ rPortID: IBCPortID;
+ rChannelID: IBCChannelID;
+} => {
+ const match = address.match(REMOTE_ADDR_RE);
+ if (!match || !match.groups) {
+ throw Error('Invalid remote address format');
+ }
+
+ const { portID, version, channelID } = match.groups;
+ const versionObj = JSON.parse(version);
+
+ return {
+ rConnectionID: versionObj.host_connection_id,
+ rPortID: portID,
+ rChannelID: channelID as IBCChannelID,
+ };
+};
+
+export const parseLocalAddress = (
+ address: LocalIbcAddress,
+): {
+ lConnectionID: IBCConnectionID;
+ lPortID: IBCPortID;
+ lChannelID: IBCChannelID;
+} => {
+ const match = address.match(LOCAL_ADDR_RE);
+ if (!match || !match.groups) {
+ throw Error('Invalid local address format');
+ }
+
+ const { portID, version, channelID } = match.groups;
+ const versionObj = JSON.parse(version);
+
+ return {
+ lConnectionID: versionObj.controller_connection_id,
+ lPortID: portID,
+ lChannelID: channelID as IBCChannelID,
+ };
+};
diff --git a/multichain-testing/tools/deploy.ts b/multichain-testing/tools/deploy.ts
index 01dc0d1270e..5cd3fba5e53 100755
--- a/multichain-testing/tools/deploy.ts
+++ b/multichain-testing/tools/deploy.ts
@@ -16,7 +16,7 @@ export const makeDeployBuilder = (
const { stdout } = await execa`agoric run ${builder}`;
const match = stdout.match(/ (?[-\w]+)-permit.json/);
if (!(match && match.groups)) {
- throw new Error('no permit found');
+ throw Error('no permit found');
}
const plan = await readJSON(`./${match.groups.name}-plan.json`);
console.log(plan);
diff --git a/multichain-testing/tools/e2e-tools.js b/multichain-testing/tools/e2e-tools.js
index d7d7d2c6620..df46fbd65b0 100644
--- a/multichain-testing/tools/e2e-tools.js
+++ b/multichain-testing/tools/e2e-tools.js
@@ -136,10 +136,9 @@ export const provisionSmartWallet = async (
chainId = 'agoriclocal',
whale = 'faucet',
progress = console.log,
+ q = makeQueryKit(makeVStorage(lcd)).query,
},
) => {
- const { query: q } = makeQueryKit(makeVStorage(lcd));
-
// TODO: skip this query if balances is {}
const vbankEntries = await q.queryData('published.agoricNames.vbankAsset');
const byName = Object.fromEntries(
@@ -507,8 +506,10 @@ export const makeE2ETools = async (
const copyFiles = makeCopyFiles({ execFileSync, log });
+ const vstorageClient = makeQueryKit(vstorage).query;
+
return {
- makeQueryTool: () => makeQueryKit(vstorage).query,
+ vstorageClient,
installBundles,
runCoreEval: buildAndRunCoreEval,
/**
@@ -516,7 +517,13 @@ export const makeE2ETools = async (
* @param {Record} amount
*/
provisionSmartWallet: (address, amount) =>
- provisionSmartWallet(address, amount, { agd, blockTool, lcd, delay }),
+ provisionSmartWallet(address, amount, {
+ agd,
+ blockTool,
+ lcd,
+ delay,
+ q: vstorageClient,
+ }),
/**
* @param {string} name
* @param {EnglishMnemonic | string} mnemonic
diff --git a/multichain-testing/tools/hermes-tools.ts b/multichain-testing/tools/hermes-tools.ts
new file mode 100644
index 00000000000..4868fdd3f88
--- /dev/null
+++ b/multichain-testing/tools/hermes-tools.ts
@@ -0,0 +1,70 @@
+import type { IBCChannelID, IBCConnectionID, IBCPortID } from '@agoric/vats';
+import type { ExecSync } from './agd-lib.js';
+
+const kubectlBinary = 'kubectl';
+
+// based on config.yaml
+const relayerMap: { [key: string]: string } = {
+ osmosis: 'hermes-agoric-osmosis-0',
+ cosmoshub: 'hermes-agoric-gaia-0',
+};
+
+const makeKubeArgs = (chainName: string) => {
+ if (!relayerMap[chainName]) throw Error('Unsupported chain: ' + chainName);
+ return [
+ 'exec',
+ '-i',
+ relayerMap[chainName],
+ '-c',
+ 'relayer',
+ '--tty=false',
+ '--',
+ 'hermes',
+ ];
+};
+
+type ChannelCloseParams = {
+ dst: {
+ chainId: string;
+ portID: IBCPortID;
+ channelID: IBCChannelID;
+ connectionID: IBCConnectionID;
+ };
+ src: {
+ chainId: string;
+ portID: IBCPortID;
+ channelID: IBCChannelID;
+ };
+};
+
+export const makeHermes = ({ execFileSync }: { execFileSync: ExecSync }) => {
+ const exec = (
+ chainName: string,
+ args: string[],
+ opts = { encoding: 'utf-8' as const, stdio: ['ignore', 'pipe', 'ignore'] },
+ ) => execFileSync(kubectlBinary, [...makeKubeArgs(chainName), ...args], opts);
+
+ /** Submit MsgChannelCloseInit to the src chain */
+ const channelCloseInit = (
+ chainName: string,
+ dst: ChannelCloseParams['dst'],
+ src: ChannelCloseParams['src'],
+ ) => {
+ return exec(chainName, [
+ 'tx',
+ 'chan-close-init',
+ `--dst-chain=${dst.chainId}`,
+ `--src-chain=${src.chainId}`,
+ `--dst-connection=${dst.connectionID}`,
+ `--dst-port=${dst.portID}`,
+ `--src-port=${src.portID}`,
+ `--dst-channel=${dst.channelID}`,
+ `--src-channel=${src.channelID}`,
+ ]);
+ };
+
+ return {
+ exec,
+ channelCloseInit,
+ };
+};
diff --git a/multichain-testing/tools/ibc-transfer.ts b/multichain-testing/tools/ibc-transfer.ts
index b4384f13313..7d4fdae8624 100644
--- a/multichain-testing/tools/ibc-transfer.ts
+++ b/multichain-testing/tools/ibc-transfer.ts
@@ -37,12 +37,14 @@ type SimpleChainAddress = {
chainName: string;
};
-export const DEFAULT_TIMEOUT_NS = 1893456000000000000n;
+// 2030-01-01T00:00:00Z
+export const DEFAULT_TIMEOUT_NS =
+ 1893456000n * NANOSECONDS_PER_MILLISECOND * MILLISECONDS_PER_SECOND;
/**
* @param {number} [ms] current time in ms (e.g. Date.now())
* @param {bigint} [minutes=5n] number of minutes in the future
- * @returns {bigint} nanosecond timestamp 5 mins in the future */
+ * @returns {bigint} nanosecond timestamp absolute since Unix epoch */
export const getTimeout = (ms: number = 0, minutes = 5n) => {
// UNTIL #9200. timestamps are getting clobbered somewhere along the way
// and we are observing failed transfers with timeouts years in the past.
@@ -126,7 +128,7 @@ export const createFundedWalletAndClient = async (
// TODO use telescope generated rpc client from @agoric/cosmic-proto
// https://github.com/Agoric/agoric-sdk/issues/9200
const client = await SigningStargateClient.connectWithSigner(
- getRpcEndpoint(),
+ await getRpcEndpoint(),
wallet,
);
return { client, wallet, address };
diff --git a/multichain-testing/tools/makeHttpClient.js b/multichain-testing/tools/makeHttpClient.js
index e422f3f3c38..37344419946 100644
--- a/multichain-testing/tools/makeHttpClient.js
+++ b/multichain-testing/tools/makeHttpClient.js
@@ -7,7 +7,7 @@ const jsonType = { 'Content-Type': 'application/json' };
const filterBadStatus = res => {
if (res.status >= 400) {
- throw new Error(`Bad status on response: ${res.status}`);
+ throw Error(`Bad status on response: ${res.status}`);
}
return res;
};
diff --git a/multichain-testing/tools/marshalTables.js b/multichain-testing/tools/marshalTables.js
index 1eb50426883..827bd230cc3 100644
--- a/multichain-testing/tools/marshalTables.js
+++ b/multichain-testing/tools/marshalTables.js
@@ -75,7 +75,7 @@ const synthesizeRemotable = (slot, iface) => {
*/
export const makeClientMarshaller = valToSlot => {
const noNewSlots = val => {
- throw new Error(`unknown value: ${val}`);
+ throw Error(`unknown value: ${val}`);
};
const { convertValToSlot, convertSlotToVal } = makeTranslationTable(
valToSlot || noNewSlots,
diff --git a/multichain-testing/tools/query.ts b/multichain-testing/tools/query.ts
index 5f1d6d18f2e..bfd9adf0ce4 100644
--- a/multichain-testing/tools/query.ts
+++ b/multichain-testing/tools/query.ts
@@ -7,6 +7,8 @@ import type { QueryValidatorsResponseSDKType } from '@agoric/cosmic-proto/cosmos
import type { QueryDelegatorDelegationsResponseSDKType } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/query.js';
import type { QueryDelegatorUnbondingDelegationsResponseSDKType } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/query.js';
import type { QueryDenomHashResponseSDKType } from '@agoric/cosmic-proto/ibc/applications/transfer/v1/query.js';
+import type { QueryChannelResponseSDKType } from '@agoric/cosmic-proto/ibc/core/channel/v1/query.js';
+import { QueryChannelsResponseSDKType } from '@agoric/cosmic-proto/ibc/core/channel/v1/query.js';
// TODO use telescope generated query client from @agoric/cosmic-proto
// https://github.com/Agoric/agoric-sdk/issues/9200
@@ -52,5 +54,11 @@ export function makeQueryClient(apiUrl: string) {
query(
`/ibc/apps/transfer/v1/denom_hashes/${path}/${baseDenom}`,
),
+ queryChannel: (portID: string, channelID: string) =>
+ query(
+ `/ibc/core/channel/v1/channels/${channelID}/ports/${portID}`,
+ ),
+ queryChannels: () =>
+ query(`/ibc/core/channel/v1/channels`),
};
}
diff --git a/multichain-testing/tools/registry.ts b/multichain-testing/tools/registry.ts
index 3d29c9baf0a..d4b15c5b8b7 100644
--- a/multichain-testing/tools/registry.ts
+++ b/multichain-testing/tools/registry.ts
@@ -8,6 +8,7 @@ export const makeGetFile =
type GetFilePathFn = ReturnType;
export const makeSetupRegistry = (getFile: GetFilePathFn) => {
+ let initialized = false;
/**
* @param {Object} opts
* @param {string} [opts.config='../config.yaml'] - The path to the starship configuration file.
@@ -20,8 +21,11 @@ export const makeSetupRegistry = (getFile: GetFilePathFn) => {
* ```
*/
const setupRegistry = async ({ config = '../config.yaml' } = {}) => {
- ConfigContext.setConfigFile(getFile(config));
- ConfigContext.setRegistry(await useRegistry(ConfigContext.configFile!));
+ if (initialized) return { useChain };
+ const configFile = getFile(config);
+ const fetcher = await useRegistry(configFile);
+ await ConfigContext.init(configFile, fetcher);
+ initialized = true;
return { useChain };
};
diff --git a/multichain-testing/tools/sleep.ts b/multichain-testing/tools/sleep.ts
index 6cb375893d6..66251a87dca 100644
--- a/multichain-testing/tools/sleep.ts
+++ b/multichain-testing/tools/sleep.ts
@@ -1,18 +1,36 @@
+const ambientSetTimeout = globalThis.setTimeout;
+
type Log = (...values: unknown[]) => void;
-export const sleep = (ms: number, log: Log = () => {}) =>
+type SleepOptions = {
+ log?: Log;
+ setTimeout?: typeof ambientSetTimeout;
+};
+
+export const sleep = (
+ ms: number,
+ { log = () => {}, setTimeout = ambientSetTimeout }: SleepOptions = {},
+) =>
new Promise(resolve => {
log(`Sleeping for ${ms}ms...`);
setTimeout(resolve, ms);
});
+export type RetryOptions = {
+ maxRetries?: number;
+ retryIntervalMs?: number;
+} & SleepOptions;
+
const retryUntilCondition = async (
operation: () => Promise,
condition: (result: T) => boolean,
message: string,
- maxRetries: number,
- retryIntervalMs: number,
- log: Log,
+ {
+ maxRetries = 6,
+ retryIntervalMs = 3500,
+ log = () => {},
+ setTimeout = ambientSetTimeout,
+ }: RetryOptions = {},
): Promise => {
console.log({ maxRetries, retryIntervalMs, message });
let retries = 0;
@@ -35,28 +53,25 @@ const retryUntilCondition = async (
console.log(
`Retry ${retries}/${maxRetries} - Waiting for ${retryIntervalMs}ms for ${message}...`,
);
- await sleep(retryIntervalMs, log);
+ await sleep(retryIntervalMs, { log, setTimeout });
}
- throw new Error(`${message} condition failed after ${maxRetries} retries.`);
+ throw Error(`${message} condition failed after ${maxRetries} retries.`);
};
-export const makeRetryUntilCondition =
- (
- log: Log = () => {},
- maxRetries: number = 6,
- retryIntervalMs: number = 3500,
- ) =>
- (
+export const makeRetryUntilCondition = (defaultOptions: RetryOptions = {}) => {
+ /**
+ * Retry an asynchronous operation until a condition is met.
+ * Defaults to maxRetries = 6, retryIntervalMs = 3500
+ */
+ return (
operation: () => Promise,
condition: (result: T) => boolean,
message: string,
+ options?: RetryOptions,
) =>
- retryUntilCondition(
- operation,
- condition,
- message,
- maxRetries,
- retryIntervalMs,
- log,
- );
+ retryUntilCondition(operation, condition, message, {
+ ...defaultOptions,
+ ...options,
+ });
+};
diff --git a/multichain-testing/yarn.lock b/multichain-testing/yarn.lock
index 7c87c33808a..0f1b49cdc29 100644
--- a/multichain-testing/yarn.lock
+++ b/multichain-testing/yarn.lock
@@ -608,7 +608,7 @@ __metadata:
languageName: node
linkType: hard
-"@noble/hashes@npm:^1, @noble/hashes@npm:^1.0.0":
+"@noble/hashes@npm:^1, @noble/hashes@npm:^1.0.0, @noble/hashes@npm:^1.2.0":
version: 1.4.0
resolution: "@noble/hashes@npm:1.4.0"
checksum: 10c0/8c3f005ee72e7b8f9cff756dfae1241485187254e3f743873e22073d63906863df5d4f13d441b7530ea614b7a093f0d889309f28b59850f33b66cb26a779a4a5
@@ -1319,6 +1319,15 @@ __metadata:
languageName: node
linkType: hard
+"bip39@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "bip39@npm:3.1.0"
+ dependencies:
+ "@noble/hashes": "npm:^1.2.0"
+ checksum: 10c0/68f9673a0d6a851e9635f3af8a85f2a1ecef9066c76d77e6f0d58d274b5bf22a67f429da3997e07c0d2cf153a4d7321f9273e656cac0526f667575ddee28ef71
+ languageName: node
+ linkType: hard
+
"blueimp-md5@npm:^2.10.0":
version: 2.19.0
resolution: "blueimp-md5@npm:2.19.0"
@@ -3303,9 +3312,9 @@ __metadata:
languageName: node
linkType: hard
-"node-fetch@npm:2.6.12":
- version: 2.6.12
- resolution: "node-fetch@npm:2.6.12"
+"node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9":
+ version: 2.7.0
+ resolution: "node-fetch@npm:2.7.0"
dependencies:
whatwg-url: "npm:^5.0.0"
peerDependencies:
@@ -3313,7 +3322,7 @@ __metadata:
peerDependenciesMeta:
encoding:
optional: true
- checksum: 10c0/10372e4b5ee07acadc15e6b2bc6fd8940582eea7b9b2a331f4e3665fdcd968498c1656f79f2fa572080ebb37ea80e1474a6478b3b36057ef901b63f4be8fd899
+ checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8
languageName: node
linkType: hard
@@ -3843,7 +3852,7 @@ __metadata:
execa: "npm:^9.2.0"
fs-extra: "npm:^11.2.0"
patch-package: "npm:^8.0.0"
- starshipjs: "npm:2.0.0"
+ starshipjs: "npm:2.4.0"
tsimp: "npm:^2.0.10"
tsx: "npm:^4.15.6"
typescript: "npm:^5.3.3"
@@ -4081,14 +4090,15 @@ __metadata:
languageName: node
linkType: hard
-"starshipjs@npm:2.0.0":
- version: 2.0.0
- resolution: "starshipjs@npm:2.0.0"
+"starshipjs@npm:2.4.0":
+ version: 2.4.0
+ resolution: "starshipjs@npm:2.4.0"
dependencies:
"@chain-registry/client": "npm:1.18.1"
+ bip39: "npm:^3.1.0"
js-yaml: "npm:^4.1.0"
node-fetch: "npm:^2.6.9"
- checksum: 10c0/8091142dac71b0f0544db87f0f6d101c4fa26792adda05f629dfb3c2f6d087233ede3672fa41ada2cd92d42ad07bbb17481049c491a2adba4a3114f363299121
+ checksum: 10c0/e62cc540bc9e8700d3bdb61ac1261b71417f0e687c98a0e3733317d363e425c7188a205d9af70f5218e87f99195fbfb5b759b4f3f9d87823989ef6b4d90442d6
languageName: node
linkType: hard
diff --git a/package.json b/package.json
index 1d1dd36b781..628a28fd66b 100644
--- a/package.json
+++ b/package.json
@@ -10,10 +10,10 @@
"type": "module",
"packageManager": "yarn@1.22.22",
"devDependencies": {
- "@endo/eslint-plugin": "^2.1.3",
+ "@endo/eslint-plugin": "^2.2.1",
"@jessie.js/eslint-plugin": "^0.4.1",
"@types/express": "^4.17.17",
- "@types/node": "^18.19.24",
+ "@types/node": "^22.0.0",
"ava": "^5.3.0",
"c8": "^9.1.0",
"conventional-changelog-conventionalcommits": "^4.6.0",
@@ -32,15 +32,15 @@
"prettier-plugin-jsdoc": "^1.3.0",
"prettier-plugin-sh": "^0.14.0",
"type-coverage": "^2.27.1",
- "typedoc": "^0.25.13",
- "typedoc-plugin-markdown": "^3.17.1",
- "typescript": "^5.5.3",
- "typescript-eslint": "^7.15.0"
+ "typedoc": "^0.26.7",
+ "typedoc-plugin-markdown": "^4.2.1",
+ "typescript": "^5.6.2",
+ "typescript-eslint": "^7.18.0"
},
"resolutions": {
"**/protobufjs": "^7.2.6",
"**/@types/estree": "^1.0.0",
- "**/@typescript-eslint/typescript-estree": "^7.15.0"
+ "@endo/eslint-plugin/typescript-eslint": "^7.18.0"
},
"engines": {
"node": "^18.12 || ^20.9"
@@ -48,8 +48,12 @@
"scripts": {
"clean": "yarn lerna run --no-bail clean",
"check-dependencies": "node ./scripts/check-mismatched-dependencies.cjs",
- "docs": "typedoc --tsconfig tsconfig.build.json",
- "docs:markdown-for-agoric-documentation-repo": "typedoc --plugin typedoc-plugin-markdown --tsconfig tsconfig.build.json",
+ "docs": "run-s docs:build docs:update-functions-path",
+ "docs:build": "typedoc --tsconfig tsconfig.build.json",
+ "docs:markdown-for-agoric-documentation-repo": "run-s docs:markdown-build 'docs:update-functions-path md'",
+ "docs:markdown-build": "typedoc --plugin typedoc-plugin-markdown --tsconfig tsconfig.build.json",
+ "docs:update-functions-path": "node ./scripts/update-typedoc-functions-path.cjs",
+ "doctor": "./scripts/env-doctor.sh",
"lerna": "lerna",
"link-cli": "yarn run create-agoric-cli",
"create-agoric-cli": "node ./scripts/create-agoric-cli.cjs",
diff --git a/packages/ERTP/package.json b/packages/ERTP/package.json
index e6f71c0e492..ca4471e6c7e 100644
--- a/packages/ERTP/package.json
+++ b/packages/ERTP/package.json
@@ -10,7 +10,7 @@
"scripts": {
"build": "exit 0",
"prepack": "tsc --build tsconfig.build.json",
- "postpack": "git clean -f '*.d.ts*'",
+ "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
"test": "ava",
"test:c8": "c8 $C8_OPTIONS ava",
"test:xs": "yarn test:xs-unit && yarn test:xs-worker",
@@ -39,21 +39,21 @@
},
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
"dependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/notifier": "^0.6.2",
"@agoric/store": "^0.9.2",
"@agoric/vat-data": "^0.5.2",
"@agoric/zone": "^0.2.2",
- "@endo/eventual-send": "^1.2.2",
- "@endo/far": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/nat": "^5.0.7",
- "@endo/patterns": "^1.4.0",
- "@endo/promise-kit": "^1.1.2"
+ "@endo/eventual-send": "^1.2.5",
+ "@endo/far": "^1.1.5",
+ "@endo/marshal": "^1.5.3",
+ "@endo/nat": "^5.0.10",
+ "@endo/patterns": "^1.4.3",
+ "@endo/promise-kit": "^1.1.5"
},
"devDependencies": {
"@agoric/swingset-vat": "^0.32.2",
- "@endo/bundle-source": "^3.2.3",
+ "@endo/bundle-source": "^3.4.0",
"@fast-check/ava": "^1.1.5",
"ava": "^5.3.0",
"tsd": "^0.31.1"
diff --git a/packages/ERTP/src/typeGuards.js b/packages/ERTP/src/typeGuards.js
index 1b2ec30fcea..4e4f38f7f04 100644
--- a/packages/ERTP/src/typeGuards.js
+++ b/packages/ERTP/src/typeGuards.js
@@ -77,6 +77,19 @@ export const AmountShape = harden({
value: AmountValueShape,
});
+/**
+ * To be used to guard an amount pattern argument, i.e., an argument which is a
+ * pattern that can be used to test amounts. Since amounts are keys, anywhere an
+ * amount pattern is expected, an amount can be provided and will match only
+ * that concrete amount, i.e., amounts that are `keyEQ` to that amount.
+ *
+ * The `AmountShape` guard above is an amount pattern. But not all amount
+ * patterns are like `AmountShape`. For example, `M.any()` is a valid amount
+ * pattern that will admit any amount, but is does not resemble the
+ * `AmountShape` pattern above.
+ */
+export const AmountPatternShape = M.pattern();
+
export const RatioShape = harden({
numerator: AmountShape,
denominator: AmountShape,
@@ -178,7 +191,7 @@ export const makeIssuerInterfaces = (
isLive: M.callWhen(M.await(PaymentShape)).returns(M.boolean()),
getAmountOf: M.callWhen(M.await(PaymentShape)).returns(amountShape),
burn: M.callWhen(M.await(PaymentShape))
- .optional(M.pattern())
+ .optional(AmountPatternShape)
.returns(amountShape),
});
@@ -205,7 +218,9 @@ export const makeIssuerInterfaces = (
// `srcPayment` is a remotable, leaving it
// to this raw method to validate that this remotable is actually
// a live payment of the correct brand with sufficient funds.
- deposit: M.call(PaymentShape).optional(M.pattern()).returns(amountShape),
+ deposit: M.call(PaymentShape)
+ .optional(AmountPatternShape)
+ .returns(amountShape),
getDepositFacet: M.call().returns(DepositFacetShape),
withdraw: M.call(amountShape).returns(PaymentShape),
getRecoverySet: M.call().returns(M.setOf(PaymentShape)),
diff --git a/packages/SwingSet/README.md b/packages/SwingSet/README.md
index 6c5d164e211..2409dc212e6 100644
--- a/packages/SwingSet/README.md
+++ b/packages/SwingSet/README.md
@@ -204,7 +204,7 @@ If wavy dot syntax is used on a Promise which rejects, the method is not invoked
the return promise's `rejection` function is called instead:
```js
-const badP = Promise.reject(new Error());
+const badP = Promise.reject(Error());
const p2 = badP~.foo();
p2.then(undefined, rej => console.log('rejected', rej));
// prints 'rejected'
diff --git a/packages/SwingSet/docs/configuration.md b/packages/SwingSet/docs/configuration.md
index 49b0d482551..9c7614ea1c6 100644
--- a/packages/SwingSet/docs/configuration.md
+++ b/packages/SwingSet/docs/configuration.md
@@ -150,7 +150,7 @@ The `snapshotInitial` property is a special snapshot interval that applies only
to the vat's very first snapshot. We treat it as a special case because a few
of the very first cranks of a vat (which involve initialization) can be quite
expensive, and we'd like to be able to promptly capture the benefit having paid
-that expense so that future replays don't need to repeat the work. Defaults to 2.
+that expense so that future replays don't need to repeat the work. Defaults to 3.
The code that realizes a vat or device can be specified in one of five
ways:
diff --git a/packages/SwingSet/docs/run-policy.md b/packages/SwingSet/docs/run-policy.md
index 0eba4d940d2..7624e9be0ff 100644
--- a/packages/SwingSet/docs/run-policy.md
+++ b/packages/SwingSet/docs/run-policy.md
@@ -12,17 +12,21 @@ But the more sophisticated approach is to call `controller.run(policy)`, with a
## Cranks
-The kernel maintains two queues. The highest priority queue contains "GC Actions", which are messages to vats that indicate an object has been garbage collected and can now be freed. These are provoked by reference-counting operations that occur as a side-effect of GC syscalls, as well as vat termination events. Each GC Action counts as a "crank", and is reported to the policy object. The policy may end a block while there is still GC Action work to do, in which case the kernel will pick it back up again when the next block begins.
+The kernel maintains multiple internal action queues. The highest priority is a special "acceptance queue" containing messages to be placed on other queues in a "routing crank" that is reported to the policy without details via `policy.emptyCrank()`. All the other queues contain messages that will prompt a "delivery crank" whose details are reported to the policy object via a different `policy` method. The policy may end a block while one or more queues still contain messages, in which case the kernel will start the next block by trying to drain them in priority order.
-If the GC Action queue is entirely empty, the kernel will look for regular work to do. This consists of the following event types:
+The highest priority delivery queue contains "GC Actions", which are messages to vats indicating that an object has been garbage collected and can now be freed. These are provoked by reference-counting operations which occur as a side-effect of GC syscalls and vat termination events.
+
+If the GC Action queue is empty, the kernel will check the "reap queue", which contains vatIDs that need to receive a "bringOutYourDead" delivery.
+
+If the GC Action queue and reap queue are both empty, the kernel will look for regular work to do. This consists of the following event types:
* message deliveries to vats (provoked by `syscall.send`, delivered as `dispatch.deliver`)
* promise resolution notifications (provoked by `syscall.resolve`, delivered as `dispatch.notify`)
* vat creation
-Each message delivery and resolution notification causes (at most) one vat to execute one "crank" (it might not execute any crank, e.g. when a message is delivered to an unresolved promise, it just gets added to the promise's queue). This crank gives the vat some amount of time to process the delivery, during which it may invoke any number of syscalls. The crank might cause the vat to be terminated, either because of an error, or because it took too much CPU and exceeded its Meter's allowance. Each crank yields a "delivery results object", which indicates the success or failure of the delivery.
+Each message delivery and resolution notification causes at most one vat to execute one "crank" (but such vat cranks are not guaranteed, e.g. delivery of a message to an unresolved promise just adds the message to the promise's queue, and delivery of a message to an abandoned object [having no owner vat] goes "splat"). This crank gives the vat some amount of time to process the delivery, during which it may invoke any number of syscalls. The crank might cause the vat to be terminated, either because of an error, or because it took too much CPU and exceeded its Meter's allowance. Each crank yields a "delivery results object", which indicates the success or failure of the delivery.
-When run in a suitable vat worker (`managerType: 'xs-worker'`), the delivery results also include the number of "computrons" consumed, as counted by the JS engine. Computrons are vaguely correlated to CPU cycles (despite being much larger) and thus some correspondence to wallclock time. A Run Policy which wishes to limit wallclock time in a consensus-base manner should pay attention to the cumulative computron count, and end the block after some experimentally-determined limit.
+When run in a suitable vat worker (`managerType: 'xs-worker'`), the delivery results also include the number of "computrons" consumed, as counted by the JS engine. Computrons are vaguely correlated to CPU cycles (despite being much larger) and thus have some correspondence to wallclock time. A Run Policy which wishes to limit wallclock time in a consensus-based manner should pay attention to the cumulative computron count, and end the block after some experimentally-determined limit.
Vat creation also gives a single vat (the brand new one) time to run the top-level forms of its source bundle, as well as the invocation of its `buildRootObject()` method. This typically takes considerably longer than the subsequent messages, and is not currently metered.
@@ -35,13 +39,18 @@ The kernel will invoke the following methods on the policy object (so all must e
* `policy.crankFailed()`
* `policy.emptyCrank()`
-All methods should return `true` if the kernel should keep running, or `false` if it should stop.
+All those methods should return `true` if the kernel should keep running, or `false` if it should stop.
+
+The following methods are optional (for backwards compatibility with policy objects created for older kernels):
-The `computrons` argument may be `undefined` (e.g. if the crank was delivered to a non-`xs worker`-based vat, such as the comms vat). The policy should probably treat this as equivalent to some "typical" number of computrons.
+* `policy.allowCleanup()` : may return budget, see "Terminated-Vat Cleanup" below
+* `policy.didCleanup({ cleanups })` (if missing, kernel pretends it returned `true` to keep running)
-`crankFailed` indicates the vat suffered an error during crank delivery, such as a metering fault, memory allocation fault, or fatal syscall. We do not currently have a way to measure the computron usage of failed cranks (many of the error cases are signaled by the worker process exiting with a distinctive status code, which does not give it an opportunity to report back detailed metering data). The run policy should assume the worst.
+The `computrons` value may be `undefined` (e.g. if the crank was delivered to a non-`xs worker`-based vat, such as the comms vat). The policy should probably treat this as equivalent to some "typical" number of computrons.
-`emptyCrank` indicates the kernel processed a queued messages which didn't result in a delivery.
+`crankFailed` indicates that the vat suffered an error during crank delivery, such as a metering fault, memory allocation fault, or fatal syscall. We do not currently have a way to measure the computron usage of failed cranks (many of the error cases are signaled by the worker process exiting with a distinctive status code, which does not give it an opportunity to report back detailed metering data). The run policy should assume the worst.
+
+`emptyCrank` indicates that the kernel processed a queued message which didn't result in a delivery.
More arguments may be added in the future, such as:
* `vatCreated:` the size of the source bundle
@@ -53,9 +62,50 @@ More arguments may be added in the future, such as:
The run policy should be provided as the first argument to `controller.run()`. If omitted, the kernel defaults to `forever`, a policy that runs until the queue is empty.
+## Terminated-Vat Cleanup
+
+Some vats may grow very large (i.e. large c-lists with lots of imported/exported objects, or lots of vatstore entries). If/when these are terminated, the burst of cleanup work might overwhelm the kernel, especially when processing all the dropped imports (which trigger GC messages to other vats).
+
+To protect the system against these bursts, the run policy can be configured to terminate vats slowly. Instead of doing all the cleanup work immediately, the policy allows the kernel to do a little bit of work each time `controller.run()` is called (e.g. once per block, for kernels hosted inside a blockchain). Internally, before servicing the run-queue, the kernel checks to see if any vats are in the "terminated but not fully deleted" state, and executes a "vat-cleanup crank", to delete some state. Depending upon what the run-policy allows, it may do multiple vat-cleanup cranks in a single `controller.run()`, or just one, or none at all. And depending upon the budget provided to each one, it may only take one vat-cleanup crank to finish the job, or millions. If the policy limits the number of cranks in a single block, and limits the budget of the crank, then the cleanup process will be spread over multiple blocks.
+
+For each terminated vat, cleanup proceeds through five phases:
+
+* `exports`: delete c-list entries for objects/promises *exported* by the vat
+* `imports`: same but for objects/promises *imported* by the vat
+* `kv`: delete all other kv entries for this vat, mostly vatstore records
+* `snapshots`: delete xsnap heap snapshots, typically one per 200 deliveries (`snapshotInterval`)
+* `transcripts`: delete transcript spans, and their associated transcript items
+
+The first two phases, `exports` and `imports`, cause the most activity in other vats. Deleting `exports` can cause objects to be retired, which will deliver `dispatch.retireImports` GC messages to other vats which have imported those objects and used them as keys in a WeakMapStore. Deleting `imports` can cause refcounts to drop to zero, delivering `dispatch.dropImports` into vats which were exporting those objects. Both of these will add `gcKref` "dirt" to the other vat, eventually triggering a BringOutYourDead, which will cause more DB activity. These are generally the phases we must rate-limit to avoid overwhelming the system.
+
+The other phases cause DB activity (deleting rows), but do not interact with other vats, so it is easier to accomodate more cleanup steps. The budget can be tuned to allow more kv/snapshots/transcripts than exports/imports in a single cleanup run.
+
+There are two RunPolicy methods which control this. The first is `runPolicy.allowCleanup()`. This will be invoked many times during `controller.run()`, each time the kernel tries to decide what to do next (once per step). The return value will enable (or not) a fixed amount of cleanup work. The second is `runPolicy.didCleanup({ cleanups })`, which is called later, to inform the policy of how much cleanup work was actually done. The policy can count the cleanups and switch `allowCleanup()` to return `false` when it reaches a threshold. (We need the pre-check `allowCleanup` method because the simple act of looking for cleanup work is itself a cost that we might not be willing to pay).
+
+If `allowCleanup()` exists, it must either return `false`, `true`, or a budget record.
+
+A `false` return value (eg `allowCleanup: () => false`) prohibits all cleanup work. This can be useful in a "only clean up during idle blocks" approach (see below), but should not be the only policy used, otherwise vat cleanup would never happen.
+
+A budget record defines properties to set limits on each phase of cleanup. For example, if `budget.exports = 5`, then each cleanup crank is limited to deleting 5 c-list export records (each of which uses two kv records, one for the kref->vref direction, and another for the vref->kref direction). `budget.transcripts = 10` would allow 10 transcript spans to be deleted, along with all transcript items they referenced (typically 10*200=2000, depending upon `snapshotInterval`).
+
+The limit can be set to `Infinity` to allow unlimited deletion of that particular phase.
+
+Each budget record must include a `{ default }` property, which is used as the default for any phase that is not explicitly mentioned in the budget. This also provides forwards-compatibility for any phases that might be added in the future. So `budget = { default: 5 }` would provide a conservative budget for cleanup, `budget = { default: 5, kv: 50 }` would enable faster deletion of the non-c-list kvstore entries, and `budget = { default: Infinity }` allows unlimited cleanup for all phases.
+
+Note that the cleanup crank ends when no more work is left to be done (which finally allows the vat to be forgotten entirely), or when an individual phase's budget is exceeded. That means multiple phases might see deletion work in a single crank, if the earlier phase finishes its work without exhausting its budget. For example, if the budget is `{ default: 5 }`, but the vat had 4 exports, 4 imports, 4 other kv entries, 4 snapshots, and 4 transcript spans, then all that work would be done in a single crank, because no individual phase would exhaust its budget. The only case that is even worth mentioning is when the end of the `exports` phase overlaps with the start of the `imports` phase, where we might do four more cleanups than usual.
+
+A `true` return value from `allowCleanup()` is equivalent to `{ default: Infinity }`, which allows unlimited cleanup work. This also happens if `allowCleanup()` is missing entirely, which maintains the old behavior for host applications that haven't been updated to make new policy objects. Note that cleanup is higher priority than any delivery, and is second only to acceptance queue routing.
+
+`didCleanup({ cleanups })` is called when the kernel actually performed some vat-termination cleanup, and the `cleanups` property is a "work record" that counts how much cleanup was performed. It contains one number for each phase that did work, plus a `total` property that is the sum of all phases. A cleanup crank which deleted two `exports` and five `imports` would yield a work record of `{ total: 7, exports: 2, imports: 5 }`. The work reported for each phase will not exceed the budget granted to it by `allowCleanup`.
+
+Like other post-run policy methods, `didCleanup` should return `true` if the kernel should keep running or `false` if it should stop.
+
+To limit the work done per block (for blockchain-based applications) the host's RunPolicy objects must keep track of how many cleanups were reported, and change the behavior of `allowCleanup()` when it reaches a per-block threshold. See below for examples.
+
+
## Typical Run Policies
-A basic policy might simply limit the block to 100 cranks with deliveries and two vat creations:
+A basic policy might simply limit the run/block to 100 cranks with deliveries and two vat creations, and not restrict cleanup at all (so terminated vats are completely deleted in a single step):
```js
function make100CrankPolicy() {
@@ -78,6 +128,7 @@ function make100CrankPolicy() {
return true;
},
});
+ return policy;
}
```
@@ -93,17 +144,17 @@ while(1) {
}
```
-Note that a new policy object should be provided for each call to `run()`.
+Note that a new instance of this kind of policy object should be provided in each call to `controller.run()`.
-A more sophisticated one would count computrons. Suppose that experiments suggest that one million computrons take about 5 seconds to execute. The policy would look like:
+A more sophisticated policy would count computrons, for example based on experimental observations that a 5-second budget is filled by about sixty-five million computrons. The policy would look like:
```js
function makeComputronCounterPolicy(limit) {
- let total = 0;
+ let total = 0n;
const policy = harden({
vatCreated() {
- total += 100000; // pretend vat creation takes 100k computrons
+ total += 100_000n; // pretend vat creation takes 100k computrons
return (total < limit);
},
crankComplete(details) {
@@ -112,17 +163,120 @@ function makeComputronCounterPolicy(limit) {
return (total < limit);
},
crankFailed() {
- total += 1000000; // who knows, 1M is as good as anything
+ total += 1_000_000n; // who knows, 1M is as good as anything
return (total < limit);
},
emptyCrank() {
return true;
}
});
+ return policy;
}
```
-See `src/runPolicies.js` for examples.
+See [runPolicies.js](../src/lib/runPolicies.js) for examples.
+
+To slowly terminate vats, limiting each block to 5 cleanups, the policy should start with a budget of 5, return the remaining `{ budget }` from `allowCleanup()`, and decrement it as `didCleanup` reports that budget being consumed:
+
+```js
+function makeSlowTerminationPolicy() {
+ let cranks = 0;
+ let vats = 0;
+ let cleanups = 5;
+ const policy = harden({
+ vatCreated() {
+ vats += 1;
+ return (vats < 2);
+ },
+ crankComplete(details) {
+ cranks += 1;
+ return (cranks < 100);
+ },
+ crankFailed() {
+ cranks += 1;
+ return (cranks < 100);
+ },
+ emptyCrank() {
+ return true;
+ },
+ allowCleanup() {
+ if (cleanups > 0) {
+ return { default: cleanups };
+ } else {
+ return false;
+ }
+ },
+ didCleanup(details) {
+ cleanups -= details.cleanups.total;
+ return true;
+ },
+ });
+ return policy;
+}
+```
+
+A more conservative approach might only allow cleanup in otherwise-empty blocks. To accompish this, use two separate policy objects, and two separate "runs". The first run only performs deliveries, and prohibits all cleanups:
+
+```js
+function makeDeliveryOnlyPolicy() {
+ let empty = true;
+ const didWork = () => { empty = false; return true; };
+ const policy = harden({
+ vatCreated: didWork,
+ crankComplete: didWork,
+ crankFailed: didWork,
+ emptyCrank: didWork,
+ allowCleanup: () => false,
+ });
+ const wasEmpty = () => empty;
+ return [ policy, wasEmpty ];
+}
+```
+
+The second performs a limited number of cleanups, along with any deliveries (like BOYD) that are caused by the cleanups:
+
+```js
+function makeCleanupOnlyPolicy() {
+ let cleanups = 5;
+ const keepGoing: () => true;
+ const policy = harden({
+ vatCreated: keepGoing,
+ crankComplete: keepGoing,
+ crankFailed: keepGoing,
+ emptyCrank: keepGoing,
+ allowCleanup() {
+ if (cleanups > 0) {
+ return { default: cleanups };
+ } else {
+ return false;
+ }
+ },
+ didCleanup(details) {
+ cleanups -= details.cleanups.total;
+ return true;
+ },
+ });
+ return policy;
+}
+```
+
+On each block, the host should only perform the second (cleanup) run if the first policy reports that the block was empty:
+
+```js
+async function doBlock() {
+ const [ firstPolicy, wasEmpty ] = makeDeliveryOnlyPolicy();
+ await controller.run(firstPolicy);
+ if (wasEmpty()) {
+ const secondPolicy = makeCleanupOnlyPolicy();
+ await controller.run(secondPolicy);
+ }
+}
+```
+
+The second run, if performed, will both delete some vat records, and deliver any GC actions that result, which may trigger a BringOutYourDead delivery for one or more vats.
+
+Also note that the budget record and cleanups work record property values are plain `Number`s, whereas `comptrons` is a `BigInt`.
+
## Non-Consensus Wallclock Limits
diff --git a/packages/SwingSet/misc-tools/replay-transcript.js b/packages/SwingSet/misc-tools/replay-transcript.js
index a5bb7a127c6..1dfdc5c1322 100644
--- a/packages/SwingSet/misc-tools/replay-transcript.js
+++ b/packages/SwingSet/misc-tools/replay-transcript.js
@@ -30,6 +30,10 @@ import { makeLocalVatManagerFactory } from '../src/kernel/vat-loader/manager-loc
import { makeSyscallSimulator } from '../src/kernel/vat-warehouse.js';
import { makeDummyMeterControl } from '../src/kernel/dummyMeterControl.js';
+/**
+ * @import {SnapStore} from '@agoric/swing-store';
+ */
+
const finished = promisify(finishedCallback);
// TODO: switch to full yargs for documenting output
@@ -213,7 +217,8 @@ async function replay(transcriptFile) {
let cleanupSnapStore;
if (argv.useCustomSnapStore) {
- snapStore = /** @type {SnapStore} */ ({
+ snapStore = {
+ // @ts-expect-error missing methods and saveSnapshot return is missing field of SnapshotResult
async saveSnapshot(_vatID, snapPos, snapshotStream) {
const snapFile = `${vatID}-${snapPos}-${
saveSnapshotID || 'unknown'
@@ -238,7 +243,7 @@ async function replay(transcriptFile) {
const snapFile = `${vatID}-${loadSnapshotID}.xss`;
yield* fs.createReadStream(snapFile);
},
- });
+ };
} else {
const tmpDb = tmpDirSync({
prefix: `ag-replay-${transcriptFile}`,
diff --git a/packages/SwingSet/package.json b/packages/SwingSet/package.json
index 29ed8e179a1..d9b784f255a 100644
--- a/packages/SwingSet/package.json
+++ b/packages/SwingSet/package.json
@@ -27,7 +27,7 @@
"@types/yargs-parser": "^21.0.0"
},
"dependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/internal": "^0.3.2",
"@agoric/kmarshal": "^0.1.0",
"@agoric/store": "^0.9.2",
@@ -38,22 +38,23 @@
"@agoric/vat-data": "^0.5.2",
"@agoric/xsnap": "^0.14.2",
"@agoric/xsnap-lockdown": "^0.14.0",
- "@endo/base64": "^1.0.5",
- "@endo/bundle-source": "^3.2.3",
- "@endo/captp": "^4.2.0",
- "@endo/check-bundle": "^1.0.7",
- "@endo/compartment-mapper": "^1.1.5",
- "@endo/eventual-send": "^1.2.2",
- "@endo/far": "^1.1.2",
- "@endo/import-bundle": "^1.1.2",
- "@endo/init": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/nat": "^5.0.7",
- "@endo/patterns": "^1.4.0",
- "@endo/promise-kit": "^1.1.2",
- "@endo/ses-ava": "^1.2.2",
- "@endo/stream": "^1.2.2",
- "@endo/zip": "^1.0.5",
+ "@endo/base64": "^1.0.7",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/captp": "^4.3.0",
+ "@endo/check-bundle": "^1.0.9",
+ "@endo/compartment-mapper": "^1.2.2",
+ "@endo/eventual-send": "^1.2.5",
+ "@endo/far": "^1.1.5",
+ "@endo/import-bundle": "^1.2.2",
+ "@endo/init": "^1.1.4",
+ "@endo/marshal": "^1.5.3",
+ "@endo/nat": "^5.0.10",
+ "@endo/pass-style": "^1.4.3",
+ "@endo/patterns": "^1.4.3",
+ "@endo/promise-kit": "^1.1.5",
+ "@endo/ses-ava": "^1.2.5",
+ "@endo/stream": "^1.2.5",
+ "@endo/zip": "^1.0.7",
"ansi-styles": "^6.2.1",
"anylogger": "^0.21.0",
"better-sqlite3": "^9.1.1",
@@ -100,6 +101,6 @@
"access": "public"
},
"typeCoverage": {
- "atLeast": 75.1
+ "atLeast": 75.81
}
}
diff --git a/packages/SwingSet/src/controller/controller.js b/packages/SwingSet/src/controller/controller.js
index 5534fa3e343..3321d1f92a6 100644
--- a/packages/SwingSet/src/controller/controller.js
+++ b/packages/SwingSet/src/controller/controller.js
@@ -21,6 +21,7 @@ import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQui
import { makeGcAndFinalize } from '@agoric/internal/src/lib-nodejs/gc-and-finalize.js';
import { kslot, krefOf } from '@agoric/kmarshal';
import { insistStorageAPI } from '../lib/storageAPI.js';
+import { insistCapData } from '../lib/capdata.js';
import {
buildKernelBundle,
swingsetIsInitialized,
@@ -33,6 +34,10 @@ import {
import { makeStartXSnap } from './startXSnap.js';
import { makeStartSubprocessWorkerNode } from './startNodeSubprocess.js';
+/**
+ * @typedef { import('../types-internal.js').VatID } VatID
+ */
+
const endoZipBase64Sha512Shape = harden({
moduleFormat: 'endoZipBase64',
endoZipBase64: M.string(harden({ stringLengthLimit: Infinity })),
@@ -441,6 +446,48 @@ export async function makeSwingsetController(
// no emitCrankHashes here because queueToVatRoot did that
return result;
},
+
+ /**
+ * terminate a vat by ID
+ *
+ * This allows the host app to terminate any vat. The effect is
+ * equivalent to the holder of the vat's `adminNode` calling
+ * `E(adminNode).terminateWithFailure(reason)`, or the vat itself
+ * calling `vatPowers.exitVatWithFailure(reason)`. It accepts a
+ * reason capdata structure (use 'kser()' to build one), which
+ * will be included in rejection data for the promise available to
+ * `E(adminNode).done()`, just like the internal termination APIs.
+ * Note that no slots/krefs are allowed in 'reason' when
+ * terminating the vat externally.
+ *
+ * This is a superpower available only from the host app, not from
+ * within vats, since `vatID` is merely a string and can be forged
+ * trivially. The host app is responsible for supplying the right
+ * vatID to kill, by looking at the database or logs (note that
+ * vats do not know their own vatID, and `controller.vatNameToID`
+ * only works for static vats, not dynamic).
+ *
+ * This will cause state changes in the swing-store (specifically
+ * marking the vat as terminated, and rejection all its
+ * outstanding promises), which must be committed before they will
+ * be durable. Either call `hostStorage.commit()` immediately
+ * after calling this, or call `controller.run()` and *then*
+ * `hostStorage.commit()` as you would normally do in response to
+ * other I/O or timer activity.
+ *
+ * The first `controller.run()` after this call will delete all
+ * the old vat's state at once, unless you use a
+ * [`runPolicy`](../docs/run-policy.md) to rate-limit cleanups.
+ *
+ * @param {VatID} vatID
+ * @param {SwingSetCapData} reasonCD
+ */
+
+ terminateVat(vatID, reasonCD) {
+ insistCapData(reasonCD);
+ assert(reasonCD.slots.length === 0, 'no slots allowed in reason');
+ kernel.terminateVatExternally(vatID, reasonCD);
+ },
});
writeSlogObject({ type: 'kernel-init-finish' });
diff --git a/packages/SwingSet/src/controller/initializeKernel.js b/packages/SwingSet/src/controller/initializeKernel.js
index e9e26f93411..aa84c4b0216 100644
--- a/packages/SwingSet/src/controller/initializeKernel.js
+++ b/packages/SwingSet/src/controller/initializeKernel.js
@@ -9,14 +9,32 @@ import { insistVatID } from '../lib/id.js';
import { makeVatSlot } from '../lib/parseVatSlots.js';
import { insistStorageAPI } from '../lib/storageAPI.js';
import { makeVatOptionRecorder } from '../lib/recordVatOptions.js';
-import makeKernelKeeper from '../kernel/state/kernelKeeper.js';
+import makeKernelKeeper, {
+ DEFAULT_DELIVERIES_PER_BOYD,
+ DEFAULT_GC_KREFS_PER_BOYD,
+} from '../kernel/state/kernelKeeper.js';
import { exportRootObject } from '../kernel/kernel.js';
import { makeKernelQueueHandler } from '../kernel/kernelQueue.js';
+/**
+ * @typedef { import('../types-external.js').SwingSetKernelConfig } SwingSetKernelConfig
+ * @typedef { import('../types-external.js').SwingStoreKernelStorage } SwingStoreKernelStorage
+ * @typedef { import('../types-internal.js').InternalKernelOptions } InternalKernelOptions
+ * @typedef { import('../types-internal.js').ReapDirtThreshold } ReapDirtThreshold
+ */
+
function makeVatRootObjectSlot() {
return makeVatSlot('object', true, 0);
}
+/**
+ * @param {SwingSetKernelConfig} config
+ * @param {SwingStoreKernelStorage} kernelStorage
+ * @param {*} [options]
+ * @returns {Promise} KPID of the bootstrap message
+ * result promise
+ */
+
export async function initializeKernel(config, kernelStorage, options = {}) {
const {
verbose = false,
@@ -25,22 +43,27 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
const logStartup = verbose ? console.debug : () => 0;
insistStorageAPI(kernelStorage.kvStore);
- const kernelSlog = null;
- const kernelKeeper = makeKernelKeeper(kernelStorage, kernelSlog);
+ const kernelKeeper = makeKernelKeeper(kernelStorage, 'uninitialized');
const optionRecorder = makeVatOptionRecorder(kernelKeeper, bundleHandler);
- const wasInitialized = kernelKeeper.getInitialized();
- assert(!wasInitialized);
const {
defaultManagerType,
- defaultReapInterval,
+ defaultReapInterval = DEFAULT_DELIVERIES_PER_BOYD,
+ defaultReapGCKrefs = DEFAULT_GC_KREFS_PER_BOYD,
relaxDurabilityRules,
snapshotInitial,
snapshotInterval,
} = config;
+ /** @type { ReapDirtThreshold } */
+ const defaultReapDirtThreshold = {
+ deliveries: defaultReapInterval,
+ gcKrefs: defaultReapGCKrefs,
+ computrons: 'never', // TODO no knob?
+ };
+ /** @type { InternalKernelOptions } */
const kernelOptions = {
defaultManagerType,
- defaultReapInterval,
+ defaultReapDirtThreshold,
relaxDurabilityRules,
snapshotInitial,
snapshotInterval,
@@ -49,7 +72,7 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
for (const id of Object.keys(config.idToBundle || {})) {
const bundle = config.idToBundle[id];
- assert.equal(bundle.moduleFormat, 'endoZipBase64');
+ assert(bundle.moduleFormat === 'endoZipBase64');
if (!kernelKeeper.hasBundle(id)) {
kernelKeeper.addBundle(id, bundle);
}
@@ -64,7 +87,7 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
// generate the genesis vats
await null;
- if (config.vats) {
+ if (config.vats && Object.keys(config.vats).length) {
for (const name of Object.keys(config.vats)) {
const {
bundleID,
@@ -86,6 +109,8 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
'useTranscript',
'critical',
'reapInterval',
+ 'reapGCKrefs',
+ 'neverReap',
'nodeOptions',
]);
const vatID = kernelKeeper.allocateVatIDForNameIfNeeded(name);
diff --git a/packages/SwingSet/src/controller/initializeSwingset.js b/packages/SwingSet/src/controller/initializeSwingset.js
index 649c68bcd6f..be85b28e066 100644
--- a/packages/SwingSet/src/controller/initializeSwingset.js
+++ b/packages/SwingSet/src/controller/initializeSwingset.js
@@ -256,7 +256,10 @@ export async function loadSwingsetConfigFile(configPath) {
}
export function swingsetIsInitialized(kernelStorage) {
- return !!kernelStorage.kvStore.get('initialized');
+ return !!(
+ kernelStorage.kvStore.get('version') ||
+ kernelStorage.kvStore.get('initialized')
+ );
}
/**
@@ -397,7 +400,7 @@ export async function initializeSwingset(
enableSetup: true,
managerType: 'local',
useTranscript: false,
- reapInterval: 'never',
+ neverReap: true,
},
};
}
diff --git a/packages/SwingSet/src/controller/upgradeSwingset.js b/packages/SwingSet/src/controller/upgradeSwingset.js
new file mode 100644
index 00000000000..87195b8cfae
--- /dev/null
+++ b/packages/SwingSet/src/controller/upgradeSwingset.js
@@ -0,0 +1,212 @@
+import {
+ DEFAULT_REAP_DIRT_THRESHOLD_KEY,
+ DEFAULT_GC_KREFS_PER_BOYD,
+ getAllDynamicVats,
+ getAllStaticVats,
+} from '../kernel/state/kernelKeeper.js';
+
+const upgradeVatV0toV1 = (kvStore, defaultReapDirtThreshold, vatID) => {
+ // This is called, once per vat, when upgradeSwingset migrates from
+ // v0 to v1
+
+ // schema v0:
+ // Each vat has a `vNN.reapInterval` and `vNN.reapCountdown`.
+ // vNN.options has a `.reapInterval` property (however it was not
+ // updated by processChangeVatOptions). Either all are numbers, or
+ // all are 'never'.
+
+ const oldReapIntervalKey = `${vatID}.reapInterval`;
+ const oldReapCountdownKey = `${vatID}.reapCountdown`;
+ const vatOptionsKey = `${vatID}.options`;
+
+ // schema v1:
+ // Each vat has a `vNN.reapDirt`, and vNN.options has a
+ // `.reapDirtThreshold` property (which overrides kernel-wide
+ // `defaultReapDirtThreshold`)
+
+ const reapDirtKey = `${vatID}.reapDirt`;
+
+ assert(kvStore.has(oldReapIntervalKey), oldReapIntervalKey);
+ assert(kvStore.has(oldReapCountdownKey), oldReapCountdownKey);
+ assert(!kvStore.has(reapDirtKey), reapDirtKey);
+
+ const reapIntervalString = kvStore.get(oldReapIntervalKey);
+ const reapCountdownString = kvStore.get(oldReapCountdownKey);
+ assert(reapIntervalString !== undefined);
+ assert(reapCountdownString !== undefined);
+
+ const intervalIsNever = reapIntervalString === 'never';
+ const countdownIsNever = reapCountdownString === 'never';
+ // these were supposed to be the same
+ assert(
+ intervalIsNever === countdownIsNever,
+ `reapInterval=${reapIntervalString}, reapCountdown=${reapCountdownString}`,
+ );
+
+ // initialize or upgrade state
+ const reapDirt = {}; // all missing keys are treated as zero
+ const threshold = {};
+
+ if (intervalIsNever) {
+ // old vats that were never reaped (eg comms) used
+ // reapInterval='never', so respect that and set the other
+ // threshold values to never as well
+ threshold.never = true;
+ } else {
+ // deduce delivery count from old countdown values
+ const reapInterval = Number.parseInt(reapIntervalString, 10);
+ const reapCountdown = Number.parseInt(reapCountdownString, 10);
+ const deliveries = reapInterval - reapCountdown;
+ reapDirt.deliveries = Math.max(deliveries, 0); // just in case
+ if (reapInterval !== defaultReapDirtThreshold.deliveries) {
+ threshold.deliveries = reapInterval;
+ }
+ }
+
+ kvStore.delete(oldReapIntervalKey);
+ kvStore.delete(oldReapCountdownKey);
+ kvStore.set(reapDirtKey, JSON.stringify(reapDirt));
+
+ // Update options to use the new schema.
+ const options = JSON.parse(kvStore.get(vatOptionsKey));
+ delete options.reapInterval;
+ options.reapDirtThreshold = threshold;
+ kvStore.set(vatOptionsKey, JSON.stringify(options));
+};
+
+/**
+ * (maybe) upgrade the kernel state to the current schema
+ *
+ * This function is responsible for bringing the kernel's portion of
+ * swing-store (kernelStorage) up to the current version. The host app
+ * must call this each time it launches with a new version of
+ * swingset, before using makeSwingsetController() to build the
+ * kernel/controller (which will throw an error if handed an old
+ * database). It is ok to call it only on those reboots, but it is
+ * also safe to call on every reboot, because upgradeSwingset() is a
+ * no-op if the DB is already up-to-date.
+ *
+ * If an upgrade is needed, this function will modify the DB state, so
+ * the host app must be prepared for export-data callbacks being
+ * called during the upgrade, and it is responsible for doing a
+ * `hostStorage.commit()` afterwards.
+ *
+ * @param {SwingStoreKernelStorage} kernelStorage
+ * @returns {boolean} true if any changes were made
+ */
+export const upgradeSwingset = kernelStorage => {
+ const { kvStore } = kernelStorage;
+ let modified = false;
+ let vstring = kvStore.get('version');
+ if (vstring === undefined) {
+ vstring = '0';
+ }
+ let version = Number(vstring);
+
+ /**
+ * @param {string} key
+ * @returns {string}
+ */
+ function getRequired(key) {
+ if (!kvStore.has(key)) {
+ throw Error(`storage lacks required key ${key}`);
+ }
+ // @ts-expect-error already checked .has()
+ return kvStore.get(key);
+ }
+
+ // kernelKeeper.js has a large comment that defines our current
+ // kvStore schema, with a section describing the deltas. The upgrade
+ // steps applied here must match.
+
+ // schema v0:
+ //
+ // The kernel overall has `kernel.defaultReapInterval` and
+ // `kernel.initialized = 'true'`.
+ //
+ // Each vat has a `vNN.reapInterval` and `vNN.reapCountdown`.
+ // vNN.options has a `.reapInterval` property (however it was not
+ // updated by processChangeVatOptions, so do not rely upon its
+ // value). Either all are numbers, or all are 'never'.
+
+ if (version < 1) {
+ // schema v1:
+ //
+ // The kernel overall has `kernel.defaultReapDirtThreshold` and
+ // `kernel.version = '1'` (instead of .initialized).
+ //
+ // Each vat has a `vNN.reapDirt`, and vNN.options has a
+ // `.reapDirtThreshold` property
+
+ // So:
+ // * replace `kernel.initialized` with `kernel.version`
+ // * replace `kernel.defaultReapInterval` with
+ // `kernel.defaultReapDirtThreshold`
+ // * replace vat's `vNN.reapInterval`/`vNN.reapCountdown` with
+ // `vNN.reapDirt` and a `vNN.reapDirtThreshold` in `vNN.options`
+ // * then do per-vat upgrades with upgradeVatV0toV1
+
+ assert(kvStore.has('initialized'));
+ kvStore.delete('initialized');
+ // 'version' will be set at the end
+
+ // upgrade from old kernel.defaultReapInterval
+
+ const oldDefaultReapIntervalKey = 'kernel.defaultReapInterval';
+ assert(kvStore.has(oldDefaultReapIntervalKey));
+ assert(!kvStore.has(DEFAULT_REAP_DIRT_THRESHOLD_KEY));
+
+ /**
+ * @typedef { import('../types-internal.js').ReapDirtThreshold } ReapDirtThreshold
+ */
+
+ /** @type ReapDirtThreshold */
+ const threshold = {
+ deliveries: 'never',
+ gcKrefs: 'never',
+ computrons: 'never',
+ };
+
+ const oldValue = getRequired(oldDefaultReapIntervalKey);
+ if (oldValue !== 'never') {
+ const value = Number.parseInt(oldValue, 10);
+ assert.typeof(value, 'number');
+ threshold.deliveries = value;
+ // if BOYD wasn't turned off entirely (eg
+ // defaultReapInterval='never', which only happens in unit
+ // tests), then pretend we wanted a gcKrefs= threshold all
+ // along, so all vats get a retroactive gcKrefs threshold, which
+ // we need for the upcoming slow-vat-deletion to not trigger
+ // gigantic BOYD and break the kernel
+ threshold.gcKrefs = DEFAULT_GC_KREFS_PER_BOYD;
+ }
+ harden(threshold);
+ kvStore.set(DEFAULT_REAP_DIRT_THRESHOLD_KEY, JSON.stringify(threshold));
+ kvStore.delete(oldDefaultReapIntervalKey);
+
+ // now upgrade all vats
+ for (const [_name, vatID] of getAllStaticVats(kvStore)) {
+ upgradeVatV0toV1(kvStore, threshold, vatID);
+ }
+ for (const vatID of getAllDynamicVats(getRequired)) {
+ upgradeVatV0toV1(kvStore, threshold, vatID);
+ }
+
+ modified = true;
+ version = 1;
+ }
+
+ if (version < 2) {
+ // schema v2: add vats.terminated = []
+ assert(!kvStore.has('vats.terminated'));
+ kvStore.set('vats.terminated', JSON.stringify([]));
+ modified = true;
+ version = 2;
+ }
+
+ if (modified) {
+ kvStore.set('version', `${version}`);
+ }
+ return modified;
+};
+harden(upgradeSwingset);
diff --git a/packages/SwingSet/src/devices/vat-admin/device-vat-admin.js b/packages/SwingSet/src/devices/vat-admin/device-vat-admin.js
index e25943a667f..dd4843bd253 100644
--- a/packages/SwingSet/src/devices/vat-admin/device-vat-admin.js
+++ b/packages/SwingSet/src/devices/vat-admin/device-vat-admin.js
@@ -82,6 +82,7 @@ bundleID before submitting to the kernel), or (temporarily) a full bundle.
* @typedef { string } VatID
* @typedef { string } UpgradeID
* @typedef {{
+ * changeOptions: (vatID: string, options: {}) => void;
* createMeter: (remaining: bigint, threshold: bigint) => MeterID
* createUnlimitedMeter: () => MeterID
* addMeterRemaining: (meterID: MeterID, delta: bigint) => void
@@ -89,7 +90,8 @@ bundleID before submitting to the kernel), or (temporarily) a full bundle.
* getMeter: (meterID: MeterID) => { remaining: bigint, threshold: bigint }
* createByBundle: (bundle: Bundle, options: {}) => VatID
* createByBundleID: (bundleID: BundleID, options: {}) => VatID
- * upgradeVat: (bundleID: BundleID, vatParameters: {}) => UpgradeID
+ * getBundleIDByName: (name: string) => string;
+ * upgradeVat: (vatID: string, bundleID: BundleID, _vatParameters: unknown, upgradeMessage: string) => UpgradeID;
* terminateWithFailure: (vatID: VatID, reason: {}) => void
* getBundleCap: (bundleID: BundleID) => BundleCap
* getNamedBundleCap: (name: string) => BundleCap
diff --git a/packages/SwingSet/src/index.js b/packages/SwingSet/src/index.js
index 3ba4767ef54..af694b5a215 100644
--- a/packages/SwingSet/src/index.js
+++ b/packages/SwingSet/src/index.js
@@ -9,7 +9,7 @@ export {
loadBasedir,
loadSwingsetConfigFile,
} from './controller/initializeSwingset.js';
-
+export { upgradeSwingset } from './controller/upgradeSwingset.js';
export {
buildMailboxStateMap,
buildMailbox,
diff --git a/packages/SwingSet/src/kernel/deviceTranslator.js b/packages/SwingSet/src/kernel/deviceTranslator.js
index 229d27512aa..6152e4b4943 100644
--- a/packages/SwingSet/src/kernel/deviceTranslator.js
+++ b/packages/SwingSet/src/kernel/deviceTranslator.js
@@ -69,7 +69,7 @@ function makeDRTranslator(deviceID, kernelKeeper) {
*
* @param {string} deviceID
* @param {string} deviceName
- * @param {*} kernelKeeper
+ * @param {KernelKeeper} kernelKeeper
* @returns {(dsc: DeviceSyscallObject) => KernelSyscallObject}
*/
export function makeDSTranslator(deviceID, deviceName, kernelKeeper) {
diff --git a/packages/SwingSet/src/kernel/gc-actions.js b/packages/SwingSet/src/kernel/gc-actions.js
index 01adbeeff45..ccc378fbbe9 100644
--- a/packages/SwingSet/src/kernel/gc-actions.js
+++ b/packages/SwingSet/src/kernel/gc-actions.js
@@ -2,9 +2,14 @@ import { Fail } from '@endo/errors';
import { insistKernelType } from './parseKernelSlots.js';
import { insistVatID } from '../lib/id.js';
+/** @import {TotalMap} from '@agoric/internal'; */
+
/**
+ * @typedef {`v${number}`} VatID
+ * @typedef {`ko${number}`} KOID
* @typedef {'dropExport' | 'retireExport' | 'retireImport'} GCActionType
* @typedef {'dropExports' | 'retireExports' | 'retireImports'} GCQueueEventType
+ * @typedef {`${VatID} ${GCActionType} ${KOID}`} GCActionString
*/
/**
@@ -16,17 +21,23 @@ const actionTypePriorities = ['dropExport', 'retireExport', 'retireImport'];
/**
* A mapping of GC action type to queue event type.
- *
- * @type {Map}
*/
-const queueTypeFromActionType = new Map([
- ['dropExport', 'dropExports'],
- ['retireExport', 'retireExports'],
- ['retireImport', 'retireImports'],
-]);
+const queueTypeFromActionType =
+ /** @type {TotalMap} */ (
+ new Map([
+ ['dropExport', 'dropExports'],
+ ['retireExport', 'retireExports'],
+ ['retireImport', 'retireImports'],
+ ])
+ );
+/**
+ * @param {GCActionString} s
+ */
function parseAction(s) {
- const [vatID, type, kref] = s.split(' ');
+ const [vatID, type, kref] = /** @type {[VatID, GCActionType, KOID]} */ (
+ s.split(' ')
+ );
insistVatID(vatID);
queueTypeFromActionType.has(type) || Fail`unknown type ${type}`;
insistKernelType('object', kref);
@@ -34,7 +45,7 @@ function parseAction(s) {
}
/**
- * @param {*} kernelKeeper
+ * @param {KernelKeeper} kernelKeeper
* @returns {import('../types-internal.js').RunQueueEvent | undefined}
*/
export function processGCActionSet(kernelKeeper) {
@@ -62,18 +73,22 @@ export function processGCActionSet(kernelKeeper) {
// we must bypass the action as redundant (since it's an error to delete
// the same c-list entry twice).
- // This `filterAction` function looks at each queued GC Action and decides
- // whether the current state of the c-lsits and reference counts warrants
- // permits the action to run, or if it should be negated/bypassed.
-
- function filterAction(vatKeeper, action, type, kref) {
+ /**
+ * Inspect a queued GC action and decide whether the current state of c-lists
+ * and reference counts warrants processing it, or if it should instead be
+ * negated/bypassed.
+ *
+ * @param {import('../types-external.js').VatKeeper} vatKeeper
+ * @param {GCActionType} type
+ * @param {KOID} kref
+ */
+ function shouldProcessAction(vatKeeper, type, kref) {
const hasCList = vatKeeper.hasCListEntry(kref);
const isReachable = hasCList ? vatKeeper.getReachableFlag(kref) : undefined;
const exists = kernelKeeper.kernelObjectExists(kref);
- // @ts-expect-error xxx
const { reachable, recognizable } = exists
? kernelKeeper.getObjectRefCount(kref)
- : {};
+ : { reachable: 0, recognizable: 0 };
if (type === 'dropExport') {
if (!exists) return false; // already, shouldn't happen
@@ -107,12 +122,16 @@ export function processGCActionSet(kernelKeeper) {
// may need to change to support that, to ensure that `dropExport` and
// `retireExport` can both be delivered.
- function filterActions(vatID, groupedActions) {
+ /**
+ * @param {VatID} vatID
+ * @param {GCActionString[]} groupedActions
+ */
+ function krefsToProcess(vatID, groupedActions) {
const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
const krefs = [];
for (const action of groupedActions) {
const { type, kref } = parseAction(action);
- if (filterAction(vatKeeper, action, type, kref)) {
+ if (shouldProcessAction(vatKeeper, type, kref)) {
krefs.push(kref);
}
allActionsSet.delete(action);
@@ -121,49 +140,50 @@ export function processGCActionSet(kernelKeeper) {
return krefs;
}
- const grouped = new Map(); // grouped.get(vatID).get(type) = krefs to process
+ /** @type {TotalMap>} */
+ const actionsByVat = new Map();
for (const action of allActionsSet) {
const { vatID, type } = parseAction(action);
- if (!grouped.has(vatID)) {
- grouped.set(vatID, new Map());
+ if (!actionsByVat.has(vatID)) {
+ actionsByVat.set(vatID, new Map());
}
- const forVat = grouped.get(vatID);
- if (!forVat.has(type)) {
- forVat.set(type, []);
+ const actionsForVatByType = actionsByVat.get(vatID);
+ if (!actionsForVatByType.has(type)) {
+ actionsForVatByType.set(type, []);
}
- forVat.get(type).push(action);
+ actionsForVatByType.get(type).push(action);
}
- const vatIDs = Array.from(grouped.keys());
+ const vatIDs = Array.from(actionsByVat.keys());
vatIDs.sort();
for (const vatID of vatIDs) {
- const forVat = grouped.get(vatID);
+ const actionsForVatByType = actionsByVat.get(vatID);
// find the highest-priority type of work to do within this vat
for (const type of actionTypePriorities) {
- if (forVat.has(type)) {
- const actions = forVat.get(type);
- const krefs = filterActions(vatID, actions);
+ if (actionsForVatByType.has(type)) {
+ const actions = actionsForVatByType.get(type);
+ const krefs = krefsToProcess(vatID, actions);
if (krefs.length) {
// at last, we act
krefs.sort();
// remove the work we're about to do from the durable set
kernelKeeper.setGCActions(allActionsSet);
- const queueType = /** @type {GCQueueEventType} */ (
- queueTypeFromActionType.get(type)
- );
+ const queueType = queueTypeFromActionType.get(type);
return harden({ type: queueType, vatID, krefs });
}
}
}
}
+
if (actionSetUpdated) {
// remove negated items from the durable set
kernelKeeper.setGCActions(allActionsSet);
- // return a special gc-nop event to tell kernel to record our
+ // return a special event to tell kernel to record our
// DB changes in their own crank
return harden({ type: 'negated-gc-action', vatID: undefined });
- } else {
- return undefined; // no GC work to do and no DB changes
}
+
+ // no GC work to do and no DB changes
+ return undefined;
}
harden(processGCActionSet);
diff --git a/packages/SwingSet/src/kernel/kernel.js b/packages/SwingSet/src/kernel/kernel.js
index 200a69a434b..b6e11dbd714 100644
--- a/packages/SwingSet/src/kernel/kernel.js
+++ b/packages/SwingSet/src/kernel/kernel.js
@@ -2,7 +2,9 @@
import { assert, Fail } from '@endo/errors';
import { isNat } from '@endo/nat';
+import { mustMatch, M } from '@endo/patterns';
import { importBundle } from '@endo/import-bundle';
+import { objectMetaMap, PromiseAllOrErrors } from '@agoric/internal';
import { makeUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
import { kser, kslot, makeError } from '@agoric/kmarshal';
import { assertKnownOptions } from '../lib/assertOptions.js';
@@ -10,7 +12,9 @@ import { foreverPolicy } from '../lib/runPolicies.js';
import { makeVatManagerFactory } from './vat-loader/manager-factory.js';
import { makeVatWarehouse } from './vat-warehouse.js';
import makeDeviceManager from './deviceManager.js';
-import makeKernelKeeper from './state/kernelKeeper.js';
+import makeKernelKeeper, {
+ CURRENT_SCHEMA_VERSION,
+} from './state/kernelKeeper.js';
import {
kdebug,
kdebugEnable,
@@ -35,7 +39,10 @@ import { makeDeviceTranslators } from './deviceTranslator.js';
import { notifyTermination } from './notifyTermination.js';
import { makeVatAdminHooks } from './vat-admin-hooks.js';
-/** @import * as liveslots from '@agoric/swingset-liveslots' */
+/**
+ * @import {MeterConsumption, VatDeliveryObject, VatDeliveryResult, VatSyscallObject, VatSyscallResult} from '@agoric/swingset-liveslots';
+ * @import {PolicyInputCleanupCounts} from '../types-external.js';
+ */
function abbreviateReplacer(_, arg) {
if (typeof arg === 'bigint') {
@@ -51,7 +58,7 @@ function abbreviateReplacer(_, arg) {
/**
* Provide the kref of a vat's root object, as if it had been exported.
*
- * @param {*} kernelKeeper Kernel keeper managing persistent kernel state.
+ * @param {KernelKeeper} kernelKeeper Kernel keeper managing persistent kernel state.
* @param {string} vatID Vat ID of the vat whose root kref is sought.
*
* @returns {string} the kref of the root object of the given vat.
@@ -112,7 +119,11 @@ export default function buildKernel(
? makeSlogger(slogCallbacks, writeSlogObject)
: makeDummySlogger(slogCallbacks, makeConsole('disabled slogger'));
- const kernelKeeper = makeKernelKeeper(kernelStorage, kernelSlog);
+ const kernelKeeper = makeKernelKeeper(
+ kernelStorage,
+ CURRENT_SCHEMA_VERSION,
+ kernelSlog,
+ );
/** @type {ReturnType} */
let vatWarehouse;
@@ -252,9 +263,12 @@ export default function buildKernel(
*/
async function terminateVat(vatID, shouldReject, info) {
console.log(`kernel terminating vat ${vatID} (failure=${shouldReject})`);
- const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
- const critical = vatKeeper.getOptions().critical;
insistCapData(info);
+ // Note that it's important for much of this work to happen within the
+ // synchronous prelude. For details, see
+ // https://github.com/Agoric/agoric-sdk/pull/10055#discussion_r1754918394
+ let critical = false;
+ const deferred = [];
// ISSUE: terminate stuff in its own crank like creation?
// TODO: if a static vat terminates, panic the kernel?
// TODO: guard against somebody telling vatAdmin to kill a vat twice
@@ -264,10 +278,22 @@ export default function buildKernel(
// check will report 'false'. That's fine, there's no state to
// clean up.
if (kernelKeeper.vatIsAlive(vatID)) {
+ // If there was no vat state, we can't make a vatKeeper to ask for
+ // options. For now, pretend the vat was non-critical. This will fail
+ // to panic the kernel for startVat failures in critical vats
+ // (#9157). The fix will add .critical to CrankResults, populated by a
+ // getOptions query in deliveryCrankResults() or copied from
+ // dynamicOptions in processCreateVat.
+ const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
+ critical = vatKeeper.getOptions().critical;
+
// Reject all promises decided by the vat, making sure to capture the list
// of kpids before that data is deleted.
const deadPromises = [...kernelKeeper.enumeratePromisesByDecider(vatID)];
- kernelKeeper.cleanupAfterTerminatedVat(vatID);
+ // remove vatID from the list of live vats, and mark for deletion
+ kernelKeeper.deleteVatID(vatID);
+ kernelKeeper.markVatAsTerminated(vatID);
+ deferred.push(kernelKeeper.removeVatFromSwingStoreExports(vatID));
for (const kpid of deadPromises) {
resolveToError(kpid, makeError('vat terminated'), vatID);
}
@@ -282,9 +308,7 @@ export default function buildKernel(
// it's going to be a small cost compared to the trouble you're probably
// already in anyway if this happens.
panic(`critical vat ${vatID} failed`, Error(info.body));
- return;
- }
- if (vatAdminRootKref) {
+ } else if (vatAdminRootKref) {
// static vat termination can happen before vat admin vat exists
notifyTermination(
vatID,
@@ -299,8 +323,11 @@ export default function buildKernel(
);
}
- // worker needs to be stopped, if any
- await vatWarehouse.stopWorker(vatID);
+ // worker, if present, needs to be stopped
+ // (note that this only applies to ephemeral vats)
+ deferred.push(vatWarehouse.stopWorker(vatID));
+
+ await PromiseAllOrErrors(deferred);
}
function notifyMeterThreshold(meterID) {
@@ -355,8 +382,8 @@ export default function buildKernel(
/**
*
- * @typedef { import('@agoric/swingset-liveslots').MeterConsumption } MeterConsumption
* @typedef { import('../types-internal.js').MeterID } MeterID
+ * @typedef { import('../types-internal.js').Dirt } Dirt
*
* Any delivery crank (send, notify, start-vat.. anything which is allowed
* to make vat delivery) emits one of these status events if a delivery
@@ -369,13 +396,15 @@ export default function buildKernel(
* illegalSyscall: { vatID: VatID, info: SwingSetCapData } | undefined,
* vatRequestedTermination: { reject: boolean, info: SwingSetCapData } | undefined,
* } } DeliveryStatus
+ * @import {PolicyInputCleanupCounts} from '../types-external.js';
* @typedef { {
* abort?: boolean, // changes should be discarded, not committed
* consumeMessage?: boolean, // discard the aborted delivery
* didDelivery?: VatID, // we made a delivery to a vat, for run policy and save-snapshot
- * computrons?: BigInt, // computron count for run policy
+ * computrons?: bigint, // computron count for run policy
+ * cleanups?: PolicyInputCleanupCounts, // cleanup budget spent
* meterID?: string, // deduct those computrons from a meter
- * decrementReapCount?: { vatID: VatID }, // the reap counter should decrement
+ * measureDirt?: { vatID: VatID, dirt: Dirt }, // dirt counters should increment
* terminate?: { vatID: VatID, reject: boolean, info: SwingSetCapData }, // terminate vat, notify vat-admin
* vatAdminMethargs?: RawMethargs, // methargs to notify vat-admin about create/upgrade results
* } } CrankResults
@@ -388,7 +417,7 @@ export default function buildKernel(
*
* @param {VatID} vatID
* @param {KernelDeliveryObject} kd
- * @param {liveslots.VatDeliveryObject} vd
+ * @param {VatDeliveryObject} vd
*/
async function deliverAndLogToVat(vatID, kd, vd) {
vatRequestedTermination = undefined;
@@ -398,7 +427,7 @@ export default function buildKernel(
const vs = kernelSlog.provideVatSlogger(vatID).vatSlog;
await null;
try {
- /** @type { liveslots.VatDeliveryResult } */
+ /** @type { VatDeliveryResult } */
const deliveryResult = await vatWarehouse.deliverToVat(vatID, kd, vd, vs);
insistVatDeliveryResult(deliveryResult);
// const [ ok, problem, usage ] = deliveryResult;
@@ -442,16 +471,17 @@ export default function buildKernel(
* event handler.
*
* Two flags influence this:
- * `decrementReapCount` is used for deliveries that run userspace code
+ * `measureDirt` is used for non-BOYD deliveries
* `meterID` means we should check a meter
*
* @param {VatID} vatID
* @param {DeliveryStatus} status
- * @param {boolean} decrementReapCount
+ * @param {boolean} measureDirt
* @param {MeterID} [meterID]
+ * @param {number} [gcKrefs]
* @returns {CrankResults}
*/
- function deliveryCrankResults(vatID, status, decrementReapCount, meterID) {
+ function deliveryCrankResults(vatID, status, measureDirt, meterID, gcKrefs) {
let meterUnderrun = false;
let computrons;
if (status.metering?.compute) {
@@ -495,8 +525,16 @@ export default function buildKernel(
results.terminate = { vatID, ...status.vatRequestedTermination };
}
- if (decrementReapCount && !(results.abort || results.terminate)) {
- results.decrementReapCount = { vatID };
+ if (measureDirt && !(results.abort || results.terminate)) {
+ const dirt = { deliveries: 1 };
+ if (computrons) {
+ // this is BigInt, but we use plain Number in Dirt records
+ dirt.computrons = Number(computrons);
+ }
+ if (gcKrefs) {
+ dirt.gcKrefs = gcKrefs;
+ }
+ results.measureDirt = { vatID, dirt };
}
// We leave results.consumeMessage up to the caller. Send failures
@@ -535,7 +573,8 @@ export default function buildKernel(
}
const status = await deliverAndLogToVat(vatID, kd, vd);
- return deliveryCrankResults(vatID, status, true, meterID);
+ const gcKrefs = undefined; // TODO maybe increase by number of vrefs in args?
+ return deliveryCrankResults(vatID, status, true, meterID, gcKrefs);
}
/**
@@ -581,7 +620,8 @@ export default function buildKernel(
const vd = vatWarehouse.kernelDeliveryToVatDelivery(vatID, kd);
vatKeeper.deleteCListEntriesForKernelSlots(targets);
const status = await deliverAndLogToVat(vatID, kd, vd);
- return deliveryCrankResults(vatID, status, true, meterID);
+ const gcKrefs = undefined; // TODO maybe increase by number of vrefs in args?
+ return deliveryCrankResults(vatID, status, true, meterID, gcKrefs);
}
/**
@@ -609,7 +649,9 @@ export default function buildKernel(
}
const vd = vatWarehouse.kernelDeliveryToVatDelivery(vatID, kd);
const status = await deliverAndLogToVat(vatID, kd, vd);
- return deliveryCrankResults(vatID, status, false); // no meterID
+ const meterID = undefined; // no meterID
+ const gcKrefs = krefs.length;
+ return deliveryCrankResults(vatID, status, true, meterID, gcKrefs);
}
/**
@@ -628,7 +670,50 @@ export default function buildKernel(
const kd = harden([type]);
const vd = vatWarehouse.kernelDeliveryToVatDelivery(vatID, kd);
const status = await deliverAndLogToVat(vatID, kd, vd);
- return deliveryCrankResults(vatID, status, false); // no meter
+ // no gcKrefs, BOYD clears them anyways
+ return deliveryCrankResults(vatID, status, false); // no meter, BOYD clears dirt
+ }
+
+ /**
+ * Perform a small (budget-limited) amount of dead-vat cleanup work.
+ *
+ * @param {RunQueueEventCleanupTerminatedVat} message
+ * 'message' is the run-queue cleanup action, which includes a
+ * vatID and budget. The budget contains work limits for each
+ * phase of cleanup (perhaps Infinity to allow unlimited
+ * work). Cleanup should not touch more than maybe 5*limit DB
+ * rows.
+ * @returns {Promise}
+ */
+ async function processCleanupTerminatedVat(message) {
+ const { vatID, budget } = message;
+ const { done, work } = kernelKeeper.cleanupAfterTerminatedVat(
+ vatID,
+ budget,
+ );
+ const zeroFreeWorkCounts = objectMetaMap(work, desc =>
+ desc.value ? desc : undefined,
+ );
+ kernelSlog.write({ type: 'vat-cleanup', vatID, work: zeroFreeWorkCounts });
+
+ /** @type {PolicyInputCleanupCounts} */
+ const cleanups = {
+ total:
+ work.exports +
+ work.imports +
+ work.kv +
+ work.snapshots +
+ work.transcripts,
+ ...work,
+ };
+ if (done) {
+ kernelKeeper.forgetTerminatedVat(vatID);
+ kernelSlog.write({ type: 'vat-cleanup-complete', vatID });
+ }
+ // We don't perform any deliveries here, so there are no computrons to
+ // report, but we do tell the runPolicy know how much kernel-side DB
+ // work we did, so it can decide how much was too much.
+ return harden({ computrons: 0n, cleanups });
}
/**
@@ -669,8 +754,9 @@ export default function buildKernel(
const status = await deliverAndLogToVat(vatID, kd, vd);
// note: if deliveryCrankResults() learns to suspend vats,
// startVat errors should still terminate them
+ const gcKrefs = undefined; // TODO maybe increase by number of vrefs in args?
const results = harden({
- ...deliveryCrankResults(vatID, status, true, meterID),
+ ...deliveryCrankResults(vatID, status, true, meterID, gcKrefs),
consumeMessage: true,
});
return results;
@@ -735,9 +821,17 @@ export default function buildKernel(
function setKernelVatOption(vatID, option, value) {
switch (option) {
case 'reapInterval': {
+ // This still controls reapDirtThreshold.deliveries, and we do not
+ // yet offer controls for the other limits (gcKrefs or computrons).
if (value === 'never' || isNat(value)) {
const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
- vatKeeper.updateReapInterval(value);
+ const threshold = { ...vatKeeper.getReapDirtThreshold() };
+ if (value === 'never') {
+ threshold.deliveries = value;
+ } else {
+ threshold.deliveries = Number(value);
+ }
+ vatKeeper.setReapDirtThreshold(threshold);
} else {
console.log(`WARNING: invalid reapInterval value`, value);
}
@@ -911,10 +1005,7 @@ export default function buildKernel(
const abandonedObjects = [
...kernelKeeper.enumerateNonDurableObjectExports(vatID),
];
- for (const { kref, vref } of abandonedObjects) {
- /** @see translateAbandonExports in {@link ./vatTranslator.js} */
- vatKeeper.deleteCListEntry(kref, vref);
- /** @see abandonExports in {@link ./kernelSyscall.js} */
+ for (const { kref } of abandonedObjects) {
kernelKeeper.orphanKernelObject(kref, vatID);
}
@@ -951,7 +1042,14 @@ export default function buildKernel(
startVatKD,
startVatVD,
);
- const startVatResults = deliveryCrankResults(vatID, startVatStatus, false);
+ const gcKrefs = undefined; // TODO maybe increase by number of vrefs in args?
+ const startVatResults = deliveryCrankResults(
+ vatID,
+ startVatStatus,
+ true,
+ meterID,
+ gcKrefs,
+ );
computrons = addComputrons(computrons, startVatResults.computrons);
if (startVatResults.terminate) {
@@ -1125,6 +1223,7 @@ export default function buildKernel(
* @typedef { import('../types-internal.js').RunQueueEventRetireImports } RunQueueEventRetireImports
* @typedef { import('../types-internal.js').RunQueueEventNegatedGCAction } RunQueueEventNegatedGCAction
* @typedef { import('../types-internal.js').RunQueueEventBringOutYourDead } RunQueueEventBringOutYourDead
+ * @typedef { import('../types-internal.js').RunQueueEventCleanupTerminatedVat } RunQueueEventCleanupTerminatedVat
* @typedef { import('../types-internal.js').RunQueueEvent } RunQueueEvent
*/
@@ -1192,6 +1291,8 @@ export default function buildKernel(
} else if (message.type === 'negated-gc-action') {
// processGCActionSet pruned some negated actions, but had no GC
// action to perform. Record the DB changes in their own crank.
+ } else if (message.type === 'cleanup-terminated-vat') {
+ deliverP = processCleanupTerminatedVat(message);
} else if (gcMessages.includes(message.type)) {
deliverP = processGCMessage(message);
} else {
@@ -1242,18 +1343,13 @@ export default function buildKernel(
const crankResults = await deliverRunQueueEvent(message);
// { abort/commit, deduct, terminate+notify, consumeMessage }
- if (crankResults.didDelivery) {
- if (message.type === 'create-vat') {
- // TODO: create-vat now gets metering, at least for the
- // dispatch.startVat . We should probably tell the policy about
- // the creation too since there's extra overhead (we're
- // launching a new child process, at least, although that
- // sometimes happens randomly because of vat eviction policy
- // which should not affect the in-consensus policyInput)
- policyInput = ['create-vat', {}];
- } else {
- policyInput = ['crank', {}];
- }
+ if (message.type === 'cleanup-terminated-vat') {
+ const { cleanups } = crankResults;
+ assert(cleanups !== undefined);
+ policyInput = ['cleanup', { cleanups }];
+ } else if (crankResults.didDelivery) {
+ const tag = message.type === 'create-vat' ? 'create-vat' : 'crank';
+ policyInput = [tag, {}];
}
// Deliveries cause syscalls, syscalls might cause errors
@@ -1292,13 +1388,11 @@ export default function buildKernel(
}
}
}
- if (crankResults.decrementReapCount) {
+ if (crankResults.measureDirt) {
// deliveries cause garbage, garbage needs collection
- const { vatID } = crankResults.decrementReapCount;
+ const { vatID, dirt } = crankResults.measureDirt;
const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
- if (vatKeeper.countdownToReap()) {
- kernelKeeper.scheduleReap(vatID);
- }
+ vatKeeper.addDirt(dirt); // might schedule a reap for that vat
}
// Vat termination (during delivery) is triggered by an illegal
@@ -1449,8 +1543,8 @@ export default function buildKernel(
// not
/**
*
- * @param {liveslots.VatSyscallObject} vatSyscallObject
- * @returns {liveslots.VatSyscallResult}
+ * @param {VatSyscallObject} vatSyscallObject
+ * @returns {VatSyscallResult}
*/
function vatSyscallHandler(vatSyscallObject) {
if (!vatWarehouse.lookup(vatID)) {
@@ -1465,7 +1559,7 @@ export default function buildKernel(
let ksc;
/** @type { KernelSyscallResult } */
let kres = harden(['error', 'incomplete']);
- /** @type { liveslots.VatSyscallResult } */
+ /** @type { VatSyscallResult } */
let vres = harden(['error', 'incomplete']);
try {
@@ -1572,10 +1666,14 @@ export default function buildKernel(
'bundleID',
'enablePipelining',
'reapInterval',
+ 'reapGCKrefs',
+ 'neverReap',
]);
const {
bundleID = 'b1-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
reapInterval = 'never',
+ reapGCKrefs = 'never',
+ neverReap = false,
enablePipelining,
} = creationOptions;
const vatID = kernelKeeper.allocateVatIDForNameIfNeeded(name);
@@ -1587,6 +1685,8 @@ export default function buildKernel(
const options = {
name,
reapInterval,
+ reapGCKrefs,
+ neverReap,
enablePipelining,
managerType,
};
@@ -1617,7 +1717,6 @@ export default function buildKernel(
throw Error('kernel.start already called');
}
started = true;
- kernelKeeper.getInitialized() || Fail`kernel not initialized`;
kernelKeeper.loadStats();
@@ -1708,16 +1807,38 @@ export default function buildKernel(
}
}
+ // match return value of runPolicy.allowCleanup, which is
+ // PolicyOutputCleanupBudget | true | false
+ const allowCleanupShape = M.or(
+ // 'false' will prohibit cleanup
+ false,
+ // 'true' will allow unlimited cleanup
+ true,
+ // otherwise allow cleanup, optionally with a limiting budget
+ M.splitRecord(
+ { default: M.number() },
+ {
+ exports: M.number(),
+ imports: M.number(),
+ kv: M.number(),
+ snapshots: M.number(),
+ transcripts: M.number(),
+ },
+ M.record(),
+ ),
+ );
+
/**
* Pulls the next message from the highest-priority queue and returns it
* along with a corresponding processor.
*
+ * @param {RunPolicy} [policy] - a RunPolicy to limit the work being done
* @returns {{
* message: RunQueueEvent | undefined,
* processor: (message: RunQueueEvent) => Promise,
* }}
*/
- function getNextMessageAndProcessor() {
+ function getNextMessageAndProcessor(policy) {
const acceptanceMessage = kernelKeeper.getNextAcceptanceQueueMsg();
if (acceptanceMessage) {
return {
@@ -1725,7 +1846,12 @@ export default function buildKernel(
processor: processAcceptanceMessage,
};
}
+ // Absent specific configuration, allow unlimited cleanup.
+ const allowCleanup = policy?.allowCleanup?.() ?? true;
+ mustMatch(harden(allowCleanup), allowCleanupShape);
+
const message =
+ kernelKeeper.nextCleanupTerminatedVatAction(allowCleanup) ||
processGCActionSet(kernelKeeper) ||
kernelKeeper.nextReapAction() ||
kernelKeeper.getNextRunQueueMsg();
@@ -1733,14 +1859,36 @@ export default function buildKernel(
}
function changeKernelOptions(options) {
- assertKnownOptions(options, ['defaultReapInterval', 'snapshotInterval']);
+ assertKnownOptions(options, [
+ 'defaultReapInterval',
+ 'defaultReapGCKrefs',
+ 'snapshotInterval',
+ ]);
kernelKeeper.startCrank();
try {
for (const option of Object.getOwnPropertyNames(options)) {
const value = options[option];
switch (option) {
case 'defaultReapInterval': {
- kernelKeeper.setDefaultReapInterval(value);
+ assert(
+ (typeof value === 'number' && value > 0) || value === 'never',
+ `defaultReapInterval ${value} must be a positive number or "never"`,
+ );
+ kernelKeeper.setDefaultReapDirtThreshold({
+ ...kernelKeeper.getDefaultReapDirtThreshold(),
+ deliveries: value,
+ });
+ break;
+ }
+ case 'defaultReapGCKrefs': {
+ assert(
+ (typeof value === 'number' && value > 0) || value === 'never',
+ `defaultReapGCKrefs ${value} must be a positive number or "never"`,
+ );
+ kernelKeeper.setDefaultReapDirtThreshold({
+ ...kernelKeeper.getDefaultReapDirtThreshold(),
+ gcKrefs: value,
+ });
break;
}
case 'snapshotInterval': {
@@ -1813,7 +1961,7 @@ export default function buildKernel(
kernelKeeper.startCrank();
try {
kernelKeeper.establishCrankSavepoint('start');
- const { processor, message } = getNextMessageAndProcessor();
+ const { processor, message } = getNextMessageAndProcessor(policy);
if (!message) {
break;
}
@@ -1835,6 +1983,13 @@ export default function buildKernel(
case 'crank-failed':
policyOutput = policy.crankFailed(policyInput[1]);
break;
+ case 'cleanup': {
+ // Give the policy a chance to interrupt kernel execution,
+ // but default to continuing.
+ const { didCleanup } = policy;
+ policyOutput = didCleanup ? didCleanup(policyInput[1]) : true;
+ break;
+ }
case 'none':
policyOutput = policy.emptyCrank();
break;
@@ -1944,6 +2099,16 @@ export default function buildKernel(
hooks[hookName] = hook;
}
+ function terminateVatExternally(vatID, reasonCD) {
+ assert(started, 'must do kernel.start() before terminateVatExternally()');
+ insistCapData(reasonCD);
+ assert(reasonCD.slots.length === 0, 'no slots allowed in reason');
+ // this fires a promise when worker is dead, mostly for tests, so don't
+ // give it to external callers
+ void terminateVat(vatID, true, reasonCD);
+ console.log(`scheduled vatID ${vatID} for termination`);
+ }
+
const kernel = harden({
// these are meant for the controller
installBundle,
@@ -2019,6 +2184,7 @@ export default function buildKernel(
kpStatus,
kpResolution,
addDeviceHook,
+ terminateVatExternally,
});
return kernel;
diff --git a/packages/SwingSet/src/kernel/kernelSyscall.js b/packages/SwingSet/src/kernel/kernelSyscall.js
index fa1ce165daf..573b2b351b7 100644
--- a/packages/SwingSet/src/kernel/kernelSyscall.js
+++ b/packages/SwingSet/src/kernel/kernelSyscall.js
@@ -178,24 +178,13 @@ export function makeKernelSyscallHandler(tools) {
function retireExports(koids) {
Array.isArray(koids) || Fail`retireExports given non-Array ${koids}`;
- const newActions = [];
- for (const koid of koids) {
- const importers = kernelKeeper.getImporters(koid);
- for (const vatID of importers) {
- newActions.push(`${vatID} retireImport ${koid}`);
- }
- // TODO: decref and delete any #2069 auxdata
- kernelKeeper.deleteKernelObject(koid);
- }
- kernelKeeper.addGCActions(newActions);
+ kernelKeeper.retireKernelObjects(koids);
return OKNULL;
}
function abandonExports(vatID, koids) {
Array.isArray(koids) || Fail`abandonExports given non-Array ${koids}`;
for (const koid of koids) {
- // note that this is effectful and also performed outside of a syscall
- // by processUpgradeVat in {@link ./kernel.js}
kernelKeeper.orphanKernelObject(koid, vatID);
}
return OKNULL;
diff --git a/packages/SwingSet/src/kernel/state/kernelKeeper.js b/packages/SwingSet/src/kernel/state/kernelKeeper.js
index 192be013c41..1d456160bf8 100644
--- a/packages/SwingSet/src/kernel/state/kernelKeeper.js
+++ b/packages/SwingSet/src/kernel/state/kernelKeeper.js
@@ -1,6 +1,11 @@
+/* eslint-disable no-use-before-define */
import { Nat, isNat } from '@endo/nat';
import { assert, Fail } from '@endo/errors';
-import { initializeVatState, makeVatKeeper } from './vatKeeper.js';
+import {
+ initializeVatState,
+ makeVatKeeper,
+ DEFAULT_REAP_DIRT_THRESHOLD_KEY,
+} from './vatKeeper.js';
import { initializeDeviceState, makeDeviceKeeper } from './deviceKeeper.js';
import { parseReachableAndVatSlot } from './reachable.js';
import { insistStorageAPI } from '../../lib/storageAPI.js';
@@ -33,14 +38,22 @@ const enableKernelGC = true;
* @typedef { import('../../types-external.js').BundleCap } BundleCap
* @typedef { import('../../types-external.js').BundleID } BundleID
* @typedef { import('../../types-external.js').EndoZipBase64Bundle } EndoZipBase64Bundle
- * @typedef { import('../../types-external.js').KernelOptions } KernelOptions
* @typedef { import('../../types-external.js').KernelSlog } KernelSlog
* @typedef { import('../../types-external.js').ManagerType } ManagerType
* @typedef { import('../../types-external.js').SnapStore } SnapStore
* @typedef { import('../../types-external.js').TranscriptStore } TranscriptStore
* @typedef { import('../../types-external.js').VatKeeper } VatKeeper
+ * @typedef { import('../../types-internal.js').InternalKernelOptions } InternalKernelOptions
+ * @typedef { import('../../types-internal.js').ReapDirtThreshold } ReapDirtThreshold
+ * @import {CleanupBudget, CleanupWork, PolicyOutputCleanupBudget} from '../../types-external.js';
+ * @import {RunQueueEventCleanupTerminatedVat} from '../../types-internal.js';
*/
+export { DEFAULT_REAP_DIRT_THRESHOLD_KEY };
+
+// most recent DB schema version
+export const CURRENT_SCHEMA_VERSION = 2;
+
// Kernel state lives in a key-value store supporting key retrieval by
// lexicographic range. All keys and values are strings.
// We simulate a tree by concatenating path-name components with ".". When we
@@ -52,13 +65,21 @@ const enableKernelGC = true;
// allowed to vary between instances in a consensus machine. Everything else
// is required to be deterministic.
//
-// The schema is:
//
+// The schema is indicated by the value of the "version" key, which
+// was added for version 1 (i.e., version 0 had no such key), and is
+// only modified by a call to upgradeSwingset(). See below for
+// deltas/upgrades from one version to the next.
+//
+// The current ("v2") schema keys/values are:
+//
+// version = '2'
// vat.names = JSON([names..])
// vat.dynamicIDs = JSON([vatIDs..])
// vat.name.$NAME = $vatID = v$NN
// vat.nextID = $NN
// vat.nextUpgradeID = $NN
+// vats.terminated = JSON([vatIDs..])
// device.names = JSON([names..])
// device.name.$NAME = $deviceID = d$NN
// device.nextID = $NN
@@ -68,13 +89,22 @@ const enableKernelGC = true;
// bundle.$BUNDLEID = JSON(bundle)
//
// kernel.defaultManagerType = managerType
-// kernel.defaultReapInterval = $NN
+// (old) kernel.defaultReapInterval = $NN
+// kernel.defaultReapDirtThreshold = JSON({ thresholds })
+// thresholds (all optional)
+// deliveries: number or 'never' (default)
+// gcKrefs: number or 'never' (default)
+// computrons: number or 'never' (default)
+// never: boolean (default false)
// kernel.relaxDurabilityRules = missing | 'true'
// kernel.snapshotInitial = $NN
// kernel.snapshotInterval = $NN
// v$NN.source = JSON({ bundle }) or JSON({ bundleName })
-// v$NN.options = JSON
+// v$NN.options = JSON , options include:
+// .reapDirtThreshold = JSON({ thresholds })
+// thresholds (all optional, default to kernel-wide defaultReapDirtThreshold)
+// (leave room for .snapshotDirtThreshold for #6786)
// v$NN.o.nextID = $NN
// v$NN.p.nextID = $NN
// v$NN.d.nextID = $NN
@@ -83,9 +113,10 @@ const enableKernelGC = true;
// $vatSlot is one of: o+$NN/o-$NN/p+$NN/p-$NN/d+$NN/d-$NN
// v$NN.c.$vatSlot = $kernelSlot = ko$NN/kp$NN/kd$NN
// v$NN.vs.$key = string
-// v$NN.meter = m$NN // XXX does this exist?
-// v$NN.reapInterval = $NN or 'never'
-// v$NN.reapCountdown = $NN or 'never'
+// old (v0): v$NN.reapInterval = $NN or 'never'
+// old (v0): v$NN.reapCountdown = $NN or 'never'
+// v$NN.reapDirt = JSON({ deliveries, gcKrefs, computrons }) // missing keys treated as zero
+// (leave room for v$NN.snapshotDirt and options.snapshotDirtThreshold for #6786)
// exclude from consensus
// local.*
@@ -132,6 +163,22 @@ const enableKernelGC = true;
// Prefix reserved for host written data:
// host.
+// Kernel state schema changes:
+//
+// v0: the original
+// * no `version`
+// * uses `initialized = 'true'`
+// v1:
+// * add `version = '1'`
+// * remove `initialized`
+// * replace `kernel.defaultReapInterval` with `kernel.defaultReapDirtThreshold`
+// * replace vat's `vNN.reapInterval`/`vNN.reapCountdown` with `vNN.reapDirt`
+// and a `vNN.reapDirtThreshold` in `vNN.options`
+// v2:
+// * change `version` to `'2'`
+// * add `vats.terminated` with `[]` as initial value
+
+/** @type {(s: string) => string[]} s */
export function commaSplit(s) {
if (s === '') {
return [];
@@ -139,12 +186,32 @@ export function commaSplit(s) {
return s.split(',');
}
+export function stripPrefix(prefix, str) {
+ assert(str.startsWith(prefix), str);
+ return str.slice(prefix.length);
+}
+
function insistMeterID(m) {
assert.typeof(m, 'string');
assert.equal(m[0], 'm');
Nat(BigInt(m.slice(1)));
}
+export const getAllStaticVats = kvStore => {
+ const result = [];
+ const prefix = 'vat.name.';
+ for (const k of enumeratePrefixedKeys(kvStore, prefix)) {
+ const vatID = kvStore.get(k) || Fail`getNextKey ensures get`;
+ const name = k.slice(prefix.length);
+ result.push([name, vatID]);
+ }
+ return result;
+};
+
+export const getAllDynamicVats = getRequired => {
+ return JSON.parse(getRequired('vat.dynamicIDs'));
+};
+
// we use different starting index values for the various vNN/koNN/kdNN/kpNN
// slots, to reduce confusing overlap when looking at debug messages (e.g.
// seeing both kp1 and ko1, which are completely unrelated despite having the
@@ -163,15 +230,59 @@ const FIRST_PROMISE_ID = 40n;
const FIRST_CRANK_NUMBER = 0n;
const FIRST_METER_ID = 1n;
+// this default "reap interval" is low for the benefit of tests:
+// applications should set it to something higher (perhaps 200) based
+// on their expected usage
+
+export const DEFAULT_DELIVERIES_PER_BOYD = 1;
+
+// "20" will trigger a BOYD after 10 krefs are dropped and retired
+// (drops and retires are delivered in separate messages, so
+// 10+10=20). The worst case work-expansion we've seen is in #8401,
+// where one drop breaks one cycle, and each cycle's cleanup causes 50
+// syscalls in the next v9-zoe BOYD. So this should limit each BOYD
+// to cleaning 10 cycles, in 500 syscalls.
+
+export const DEFAULT_GC_KREFS_PER_BOYD = 20;
+
/**
* @param {SwingStoreKernelStorage} kernelStorage
- * @param {KernelSlog|null} kernelSlog
+ * @param {number | 'uninitialized'} expectedVersion
+ * @param {KernelSlog} [kernelSlog]
*/
-export default function makeKernelKeeper(kernelStorage, kernelSlog) {
+export default function makeKernelKeeper(
+ kernelStorage,
+ expectedVersion,
+ kernelSlog,
+) {
const { kvStore, transcriptStore, snapStore, bundleStore } = kernelStorage;
insistStorageAPI(kvStore);
+ // the terminated-vats cache is normally populated from
+ // 'vats.terminated', but for initialization purposes we need give
+ // it a value here, and then populate it for real if we're dealing
+ // with an up-to-date DB
+ let terminatedVats = [];
+
+ const versionString = kvStore.get('version');
+ const version = Number(versionString || '0');
+ if (expectedVersion === 'uninitialized') {
+ if (kvStore.has('initialized')) {
+ throw Error(`kernel DB already initialized (v0)`);
+ }
+ if (versionString) {
+ throw Error(`kernel DB already initialized (v${versionString})`);
+ }
+ } else if (expectedVersion !== version) {
+ throw Error(
+ `kernel DB is too old: has version v${version}, but expected v${expectedVersion}`,
+ );
+ } else {
+ // DB is up-to-date, so populate any caches we use
+ terminatedVats = JSON.parse(getRequired('vats.terminated'));
+ }
+
/**
* @param {string} key
* @returns {string}
@@ -233,12 +344,10 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
deviceKeepers: new Map(), // deviceID -> deviceKeeper
});
- function getInitialized() {
- return !!kvStore.get('initialized');
- }
-
function setInitialized() {
- kvStore.set('initialized', 'true');
+ assert(!kvStore.has('initialized'));
+ assert(!kvStore.has('version'));
+ kvStore.set('version', `${CURRENT_SCHEMA_VERSION}`);
}
function getCrankNumber() {
@@ -290,12 +399,17 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
}
/**
- * @param {KernelOptions} kernelOptions
+ * @param {InternalKernelOptions} kernelOptions
*/
function createStartingKernelState(kernelOptions) {
+ // this should probably be a standalone function, not a method
const {
defaultManagerType = 'local',
- defaultReapInterval = 1,
+ defaultReapDirtThreshold = {
+ deliveries: DEFAULT_DELIVERIES_PER_BOYD,
+ gcKrefs: DEFAULT_GC_KREFS_PER_BOYD,
+ computrons: 'never',
+ },
relaxDurabilityRules = false,
snapshotInitial = 3,
snapshotInterval = 200,
@@ -305,6 +419,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
kvStore.set('vat.dynamicIDs', '[]');
kvStore.set('vat.nextID', `${FIRST_VAT_ID}`);
kvStore.set('vat.nextUpgradeID', `1`);
+ kvStore.set('vats.terminated', '[]');
kvStore.set('device.names', '[]');
kvStore.set('device.nextID', `${FIRST_DEVICE_ID}`);
kvStore.set('ko.nextID', `${FIRST_OBJECT_ID}`);
@@ -317,7 +432,10 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
initQueue('acceptanceQueue');
kvStore.set('crankNumber', `${FIRST_CRANK_NUMBER}`);
kvStore.set('kernel.defaultManagerType', defaultManagerType);
- kvStore.set('kernel.defaultReapInterval', `${defaultReapInterval}`);
+ kvStore.set(
+ DEFAULT_REAP_DIRT_THRESHOLD_KEY,
+ JSON.stringify(defaultReapDirtThreshold),
+ );
kvStore.set('kernel.snapshotInitial', `${snapshotInitial}`);
kvStore.set('kernel.snapshotInterval', `${snapshotInterval}`);
if (relaxDurabilityRules) {
@@ -352,21 +470,25 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
/**
*
- * @returns {number | 'never'}
+ * @returns {ReapDirtThreshold}
*/
- function getDefaultReapInterval() {
- const r = getRequired('kernel.defaultReapInterval');
- const ri = r === 'never' ? r : Number.parseInt(r, 10);
- assert(ri === 'never' || typeof ri === 'number', `k.dri is '${ri}'`);
- return ri;
+ function getDefaultReapDirtThreshold() {
+ return JSON.parse(getRequired(DEFAULT_REAP_DIRT_THRESHOLD_KEY));
}
- function setDefaultReapInterval(interval) {
- assert(
- interval === 'never' || isNat(interval),
- 'invalid defaultReapInterval value',
- );
- kvStore.set('kernel.defaultReapInterval', `${interval}`);
+ /**
+ * @param {ReapDirtThreshold} threshold
+ */
+ function setDefaultReapDirtThreshold(threshold) {
+ assert.typeof(threshold, 'object');
+ assert(threshold);
+ for (const [key, value] of Object.entries(threshold)) {
+ assert(
+ (typeof value === 'number' && value > 0) || value === 'never',
+ `threshold[${key}] ${value} must be a positive number or "never"`,
+ );
+ }
+ kvStore.set(DEFAULT_REAP_DIRT_THRESHOLD_KEY, JSON.stringify(threshold));
}
function getNat(key) {
@@ -500,7 +622,9 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
function getObjectRefCount(kernelSlot) {
const data = kvStore.get(`${kernelSlot}.refCount`);
- data || Fail`getObjectRefCount(${kernelSlot}) was missing`;
+ if (!data) {
+ return { reachable: 0, recognizable: 0 };
+ }
const [reachable, recognizable] = commaSplit(data).map(Number);
reachable <= recognizable ||
Fail`refmismatch(get) ${kernelSlot} ${reachable},${recognizable}`;
@@ -578,19 +702,42 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
function ownerOfKernelObject(kernelSlot) {
insistKernelType('object', kernelSlot);
const owner = kvStore.get(`${kernelSlot}.owner`);
- if (owner) {
- insistVatID(owner);
+ if (!owner) {
+ return undefined;
+ }
+ insistVatID(owner);
+ if (terminatedVats.includes(owner)) {
+ return undefined;
}
return owner;
}
+ function retireKernelObjects(koids) {
+ Array.isArray(koids) || Fail`retireExports given non-Array ${koids}`;
+ const newActions = [];
+ for (const koid of koids) {
+ const importers = getImporters(koid);
+ for (const vatID of importers) {
+ newActions.push(`${vatID} retireImport ${koid}`);
+ }
+ deleteKernelObject(koid);
+ }
+ addGCActions(newActions);
+ }
+
function orphanKernelObject(kref, oldVat) {
+ // termination orphans all exports, upgrade orphans non-durable
+ // exports, and syscall.abandonExports orphans specific ones
const ownerKey = `${kref}.owner`;
const ownerVat = kvStore.get(ownerKey);
ownerVat === oldVat || Fail`export ${kref} not owned by old vat`;
kvStore.delete(ownerKey);
+ const { vatSlot: vref } = getReachableAndVatSlot(oldVat, kref);
+ kvStore.delete(`${oldVat}.c.${kref}`);
+ kvStore.delete(`${oldVat}.c.${vref}`);
+ addMaybeFreeKref(kref);
// note that we do not delete the object here: it will be
- // collected if/when all other references are dropped
+ // retired if/when all other references are dropped
}
function deleteKernelObject(koid) {
@@ -658,6 +805,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
p.decider = undefined;
}
p.policy = kvStore.get(`${kernelSlot}.policy`) || 'ignore';
+ // @ts-expect-error get() may fail
p.subscribers = commaSplit(kvStore.get(`${kernelSlot}.subscribers`));
p.queue = Array.from(
getPrefixedValues(kvStore, `${kernelSlot}.queue.`),
@@ -669,6 +817,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
p.refCount = Number(kvStore.get(`${kernelSlot}.refCount`));
p.data = {
body: kvStore.get(`${kernelSlot}.data.body`),
+ // @ts-expect-error get() may fail
slots: commaSplit(kvStore.get(`${kernelSlot}.data.slots`)),
};
for (const s of p.data.slots) {
@@ -764,7 +913,6 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
let idx = 0;
for (const dataSlot of capdata.slots) {
- // eslint-disable-next-line no-use-before-define
incrementRefCount(dataSlot, `resolve|${kernelSlot}|s${idx}`);
idx += 1;
}
@@ -785,14 +933,64 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
kvStore.set(`${kernelSlot}.data.slots`, capdata.slots.join(','));
}
- function cleanupAfterTerminatedVat(vatID) {
+ async function removeVatFromSwingStoreExports(vatID) {
+ // Delete primary swingstore records for this vat, in preparation
+ // for (slow) deletion. After this, swingstore exports will omit
+ // this vat. This is called from the kernel's terminateVat, which
+ // initiates (but does not complete) deletion.
+ snapStore.stopUsingLastSnapshot(vatID);
+ await transcriptStore.stopUsingTranscript(vatID);
+ }
+
+ /**
+ * Perform some cleanup work for a specific (terminated but not
+ * fully-deleted) vat, possibly limited by a budget. Returns 'done'
+ * (where false means "please call me again", and true means "you
+ * can delete the vatID now"), and a count of how much work was done
+ * (so the runPolicy can decide when to stop).
+ *
+ * @param {string} vatID
+ * @param {CleanupBudget} budget
+ * @returns {{ done: boolean, work: CleanupWork }}
+ *
+ */
+ function cleanupAfterTerminatedVat(vatID, budget) {
+ // this is called from terminateVat, which is called from either:
+ // * end of processDeliveryMessage, if crankResults.terminate
+ // * device-vat-admin (when vat-v-a does adminNode.terminateVat)
+ // (which always happens inside processDeliveryMessage)
+ // so we're always followed by a call to processRefcounts, at
+ // end-of-delivery in processDeliveryMessage, after checking
+ // crankResults.terminate
+
insistVatID(vatID);
- // eslint-disable-next-line no-use-before-define
- const vatKeeper = provideVatKeeper(vatID);
- const exportPrefix = `${vatID}.c.o+`;
- const importPrefix = `${vatID}.c.o-`;
+ const work = {
+ exports: 0,
+ imports: 0,
+ kv: 0,
+ snapshots: 0,
+ transcripts: 0,
+ };
+ let remaining = 0;
+
+ // TODO: it would be slightly cheaper to walk all kvStore keys in
+ // order, and act on each one according to its category (c-list
+ // export, c-list import, vatstore, other), so we use a single
+ // enumeratePrefixedKeys() call each time. Until we do that, the
+ // last phase of the cleanup (where we've deleted all the exports
+ // and imports, and are working on the remaining keys) will waste
+ // two DB queries on each call. OTOH, those queries will probably
+ // hit the same SQLite index page as the successful one, so it
+ // probably won't cause any extra disk IO. So we can defer this
+ // optimization for a while. Note: when we implement it, be
+ // prepared to encounter the clist entries in eiher order (kref
+ // first or vref first), and delete the other one in the same
+ // call, so we don't wind up with half an entry.
- vatKeeper.deleteSnapshotsAndTranscript();
+ const vatKeeper = provideVatKeeper(vatID);
+ const clistPrefix = `${vatID}.c.`;
+ const exportPrefix = `${clistPrefix}o+`;
+ const importPrefix = `${clistPrefix}o-`;
// Note: ASCII order is "+,-./", and we rely upon this to split the
// keyspace into the various o+NN/o-NN/etc spaces. If we were using a
@@ -808,6 +1006,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
// used.
// first, scan for exported objects, which must be orphaned
+ remaining = budget.exports ?? budget.default;
for (const k of enumeratePrefixedKeys(kvStore, exportPrefix)) {
// The void for an object exported by a vat will always be of the form
// `o+NN`. The '+' means that the vat exported the object (rather than
@@ -816,28 +1015,67 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
// begin with `vMM.c.o+`. In addition to deleting the c-list entry, we
// must also delete the corresponding kernel owner entry for the object,
// since the object will no longer be accessible.
+ const vref = stripPrefix(clistPrefix, k);
+ assert(vref.startsWith('o+'), vref);
const kref = kvStore.get(k);
+ // note: adds to maybeFreeKrefs, deletes c-list and .owner
orphanKernelObject(kref, vatID);
+ work.exports += 1;
+ remaining -= 1;
+ if (remaining <= 0) {
+ return { done: false, work };
+ }
}
// then scan for imported objects, which must be decrefed
+ remaining = budget.imports ?? budget.default;
for (const k of enumeratePrefixedKeys(kvStore, importPrefix)) {
// abandoned imports: delete the clist entry as if the vat did a
// drop+retire
const kref = kvStore.get(k) || Fail`getNextKey ensures get`;
- const vref = k.slice(`${vatID}.c.`.length);
+ const vref = stripPrefix(clistPrefix, k);
vatKeeper.deleteCListEntry(kref, vref);
// that will also delete both db keys
+ work.imports += 1;
+ remaining -= 1;
+ if (remaining <= 0) {
+ return { done: false, work };
+ }
}
// the caller used enumeratePromisesByDecider() before calling us,
// so they already know the orphaned promises to reject
// now loop back through everything and delete it all
+ remaining = budget.kv ?? budget.default;
for (const k of enumeratePrefixedKeys(kvStore, `${vatID}.`)) {
kvStore.delete(k);
+ work.kv += 1;
+ remaining -= 1;
+ if (remaining <= 0) {
+ return { done: false, work };
+ }
}
+ // this will internally loop through 'budget' deletions
+ remaining = budget.snapshots ?? budget.default;
+ const dsc = vatKeeper.deleteSnapshots(remaining);
+ work.snapshots += dsc.cleanups;
+ remaining -= dsc.cleanups;
+ if (remaining <= 0) {
+ return { done: false, work };
+ }
+
+ // same
+ remaining = budget.transcripts ?? budget.default;
+ const dts = vatKeeper.deleteTranscripts(remaining);
+ work.transcripts += dts.cleanups;
+ remaining -= dts.cleanups;
+ // last task, so increment cleanups, but dc.done is authoritative
+ return { done: dts.done, work };
+ }
+
+ function deleteVatID(vatID) {
// TODO: deleting entries from the dynamic vat IDs list requires a linear
// scan of the list; arguably this collection ought to be represented in a
// different way that makes it efficient to remove an entry from it, though
@@ -1102,15 +1340,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
kvStore.set(KEY, JSON.stringify(dynamicVatIDs));
}
- function getStaticVats() {
- const result = [];
- for (const k of enumeratePrefixedKeys(kvStore, 'vat.name.')) {
- const name = k.slice(9);
- const vatID = kvStore.get(k) || Fail`getNextKey ensures get`;
- result.push([name, vatID]);
- }
- return result;
- }
+ const getStaticVats = () => getAllStaticVats(kvStore);
function getDevices() {
const result = [];
@@ -1122,9 +1352,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
return result;
}
- function getDynamicVats() {
- return JSON.parse(getRequired('vat.dynamicIDs'));
- }
+ const getDynamicVats = () => getAllDynamicVats(getRequired);
function allocateUpgradeID() {
const nextID = Nat(BigInt(getRequired(`vat.nextUpgradeID`)));
@@ -1132,6 +1360,44 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
return makeUpgradeID(nextID);
}
+ function markVatAsTerminated(vatID) {
+ if (!terminatedVats.includes(vatID)) {
+ terminatedVats.push(vatID);
+ kvStore.set(`vats.terminated`, JSON.stringify(terminatedVats));
+ }
+ }
+
+ function getFirstTerminatedVat() {
+ if (terminatedVats.length) {
+ return terminatedVats[0];
+ }
+ return undefined;
+ }
+
+ function forgetTerminatedVat(vatID) {
+ terminatedVats = terminatedVats.filter(id => id !== vatID);
+ kvStore.set(`vats.terminated`, JSON.stringify(terminatedVats));
+ }
+
+ /**
+ * @param {PolicyOutputCleanupBudget} allowCleanup
+ * @returns {RunQueueEventCleanupTerminatedVat | undefined}
+ */
+ function nextCleanupTerminatedVatAction(allowCleanup) {
+ if (allowCleanup === false) {
+ return undefined;
+ } else {
+ const unlimited = { default: Infinity };
+ /** @type {CleanupBudget} */
+ const budget = allowCleanup === true ? unlimited : allowCleanup;
+ const vatID = getFirstTerminatedVat();
+ if (vatID) {
+ return { type: 'cleanup-terminated-vat', vatID, budget };
+ }
+ return undefined;
+ }
+ }
+
// As refcounts are decremented, we accumulate a set of krefs for which
// action might need to be taken:
// * promises which are now resolved and unreferenced can be deleted
@@ -1232,14 +1498,43 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
return false;
}
+ // TODO (#9888): change the processRefcounts maybeFreeKrefs
+ // iteration to handle krefs that get added multiple times (while
+ // we're iterating), because we might do different work the second
+ // time around. The concerning scenario is:
+ //
+ // * kp2 has resolution data which references ko1
+ // * somehow both kp2 and ko1 end up on maybeFreeKrefs, but ko1.reachable=1
+ // (via kp2)
+ // * our iterator visits ko1 first, sees it is still reachable, ignores it
+ // * then the iterator visits kp2, decrefs its kp.data.slots
+ // * this pushes ko1 back onto maybeFreeKrefs
+ // * we need to examine ko1 again, so it can be released
+ //
+ // It could also happen if/when we implement #2069 auxdata:
+ //
+ // * ko2 has auxdata that references ko1
+ // * both ko1 and ko2 end up on maybeFreeKrefs, but ko1.reachable = 1
+ // (via the ko2 auxdata)
+ // * our iterator visits ko1 first, sees it is still reachable, ignores it
+ // * then the iterator visits ko2, does deleteKernelObject
+ // * this frees the auxdata, which pushes ko1 back onto maybeFreeKrefs
+ // * we need to examine ko1 again, so it can be released
+ //
+ // We should use something like an ordered Set, and a loop that does:
+ // * pop the first kref off
+ // * processes it (maybe adding more krefs)
+ // * repeats until the thing is empty
+ // Or maybe make a copy of maybeFreeKrefs at the start, clear the
+ // original, and wrap this in a loop that keeps going until
+ // maybeFreeKrefs is still empty at the end. Be sure to imagine a
+ // very deep linked list: don't just process it twice, keep
+ // processing until there's nothing left to do, otherwise we'll be
+ // leaving work for the next delivery.
+
function processRefcounts() {
if (enableKernelGC) {
- const actions = getGCActions(); // local cache
- // TODO (else buggy): change the iteration to handle krefs that get
- // added multiple times (while we're iterating), because we might do
- // different work the second time around. Something like an ordered
- // Set, and a loop that: pops the first kref off, processes it (maybe
- // adding more krefs), repeats until the thing is empty.
+ const actions = new Set();
for (const kref of maybeFreeKrefs.values()) {
const { type } = parseKernelSlot(kref);
if (type === 'promise') {
@@ -1247,6 +1542,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
const kp = getKernelPromise(kpid);
if (kp.refCount === 0) {
let idx = 0;
+ // TODO (#9889) don't assume promise is settled
for (const slot of kp.data.slots) {
// Note: the following decrement can result in an addition to the
// maybeFreeKrefs set, which we are in the midst of iterating.
@@ -1257,46 +1553,89 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
deleteKernelPromise(kpid);
}
}
+
if (type === 'object') {
const { reachable, recognizable } = getObjectRefCount(kref);
if (reachable === 0) {
- const ownerVatID = ownerOfKernelObject(kref);
- if (ownerVatID) {
- // eslint-disable-next-line no-use-before-define
+ // We avoid ownerOfKernelObject(), which will report
+ // 'undefined' if the owner is dead (and being slowly
+ // deleted). Message delivery should use that, but not us.
+ const ownerKey = `${kref}.owner`;
+ let ownerVatID = kvStore.get(ownerKey);
+ const terminated = terminatedVats.includes(ownerVatID);
+
+ // Some objects that are still owned, but the owning vat
+ // might still alive, or might be terminated and in the
+ // process of being deleted. These two clauses are
+ // mutually exclusive.
+
+ if (ownerVatID && !terminated) {
const vatKeeper = provideVatKeeper(ownerVatID);
- const isReachable = vatKeeper.getReachableFlag(kref);
- if (isReachable) {
+ const vatConsidersReachable = vatKeeper.getReachableFlag(kref);
+ if (vatConsidersReachable) {
// the reachable count is zero, but the vat doesn't realize it
actions.add(`${ownerVatID} dropExport ${kref}`);
}
if (recognizable === 0) {
- // TODO: rethink this
- // assert.equal(isReachable, false, `${kref} is reachable but not recognizable`);
+ // TODO: rethink this assert
+ // assert.equal(vatConsidersReachable, false, `${kref} is reachable but not recognizable`);
actions.add(`${ownerVatID} retireExport ${kref}`);
}
- } else if (recognizable === 0) {
- // unreachable, unrecognizable, orphaned: delete the
- // empty refcount here, since we can't send a GC
- // action without an ownerVatID
- deleteKernelObject(kref);
+ } else if (ownerVatID && terminated) {
+ // When we're slowly deleting a vat, and one of its
+ // exports becomes unreferenced, we obviously must not
+ // send dropExports or retireExports into the dead vat.
+ // We fast-forward the abandonment that slow-deletion
+ // would have done, then treat the object as orphaned.
+
+ const { vatSlot } = getReachableAndVatSlot(ownerVatID, kref);
+ // delete directly, not orphanKernelObject(), which
+ // would re-submit to maybeFreeKrefs
+ kvStore.delete(ownerKey);
+ kvStore.delete(`${ownerVatID}.c.${kref}`);
+ kvStore.delete(`${ownerVatID}.c.${vatSlot}`);
+ // now fall through to the orphaned case
+ ownerVatID = undefined;
+ }
+
+ // Now handle objects which were orphaned. NOTE: this
+ // includes objects which were owned by a terminated (but
+ // not fully deleted) vat, where `ownerVatID` was cleared
+ // in the last line of that previous clause (the
+ // fall-through case). Don't try to change this `if
+ // (!ownerVatID)` into an `else if`: the two clauses are
+ // *not* mutually-exclusive.
+
+ if (!ownerVatID) {
+ // orphaned and unreachable, so retire it. If the kref
+ // is recognizable, then we need retireKernelObjects()
+ // to scan for importers and send retireImports (and
+ // delete), else we can call deleteKernelObject directly
+ if (recognizable) {
+ retireKernelObjects([kref]);
+ } else {
+ deleteKernelObject(kref);
+ }
}
}
}
}
- setGCActions(actions);
+ addGCActions([...actions]);
}
maybeFreeKrefs.clear();
}
+ function createVatState(vatID, source, options) {
+ initializeVatState(kvStore, transcriptStore, vatID, source, options);
+ }
+
function provideVatKeeper(vatID) {
insistVatID(vatID);
const found = ephemeral.vatKeepers.get(vatID);
if (found !== undefined) {
return found;
}
- if (!kvStore.has(`${vatID}.o.nextID`)) {
- initializeVatState(kvStore, transcriptStore, vatID);
- }
+ assert(kvStore.has(`${vatID}.o.nextID`), `${vatID} was not initialized`);
const vk = makeVatKeeper(
kvStore,
transcriptStore,
@@ -1314,6 +1653,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
incStat,
decStat,
getCrankNumber,
+ scheduleReap,
snapStore,
);
ephemeral.vatKeepers.set(vatID, vk);
@@ -1322,7 +1662,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
function vatIsAlive(vatID) {
insistVatID(vatID);
- return kvStore.has(`${vatID}.o.nextID`);
+ return kvStore.has(`${vatID}.o.nextID`) && !terminatedVats.includes(vatID);
}
/**
@@ -1530,13 +1870,13 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
}
return harden({
- getInitialized,
setInitialized,
createStartingKernelState,
getDefaultManagerType,
- getDefaultReapInterval,
getRelaxDurabilityRules,
- setDefaultReapInterval,
+ getDefaultReapDirtThreshold,
+ setDefaultReapDirtThreshold,
+
getSnapshotInitial,
getSnapshotInterval,
setSnapshotInterval,
@@ -1570,6 +1910,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
kernelObjectExists,
getImporters,
orphanKernelObject,
+ retireKernelObjects,
deleteKernelObject,
pinObject,
@@ -1610,14 +1951,22 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
getVatIDForName,
allocateVatIDForNameIfNeeded,
allocateUnusedVatID,
+ createVatState,
provideVatKeeper,
vatIsAlive,
evictVatKeeper,
+ removeVatFromSwingStoreExports,
cleanupAfterTerminatedVat,
addDynamicVatID,
getDynamicVats,
getStaticVats,
getDevices,
+ deleteVatID,
+
+ markVatAsTerminated,
+ getFirstTerminatedVat,
+ forgetTerminatedVat,
+ nextCleanupTerminatedVatAction,
allocateUpgradeID,
@@ -1635,3 +1984,4 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
dump,
});
}
+/** @typedef {ReturnType} KernelKeeper */
diff --git a/packages/SwingSet/src/kernel/state/vatKeeper.js b/packages/SwingSet/src/kernel/state/vatKeeper.js
index 2d6312c7c4c..7322f34ee37 100644
--- a/packages/SwingSet/src/kernel/state/vatKeeper.js
+++ b/packages/SwingSet/src/kernel/state/vatKeeper.js
@@ -1,8 +1,9 @@
/**
* Kernel's keeper of persistent state for a vat.
*/
-import { Nat, isNat } from '@endo/nat';
+import { Nat } from '@endo/nat';
import { assert, q, Fail } from '@endo/errors';
+import { isObject } from '@endo/marshal';
import { parseKernelSlot } from '../parseKernelSlots.js';
import { makeVatSlot, parseVatSlot } from '../../lib/parseVatSlots.js';
import { insistVatID } from '../../lib/id.js';
@@ -18,7 +19,9 @@ import { enumeratePrefixedKeys } from './storageHelper.js';
* @typedef { import('../../types-external.js').SnapStore } SnapStore
* @typedef { import('../../types-external.js').SourceOfBundle } SourceOfBundle
* @typedef { import('../../types-external.js').TranscriptStore } TranscriptStore
+ * @typedef { import('../../types-internal.js').Dirt } Dirt
* @typedef { import('../../types-internal.js').VatManager } VatManager
+ * @typedef { import('../../types-internal.js').ReapDirtThreshold } ReapDirtThreshold
* @typedef { import('../../types-internal.js').RecordedVatOptions } RecordedVatOptions
* @typedef { import('../../types-internal.js').TranscriptEntry } TranscriptEntry
* @import {TranscriptDeliverySaveSnapshot} from '../../types-internal.js'
@@ -32,18 +35,50 @@ const FIRST_OBJECT_ID = 50n;
const FIRST_PROMISE_ID = 60n;
const FIRST_DEVICE_ID = 70n;
+// TODO: we export this from vatKeeper.js, and import it from
+// kernelKeeper.js, because both files need it, and we want to avoid
+// an import cycle (kernelKeeper imports other things from vatKeeper),
+// but it really wants to live in kernelKeeper not vatKeeper
+export const DEFAULT_REAP_DIRT_THRESHOLD_KEY =
+ 'kernel.defaultReapDirtThreshold';
+
+const isBundleSource = source => {
+ return (
+ isObject(source) &&
+ (isObject(source.bundle) ||
+ typeof source.bundleName === 'string' ||
+ typeof source.bundleID === 'string')
+ );
+};
+
/**
* Establish a vat's state.
*
* @param {*} kvStore The key-value store in which the persistent state will be kept
* @param {*} transcriptStore Accompanying transcript store
* @param {string} vatID The vat ID string of the vat in question
- * TODO: consider making this part of makeVatKeeper
+ * @param {SourceOfBundle} source
+ * @param {RecordedVatOptions} options
*/
-export function initializeVatState(kvStore, transcriptStore, vatID) {
+export function initializeVatState(
+ kvStore,
+ transcriptStore,
+ vatID,
+ source,
+ options,
+) {
+ assert(isBundleSource(source), `vat ${vatID} source has wrong shape`);
+ assert(
+ isObject(options) && isObject(options.workerOptions),
+ `vat ${vatID} options is missing workerOptions`,
+ );
+
kvStore.set(`${vatID}.o.nextID`, `${FIRST_OBJECT_ID}`);
kvStore.set(`${vatID}.p.nextID`, `${FIRST_PROMISE_ID}`);
kvStore.set(`${vatID}.d.nextID`, `${FIRST_DEVICE_ID}`);
+ kvStore.set(`${vatID}.reapDirt`, JSON.stringify({}));
+ kvStore.set(`${vatID}.source`, JSON.stringify(source));
+ kvStore.set(`${vatID}.options`, JSON.stringify(options));
transcriptStore.initTranscript(vatID);
}
@@ -68,6 +103,7 @@ export function initializeVatState(kvStore, transcriptStore, vatID) {
* @param {*} incStat
* @param {*} decStat
* @param {*} getCrankNumber
+ * @param {*} scheduleReap
* @param {SnapStore} [snapStore]
* returns an object to hold and access the kernel's state for the given vat
*/
@@ -88,10 +124,16 @@ export function makeVatKeeper(
incStat,
decStat,
getCrankNumber,
+ scheduleReap,
snapStore = undefined,
) {
insistVatID(vatID);
+ // note: calling makeVatKeeper() does not change the DB. Any
+ // initialization or upgrade must be complete before it is
+ // called. Only the methods returned by makeVatKeeper() will change
+ // the DB.
+
function getRequired(key) {
const value = kvStore.get(key);
if (value === undefined) {
@@ -100,6 +142,8 @@ export function makeVatKeeper(
return value;
}
+ const reapDirtKey = `${vatID}.reapDirt`;
+
/**
* @param {SourceOfBundle} source
* @param {RecordedVatOptions} options
@@ -125,45 +169,80 @@ export function makeVatKeeper(
function getOptions() {
/** @type { RecordedVatOptions } */
- const options = JSON.parse(kvStore.get(`${vatID}.options`) || '{}');
+ const options = JSON.parse(getRequired(`${vatID}.options`));
return harden(options);
}
- function initializeReapCountdown(count) {
- count === 'never' || isNat(count) || Fail`bad reapCountdown ${count}`;
- kvStore.set(`${vatID}.reapInterval`, `${count}`);
- kvStore.set(`${vatID}.reapCountdown`, `${count}`);
- }
+ // This is named "addDirt" because it should increment all dirt
+ // counters (both for reap/BOYD and for heap snapshotting). We don't
+ // have `heapSnapshotDirt` yet, but when we do, it should get
+ // incremented here.
- function updateReapInterval(reapInterval) {
- reapInterval === 'never' ||
- isNat(reapInterval) ||
- Fail`bad reapInterval ${reapInterval}`;
- kvStore.set(`${vatID}.reapInterval`, `${reapInterval}`);
- if (reapInterval === 'never') {
- kvStore.set(`${vatID}.reapCountdown`, 'never');
+ /**
+ * Add some "dirt" to the vat, possibly triggering a reap/BOYD.
+ *
+ * @param {Dirt} moreDirt
+ */
+ function addDirt(moreDirt) {
+ assert.typeof(moreDirt, 'object');
+ const reapDirt = JSON.parse(getRequired(reapDirtKey));
+ const thresholds = {
+ ...JSON.parse(getRequired(DEFAULT_REAP_DIRT_THRESHOLD_KEY)),
+ ...JSON.parse(getRequired(`${vatID}.options`)).reapDirtThreshold,
+ };
+ let reap = false;
+ for (const key of Object.keys(moreDirt)) {
+ const threshold = thresholds[key];
+ // Don't accumulate dirt if it can't eventually trigger a
+ // BOYD. This is mainly to keep comms from counting upwards
+ // forever. TODO revisit this when we add heapSnapshotDirt,
+ // maybe check both thresholds and accumulate the dirt if either
+ // one is non-'never'.
+ if (threshold && threshold !== 'never') {
+ const oldDirt = reapDirt[key] || 0;
+ // The 'moreDirt' value might be Number or BigInt (eg
+ // .computrons). We coerce to Number so we can JSON-stringify.
+ const newDirt = oldDirt + Number(moreDirt[key]);
+ reapDirt[key] = newDirt;
+ if (newDirt >= threshold) {
+ reap = true;
+ }
+ }
}
- }
-
- function countdownToReap() {
- const rawCount = getRequired(`${vatID}.reapCountdown`);
- if (rawCount === 'never') {
- return false;
- } else {
- const count = Number.parseInt(rawCount, 10);
- if (count === 1) {
- kvStore.set(
- `${vatID}.reapCountdown`,
- getRequired(`${vatID}.reapInterval`),
- );
- return true;
- } else {
- kvStore.set(`${vatID}.reapCountdown`, `${count - 1}`);
- return false;
+ if (!thresholds.never) {
+ kvStore.set(reapDirtKey, JSON.stringify(reapDirt));
+ if (reap) {
+ scheduleReap(vatID);
}
}
}
+ function getReapDirt() {
+ return JSON.parse(getRequired(reapDirtKey));
+ }
+
+ function clearReapDirt() {
+ // This is only called after a BOYD, so it should only clear the
+ // reap/BOYD counters. If/when we add heap-snapshot counters,
+ // those should get cleared in a separate clearHeapSnapshotDirt()
+ // function.
+ const reapDirt = {};
+ kvStore.set(reapDirtKey, JSON.stringify(reapDirt));
+ }
+
+ function getReapDirtThreshold() {
+ return getOptions().reapDirtThreshold;
+ }
+
+ /**
+ * @param {ReapDirtThreshold} reapDirtThreshold
+ */
+ function setReapDirtThreshold(reapDirtThreshold) {
+ assert.typeof(reapDirtThreshold, 'object');
+ const options = { ...getOptions(), reapDirtThreshold };
+ kvStore.set(`${vatID}.options`, JSON.stringify(options));
+ }
+
function nextDeliveryNum() {
const { endPos } = transcriptStore.getCurrentSpanBounds(vatID);
return Nat(endPos);
@@ -576,7 +655,7 @@ export function makeVatKeeper(
addToTranscript(makeSaveSnapshotItem(snapshotID));
// then start a new transcript span
- transcriptStore.rolloverSpan(vatID);
+ await transcriptStore.rolloverSpan(vatID);
// then push a load-snapshot entry, so that the current span
// always starts with an initialize-worker or load-snapshot
@@ -596,14 +675,47 @@ export function makeVatKeeper(
});
}
- function deleteSnapshotsAndTranscript() {
- if (snapStore) {
- snapStore.deleteVatSnapshots(vatID);
+ /**
+ * Perform some (possibly-limited) cleanup work for a vat. Returns
+ * 'done' (where false means "please call me again", and true means
+ * "you can delete the vatID now"), and a count of how much work was
+ * done (so the runPolicy can decide when to stop).
+ *
+ * @param {number} [budget]
+ * @returns {{ done: boolean, cleanups: number }}
+ *
+ */
+ function deleteSnapshots(budget = undefined) {
+ // Each budget=1 allows us to delete one snapshot entry.
+ if (!snapStore) {
+ return { done: true, cleanups: 0 };
}
- transcriptStore.deleteVatTranscripts(vatID);
+ // initially uses 2+2*budget DB statements, then just 1 when done
+ return snapStore.deleteVatSnapshots(vatID, budget);
+ }
+
+ /**
+ * Perform some (possibly-limited) cleanup work for a vat. Returns
+ * 'done' (where false means "please call me again", and true means
+ * "you can delete the vatID now"), and a count of how much work was
+ * done (so the runPolicy can decide when to stop).
+ *
+ * @param {number} [budget]
+ * @returns {{ done: boolean, cleanups: number }}
+ *
+ */
+ function deleteTranscripts(budget = undefined) {
+ // Each budget=1 allows us to delete one transcript span and any
+ // transcript items associated with that span. Some nodes will
+ // have historical transcript items, some will not. Using budget=5
+ // and snapshotInterval=200 means we delete 5 span records and
+ // maybe 1000 span items.
+
+ // initially uses 2+3*budget DB statements, then just 1 when done
+ return transcriptStore.deleteVatTranscripts(vatID, budget);
}
- function beginNewIncarnation() {
+ async function beginNewIncarnation() {
if (snapStore) {
snapStore.stopUsingLastSnapshot(vatID);
}
@@ -656,9 +768,11 @@ export function makeVatKeeper(
setSourceAndOptions,
getSourceAndOptions,
getOptions,
- initializeReapCountdown,
- countdownToReap,
- updateReapInterval,
+ addDirt,
+ getReapDirt,
+ clearReapDirt,
+ getReapDirtThreshold,
+ setReapDirtThreshold,
nextDeliveryNum,
getIncarnationNumber,
importsKernelSlot,
@@ -680,7 +794,8 @@ export function makeVatKeeper(
dumpState,
saveSnapshot,
getSnapshotInfo,
- deleteSnapshotsAndTranscript,
+ deleteSnapshots,
+ deleteTranscripts,
beginNewIncarnation,
});
}
diff --git a/packages/SwingSet/src/kernel/vat-admin-hooks.js b/packages/SwingSet/src/kernel/vat-admin-hooks.js
index affff0758b5..b72f10a6cc4 100644
--- a/packages/SwingSet/src/kernel/vat-admin-hooks.js
+++ b/packages/SwingSet/src/kernel/vat-admin-hooks.js
@@ -94,6 +94,9 @@ export function makeVatAdminHooks(tools) {
// we don't need to incrementRefCount because if terminateVat sends
// 'reason' to vat-admin, it uses notifyTermination / queueToKref /
// doSend, and doSend() does its own incref
+ // FIXME: This assumes that most work of terminateVat happens in the
+ // synchronous prelude, which should be made more obvious. For details,
+ // see https://github.com/Agoric/agoric-sdk/pull/10055#discussion_r1754918394
void terminateVat(vatID, true, marshalledReason);
// TODO: terminateVat is async, result doesn't fire until worker
// is dead. To fix this we'll probably need to move termination
diff --git a/packages/SwingSet/src/kernel/vat-loader/manager-factory.js b/packages/SwingSet/src/kernel/vat-loader/manager-factory.js
index 2b8de555d9c..cb1b28c68c9 100644
--- a/packages/SwingSet/src/kernel/vat-loader/manager-factory.js
+++ b/packages/SwingSet/src/kernel/vat-loader/manager-factory.js
@@ -45,7 +45,6 @@ export function makeVatManagerFactory({
'enableSetup',
'useTranscript',
'critical',
- 'reapInterval',
'sourcedConsole',
'name',
]);
diff --git a/packages/SwingSet/src/kernel/vat-loader/vat-loader.js b/packages/SwingSet/src/kernel/vat-loader/vat-loader.js
index 34fc179af0d..c67fb97fa9c 100644
--- a/packages/SwingSet/src/kernel/vat-loader/vat-loader.js
+++ b/packages/SwingSet/src/kernel/vat-loader/vat-loader.js
@@ -26,7 +26,7 @@ export function makeVatLoader(stuff) {
'enablePipelining',
'useTranscript',
'critical',
- 'reapInterval',
+ 'reapDirtThreshold',
];
/**
diff --git a/packages/SwingSet/src/kernel/vat-warehouse.js b/packages/SwingSet/src/kernel/vat-warehouse.js
index 9dc8903c713..2d4a167c398 100644
--- a/packages/SwingSet/src/kernel/vat-warehouse.js
+++ b/packages/SwingSet/src/kernel/vat-warehouse.js
@@ -544,6 +544,10 @@ export function makeVatWarehouse({
vatKeeper.addToTranscript(getTranscriptEntry(vd, deliveryResult));
}
+ if (kd[0] === 'bringOutYourDead') {
+ vatKeeper.clearReapDirt(); // BOYD zeros out the when-to-BOYD counters
+ }
+
// TODO: if per-vat policy decides it wants a BOYD or heap snapshot,
// now is the time to do it, or to ask the kernel to schedule it
diff --git a/packages/SwingSet/src/kernel/vatTranslator.js b/packages/SwingSet/src/kernel/vatTranslator.js
index 4f1d1e2aa08..d781a41cf38 100644
--- a/packages/SwingSet/src/kernel/vatTranslator.js
+++ b/packages/SwingSet/src/kernel/vatTranslator.js
@@ -481,9 +481,6 @@ function makeTranslateVatSyscallToKernelSyscall(vatID, kernelKeeper) {
assert.equal(allocatedByVat, true); // abandon *exports*, not imports
// kref must already be in the clist
const kref = mapVatSlotToKernelSlot(vref, gcSyscallMapOpts);
- // note that this is effectful and also performed outside of a syscall
- // by processUpgradeVat in {@link ./kernel.js}
- vatKeeper.deleteCListEntry(kref, vref);
return kref;
});
kdebug(`syscall[${vatID}].abandonExports(${krefs.join(' ')})`);
diff --git a/packages/SwingSet/src/lib/recordVatOptions.js b/packages/SwingSet/src/lib/recordVatOptions.js
index 09b8e9c759a..f3c6c19c0a5 100644
--- a/packages/SwingSet/src/lib/recordVatOptions.js
+++ b/packages/SwingSet/src/lib/recordVatOptions.js
@@ -10,7 +10,9 @@ export const makeVatOptionRecorder = (kernelKeeper, bundleHandler) => {
enablePipelining = false,
enableDisavow = false,
useTranscript = true,
- reapInterval = kernelKeeper.getDefaultReapInterval(),
+ reapInterval,
+ reapGCKrefs,
+ neverReap = false,
critical = false,
meterID = undefined,
managerType = kernelKeeper.getDefaultManagerType(),
@@ -21,6 +23,17 @@ export const makeVatOptionRecorder = (kernelKeeper, bundleHandler) => {
if (unused.length) {
Fail`OptionRecorder: ${vatID} unused options ${unused.join(',')}`;
}
+ const reapDirtThreshold = {};
+ if (reapInterval !== undefined) {
+ reapDirtThreshold.deliveries = reapInterval;
+ }
+ if (reapGCKrefs !== undefined) {
+ reapDirtThreshold.gcKrefs = reapGCKrefs;
+ }
+ if (neverReap) {
+ reapDirtThreshold.never = true;
+ }
+ // TODO no computrons knob?
const workerOptions = await makeWorkerOptions(
managerType,
bundleHandler,
@@ -35,13 +48,12 @@ export const makeVatOptionRecorder = (kernelKeeper, bundleHandler) => {
enablePipelining,
enableDisavow,
useTranscript,
- reapInterval,
+ reapDirtThreshold,
critical,
meterID,
});
- const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
- vatKeeper.setSourceAndOptions(source, vatOptions);
- vatKeeper.initializeReapCountdown(vatOptions.reapInterval);
+ // want vNN.options to be in place before provideVatKeeper, so it can cache reapDirtThreshold in RAM, so:
+ kernelKeeper.createVatState(vatID, source, vatOptions);
};
/**
diff --git a/packages/SwingSet/src/lib/runPolicies.js b/packages/SwingSet/src/lib/runPolicies.js
index 2b54eace7af..e0770c4b8d8 100644
--- a/packages/SwingSet/src/lib/runPolicies.js
+++ b/packages/SwingSet/src/lib/runPolicies.js
@@ -3,6 +3,9 @@ import { assert } from '@endo/errors';
export function foreverPolicy() {
/** @type { RunPolicy } */
return harden({
+ allowCleanup() {
+ return true; // unlimited budget
+ },
vatCreated(_details) {
return true;
},
@@ -27,6 +30,9 @@ export function crankCounter(
let vats = 0;
/** @type { RunPolicy } */
const policy = harden({
+ allowCleanup() {
+ return { default: 100 }; // limited budget
+ },
vatCreated() {
vats += 1;
return vats < maxCreateVats;
@@ -47,13 +53,21 @@ export function crankCounter(
return policy;
}
-export function computronCounter(limit) {
+export function computronCounter(limit, options = {}) {
assert.typeof(limit, 'bigint');
+ const {
+ cleanupBudget = 100,
+ vatCreatedComputrons = 100_000n, // pretend that's the cost
+ crankFailedComputrons = 1_000_000n,
+ } = options;
let total = 0n;
/** @type { RunPolicy } */
const policy = harden({
+ allowCleanup() {
+ return { default: cleanupBudget }; // limited budget
+ },
vatCreated() {
- total += 100000n; // pretend vat creation takes 100k computrons
+ total += vatCreatedComputrons;
return total < limit;
},
crankComplete(details = {}) {
@@ -65,7 +79,7 @@ export function computronCounter(limit) {
return total < limit;
},
crankFailed() {
- total += 1000000n; // who knows, 1M is as good as anything
+ total += crankFailedComputrons;
return total < limit;
},
emptyCrank() {
@@ -79,6 +93,7 @@ export function wallClockWaiter(seconds) {
const timeout = Date.now() + 1000 * seconds;
/** @type { RunPolicy } */
const policy = harden({
+ allowCleanup: () => true, // unlimited budget
vatCreated: () => Date.now() < timeout,
crankComplete: () => Date.now() < timeout,
crankFailed: () => Date.now() < timeout,
@@ -86,3 +101,34 @@ export function wallClockWaiter(seconds) {
});
return policy;
}
+
+export function noCleanup() {
+ /** @type { RunPolicy } */
+ const policy = harden({
+ allowCleanup: () => false,
+ vatCreated: () => true,
+ crankComplete: () => true,
+ crankFailed: () => true,
+ emptyCrank: () => true,
+ });
+ return policy;
+}
+
+export function someCleanup(budget) {
+ let once = true;
+ /** @type { RunPolicy } */
+ const policy = harden({
+ allowCleanup: () => {
+ if (once) {
+ once = false;
+ return { default: budget };
+ }
+ return false;
+ },
+ vatCreated: () => true,
+ crankComplete: () => true,
+ crankFailed: () => true,
+ emptyCrank: () => true,
+ });
+ return policy;
+}
diff --git a/packages/SwingSet/src/types-external.js b/packages/SwingSet/src/types-external.js
index a62c411bd6b..e04f1313e6a 100644
--- a/packages/SwingSet/src/types-external.js
+++ b/packages/SwingSet/src/types-external.js
@@ -28,14 +28,14 @@ export {};
*/
/**
- * @typedef {{
- * defaultManagerType?: ManagerType,
- * defaultReapInterval?: number | 'never',
- * relaxDurabilityRules?: boolean,
- * snapshotInitial?: number,
- * snapshotInterval?: number,
- * pinBootstrapRoot?: boolean,
- * }} KernelOptions
+ * @typedef {object} KernelOptions
+ * @property {ManagerType} [defaultManagerType]
+ * @property {number | 'never'} [defaultReapGCKrefs]
+ * @property {number | 'never'} [defaultReapInterval]
+ * @property {boolean} [relaxDurabilityRules]
+ * @property {number} [snapshotInitial]
+ * @property {number} [snapshotInterval]
+ * @property {boolean} [pinBootstrapRoot]
*/
/**
@@ -124,7 +124,7 @@ export {};
*
* @typedef { { transcriptCount: number } } VatStats
* @typedef { ReturnType } VatKeeper
- * @typedef { ReturnType } KernelKeeper
+ * @typedef { import('./kernel/state/kernelKeeper.js').KernelKeeper } KernelKeeper
* @typedef { Awaited> } XSnap
* @typedef { (dr: VatDeliveryResult) => void } SlogFinishDelivery
* @typedef { (ksr: KernelSyscallResult, vsr: VatSyscallResult) => void } SlogFinishSyscall
@@ -167,6 +167,7 @@ export {};
* bundleName: string
* }} BundleName
* @typedef {(SourceSpec | BundleSpec | BundleRef | BundleName ) & {
+ * bundleID?: BundleID,
* creationOptions?: Record,
* parameters?: Record,
* }} SwingSetConfigProperties
@@ -218,19 +219,65 @@ export {};
*/
/**
+ * PolicyInput is used internally within kernel.js, returned by each
+ * message processor, and used to decide which of the host's runPolicy
+ * methods to invoke. The 'details' portion of PolicyInput is passed
+ * as an argument to those methods, so those types are
+ * externally-visible.
+ *
+ * @typedef { { exports: number,
+ * imports: number,
+ * kv: number,
+ * snapshots: number,
+ * transcripts: number,
+ * } } CleanupWork
+ *
+ * @typedef { { total: number } & CleanupWork } PolicyInputCleanupCounts
+ * @typedef { { cleanups: PolicyInputCleanupCounts, computrons?: bigint } } PolicyInputCleanupDetails
* @typedef { { computrons?: bigint } } PolicyInputDetails
+ *
* @typedef { [tag: 'none', details: PolicyInputDetails ] } PolicyInputNone
* @typedef { [tag: 'create-vat', details: PolicyInputDetails ]} PolicyInputCreateVat
* @typedef { [tag: 'crank', details: PolicyInputDetails ] } PolicyInputCrankComplete
* @typedef { [tag: 'crank-failed', details: PolicyInputDetails ]} PolicyInputCrankFailed
- * @typedef { PolicyInputNone | PolicyInputCreateVat | PolicyInputCrankComplete | PolicyInputCrankFailed } PolicyInput
- * @typedef { boolean } PolicyOutput
- * @typedef { { vatCreated: (details: {}) => PolicyOutput,
+ * @typedef { [tag: 'cleanup', details: PolicyInputCleanupDetails] } PolicyInputCleanup
+ *
+ * @typedef { PolicyInputNone | PolicyInputCreateVat | PolicyInputCrankComplete |
+ * PolicyInputCrankFailed | PolicyInputCleanup } PolicyInput
+ *
+ * CleanupBudget is the internal record used to limit the slow
+ * deletion of terminated vats. Each property limits the number of
+ * deletions per 'cleanup-terminated-vat' run-queue event, for a
+ * specific phase (imports, exports, snapshots, etc). It must always
+ * have a 'default' property, which is used for phases that aren't
+ * otherwise specified.
+ *
+ * @typedef { { default: number } & Partial } CleanupBudget
+ *
+ * PolicyOutputCleanupBudget is the return value of
+ * runPolicy.allowCleanup(), and tells the kernel how much it is
+ * allowed to clean up. It is either a CleanupBudget, or 'true' to
+ * allow unlimited cleanup, or 'false' to forbid any cleanup.
+ *
+ * @typedef {CleanupBudget | true | false} PolicyOutputCleanupBudget
+ *
+ * PolicyOutput is the boolean returned by all the other runPolicy
+ * methods, where 'true' means "keep going", and 'false' means "stop
+ * now".
+ *
+ * @typedef {boolean} PolicyOutput
+ *
+ * @typedef { {
+ * allowCleanup?: () => boolean | PolicyOutputCleanupBudget,
+ * vatCreated: (details: {}) => PolicyOutput,
* crankComplete: (details: { computrons?: bigint }) => PolicyOutput,
* crankFailed: (details: {}) => PolicyOutput,
* emptyCrank: () => PolicyOutput,
+ * didCleanup?: (details: PolicyInputCleanupDetails) => PolicyOutput,
* } } RunPolicy
- *
+ */
+
+/**
* @typedef {object} VatWarehousePolicy
* @property { number } [maxVatsOnline] Limit the number of simultaneous workers
* @property { boolean } [restartWorkerOnSnapshot] Reload worker immediately upon snapshot creation
@@ -292,13 +339,15 @@ export {};
* reconstructed via replay. If false, no such record is kept.
* Defaults to true.
* @property { number | 'never' } [reapInterval]
- * The interval (measured in number of deliveries to the vat)
- * after which the kernel will deliver the 'bringOutYourDead'
- * directive to the vat. If the value is 'never',
- * 'bringOutYourDead' will never be delivered and the vat will
- * be responsible for internally managing (in a deterministic
- * manner) any visible effects of garbage collection. Defaults
- * to the kernel's configured 'defaultReapInterval' value.
+ * Trigger a bringOutYourDead after the vat has received
+ * this many deliveries. If the value is 'never',
+ * 'bringOutYourDead' will not be triggered by a delivery
+ * count (but might be triggered for other reasons).
+ * @property { number | 'never' } [reapGCKrefs]
+ * Trigger a bringOutYourDead when the vat has been given
+ * this many krefs in GC deliveries (dropImports,
+ * retireImports, retireExports). If the value is 'never',
+ * GC deliveries and their krefs are not treated specially.
* @property { boolean } [critical]
*/
diff --git a/packages/SwingSet/src/types-internal.js b/packages/SwingSet/src/types-internal.js
index 9140db5b5ec..1ef68a5735f 100644
--- a/packages/SwingSet/src/types-internal.js
+++ b/packages/SwingSet/src/types-internal.js
@@ -1,6 +1,19 @@
export {};
/**
+ * The host provides (external) KernelOptions as part of the
+ * SwingSetConfig record it passes to initializeSwingset(). This
+ * internal type represents the modified form passed to
+ * initializeKernel() and kernelKeeper.createStartingKernelState .
+ *
+ * @typedef {object} InternalKernelOptions
+ * @property {ManagerType} [defaultManagerType]
+ * @property {ReapDirtThreshold} [defaultReapDirtThreshold]
+ * @property {boolean} [relaxDurabilityRules]
+ * @property {number} [snapshotInitial]
+ * @property {number} [snapshotInterval]
+ *
+ *
* The internal data that controls which worker we use (and how we use it) is
* stored in a WorkerOptions record, which comes in "local", "node-subprocess",
* and "xsnap" flavors.
@@ -35,11 +48,48 @@ export {};
* @property { boolean } enableSetup
* @property { boolean } enablePipelining
* @property { boolean } useTranscript
- * @property { number | 'never' } reapInterval
+ * @property { ReapDirtThreshold } reapDirtThreshold
* @property { boolean } critical
* @property { MeterID } [meterID] // property must be present, but can be undefined
* @property { WorkerOptions } workerOptions
* @property { boolean } enableDisavow
+ *
+ * @typedef ChangeVatOptions
+ * @property {number} [reapInterval]
+ */
+
+/**
+ * Reap/BringOutYourDead/BOYD Scheduling
+ *
+ * We trigger a BringOutYourDead delivery (which "reaps" all dead
+ * objects from the vat) after a certain threshold of "dirt" has
+ * accumulated. This type is used to define the thresholds for three
+ * counters: 'deliveries', 'gcKrefs', and 'computrons'. If a property
+ * is a number, we trigger BOYD when the counter for that property
+ * exceeds the threshold value. If a property is the string 'never' or
+ * missing we do not use that counter to trigger BOYD.
+ *
+ * Each vat has a .reapDirtThreshold in their vNN.options record,
+ * which overrides the kernel-wide settings in
+ * 'kernel.defaultReapDirtThreshold'
+ *
+ * @typedef {object} ReapDirtThreshold
+ * @property {number | 'never'} [deliveries]
+ * @property {number | 'never'} [gcKrefs]
+ * @property {number | 'never'} [computrons]
+ * @property {boolean} [never]
+ */
+
+/**
+ * Each counter in Dirt matches a threshold in
+ * ReapDirtThreshold. Missing values are treated as zero, so vats
+ * start with {} and accumulate dirt as deliveries are made, until a
+ * BOYD clears them.
+ *
+ * @typedef {object} Dirt
+ * @property {number} [deliveries]
+ * @property {number} [gcKrefs]
+ * @property {number} [computrons]
*/
/**
@@ -86,17 +136,20 @@ export {};
* @typedef { { type: 'upgrade-vat', vatID: VatID, upgradeID: string,
* bundleID: BundleID, vatParameters: SwingSetCapData,
* upgradeMessage: string } } RunQueueEventUpgradeVat
- * @typedef { { type: 'changeVatOptions', vatID: VatID, options: Record } } RunQueueEventChangeVatOptions
+ * @typedef { { type: 'changeVatOptions', vatID: VatID, options: ChangeVatOptions } } RunQueueEventChangeVatOptions
* @typedef { { type: 'startVat', vatID: VatID, vatParameters: SwingSetCapData } } RunQueueEventStartVat
* @typedef { { type: 'dropExports', vatID: VatID, krefs: string[] } } RunQueueEventDropExports
* @typedef { { type: 'retireExports', vatID: VatID, krefs: string[] } } RunQueueEventRetireExports
* @typedef { { type: 'retireImports', vatID: VatID, krefs: string[] } } RunQueueEventRetireImports
* @typedef { { type: 'negated-gc-action', vatID?: VatID } } RunQueueEventNegatedGCAction
* @typedef { { type: 'bringOutYourDead', vatID: VatID } } RunQueueEventBringOutYourDead
+ * @import {CleanupBudget} from './types-external.js';
+ * @typedef { { type: 'cleanup-terminated-vat', vatID: VatID,
+ * budget: CleanupBudget } } RunQueueEventCleanupTerminatedVat
* @typedef { RunQueueEventNotify | RunQueueEventSend | RunQueueEventCreateVat |
* RunQueueEventUpgradeVat | RunQueueEventChangeVatOptions | RunQueueEventStartVat |
* RunQueueEventDropExports | RunQueueEventRetireExports | RunQueueEventRetireImports |
- * RunQueueEventNegatedGCAction | RunQueueEventBringOutYourDead
+ * RunQueueEventNegatedGCAction | RunQueueEventBringOutYourDead | RunQueueEventCleanupTerminatedVat
* } RunQueueEvent
*/
diff --git a/packages/SwingSet/src/vats/vat-admin/vat-vat-admin.js b/packages/SwingSet/src/vats/vat-admin/vat-vat-admin.js
index 058692f036a..965fcb47864 100644
--- a/packages/SwingSet/src/vats/vat-admin/vat-vat-admin.js
+++ b/packages/SwingSet/src/vats/vat-admin/vat-vat-admin.js
@@ -18,6 +18,12 @@ import {
prepareSingleton,
} from '@agoric/vat-data';
+/**
+ * @import {VatAdminRootDeviceNode} from '../../devices/vat-admin/device-vat-admin.js';
+ * @import {DProxy} from'../plugin-manager.js';
+ * @import {Baggage} from '@agoric/vat-data';
+ */
+
const managerTypes = ['local', 'node-subprocess', 'xsnap', 'xs-worker']; // xs-worker is alias
function producePRR() {
@@ -25,14 +31,25 @@ function producePRR() {
return /** @type {const} */ ([promise, { resolve, reject }]);
}
+/**
+ * Build root object of the bootstrap vat.
+ *
+ * @param {VatPowers & {
+ * D: DProxy;
+ * }} vatPowers
+ * @param {never} _vatParameters
+ * @param {Baggage} baggage
+ */
export function buildRootObject(vatPowers, _vatParameters, baggage) {
const criticalVatKey = prepareSingleton(baggage, 'criticalVatKey', {});
const { D } = vatPowers;
const pendingVatCreations = new Map(); // vatID -> { resolve, reject } for promise
- const pendingBundles = new Map(); // bundleID -> Promise
+ /** @type {Map>} */
+ const pendingBundles = new Map();
const pendingUpgrades = new Map(); // upgradeID -> Promise
+ /** @type {import('../plugin-manager.js').Device} */
let vatAdminDev;
const runningVats = new Map(); // vatID -> [doneP, { resolve, reject }]
@@ -200,7 +217,7 @@ export function buildRootObject(vatPowers, _vatParameters, baggage) {
console.log(`bundle ${bundleID} missing, hoping for reinstall`);
return;
}
- pendingBundles.get(bundleID).resolve(bundlecap);
+ pendingBundles.get(bundleID)?.resolve(bundlecap);
pendingBundles.delete(bundleID);
checkForQuiescence();
}
@@ -418,8 +435,9 @@ export function buildRootObject(vatPowers, _vatParameters, baggage) {
if (!pendingBundles.has(bundleID)) {
pendingBundles.set(bundleID, makePromiseKit());
}
- return pendingBundles.get(bundleID).promise;
+ return pendingBundles.get(bundleID)?.promise;
},
+ /** @type {(bundleID: BundleID) => BundleCap} */
getBundleCap(bundleID) {
const bundlecap = D(vatAdminDev).getBundleCap(bundleID);
if (bundlecap) {
diff --git a/packages/SwingSet/test/abandon-export.test.js b/packages/SwingSet/test/abandon-export.test.js
index 55d3762e22e..d619b93df9a 100644
--- a/packages/SwingSet/test/abandon-export.test.js
+++ b/packages/SwingSet/test/abandon-export.test.js
@@ -5,15 +5,21 @@ import { test } from '../tools/prepare-test-env-ava.js';
import buildKernel from '../src/kernel/index.js';
import { initializeKernel } from '../src/controller/initializeKernel.js';
import { extractMethod } from '../src/lib/kdebug.js';
+import makeKernelKeeper, {
+ CURRENT_SCHEMA_VERSION,
+} from '../src/kernel/state/kernelKeeper.js';
import { makeKernelEndowments, buildDispatch } from './util.js';
import { kser, kunser, kslot } from '@agoric/kmarshal';
const makeKernel = async () => {
const endowments = makeKernelEndowments();
- const { kvStore } = endowments.kernelStorage;
- await initializeKernel({}, endowments.kernelStorage);
+ const { kernelStorage } = endowments;
+ const { kvStore } = kernelStorage;
+ await initializeKernel({}, kernelStorage);
const kernel = buildKernel(endowments, {}, {});
- return { kernel, kvStore };
+ const kernelKeeper = makeKernelKeeper(kernelStorage, CURRENT_SCHEMA_VERSION);
+ kernelKeeper.loadStats();
+ return { kernel, kvStore, kernelKeeper };
};
/**
@@ -43,7 +49,7 @@ const assertSingleEntryLog = (t, log, type, details = {}) => {
return entry;
};
-const makeTestVat = async (t, kernel, name) => {
+const makeTestVat = async (kernel, name, kernelKeeper) => {
const { log, dispatch } = buildDispatch();
let syscall;
const setup = providedSyscall => {
@@ -56,21 +62,29 @@ const makeTestVat = async (t, kernel, name) => {
const kref = kernel.getRootObject(vatID);
kernel.pinObject(kref);
const flushDeliveries = async () => {
- // Make a dummy delivery so the kernel will call processRefcounts().
- // This isn't normally needed, but we're directly making syscalls
- // outside of a delivery.
- // If that ever stops working, we can update `makeTestVat` to return
- // functions supporting more true-to-production vat behavior like
- // ```js
- // enqueueSyscall('send', target, kser([...args]), resultVPID);
- // enqueueSyscall('subscribe', resultVPID);
- // flushSyscalls(); // issues queued syscalls inside a dummy delivery
- // ```
- kernel.queueToKref(kref, 'flush', []);
+ // This test use a really lazy+sketchy approach to triggering
+ // syscalls and the refcount bookkeeping that we want to exercise.
+ //
+ // The kernel only runs processRefcounts() after a real crank
+ // (i.e. inside processDeliveryMessage and
+ // processAcceptanceMessage) but we want to avoid cluttering
+ // delivery logs of our vats with dummy activity, so we avoid
+ // making dispatches *into* the vat.
+ //
+ // The hack is to grab the vat's `syscall` object and invoke it
+ // directly, from *outside* a crank. Then, to trigger
+ // `processRefcounts()`, we inject a `{ type: 'negated-gc-action'
+ // }` onto the run-queue, which is handled by
+ // processDeliveryMessage but doesn't actually deliver anything.
+ //
+ // A safer approach would be to define the vat's dispatch() to
+ // listen for some messages that trigger each of the syscalls we
+ // want to invoke
+ //
+ kernelKeeper.addToRunQueue({ type: 'negated-gc-action' });
await kernel.run();
- assertFirstLogEntry(t, log, 'deliver', { method: 'flush' });
};
- return { vatID, kref, dispatch, log, syscall, flushDeliveries };
+ return { vatID, kref, log, syscall, flushDeliveries };
};
async function doAbandon(t, reachable) {
@@ -78,7 +92,7 @@ async function doAbandon(t, reachable) {
// vatB abandons it
// vatA should retain the object
// sending to the abandoned object should get an error
- const { kernel, kvStore } = await makeKernel();
+ const { kernel, kvStore, kernelKeeper } = await makeKernel();
await kernel.start();
const {
@@ -87,13 +101,14 @@ async function doAbandon(t, reachable) {
log: logA,
syscall: syscallA,
flushDeliveries: flushDeliveriesA,
- } = await makeTestVat(t, kernel, 'vatA');
+ } = await makeTestVat(kernel, 'vatA', kernelKeeper);
const {
vatID: vatB,
kref: bobKref,
log: logB,
syscall: syscallB,
- } = await makeTestVat(t, kernel, 'vatB');
+ flushDeliveries: flushDeliveriesB,
+ } = await makeTestVat(kernel, 'vatB', kernelKeeper);
await kernel.run();
// introduce B to A, so it can send 'holdThis' later
@@ -142,16 +157,24 @@ async function doAbandon(t, reachable) {
// now have vatB abandon the export
syscallB.abandonExports([targetForBob]);
- await flushDeliveriesA();
-
- // no GC messages for either vat
- t.deepEqual(logA, []);
- t.deepEqual(logB, []);
-
+ await flushDeliveriesB();
targetOwner = kvStore.get(`${targetKref}.owner`);
targetRefCount = kvStore.get(`${targetKref}.refCount`);
- t.is(targetOwner, undefined);
- t.is(targetRefCount, expectedRefCount); // unchanged
+
+ if (reachable) {
+ // no GC messages for either vat
+ t.deepEqual(logA, []);
+ t.deepEqual(logB, []);
+ t.is(targetOwner, undefined);
+ t.is(targetRefCount, expectedRefCount); // unchanged
+ } else {
+ // 'target' was orphaned and unreachable, kernel will delete it,
+ // so A will get a retireImports now
+ assertSingleEntryLog(t, logA, 'retireImports', { vrefs: [targetForAlice] });
+ t.deepEqual(logB, []);
+ t.is(targetOwner, undefined);
+ t.is(targetRefCount, undefined);
+ }
if (reachable) {
// vatA can send a message, but it will reject
@@ -180,17 +203,11 @@ async function doAbandon(t, reachable) {
await flushDeliveriesA();
// vatB should not get a dispatch.dropImports
t.deepEqual(logB, []);
- // the object still exists, now only recognizable
- targetRefCount = kvStore.get(`${targetKref}.refCount`);
- expectedRefCount = '0,1';
- t.is(targetRefCount, expectedRefCount); // merely recognizable
+ // the kernel automatically retires the orphaned
+ // now-merely-recognizable object
+ assertSingleEntryLog(t, logA, 'retireImports', { vrefs: [targetForAlice] });
+ // which deletes it
}
-
- // now vatA retires the object too
- syscallA.retireImports([targetForAlice]);
- await flushDeliveriesA();
- // vatB should not get a dispatch.retireImports
- t.deepEqual(logB, []);
// the object no longer exists
targetRefCount = kvStore.get(`${targetKref}.refCount`);
expectedRefCount = undefined;
diff --git a/packages/SwingSet/test/bundling/bundles-kernel.test.js b/packages/SwingSet/test/bundling/bundles-kernel.test.js
index cd6964e8682..8ec75bfb38a 100644
--- a/packages/SwingSet/test/bundling/bundles-kernel.test.js
+++ b/packages/SwingSet/test/bundling/bundles-kernel.test.js
@@ -12,7 +12,8 @@ import { initializeKernel } from '../../src/controller/initializeKernel.js';
test('install bundle', async t => {
const endowments = makeKernelEndowments();
const { bundleStore } = endowments.kernelStorage;
- await initializeKernel({}, endowments.kernelStorage);
+ const kconfig = { vats: {}, namedBundleIDs: {}, idToBundle: {} };
+ await initializeKernel(kconfig, endowments.kernelStorage);
const kernel = buildKernel(endowments, {}, {});
await kernel.start(); // empty queue
diff --git a/packages/SwingSet/test/change-parameters/change-parameters.test.js b/packages/SwingSet/test/change-parameters/change-parameters.test.js
index 0e2de993dee..200206f2f85 100644
--- a/packages/SwingSet/test/change-parameters/change-parameters.test.js
+++ b/packages/SwingSet/test/change-parameters/change-parameters.test.js
@@ -29,14 +29,22 @@ async function testChangeParameters(t) {
t.teardown(c.shutdown);
c.pinVatRoot('bootstrap');
await c.run();
- t.is(kvStore.get('kernel.defaultReapInterval'), '1');
+ t.deepEqual(JSON.parse(kvStore.get('kernel.defaultReapDirtThreshold')), {
+ deliveries: 1,
+ gcKrefs: 20,
+ computrons: 'never',
+ });
c.changeKernelOptions({
snapshotInterval: 1000,
defaultReapInterval: 10,
});
- t.is(kvStore.get('kernel.defaultReapInterval'), '10');
+ t.deepEqual(JSON.parse(kvStore.get('kernel.defaultReapDirtThreshold')), {
+ deliveries: 10,
+ gcKrefs: 20,
+ computrons: 'never',
+ });
t.throws(() => c.changeKernelOptions({ defaultReapInterval: 'banana' }), {
- message: 'invalid defaultReapInterval value',
+ message: 'defaultReapInterval banana must be a positive number or "never"',
});
t.throws(() => c.changeKernelOptions({ snapshotInterval: 'elephant' }), {
message: 'invalid heap snapshotInterval value',
@@ -44,6 +52,14 @@ async function testChangeParameters(t) {
t.throws(() => c.changeKernelOptions({ baz: 'howdy' }), {
message: 'unknown option "baz"',
});
+ c.changeKernelOptions({
+ defaultReapGCKrefs: 77,
+ });
+ t.deepEqual(JSON.parse(kvStore.get('kernel.defaultReapDirtThreshold')), {
+ deliveries: 10,
+ gcKrefs: 77,
+ computrons: 'never',
+ });
async function run(method, args = []) {
assert(Array.isArray(args));
@@ -57,7 +73,10 @@ async function testChangeParameters(t) {
// setup target vat
const [prepStatus] = await run('prepare', []);
t.is(prepStatus, 'fulfilled');
- t.is(kvStore.get('v6.reapInterval'), '10');
+ // the vat was created without option overrides, so
+ // reapDirtThreshold will be empty (everything defaults to the
+ // kernel-wide values)
+ t.deepEqual(JSON.parse(kvStore.get('v6.options')).reapDirtThreshold, {});
// now fiddle with stuff
const [c1Status, c1Result] = await run('change', [{ foo: 47 }]);
@@ -71,7 +90,9 @@ async function testChangeParameters(t) {
const [c4Status, c4Result] = await run('change', [{ reapInterval: 20 }]);
t.is(c4Status, 'fulfilled');
t.is(c4Result, 'ok');
- t.is(kvStore.get('v6.reapInterval'), '20');
+ t.deepEqual(JSON.parse(kvStore.get('v6.options')).reapDirtThreshold, {
+ deliveries: 20,
+ });
}
test('change vat options', async t => {
diff --git a/packages/SwingSet/test/clist.test.js b/packages/SwingSet/test/clist.test.js
index 2b3831da74c..1210fb3afc4 100644
--- a/packages/SwingSet/test/clist.test.js
+++ b/packages/SwingSet/test/clist.test.js
@@ -4,15 +4,26 @@ import { test } from '../tools/prepare-test-env-ava.js';
// eslint-disable-next-line import/order
import { initSwingStore } from '@agoric/swing-store';
import { makeDummySlogger } from '../src/kernel/slogger.js';
-import makeKernelKeeper from '../src/kernel/state/kernelKeeper.js';
+import makeKernelKeeper, {
+ CURRENT_SCHEMA_VERSION,
+} from '../src/kernel/state/kernelKeeper.js';
test(`clist reachability`, async t => {
const slog = makeDummySlogger({});
const kernelStorage = initSwingStore(null).kernelStorage;
- const kk = makeKernelKeeper(kernelStorage, slog);
+ const k0 = makeKernelKeeper(kernelStorage, 'uninitialized');
+ k0.createStartingKernelState({ defaultManagerType: 'local' });
+ k0.setInitialized();
+ k0.saveStats();
+
+ const kk = makeKernelKeeper(kernelStorage, CURRENT_SCHEMA_VERSION, slog);
+ kk.loadStats();
+
const s = kk.kvStore;
- kk.createStartingKernelState({ defaultManagerType: 'local' });
const vatID = kk.allocateUnusedVatID();
+ const source = { bundleID: 'foo' };
+ const options = { workerOptions: {}, reapDirtThreshold: {} };
+ kk.createVatState(vatID, source, options);
const vk = kk.provideVatKeeper(vatID);
const ko1 = kk.addKernelObject('v1', 1);
@@ -94,16 +105,27 @@ test(`clist reachability`, async t => {
test('getImporters', async t => {
const slog = makeDummySlogger({});
const kernelStorage = initSwingStore(null).kernelStorage;
- const kk = makeKernelKeeper(kernelStorage, slog);
+ const k0 = makeKernelKeeper(kernelStorage, 'uninitialized');
+ k0.createStartingKernelState({ defaultManagerType: 'local' });
+ k0.setInitialized();
+ k0.saveStats();
+
+ const kk = makeKernelKeeper(kernelStorage, CURRENT_SCHEMA_VERSION, slog);
+ kk.loadStats();
kk.createStartingKernelState({ defaultManagerType: 'local' });
const vatID1 = kk.allocateUnusedVatID();
+ const source = { bundleID: 'foo' };
+ const options = { workerOptions: {}, reapDirtThreshold: {} };
+ kk.createVatState(vatID1, source, options);
kk.addDynamicVatID(vatID1);
const vk1 = kk.provideVatKeeper(vatID1);
const vatID2 = kk.allocateUnusedVatID();
+ kk.createVatState(vatID2, source, options);
kk.addDynamicVatID(vatID2);
const vk2 = kk.provideVatKeeper(vatID2);
const vatID3 = kk.allocateUnusedVatID();
+ kk.createVatState(vatID3, source, options);
kk.addDynamicVatID(vatID3);
const vk3 = kk.provideVatKeeper(vatID3);
diff --git a/packages/SwingSet/test/controller.test.js b/packages/SwingSet/test/controller.test.js
index e731182d6fc..47464616ddb 100644
--- a/packages/SwingSet/test/controller.test.js
+++ b/packages/SwingSet/test/controller.test.js
@@ -11,6 +11,9 @@ import {
initializeSwingset,
makeSwingsetController,
} from '../src/index.js';
+import makeKernelKeeper, {
+ CURRENT_SCHEMA_VERSION,
+} from '../src/kernel/state/kernelKeeper.js';
import { checkKT } from './util.js';
const emptyVP = kser({});
@@ -487,3 +490,16 @@ test.serial('bootstrap export', async t => {
removeTriple(kt, vattp0, vatTPVatID, 'o+0');
checkKT(t, c, kt);
});
+
+test('comms vat does not BOYD', async t => {
+ const config = {};
+ const kernelStorage = initSwingStore().kernelStorage;
+ const controller = await buildVatController(config, [], { kernelStorage });
+ t.teardown(controller.shutdown);
+ const k = makeKernelKeeper(kernelStorage, CURRENT_SCHEMA_VERSION);
+ const commsVatID = k.getVatIDForName('comms');
+ t.deepEqual(
+ JSON.parse(k.kvStore.get(`${commsVatID}.options`)).reapDirtThreshold,
+ { never: true },
+ );
+});
diff --git a/packages/SwingSet/test/external-termination/bootstrap-external-termination.js b/packages/SwingSet/test/external-termination/bootstrap-external-termination.js
new file mode 100644
index 00000000000..70e24801a4d
--- /dev/null
+++ b/packages/SwingSet/test/external-termination/bootstrap-external-termination.js
@@ -0,0 +1,27 @@
+import { Far, E } from '@endo/far';
+
+export function buildRootObject() {
+ let vatAdmin;
+ let bcap;
+ let root;
+ let adminNode;
+ let exitval;
+
+ return Far('root', {
+ bootstrap: async (vats, devices) => {
+ vatAdmin = await E(vats.vatAdmin).createVatAdminService(devices.vatAdmin);
+ bcap = await E(vatAdmin).getNamedBundleCap('doomed');
+ const res = await E(vatAdmin).createVat(bcap);
+ root = res.root;
+ adminNode = res.adminNode;
+ E(adminNode)
+ .done()
+ .then(
+ happy => (exitval = ['fulfill', happy]),
+ sad => (exitval = ['reject', sad]),
+ );
+ },
+ ping: async count => E(root).ping(count),
+ getExitVal: () => exitval,
+ });
+}
diff --git a/packages/SwingSet/test/external-termination/external-termination.test.js b/packages/SwingSet/test/external-termination/external-termination.test.js
new file mode 100644
index 00000000000..6fa0a1ef807
--- /dev/null
+++ b/packages/SwingSet/test/external-termination/external-termination.test.js
@@ -0,0 +1,80 @@
+// eslint-disable-next-line import/order
+import { test } from '../../tools/prepare-test-env-ava.js';
+
+import { initSwingStore } from '@agoric/swing-store';
+import { kser, kunser } from '@agoric/kmarshal';
+import { initializeSwingset, makeSwingsetController } from '../../src/index.js';
+
+const bfile = name => new URL(name, import.meta.url).pathname;
+
+const testExternalTermination = async (t, defaultManagerType) => {
+ /** @type {SwingSetConfig} */
+ const config = {
+ defaultManagerType,
+ bootstrap: 'bootstrap',
+ vats: {
+ bootstrap: { sourceSpec: bfile('./bootstrap-external-termination.js') },
+ },
+ bundles: {
+ doomed: { sourceSpec: bfile('./vat-doomed.js') },
+ },
+ };
+
+ const kernelStorage = initSwingStore().kernelStorage;
+ await initializeSwingset(config, [], kernelStorage);
+ const c = await makeSwingsetController(kernelStorage);
+ t.teardown(c.shutdown);
+ c.pinVatRoot('bootstrap');
+ await c.run();
+
+ const getVatIDs = () => c.dump().vatTables.map(vt => vt.vatID);
+
+ // vat-doomed should now be running. We casually assume the new vat
+ // has the last ID
+ const vatIDs = getVatIDs();
+ const vatID = vatIDs[vatIDs.length - 1];
+
+ {
+ const kpid = c.queueToVatRoot('bootstrap', 'ping', [1]);
+ await c.run();
+ t.is(kunser(c.kpResolution(kpid)), 1);
+ }
+ {
+ const kpid = c.queueToVatRoot('bootstrap', 'getExitVal');
+ await c.run();
+ t.is(kunser(c.kpResolution(kpid)), undefined);
+ }
+
+ // The "vat has been terminated" flags are set synchronously during
+ // c.terminateVat(), as well as all the vat's promises being
+ // rejected. The deletion of state happens during the first cleanup
+ // crank, which (since we aren't limiting it with a runPolicy)
+ // cleans to completion during this c.run()
+
+ c.terminateVat(vatID, kser('doom!'));
+ await c.run();
+
+ t.false(getVatIDs().includes(vatID));
+
+ {
+ // this provokes noise: liveslots logs one RemoteError
+ const kpid = c.queueToVatRoot('bootstrap', 'ping', [1]);
+ await c.run();
+ t.is(c.kpStatus(kpid), 'rejected');
+ t.deepEqual(kunser(c.kpResolution(kpid)), Error('vat terminated'));
+ }
+
+ {
+ const kpid = c.queueToVatRoot('bootstrap', 'getExitVal');
+ await c.run();
+ t.deepEqual(kunser(c.kpResolution(kpid)), ['reject', 'doom!']);
+ }
+};
+
+test('external termination: local worker', async t => {
+ await testExternalTermination(t, 'local');
+});
+
+test('external termination: xsnap worker', async t => {
+ await testExternalTermination(t, 'xsnap');
+});
diff --git a/packages/SwingSet/test/external-termination/vat-doomed.js b/packages/SwingSet/test/external-termination/vat-doomed.js
new file mode 100644
index 00000000000..c2a1e079f51
--- /dev/null
+++ b/packages/SwingSet/test/external-termination/vat-doomed.js
@@ -0,0 +1,7 @@
+import { Far } from '@endo/far';
+
+export function buildRootObject() {
+ return Far('doomed', {
+ ping: count => count,
+ });
+}
diff --git a/packages/SwingSet/test/gc-actions.test.js b/packages/SwingSet/test/gc-actions.test.js
index cfb16f8ce56..14030712810 100644
--- a/packages/SwingSet/test/gc-actions.test.js
+++ b/packages/SwingSet/test/gc-actions.test.js
@@ -13,6 +13,7 @@ test('gc actions', t => {
}
const clistState = { v1: { ko1: {}, ko2: {} }, v2: { ko2: {} } };
+ /** @type {KernelKeeper} */
const kernelKeeper = {
getGCActions() {
return new Set(actions);
@@ -28,7 +29,9 @@ test('gc actions', t => {
const [reachable, recognizable] = rc[kref];
return { reachable, recognizable };
},
+ // @ts-expect-error mock
emitCrankHashes() {},
+ // @ts-expect-error mock
provideVatKeeper(vatID) {
return {
hasCListEntry(kref) {
diff --git a/packages/SwingSet/test/gc-dead-vat/bootstrap.js b/packages/SwingSet/test/gc-dead-vat/bootstrap.js
index 50668b2902b..7bf0c47039b 100644
--- a/packages/SwingSet/test/gc-dead-vat/bootstrap.js
+++ b/packages/SwingSet/test/gc-dead-vat/bootstrap.js
@@ -1,5 +1,6 @@
import { Far, E } from '@endo/far';
import { makePromiseKit } from '@endo/promise-kit';
+import { makeScalarBigWeakSetStore } from '@agoric/vat-data';
async function sendExport(doomedRoot) {
const exportToDoomed = Far('exportToDoomed', {});
@@ -11,6 +12,7 @@ export function buildRootObject() {
let doomedRoot;
const pin = [];
const pk1 = makePromiseKit();
+ const wh = makeScalarBigWeakSetStore('weak-holder');
return Far('root', {
async bootstrap(vats, devices) {
const vatMaker = E(vats.vatAdmin).createVatAdminService(devices.vatAdmin);
@@ -19,6 +21,8 @@ export function buildRootObject() {
await sendExport(doomedRoot);
const doomedExport1Presence = await E(doomedRoot).getDoomedExport1();
pin.push(doomedExport1Presence);
+ const doomedExport3Presence = await E(doomedRoot).getDoomedExport3();
+ wh.add(doomedExport3Presence);
},
async stash() {
// Give vat-doomed a target that doesn't resolve one() right away.
diff --git a/packages/SwingSet/test/gc-dead-vat/vat-doomed.js b/packages/SwingSet/test/gc-dead-vat/vat-doomed.js
index f3ad636b7c0..19acca8758b 100644
--- a/packages/SwingSet/test/gc-dead-vat/vat-doomed.js
+++ b/packages/SwingSet/test/gc-dead-vat/vat-doomed.js
@@ -4,6 +4,7 @@ export function buildRootObject(vatPowers) {
const pin = [];
const doomedExport1 = Far('doomedExport1', {});
const doomedExport2 = Far('doomedExport2', {});
+ const doomedExport3 = Far('doomedExport3', {});
return Far('root', {
accept(exportToDoomedPresence) {
pin.push(exportToDoomedPresence);
@@ -14,6 +15,9 @@ export function buildRootObject(vatPowers) {
stashDoomedExport2(target) {
E(E(target).one()).neverCalled(doomedExport2);
},
+ getDoomedExport3() {
+ return doomedExport3;
+ },
terminate() {
vatPowers.exitVat('completion');
},
diff --git a/packages/SwingSet/test/gc-kernel-orphan.test.js b/packages/SwingSet/test/gc-kernel-orphan.test.js
new file mode 100644
index 00000000000..d6b30126493
--- /dev/null
+++ b/packages/SwingSet/test/gc-kernel-orphan.test.js
@@ -0,0 +1,463 @@
+// @ts-nocheck
+/* global WeakRef, FinalizationRegistry */
+
+import anylogger from 'anylogger';
+// eslint-disable-next-line import/order
+import { test } from '../tools/prepare-test-env-ava.js';
+
+import { assert } from '@endo/errors';
+import { kser, kunser, kslot } from '@agoric/kmarshal';
+import { initSwingStore } from '@agoric/swing-store';
+import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
+import buildKernel from '../src/kernel/index.js';
+import { initializeKernel } from '../src/controller/initializeKernel.js';
+
+function makeConsole(tag) {
+ const log = anylogger(tag);
+ const cons = {};
+ for (const level of ['debug', 'log', 'info', 'warn', 'error']) {
+ cons[level] = log[level];
+ }
+ return harden(cons);
+}
+
+function writeSlogObject(o) {
+ function bigintReplacer(_, arg) {
+ if (typeof arg === 'bigint') {
+ return Number(arg);
+ }
+ return arg;
+ }
+ 0 && console.log(JSON.stringify(o, bigintReplacer));
+}
+
+function makeEndowments() {
+ return {
+ waitUntilQuiescent,
+ kernelStorage: initSwingStore().kernelStorage,
+ runEndOfCrank: () => {},
+ makeConsole,
+ writeSlogObject,
+ WeakRef,
+ FinalizationRegistry,
+ };
+}
+
+async function makeKernel() {
+ const endowments = makeEndowments();
+ const { kvStore } = endowments.kernelStorage;
+ await initializeKernel({}, endowments.kernelStorage);
+ const kernel = buildKernel(endowments, {}, {});
+ return { kernel, kvStore };
+}
+
+const orphanTest = test.macro(async (t, cause, when, amyState) => {
+ assert(['reachable', 'recognizable', 'none'].includes(amyState));
+ assert(['abandon', 'terminate'].includes(cause));
+ // There is a third case (vatA gets upgraded, and the object wasn't
+ // durable), but we can't upgrade vats created by createTestVat().
+ assert(['before', 'after'].includes(when));
+ const retireImmediately = false;
+ const { kernel, kvStore } = await makeKernel();
+ await kernel.start();
+
+ const vrefs = {}; // track vrefs within vats
+
+ // Our two root objects (alice and bob) are pinned so they don't disappear
+ // while the test is talking to them. So we make alice introduce "amy" as a
+ // new object that's doomed to be collected. Bob first drops amy, then
+ // retires her, provoking first a dropExports then a retireImports on
+ // alice.
+
+ vrefs.aliceForA = 'o+100';
+ vrefs.amyForA = 'o+101';
+ function setupA(syscall, _state, _helpers, _vatPowers) {
+ let exportingAmy = false;
+ function dispatch(vd) {
+ if (vd[0] === 'startVat') {
+ return; // skip startVat
+ }
+ let method;
+ if (vd[0] === 'message') {
+ const methargs = kunser(vd[2].methargs);
+ [method] = methargs;
+ if (method === 'init') {
+ // initial conditions: bob holds a reference to amy
+ vrefs.bobForA = vd[2].methargs.slots[0];
+ syscall.send(
+ vrefs.bobForA,
+ kser(['accept-amy', [kslot(vrefs.amyForA)]]),
+ );
+ exportingAmy = true;
+ }
+ if (method === 'abandon') {
+ if (exportingAmy) {
+ syscall.abandonExports([vrefs.amyForA]);
+ }
+ }
+ if (method === 'terminate') {
+ syscall.exit(false, kser('terminated'));
+ }
+ }
+ if (vd[0] === 'dropExports') {
+ if (retireImmediately) {
+ // pretend there are no local strongrefs, and as soon as liveslots
+ // drops it's claim, the object goes away completely
+ syscall.retireExports(vd[1]);
+ }
+ }
+ if (vd[0] === 'retireExports') {
+ exportingAmy = false;
+ }
+ }
+ return dispatch;
+ }
+ await kernel.createTestVat('vatA', setupA);
+ const vatA = kernel.vatNameToID('vatA');
+ const alice = kernel.addExport(vatA, vrefs.aliceForA);
+
+ let amyRetiredToB = false;
+ function setupB(syscall, _state, _helpers, _vatPowers) {
+ function dispatch(vd) {
+ if (vd[0] === 'startVat') {
+ return; // skip startVat
+ }
+ let method;
+ if (vd[0] === 'message') {
+ [method] = kunser(vd[2].methargs);
+ if (method === 'accept-amy') {
+ vrefs.amyForB = vd[2].methargs.slots[0];
+ }
+ if (method === 'drop') {
+ syscall.dropImports([vrefs.amyForB]);
+ }
+ if (method === 'drop and retire') {
+ syscall.dropImports([vrefs.amyForB]);
+ syscall.retireImports([vrefs.amyForB]);
+ }
+ if (method === 'retire') {
+ // it would be an error for bob to do this before or without
+ // dropImports
+ syscall.retireImports([vrefs.amyForB]);
+ }
+ }
+ if (vd[0] === 'retireImports') {
+ t.deepEqual(vd[1], [vrefs.amyForB]);
+ amyRetiredToB = true;
+ }
+ }
+ return dispatch;
+ }
+ await kernel.createTestVat('vatB', setupB);
+ const vatB = kernel.vatNameToID('vatB');
+ vrefs.bobForB = 'o+200';
+ const bob = kernel.addExport(vatB, vrefs.bobForB);
+
+ // we always start with bob importing an object from alice
+ kernel.queueToKref(alice, 'init', [kslot(bob)], 'none');
+ await kernel.run();
+
+ const amy = kvStore.get(`${vatA}.c.${vrefs.amyForA}`);
+ t.is(amy, 'ko22'); // probably
+
+ if (when === 'before') {
+ // the object is abandoned before vatB drops anything
+ if (cause === 'abandon') {
+ kernel.queueToKref(alice, 'abandon', [], 'none');
+ } else if (cause === 'terminate') {
+ kernel.queueToKref(alice, 'terminate', [], 'none');
+ }
+ await kernel.run();
+ t.is(kvStore.get(`${amy}.owner`), undefined);
+ }
+
+ t.is(kvStore.get(`${amy}.refCount`), '1,1');
+ t.is(kvStore.get(`${vatB}.c.${amy}`), `R ${vrefs.amyForB}`);
+
+ // vatB now drops/retires/neither the "amy" object
+
+ if (amyState === 'reachable') {
+ // no change
+ } else if (amyState === 'recognizable') {
+ kernel.queueToKref(bob, 'drop', [], 'none');
+ await kernel.run();
+ if (when === 'before') {
+ // dropping an abandoned object should also retire it
+ t.true(amyRetiredToB); // fixed by #7212
+ t.is(kvStore.get(`${vatB}.c.${amy}`), undefined);
+ t.is(kvStore.get(`${amy}.refCount`), undefined);
+ } else {
+ // dropping a living object should merely drop it
+ t.is(kvStore.get(`${vatB}.c.${amy}`), `_ ${vrefs.amyForB}`);
+ t.is(kvStore.get(`${amy}.refCount`), '0,1');
+ }
+ } else if (amyState === 'none') {
+ kernel.queueToKref(bob, 'drop and retire', [], 'none');
+ await kernel.run();
+ t.is(kvStore.get(`${vatB}.c.${amy}`), undefined);
+ t.is(kvStore.get(`${amy}.refCount`), undefined);
+ }
+
+ if (when === 'after') {
+ // the object is abandoned *after* vatB drops anything
+ if (cause === 'abandon') {
+ kernel.queueToKref(alice, 'abandon', [], 'none');
+ } else if (cause === 'terminate') {
+ kernel.queueToKref(alice, 'terminate', [], 'none');
+ }
+ await kernel.run();
+ }
+
+ t.is(kvStore.get(`${amy}.owner`), undefined);
+
+ if (amyState === 'reachable') {
+ // amy should remain defined and reachable, just lacking an owner
+ t.is(kvStore.get(`${vatB}.c.${amy}`), `R ${vrefs.amyForB}`);
+ t.is(kvStore.get(`${amy}.refCount`), '1,1');
+ } else if (amyState === 'recognizable') {
+ // an unreachable koid should be retired upon abandonment
+ t.true(amyRetiredToB); // fixed by #7212
+ t.is(kvStore.get(`${vatB}.c.${amy}`), undefined);
+ t.is(kvStore.get(`${amy}.refCount`), undefined);
+ } else if (amyState === 'none') {
+ // no change
+ }
+});
+
+for (const cause of ['abandon', 'terminate']) {
+ for (const when of ['before', 'after']) {
+ for (const amyState of ['reachable', 'recognizable', 'none']) {
+ test(
+ `orphan test ${cause}-${when}-${amyState}`,
+ orphanTest,
+ cause,
+ when,
+ amyState,
+ );
+ }
+ }
+}
+
+// exercise a failure case I saw in the zoe tests (zoe -
+// secondPriceAuction - valid inputs):
+// * vatB is exporting an object ko120 to vatA
+// * vatA does E(ko120).wake(), then drops the reference
+// (vatA can still recognize ko120)
+// * vatA gets a BOYD, does syscall.dropImport(ko120)
+// * ko120.refCount = 1,2 (0,1 from vatA, 1,1 from the run-queue wake())
+// * wake() is delivered to vatB
+// * removing it from the run-queue drops refCount to 0,1
+// * and adds ko120 to maybeFreeKrefs
+// * wake() provokes vatB to syscall.exit
+// * post-crank terminateVat() orphans ko120, then retires it
+// * deleting both .owner and .refCount
+// * post-er-crank processRefcounts sees ko120 in maybeFreeKrefs
+// * tries to look up .refCount, fails, panics
+
+// the fix was to change kernelKeeper.getRefCounts to handle a missing
+// koNN.refCounts by just returning 0,0
+
+test('termination plus maybeFreeKrefs - dropped', async t => {
+ const { kernel, kvStore } = await makeKernel();
+ await kernel.start();
+
+ const vrefs = {}; // track vrefs within vats
+
+ // vatB exports an object to vatA, vatA sends it a message and drops
+ // it (but doesn't retire it), vatB will self-terminate upon
+ // receiving that message, creating two places that try to retire it
+
+ // The order of events will be:
+ // * 'terminate' translated, drops reachable to zero, adds to maybeFreeKrefs
+ // * 'terminate' delivered, delivery marks vat for termination
+ // * post-delivery crankResults.terminate check marks vat as terminated
+ // (but slow-deletion means nothing is deleted on that crank)
+ // * post-delivery does processRefCounts()
+ // * that processes ko22/billy, sees 0,1, owner=v2, v2 is terminated
+ // so it orphans ko22 (removes from vatB c-list and clears .owner)
+ // and falls through to (owner=undefined) case
+ // which sees recognizable=1 and retires the object
+ // (i.e. pushes retireImport gcAction and deletes .owner and .refCounts)
+ // * next crank starts cleanup, walks c-list, orphans ko21/bob
+ // which adds ko21 to maybeFreeKrefs
+ // * post-cleanup processRefCounts() does ko21, sees 1,1, owner=undefined
+ // does nothing, since vatA still holds an (orphaned) reference
+ // * cleanup finishes
+
+ // Our two root objects (alice and bob) are pinned so they don't
+ // disappear while the test is talking to them, so vatB exports
+ // "billy".
+
+ vrefs.aliceForA = 'o+100';
+ vrefs.bobForB = 'o+200';
+ vrefs.billyForB = 'o+201';
+ let billyKref;
+
+ let vatA;
+ function setupA(syscall, _state, _helpers, _vatPowers) {
+ function dispatch(vd) {
+ if (vd[0] === 'startVat') {
+ return; // skip startVat
+ }
+ // console.log(`deliverA:`, JSON.stringify(vd));
+ if (vd[0] === 'message') {
+ const methargs = kunser(vd[2].methargs);
+ const [method] = methargs;
+ if (method === 'call-billy') {
+ t.is(vd[2].methargs.slots.length, 1);
+ vrefs.billyForA = vd[2].methargs.slots[0];
+ t.is(vrefs.billyForA, 'o-50'); // probably
+ billyKref = kvStore.get(`${vatA}.c.${vrefs.billyForA}`);
+ syscall.send(
+ vrefs.billyForA,
+ kser(['terminate', [kslot(vrefs.billyForA, 'billy-A')]]),
+ );
+ syscall.dropImports([vrefs.billyForA]);
+ }
+ }
+ }
+ return dispatch;
+ }
+ await kernel.createTestVat('vatA', setupA);
+ vatA = kernel.vatNameToID('vatA');
+ const alice = kernel.addExport(vatA, vrefs.aliceForA);
+
+ function setupB(syscall, _state, _helpers, _vatPowers) {
+ function dispatch(vd) {
+ if (vd[0] === 'startVat') {
+ return; // skip startVat
+ }
+ // console.log(`deliverB:`, JSON.stringify(vd));
+ if (vd[0] === 'message') {
+ const [method] = kunser(vd[2].methargs);
+ if (method === 'init') {
+ vrefs.aliceForB = vd[2].methargs.slots[0];
+ syscall.send(
+ vrefs.aliceForB,
+ kser(['call-billy', [kslot(vrefs.billyForB, 'billy-B')]]),
+ );
+ }
+ if (method === 'terminate') {
+ t.is(vd[2].methargs.slots.length, 1);
+ assert.equal(vd[2].methargs.slots[0], vrefs.billyForB);
+ syscall.exit(false, kser('reason'));
+ }
+ }
+ }
+ return dispatch;
+ }
+ await kernel.createTestVat('vatB', setupB);
+ const vatB = kernel.vatNameToID('vatB');
+ const bob = kernel.addExport(vatB, vrefs.bobForB);
+
+ // this triggers everything, the bug was a kernel crash
+ kernel.queueToKref(bob, 'init', [kslot(alice, 'alice')], 'none');
+ await kernel.run();
+
+ t.is(kvStore.get(`${billyKref}.owner`), undefined);
+ t.is(kvStore.get(`${billyKref}.refCounts`), undefined);
+ t.is(kvStore.get(`${vatA}.c.${billyKref}`), undefined);
+ t.is(kvStore.get(`${vatA}.c.${vrefs.billyForA}`), undefined);
+ t.is(kvStore.get(`${vatB}.c.${billyKref}`), undefined);
+ t.is(kvStore.get(`${vatB}.c.${vrefs.billyForB}`), undefined);
+});
+
+// like above, but the object doesn't remain recognizable
+test('termination plus maybeFreeKrefs - retired', async t => {
+ const { kernel, kvStore } = await makeKernel();
+ await kernel.start();
+
+ const vrefs = {}; // track vrefs within vats
+
+ // vatB exports an object to vatA, vatA sends it a message and drops
+ // and retires it, vatB will self-terminate upon receiving that
+ // message. The order of events will be:
+ // * 'terminate' translated, drops refcount to zero, adds to maybeFreeKrefs
+ // * 'terminate' delivered, delivery marks vat for termination
+ // * post-delivery crankResults.terminate check marks vat as terminated
+ // (but slow-deletion means nothing is deleted on that crank)
+ // * post-delivery does processRefCounts()
+ // * that processes ko22/billy, sees 0,0, owner=v2, v2 is terminated
+ // so it orphans ko22 (removes from vatB c-list and clears .owner)
+ // and falls through to (owner=undefined) case
+ // which sees recognizable=0 and deletes the object (just .refCount now)
+ // * next crank starts cleanup, walks c-list, orphans ko21/bob
+ // which adds ko21 to maybeFreeKrefs
+ // * post-cleanup processRefCounts() does ko21, sees 1,1, owner=undefined
+ // does nothing, since vatA still holds an (orphaned) reference
+ // * cleanup finishes
+
+ vrefs.aliceForA = 'o+100';
+ vrefs.bobForB = 'o+200';
+ vrefs.billyForB = 'o+201';
+ let billyKref;
+
+ let vatA;
+ function setupA(syscall, _state, _helpers, _vatPowers) {
+ function dispatch(vd) {
+ if (vd[0] === 'startVat') {
+ return; // skip startVat
+ }
+ console.log(`deliverA:`, JSON.stringify(vd));
+ if (vd[0] === 'message') {
+ const methargs = kunser(vd[2].methargs);
+ const [method] = methargs;
+ if (method === 'call-billy') {
+ t.is(vd[2].methargs.slots.length, 1);
+ vrefs.billyForA = vd[2].methargs.slots[0];
+ t.is(vrefs.billyForA, 'o-50'); // probably
+ billyKref = kvStore.get(`${vatA}.c.${vrefs.billyForA}`);
+ syscall.send(
+ vrefs.billyForA,
+ kser(['terminate', [kslot(vrefs.billyForA, 'billy-A')]]),
+ );
+ syscall.dropImports([vrefs.billyForA]);
+ syscall.retireImports([vrefs.billyForA]);
+ }
+ }
+ }
+ return dispatch;
+ }
+ await kernel.createTestVat('vatA', setupA);
+ vatA = kernel.vatNameToID('vatA');
+ const alice = kernel.addExport(vatA, vrefs.aliceForA);
+
+ function setupB(syscall, _state, _helpers, _vatPowers) {
+ function dispatch(vd) {
+ if (vd[0] === 'startVat') {
+ return; // skip startVat
+ }
+ console.log(`deliverB:`, JSON.stringify(vd));
+ if (vd[0] === 'message') {
+ const [method] = kunser(vd[2].methargs);
+ if (method === 'init') {
+ vrefs.aliceForB = vd[2].methargs.slots[0];
+ syscall.send(
+ vrefs.aliceForB,
+ kser(['call-billy', [kslot(vrefs.billyForB, 'billy-B')]]),
+ );
+ }
+ if (method === 'terminate') {
+ t.is(vd[2].methargs.slots.length, 1);
+ assert.equal(vd[2].methargs.slots[0], vrefs.billyForB);
+ syscall.exit(false, kser('reason'));
+ }
+ }
+ }
+ return dispatch;
+ }
+ await kernel.createTestVat('vatB', setupB);
+ const vatB = kernel.vatNameToID('vatB');
+ const bob = kernel.addExport(vatB, vrefs.bobForB);
+
+ // this triggers everything, the bug was a kernel crash
+ kernel.queueToKref(bob, 'init', [kslot(alice, 'alice')], 'none');
+ await kernel.run();
+
+ t.is(kvStore.get(`${billyKref}.owner`), undefined);
+ t.is(kvStore.get(`${billyKref}.refCounts`), undefined);
+ t.is(kvStore.get(`${vatA}.c.${billyKref}`), undefined);
+ t.is(kvStore.get(`${vatA}.c.${vrefs.billyForA}`), undefined);
+ t.is(kvStore.get(`${vatB}.c.${billyKref}`), undefined);
+ t.is(kvStore.get(`${vatB}.c.${vrefs.billyForB}`), undefined);
+});
diff --git a/packages/SwingSet/test/gc-kernel.test.js b/packages/SwingSet/test/gc-kernel.test.js
index eef51e76a4f..ea6fa54b929 100644
--- a/packages/SwingSet/test/gc-kernel.test.js
+++ b/packages/SwingSet/test/gc-kernel.test.js
@@ -1031,7 +1031,7 @@ test('terminated vat', async t => {
bootstrap: {
sourceSpec: new URL('gc-dead-vat/bootstrap.js', import.meta.url)
.pathname,
- creationOptions: { managerType: 'local' },
+ creationOptions: { managerType: 'xs-worker' },
},
},
bootstrap: 'bootstrap',
@@ -1091,12 +1091,15 @@ test('terminated vat', async t => {
// we'll watch for this to be deleted when the vat is terminated
// console.log(`pinKref`, pinKref);
- // find the highest export: doomedExport1 / doomedExport1Presence
+ // find the two highest exports: doomedExport[13] / doomedExport[13]Presence
let exports = Object.keys(vrefs).filter(vref => vref.startsWith('o+'));
sortVrefs(exports);
- const doomedExport1Vref = exports[exports.length - 1];
+ const doomedExport1Vref = exports[exports.length - 2];
+ const doomedExport3Vref = exports[exports.length - 1];
t.is(doomedExport1Vref, 'o+10'); // arbitrary
+ t.is(doomedExport3Vref, 'o+11'); // arbitrary
const doomedExport1Kref = vrefs[doomedExport1Vref];
+ const doomedExport3Kref = vrefs[doomedExport3Vref];
// this should also be deleted
// console.log(`doomedExport1Kref`, doomedExport1Kref);
@@ -1105,6 +1108,8 @@ test('terminated vat', async t => {
t.is(owners[pinKref], bootstrapVat);
t.deepEqual(refcounts[doomedExport1Kref], [1, 1]);
t.is(owners[doomedExport1Kref], doomedVat);
+ t.deepEqual(refcounts[doomedExport3Kref], [0, 1]);
+ t.is(owners[doomedExport3Kref], doomedVat);
// Tell bootstrap to give a promise to the doomed vat. The doomed vat will
// send a second export in a message to this promise, so the only
@@ -1117,7 +1122,7 @@ test('terminated vat', async t => {
exports = Object.keys(vrefs).filter(vref => vref.startsWith('o+'));
sortVrefs(exports);
const doomedExport2Vref = exports[exports.length - 1];
- t.is(doomedExport2Vref, 'o+11'); // arbitrary
+ t.is(doomedExport2Vref, 'o+12'); // arbitrary
const doomedExport2Kref = vrefs[doomedExport2Vref];
[refcounts, owners] = getRefCountsAndOwners();
t.deepEqual(refcounts[doomedExport2Kref], [1, 1]); // from promise queue
@@ -1137,6 +1142,9 @@ test('terminated vat', async t => {
t.deepEqual(refcounts[doomedExport2Kref], [1, 1]);
t.falsy(owners[doomedExport1Kref]);
t.falsy(owners[doomedExport2Kref]);
+ // but the merely-recognizable export should be deleted
+ t.falsy(owners[doomedExport3Kref]);
+ t.deepEqual(refcounts[doomedExport3Kref], undefined);
// send a message to the orphan, to wiggle refcounts some more
const r = c.queueToVatRoot('bootstrap', 'callOrphan', [], 'panic');
@@ -1157,12 +1165,8 @@ test('terminated vat', async t => {
c.queueToVatRoot('bootstrap', 'drop', [], 'panic');
await c.run();
- // TODO: however, for some reason neither Node.js nor XS actually drops
- // 'doomedExport1Presence', despite it clearly going out of scope. I don't
- // know why. Until we can find way to make it drop, this check is commented
- // out.
[refcounts, owners] = getRefCountsAndOwners();
- // t.is(refcounts[doomedExport1Kref], undefined);
+ t.is(refcounts[doomedExport1Kref], undefined);
t.falsy(owners[doomedExport1Kref]);
t.is(refcounts[doomedExport2Kref], undefined);
diff --git a/packages/SwingSet/test/gc/bootstrap.js b/packages/SwingSet/test/gc/bootstrap.js
index 3c08bb01b4e..8cdf7ce4dfe 100644
--- a/packages/SwingSet/test/gc/bootstrap.js
+++ b/packages/SwingSet/test/gc/bootstrap.js
@@ -23,5 +23,10 @@ export function buildRootObject() {
async makeInvitation0() {
await E(target).makeInvitationTarget(zoe);
},
+
+ // for #9939
+ async storePresenceInWeakSet() {
+ await E(target).store(A);
+ },
});
}
diff --git a/packages/SwingSet/test/gc/gc-vat.test.js b/packages/SwingSet/test/gc/gc-vat.test.js
index a593ff6cec7..617e4b07a7e 100644
--- a/packages/SwingSet/test/gc/gc-vat.test.js
+++ b/packages/SwingSet/test/gc/gc-vat.test.js
@@ -158,3 +158,84 @@ test('forward to fake zoe', async t => {
// 'makeInvitationTarget' result promise with it, then dropped it
t.is(findClist(c, targetID, invitation), undefined);
});
+
+// see #9939
+test('drop without retire', async t => {
+ let targetID;
+ let didBOYD = false;
+ // const msgs = ['deliver', 'deliver-result', 'syscall', 'syscall-result'];
+
+ function slogSender(slogObj) {
+ const {
+ time: _1,
+ replay: _2,
+ crankNum: _3,
+ deliveryNum: _4,
+ monotime: _5,
+ ...o
+ } = slogObj;
+ if (o.vatID !== targetID) return;
+ if (o.type === 'deliver' && o.kd[0] === 'bringOutYourDead') {
+ didBOYD = true;
+ }
+ // if (msgs.includes(o.type)) console.log(JSON.stringify(o));
+ }
+ const config = {
+ bootstrap: 'bootstrap', // v6
+ vats: {
+ bootstrap: {
+ // v6
+ sourceSpec: new URL('bootstrap.js', import.meta.url).pathname,
+ },
+ target: {
+ // v1
+ sourceSpec: new URL('vat-target.js', import.meta.url).pathname,
+ // avoid V8's GC nondeterminism, only needed on the target vat
+ creationOptions: { managerType: 'xs-worker' },
+ },
+ },
+ };
+ const kernelStorage = initSwingStore().kernelStorage;
+ await initializeSwingset(config, [], kernelStorage);
+ const c = await makeSwingsetController(kernelStorage, {}, { slogSender });
+ t.teardown(c.shutdown);
+
+ c.pinVatRoot('bootstrap');
+ targetID = c.vatNameToID('target');
+ c.pinVatRoot('target');
+
+ await c.run();
+
+ c.queueToVatRoot('bootstrap', 'storePresenceInWeakSet', []);
+ await c.run();
+
+ // now do enough dummy messages to trigger a new BOYD
+ didBOYD = false;
+ while (!didBOYD) {
+ c.queueToVatRoot('target', 'dummy', []);
+ await c.run();
+ }
+
+ // now tell vat-target to drop its WeakSet
+ c.queueToVatRoot('target', 'drop', []);
+ await c.run();
+
+ // and trigger a second BOYD
+ didBOYD = false;
+ while (!didBOYD) {
+ // this will fail once the vat is terminated
+ try {
+ c.queueToVatRoot('target', 'dummy', []);
+ } catch (e) {
+ if (/vat name "target" must exist/.test(e.message)) {
+ t.fail('vat terminated, bug is present');
+ break;
+ }
+ }
+ await c.run();
+ }
+ t.true(didBOYD);
+
+ // the test passes if the vat survived
+ return t.pass();
+});
diff --git a/packages/SwingSet/test/gc/vat-target.js b/packages/SwingSet/test/gc/vat-target.js
index dd4c1d5d0a6..53900b66055 100644
--- a/packages/SwingSet/test/gc/vat-target.js
+++ b/packages/SwingSet/test/gc/vat-target.js
@@ -1,6 +1,9 @@
import { Far, E } from '@endo/far';
-export function buildRootObject() {
+export function buildRootObject(_vatPowers, _vatParameters, baggage) {
+ /** @type { WeakSet | undefined } */
+ let ws = new WeakSet();
+
return Far('root', {
async two(A, B) {
// A=ko26 B=ko27
@@ -10,5 +13,14 @@ export function buildRootObject() {
makeInvitationTarget(zoe) {
return E(zoe).makeInvitationZoe();
},
+
+ // these three are for testing #9939
+ store: x => {
+ baggage.init('x', x);
+ assert(ws);
+ ws.add(x);
+ },
+ dummy: () => 0,
+ drop: () => (ws = undefined),
});
}
diff --git a/packages/SwingSet/test/kernel.test.js b/packages/SwingSet/test/kernel.test.js
index 95dc619a19b..f18a0720ff3 100644
--- a/packages/SwingSet/test/kernel.test.js
+++ b/packages/SwingSet/test/kernel.test.js
@@ -3,7 +3,7 @@
import { test } from '../tools/prepare-test-env-ava.js';
import { Fail } from '@endo/errors';
-import { kser, kslot } from '@agoric/kmarshal';
+import { kser, kunser, kslot } from '@agoric/kmarshal';
import buildKernel from '../src/kernel/index.js';
import { initializeKernel } from '../src/controller/initializeKernel.js';
import { makeVatSlot } from '../src/lib/parseVatSlots.js';
@@ -1567,10 +1567,14 @@ test('xs-worker default manager type', async t => {
);
});
-async function reapTest(t, freq) {
- const kernel = await makeKernel();
+async function reapTest(t, freq, overrideNever) {
+ const endowments = makeKernelEndowments();
+ await initializeKernel({}, endowments.kernelStorage);
+ const kernel = buildKernel(endowments, {}, {});
await kernel.start();
+ const { kernelStorage } = endowments;
const log = [];
+
function setup() {
function dispatch(vatDeliverObject) {
if (vatDeliverObject[0] === 'startVat') {
@@ -1583,6 +1587,20 @@ async function reapTest(t, freq) {
await kernel.createTestVat('vat1', setup, {}, { reapInterval: freq });
const vat1 = kernel.vatNameToID('vat1');
t.deepEqual(log, []);
+ const options = JSON.parse(kernelStorage.kvStore.get(`${vat1}.options`));
+ t.deepEqual(options.reapDirtThreshold, {
+ deliveries: freq,
+ gcKrefs: 'never', // createTestVat minimizes BOYD
+ });
+
+ if (overrideNever) {
+ // when upgradeSwingset v0->v1 encounters a non-reaping vat (like
+ // comms), it sets the .options reapDirtThreshold to `{ never:
+ // true }`, so verify that this inhibits BOYD
+ options.reapDirtThreshold = { never: true };
+ kernelStorage.kvStore.set(`${vat1}.options`, JSON.stringify(options));
+ freq = 'never';
+ }
const vatRoot = kernel.addExport(vat1, 'o+1');
function deliverMessage(ordinal) {
@@ -1602,11 +1620,28 @@ async function reapTest(t, freq) {
return ['bringOutYourDead'];
}
- for (let i = 0; i < 100; i += 1) {
- deliverMessage(i);
- }
+ t.deepEqual(JSON.parse(kernelStorage.kvStore.get(`${vat1}.reapDirt`)), {});
+ deliverMessage(0); // enqueues only
t.deepEqual(log, []);
await kernel.run();
+
+ // The first delivery increments dirt.deliveries . If freq=1 that
+ // will trigger an immediate BOYD and resets the counter, but for
+ // the slower-interval cases the counter will be left at 1.
+
+ const expected1 = {};
+ if (freq !== 'never' && freq > 1) {
+ expected1.deliveries = 1;
+ }
+ t.deepEqual(
+ JSON.parse(kernelStorage.kvStore.get(`${vat1}.reapDirt`)),
+ expected1,
+ );
+
+ for (let i = 1; i < 100; i += 1) {
+ deliverMessage(i); // enqueues only
+ }
+ await kernel.run();
for (let i = 0; i < 100; i += 1) {
t.deepEqual(log.shift(), matchMsg(i));
if (freq !== 'never' && (i + 1) % freq === 0) {
@@ -1635,3 +1670,150 @@ test('reap interval 17', async t => {
test('reap interval never', async t => {
await reapTest(t, 'never');
});
+
+test('reap interval override never', async t => {
+ await reapTest(t, 5, true);
+});
+
+// Set up two vats, one to export vrefs, the other to import/drop
+// them. The first will get a reapDirtThreshold.gcKrefs, and will log
+// when the kernel sends it BOYD.
+
+async function reapGCKrefsTest(t, freq, overrideNever) {
+ const endowments = makeKernelEndowments();
+ await initializeKernel({}, endowments.kernelStorage);
+ const kernel = buildKernel(endowments, {}, {});
+ await kernel.start();
+ const { kernelStorage } = endowments;
+ // note: worker=local, otherwise snapshotInitial/Interval would interfere
+
+ let boyds = 0;
+ let rxGCkrefs = 0;
+ let lastExported = 2;
+
+ // vat-under-test, export vrefs on request, watch for BOYDs
+ function setup1(syscall) {
+ function dispatch(vatDeliverObject) {
+ if (vatDeliverObject[0] === 'startVat') {
+ return; // skip startVat
+ }
+ if (vatDeliverObject[0] === 'message') {
+ // export vrefs, one per message
+ const target = vatDeliverObject[2].methargs.slots[0];
+ const vref = `o+${lastExported}`;
+ lastExported += 1;
+ syscall.send(target, kser(['hold', [kslot(vref)]]));
+ return;
+ }
+ if (vatDeliverObject[0] === 'bringOutYourDead') {
+ boyds += 1;
+ }
+ if (vatDeliverObject[0] === 'dropExports') {
+ rxGCkrefs += vatDeliverObject[1].length;
+ }
+ if (vatDeliverObject[0] === 'retireExports') {
+ rxGCkrefs += vatDeliverObject[1].length;
+ }
+ if (vatDeliverObject[0] === 'retireImports') {
+ rxGCkrefs += vatDeliverObject[1].length;
+ }
+ }
+ return dispatch;
+ }
+ const vat1 = await kernel.createTestVat(
+ 'vat1',
+ setup1,
+ {},
+ { reapInterval: 'never', reapGCKrefs: freq },
+ );
+ const v1root = kernel.getRootObject(vat1);
+ kernel.pinObject(v1root);
+
+ if (overrideNever) {
+ // when upgradeSwingset v0->v1 encounters a non-reaping vat (like
+ // comms), it sets the .options reapDirtThreshold to `{ never:
+ // true }`, so verify that this inhibits BOYD. It is especially
+ // important that this works against gcKrefs, otherwise we'd be
+ // BOYDing vat-comms all the time, which is pointless.
+ const options = JSON.parse(kernelStorage.kvStore.get(`${vat1}.options`));
+ options.reapDirtThreshold = { never: true };
+ kernelStorage.kvStore.set(`${vat1}.options`, JSON.stringify(options));
+ freq = 'never';
+ }
+
+ // helper vat, imports vrefs, drops on request
+ function setup2(syscall) {
+ const hold = [];
+ function dispatch(vatDeliverObject) {
+ if (vatDeliverObject[0] === 'startVat') {
+ return; // skip startVat
+ }
+ if (vatDeliverObject[0] === 'message') {
+ const [meth, args] = kunser(vatDeliverObject[2].methargs);
+ if (meth === 'hold') {
+ for (const vref of vatDeliverObject[2].methargs.slots) {
+ hold.push(vref);
+ }
+ } else {
+ const [count] = args;
+ syscall.dropImports(hold.slice(0, count));
+ syscall.retireImports(hold.slice(0, count));
+ hold.splice(0, count);
+ }
+ }
+ }
+ return dispatch;
+ }
+ const vat2 = await kernel.createTestVat('vat2', setup2, {});
+ const v2root = kernel.getRootObject(vat2);
+ kernel.pinObject(v2root);
+
+ await kernel.run();
+ t.is(boyds, 0);
+
+ async function addExport() {
+ kernel.queueToKref(v1root, `pleaseExport`, [kslot(v2root)], 'none');
+ await kernel.run();
+ }
+
+ async function doDrop(count) {
+ kernel.queueToKref(v2root, `drop`, [count], 'none');
+ await kernel.run();
+ }
+
+ await addExport();
+ await addExport();
+ t.is(boyds, 0);
+ // c-list should currently have two krefs exported by the vat
+
+ // now we drop one for every new one we add, and every 'interval'/2
+ // we should see a BOYD
+
+ let krefs = 0;
+ for (let i = 0; i < 10; i += 1) {
+ await addExport();
+ await doDrop(1);
+ krefs += 2;
+ t.is(rxGCkrefs, krefs);
+ if (freq === 'never' || krefs < freq) {
+ t.is(boyds, 0);
+ } else {
+ t.is(boyds, 1);
+ boyds = 0;
+ krefs = 0;
+ rxGCkrefs = 0;
+ }
+ }
+}
+
+test('reap gc-krefs 10', async t => {
+ await reapGCKrefsTest(t, 10);
+});
+
+test('reap gc-krefs 12', async t => {
+ await reapGCKrefsTest(t, 12);
+});
+
+test('reap gc-krefs overrideNever', async t => {
+ await reapGCKrefsTest(t, 12, true);
+});
diff --git a/packages/SwingSet/test/snapshots/state.test.js.md b/packages/SwingSet/test/snapshots/state.test.js.md
index 3ab81fd5cd5..4c02a66077d 100644
--- a/packages/SwingSet/test/snapshots/state.test.js.md
+++ b/packages/SwingSet/test/snapshots/state.test.js.md
@@ -8,8 +8,8 @@ Generated by [AVA](https://avajs.dev).
> initial state
- 'a5d302e6743578ccda03ea386abd49de0a3bf4d7dedda2f69585c663806c30bc'
+ '7b16bffd29f6a2d11bae7b536ef4c230af8cadc29284928b6cc2f7338507a987'
> expected activityhash
- 'f5f1f643f6242a73c79b0437dbab222d34642ea5d047f15aaf5551d5903711d3'
+ '7dbf5a49d4e2b999c431730fcd4927c01c713eaa54fe273626e4201853e38d3b'
diff --git a/packages/SwingSet/test/snapshots/state.test.js.snap b/packages/SwingSet/test/snapshots/state.test.js.snap
index 632a77941e6..0efcf0fac96 100644
Binary files a/packages/SwingSet/test/snapshots/state.test.js.snap and b/packages/SwingSet/test/snapshots/state.test.js.snap differ
diff --git a/packages/SwingSet/test/snapshots/xsnap-store.test.js.md b/packages/SwingSet/test/snapshots/xsnap-store.test.js.md
index 52a1b44b201..3a279e17741 100644
--- a/packages/SwingSet/test/snapshots/xsnap-store.test.js.md
+++ b/packages/SwingSet/test/snapshots/xsnap-store.test.js.md
@@ -9,6 +9,7 @@ Generated by [AVA](https://avajs.dev).
> initial snapshot
{
+ archiveWriteSeconds: undefined,
compressSeconds: 0,
dbSaveSeconds: 0,
hash: 'bee3b82eebdde4c5c3774fb95b7efe88382f7dc4afab90b4e0e58add54d6b81c',
@@ -18,17 +19,19 @@ Generated by [AVA](https://avajs.dev).
> after SES boot - sensitive to SES-shim, XS, and supervisor
{
+ archiveWriteSeconds: undefined,
compressSeconds: 0,
dbSaveSeconds: 0,
- hash: '30d2d6ce649f1f3b9d5dd48404ee32c4ff0cc9935b7aa4498c0bcd218eedca71',
- uncompressedSize: 827651,
+ hash: '5433501987ce52b3bd9ab47956195669c5adea89b050e8c787eb9da431ce1a6e',
+ uncompressedSize: 834907,
}
> after use of harden() - sensitive to SES-shim, XS, and supervisor
{
+ archiveWriteSeconds: undefined,
compressSeconds: 0,
dbSaveSeconds: 0,
- hash: '46d4988aa5eed7354684b76362fa8b6049e4467139e064a5b73fa8e80bed26a7',
- uncompressedSize: 827811,
+ hash: '4cdc352b710f0719bc6f541631315652b5da19093e18ce844ec274340a37efd5',
+ uncompressedSize: 835067,
}
diff --git a/packages/SwingSet/test/snapshots/xsnap-store.test.js.snap b/packages/SwingSet/test/snapshots/xsnap-store.test.js.snap
index 566a5d8b811..ca339e82017 100644
Binary files a/packages/SwingSet/test/snapshots/xsnap-store.test.js.snap and b/packages/SwingSet/test/snapshots/xsnap-store.test.js.snap differ
diff --git a/packages/SwingSet/test/state.test.js b/packages/SwingSet/test/state.test.js
index bdabd07f02a..c60a01aa79c 100644
--- a/packages/SwingSet/test/state.test.js
+++ b/packages/SwingSet/test/state.test.js
@@ -6,7 +6,10 @@ import { test } from '../tools/prepare-test-env-ava.js';
import { createHash } from 'crypto';
import { kser, kslot } from '@agoric/kmarshal';
import { initSwingStore } from '@agoric/swing-store';
-import makeKernelKeeper from '../src/kernel/state/kernelKeeper.js';
+import makeKernelKeeper, {
+ CURRENT_SCHEMA_VERSION,
+} from '../src/kernel/state/kernelKeeper.js';
+import { upgradeSwingset } from '../src/controller/upgradeSwingset.js';
import { makeKernelStats } from '../src/kernel/state/stats.js';
import { KERNEL_STATS_METRICS } from '../src/kernel/metrics.js';
import {
@@ -154,7 +157,7 @@ function buildKeeperStorageInMemory() {
function duplicateKeeper(serialize) {
const serialized = serialize();
const { kernelStorage } = initSwingStore(null, { serialized });
- const kernelKeeper = makeKernelKeeper(kernelStorage, null);
+ const kernelKeeper = makeKernelKeeper(kernelStorage, CURRENT_SCHEMA_VERSION);
kernelKeeper.loadStats();
return kernelKeeper;
}
@@ -174,15 +177,14 @@ test('kernelStorage param guards', async t => {
test('kernel state', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
- t.truthy(!k.getInitialized());
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
k.setInitialized();
-
k.emitCrankHashes();
+
checkState(t, store.dump, [
+ ['version', '2'],
['crankNumber', '0'],
- ['initialized', 'true'],
['gcActions', '[]'],
['runQueue', '[1,1]'],
['acceptanceQueue', '[1,1]'],
@@ -197,17 +199,22 @@ test('kernel state', async t => {
['kd.nextID', '30'],
['kp.nextID', '40'],
['kernel.defaultManagerType', 'local'],
- ['kernel.defaultReapInterval', '1'],
+ [
+ 'kernel.defaultReapDirtThreshold',
+ JSON.stringify({ deliveries: 1, gcKrefs: 20, computrons: 'never' }),
+ ],
['kernel.snapshotInitial', '3'],
['kernel.snapshotInterval', '200'],
['meter.nextID', '1'],
+ ['vats.terminated', '[]'],
]);
});
test('kernelKeeper vat names', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
const v1 = k.allocateVatIDForNameIfNeeded('vatname5');
const v2 = k.allocateVatIDForNameIfNeeded('Frank');
@@ -216,6 +223,7 @@ test('kernelKeeper vat names', async t => {
k.emitCrankHashes();
checkState(t, store.dump, [
+ ['version', '2'],
['crankNumber', '0'],
['gcActions', '[]'],
['runQueue', '[1,1]'],
@@ -233,10 +241,14 @@ test('kernelKeeper vat names', async t => {
['vat.name.vatname5', 'v1'],
['vat.name.Frank', 'v2'],
['kernel.defaultManagerType', 'local'],
- ['kernel.defaultReapInterval', '1'],
+ [
+ 'kernel.defaultReapDirtThreshold',
+ JSON.stringify({ deliveries: 1, gcKrefs: 20, computrons: 'never' }),
+ ],
['kernel.snapshotInitial', '3'],
['kernel.snapshotInterval', '200'],
['meter.nextID', '1'],
+ ['vats.terminated', '[]'],
]);
t.deepEqual(k.getStaticVats(), [
['Frank', 'v2'],
@@ -256,8 +268,9 @@ test('kernelKeeper vat names', async t => {
test('kernelKeeper device names', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
const d7 = k.allocateDeviceIDForNameIfNeeded('devicename5');
const d8 = k.allocateDeviceIDForNameIfNeeded('Frank');
@@ -266,6 +279,7 @@ test('kernelKeeper device names', async t => {
k.emitCrankHashes();
checkState(t, store.dump, [
+ ['version', '2'],
['crankNumber', '0'],
['gcActions', '[]'],
['runQueue', '[1,1]'],
@@ -283,10 +297,14 @@ test('kernelKeeper device names', async t => {
['device.name.devicename5', 'd7'],
['device.name.Frank', 'd8'],
['kernel.defaultManagerType', 'local'],
- ['kernel.defaultReapInterval', '1'],
+ [
+ 'kernel.defaultReapDirtThreshold',
+ JSON.stringify({ deliveries: 1, gcKrefs: 20, computrons: 'never' }),
+ ],
['kernel.snapshotInitial', '3'],
['kernel.snapshotInterval', '200'],
['meter.nextID', '1'],
+ ['vats.terminated', '[]'],
]);
t.deepEqual(k.getDevices(), [
['Frank', 'd8'],
@@ -306,8 +324,9 @@ test('kernelKeeper device names', async t => {
test('kernelKeeper runQueue', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
t.is(k.getRunQueueLength(), 0);
t.is(k.getNextRunQueueMsg(), undefined);
@@ -344,8 +363,9 @@ test('kernelKeeper runQueue', async t => {
test('kernelKeeper promises', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
const p1 = k.addKernelPromiseForVat('v4');
t.deepEqual(k.getKernelPromise(p1), {
@@ -442,6 +462,7 @@ test('kernelKeeper promises', async t => {
k.emitCrankHashes();
checkState(t, store.dump, [
+ ['version', '2'],
['crankNumber', '0'],
['device.nextID', '7'],
['vat.nextID', '1'],
@@ -465,10 +486,14 @@ test('kernelKeeper promises', async t => {
[`${ko}.owner`, 'v1'],
[`${ko}.refCount`, '1,1'],
['kernel.defaultManagerType', 'local'],
- ['kernel.defaultReapInterval', '1'],
+ [
+ 'kernel.defaultReapDirtThreshold',
+ JSON.stringify({ deliveries: 1, gcKrefs: 20, computrons: 'never' }),
+ ],
['kernel.snapshotInitial', '3'],
['kernel.snapshotInterval', '200'],
['meter.nextID', '1'],
+ ['vats.terminated', '[]'],
]);
k.deleteKernelObject(ko);
@@ -477,8 +502,9 @@ test('kernelKeeper promises', async t => {
test('kernelKeeper promise resolveToData', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
const p1 = k.addKernelPromiseForVat('v4');
const o1 = k.addKernelObject('v1');
@@ -493,8 +519,9 @@ test('kernelKeeper promise resolveToData', async t => {
test('kernelKeeper promise reject', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
const p1 = k.addKernelPromiseForVat('v4');
const o1 = k.addKernelObject('v1');
@@ -509,10 +536,14 @@ test('kernelKeeper promise reject', async t => {
test('vatKeeper', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
-
+ k.setInitialized();
const v1 = k.allocateVatIDForNameIfNeeded('name1');
+ const source = { bundleID: 'foo' };
+ const options = { workerOptions: {}, reapDirtThreshold: {} };
+ k.createVatState(v1, source, options);
+
const vk = k.provideVatKeeper(v1);
// TODO: confirm that this level of caching is part of the API
t.is(vk, k.provideVatKeeper(v1));
@@ -545,35 +576,35 @@ test('vatKeeper', async t => {
test('vatKeeper.getOptions', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
-
+ k.setInitialized();
const v1 = k.allocateVatIDForNameIfNeeded('name1');
- const vk = k.provideVatKeeper(v1);
const bundleID =
'b1-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
- vk.setSourceAndOptions(
- { bundleID },
- {
- workerOptions: { type: 'local' },
- name: 'fred',
- },
- );
+ const source = { bundleID };
+ const workerOptions = { type: 'local' };
+ const options = { workerOptions, name: 'fred', reapDirtThreshold: {} };
+ k.createVatState(v1, source, options);
+
+ const vk = k.provideVatKeeper(v1);
const { name } = vk.getOptions();
t.is(name, 'fred');
});
test('XS vatKeeper defaultManagerType', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'xs-worker' });
+ k.setInitialized();
t.is(k.getDefaultManagerType(), 'xs-worker');
});
test('meters', async t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
const m1 = k.allocateMeter(100n, 10n);
const m2 = k.allocateMeter(200n, 150n);
t.not(m1, m2);
@@ -657,8 +688,9 @@ const makeTestCrankHasher = (algorithm = 'sha256') => {
test('crankhash - initial state and additions', t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
k.emitCrankHashes();
// the initial state additions happen to hash to this:
const initialActivityHash = store.kvStore.get('activityhash');
@@ -696,8 +728,9 @@ Then commit the changes in .../snapshots/ path.
test('crankhash - skip keys', t => {
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
k.emitCrankHashes();
k.kvStore.set('one', '1');
@@ -723,8 +756,9 @@ test('crankhash - duplicate set', t => {
// hash as we add/delete, not just the accumulated additions/deletions set
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
k.emitCrankHashes();
k.kvStore.set('one', '1');
@@ -754,8 +788,9 @@ test('crankhash - set and delete', t => {
// setting and deleting a key is different than never setting it
const store = buildKeeperStorageInMemory();
- const k = makeKernelKeeper(store, null);
+ const k = makeKernelKeeper(store, 'uninitialized');
k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
k.emitCrankHashes();
const h1 = makeTestCrankHasher('sha256');
@@ -925,3 +960,232 @@ test('stats - can load and save existing stats', t => {
t.deepEqual(JSON.parse(getSerializedStats().consensusStats), consensusStats);
t.deepEqual(JSON.parse(getSerializedStats().localStats), localStats);
});
+
+test('vatKeeper dirt counters', async t => {
+ const store = buildKeeperStorageInMemory();
+ const k = makeKernelKeeper(store, 'uninitialized');
+ k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
+ k.saveStats();
+
+ // the defaults are designed for testing
+ t.deepEqual(JSON.parse(k.kvStore.get(`kernel.defaultReapDirtThreshold`)), {
+ deliveries: 1,
+ gcKrefs: 20,
+ computrons: 'never',
+ });
+
+ const reapDirtThreshold = { deliveries: 10, gcKrefs: 20, computrons: 100 };
+ const never = { deliveries: 'never', gcKrefs: 'never', computrons: 'never' };
+
+ // a new DB will have empty dirt entries for each vat created
+ const source = { bundleID: 'foo' };
+ const v1 = k.allocateVatIDForNameIfNeeded('name1');
+ k.createVatState(v1, source, { workerOptions: {}, reapDirtThreshold });
+ const vk1 = k.provideVatKeeper(v1);
+
+ const v2 = k.allocateVatIDForNameIfNeeded('name2');
+ k.createVatState(v2, source, { workerOptions: {}, reapDirtThreshold });
+ const vk2 = k.provideVatKeeper(v2);
+
+ const v3 = k.allocateVatIDForNameIfNeeded('name3');
+ k.createVatState(v3, source, {
+ workerOptions: {},
+ reapDirtThreshold: never,
+ });
+ const vk3 = k.provideVatKeeper(v3);
+
+ // the nominal "all clean" entry is { deliveries: 0, gcKrefs: 0,
+ // computrons: 0 }, but we only store the non-zero keys, so it's
+ // really {}
+ t.deepEqual(vk1.getReapDirt(), {});
+ t.deepEqual(vk2.getReapDirt(), {});
+
+ // our write-through cache should store the initial value in the DB
+ t.true(store.kvStore.has(`${v1}.reapDirt`));
+ t.deepEqual(JSON.parse(store.kvStore.get(`${v1}.reapDirt`)), {});
+
+ // changing one entry doesn't change any others
+ vk1.addDirt({ deliveries: 1, gcKrefs: 0, computrons: 12 });
+ t.deepEqual(vk1.getReapDirt(), { deliveries: 1, gcKrefs: 0, computrons: 12 });
+ t.deepEqual(vk2.getReapDirt(), {});
+ t.not(vk1.getReapDirt(), vk2.getReapDirt());
+ // and writes through the cache
+ t.deepEqual(JSON.parse(store.kvStore.get(`${v1}.reapDirt`)), {
+ deliveries: 1,
+ gcKrefs: 0,
+ computrons: 12,
+ });
+
+ // clearing the dirt will zero out the entries
+ vk1.clearReapDirt();
+ t.deepEqual(vk1.getReapDirt(), {});
+ t.deepEqual(JSON.parse(store.kvStore.get(`${v1}.reapDirt`)), {});
+
+ // nothing has reached the threshold yet
+ t.is(k.nextReapAction(), undefined);
+
+ vk1.addDirt({ deliveries: 4 });
+ t.deepEqual(vk1.getReapDirt(), { deliveries: 4 });
+ t.is(k.nextReapAction(), undefined);
+ vk1.addDirt({ deliveries: 5 });
+ t.deepEqual(vk1.getReapDirt(), { deliveries: 9 });
+ t.is(k.nextReapAction(), undefined);
+ vk1.addDirt({ deliveries: 6 });
+ t.deepEqual(vk1.getReapDirt(), { deliveries: 15 });
+ t.deepEqual(k.nextReapAction(), { type: 'bringOutYourDead', vatID: v1 });
+ t.is(k.nextReapAction(), undefined);
+
+ // dirt is ignored when the threshold is 'never'
+ vk3.addDirt({ deliveries: 4 });
+ t.deepEqual(vk3.getReapDirt(), {});
+});
+
+test('dirt upgrade', async t => {
+ const store = buildKeeperStorageInMemory();
+ const k = makeKernelKeeper(store, 'uninitialized');
+ k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
+ k.saveStats();
+ const v1 = k.allocateVatIDForNameIfNeeded('name1');
+ const source = { bundleID: 'foo' };
+ // actual vats get options.reapDirtThreshold ; we install
+ // options.reapInterval to simulate the old version, and we use
+ // nonsense values because .reapInterval was not updated by
+ // changeVatOptions so the upgrade process should ignore it
+ const options = { workerOptions: {}, reapInterval: 666 };
+ k.createVatState(v1, source, options);
+ // "v2" is like v1 but with the default reapInterval
+ const v2 = k.allocateVatIDForNameIfNeeded('name2');
+ const options2 = { ...options, reapInterval: 667 };
+ k.createVatState(v2, source, options2);
+ // "v3" is like comms: no BOYD
+ const v3 = k.allocateVatIDForNameIfNeeded('comms');
+ const options3 = { ...options, reapInterval: 'never' };
+ k.createVatState(v3, source, options3);
+
+ // Test that upgrade from an older version of the DB will populate
+ // the right keys. We simulate the old version by modifying a
+ // serialized copy. The old version (on mainnet) had things like:
+ // * kernel.defaultReapInterval: 1000
+ // * v1.options: { ... reapInterval: 1000 }
+ // * v1.reapCountdown: 123
+ // * v1.reapInterval: 1000
+ // * v2.options: { ... reapInterval: 300 }
+ // * v2.reapCountdown: 123
+ // * v2.reapInterval: 300
+ // * v3.options: { ... reapInterval: 'never' }
+ // * v3.reapCountdown: 'never'
+ // * v3.reapInterval: 'never'
+
+ t.is(k.kvStore.get('version'), '2');
+ k.kvStore.delete(`kernel.defaultReapDirtThreshold`);
+ k.kvStore.set(`kernel.defaultReapInterval`, '1000');
+
+ // v1 uses the default reapInterval
+ k.kvStore.delete(`${v1}.reapDirt`);
+ k.kvStore.delete(`${v1}.reapDirtThreshold`);
+ k.kvStore.set(`${v1}.reapInterval`, '1000');
+ k.kvStore.set(`${v1}.reapCountdown`, '700');
+
+ // v2 uses a custom reapCountdown
+ k.kvStore.delete(`${v2}.reapDirt`);
+ k.kvStore.delete(`${v2}.reapDirtThreshold`);
+ k.kvStore.set(`${v2}.reapInterval`, '300');
+ k.kvStore.set(`${v2}.reapCountdown`, '70');
+
+ // v3 is like comms and never reaps
+ k.kvStore.delete(`${v3}.reapDirt`);
+ k.kvStore.delete(`${v3}.reapDirtThreshold`);
+ k.kvStore.set(`${v3}.reapInterval`, 'never');
+ k.kvStore.set(`${v3}.reapCountdown`, 'never');
+
+ k.kvStore.delete(`version`);
+ k.kvStore.set('initialized', 'true');
+ k.kvStore.delete(`vats.terminated`);
+
+ // kernelKeeper refuses to work with an old state
+ t.throws(() => duplicateKeeper(store.serialize));
+
+ // it requires a manual upgrade
+ let k2;
+ {
+ const serialized = store.serialize();
+ const { kernelStorage } = initSwingStore(null, { serialized });
+ upgradeSwingset(kernelStorage);
+ k2 = makeKernelKeeper(kernelStorage, CURRENT_SCHEMA_VERSION); // works this time
+ k2.loadStats();
+ }
+
+ t.true(k2.kvStore.has(`kernel.defaultReapDirtThreshold`));
+ // threshold.deliveries is converted from defaultReapInterval
+ t.deepEqual(JSON.parse(k2.kvStore.get(`kernel.defaultReapDirtThreshold`)), {
+ deliveries: 1000,
+ gcKrefs: 20,
+ computrons: 'never',
+ });
+
+ t.true(k2.kvStore.has(`${v1}.reapDirt`));
+ // reapDirt.deliveries computed from old reapInterval-reapCountdown
+ t.deepEqual(JSON.parse(k2.kvStore.get(`${v1}.reapDirt`)), {
+ deliveries: 300,
+ });
+ // reapDirtThreshold.deliveries computed from old reapInterval, and
+ // because it matches the kernel-wide default, the .options record
+ // is left empty
+ t.deepEqual(
+ JSON.parse(k2.kvStore.get(`${v1}.options`)).reapDirtThreshold,
+ {},
+ );
+ const vk1New = k2.provideVatKeeper(v1);
+ t.deepEqual(vk1New.getReapDirt(), { deliveries: 300 });
+
+ // v2 reapDirt is computed the same way
+ t.true(k2.kvStore.has(`${v2}.reapDirt`));
+ t.deepEqual(JSON.parse(k2.kvStore.get(`${v2}.reapDirt`)), {
+ deliveries: 230,
+ });
+ // the custom reapInterval is transformed into an .options override
+ t.deepEqual(JSON.parse(k2.kvStore.get(`${v2}.options`)).reapDirtThreshold, {
+ deliveries: 300,
+ });
+ const vk2New = k2.provideVatKeeper(v2);
+ t.deepEqual(vk2New.getReapDirt(), { deliveries: 230 });
+
+ t.true(k2.kvStore.has(`${v3}.reapDirt`));
+ t.deepEqual(JSON.parse(k2.kvStore.get(`${v3}.reapDirt`)), {});
+ t.deepEqual(JSON.parse(k2.kvStore.get(`${v3}.options`)).reapDirtThreshold, {
+ never: true,
+ });
+});
+
+test('v2 upgrade', async t => {
+ // this should add vats.terminated
+ const store = buildKeeperStorageInMemory();
+ const k = makeKernelKeeper(store, 'uninitialized');
+ k.createStartingKernelState({ defaultManagerType: 'local' });
+ k.setInitialized();
+ k.saveStats();
+
+ // roll back to v1
+ t.is(k.kvStore.get('version'), '2');
+ k.kvStore.delete(`vats.terminated`);
+ k.kvStore.set('version', '1');
+
+ // kernelKeeper refuses to work with an old state
+ t.throws(() => duplicateKeeper(store.serialize));
+
+ // it requires a manual upgrade
+ let k2;
+ {
+ const serialized = store.serialize();
+ const { kernelStorage } = initSwingStore(null, { serialized });
+ upgradeSwingset(kernelStorage);
+ k2 = makeKernelKeeper(kernelStorage, CURRENT_SCHEMA_VERSION); // works this time
+ k2.loadStats();
+ }
+
+ t.true(k2.kvStore.has(`vats.terminated`));
+ t.deepEqual(JSON.parse(k2.kvStore.get(`vats.terminated`)), []);
+ t.is(k2.kvStore.get(`version`), '2');
+});
diff --git a/packages/SwingSet/test/stripPrefix.test.js b/packages/SwingSet/test/stripPrefix.test.js
new file mode 100644
index 00000000000..a34e8ac3cd6
--- /dev/null
+++ b/packages/SwingSet/test/stripPrefix.test.js
@@ -0,0 +1,8 @@
+import { test } from '../tools/prepare-test-env-ava.js';
+import { stripPrefix } from '../src/kernel/state/kernelKeeper.js';
+
+test('stripPrefix', t => {
+ t.is(stripPrefix('prefix', 'prefixed'), 'ed');
+ t.is(stripPrefix('', 'prefixed'), 'prefixed');
+ t.throws(() => stripPrefix('not', 'prefixed'), { message: /prefixed/ });
+});
diff --git a/packages/SwingSet/test/transcript-light.test.js b/packages/SwingSet/test/transcript-light.test.js
index bc934ec478a..9049eb57845 100644
--- a/packages/SwingSet/test/transcript-light.test.js
+++ b/packages/SwingSet/test/transcript-light.test.js
@@ -17,7 +17,7 @@ test('transcript-light load', async t => {
t.teardown(c.shutdown);
const serialized0 = debug.serialize();
const kvstate0 = debug.dump().kvEntries;
- t.is(kvstate0.initialized, 'true');
+ t.is(kvstate0.version, '2');
t.is(kvstate0.runQueue, '[1,1]');
t.not(kvstate0.acceptanceQueue, '[]');
diff --git a/packages/SwingSet/test/upgrade-swingset.test.js b/packages/SwingSet/test/upgrade-swingset.test.js
new file mode 100644
index 00000000000..a18b2699dd8
--- /dev/null
+++ b/packages/SwingSet/test/upgrade-swingset.test.js
@@ -0,0 +1,231 @@
+/* eslint-disable no-underscore-dangle */
+// @ts-nocheck
+
+import { initSwingStore } from '@agoric/swing-store';
+import { test } from '../tools/prepare-test-env-ava.js';
+
+import {
+ initializeSwingset,
+ makeSwingsetController,
+ upgradeSwingset,
+ buildKernelBundles,
+} from '../src/index.js';
+
+test.before(async t => {
+ const kernelBundles = await buildKernelBundles();
+ t.context.data = { kernelBundles };
+});
+
+test('kernel refuses to run with out-of-date DB - v0', async t => {
+ const { hostStorage, kernelStorage } = initSwingStore();
+ const { commit } = hostStorage;
+ const { kvStore } = kernelStorage;
+ const config = {};
+ await initializeSwingset(config, [], kernelStorage, t.context.data);
+ await commit();
+
+ // now doctor the initial state to make it look like the
+ // kernelkeeper v0 schema, just deleting the version key and adding
+ // 'initialized'
+
+ t.is(kvStore.get('version'), '2');
+ kvStore.delete(`version`);
+ kvStore.set('initialized', 'true');
+ await commit();
+
+ // Now build a controller around this modified state, which should fail.
+ await t.throwsAsync(() => makeSwingsetController(kernelStorage), {
+ message: /kernel DB is too old/,
+ });
+});
+
+test('kernel refuses to run with out-of-date DB - v1', async t => {
+ const { hostStorage, kernelStorage } = initSwingStore();
+ const { commit } = hostStorage;
+ const { kvStore } = kernelStorage;
+ const config = {};
+ await initializeSwingset(config, [], kernelStorage, t.context.data);
+ await commit();
+
+ // now doctor the initial state to make it look like the
+ // kernelkeeper v1 schema, by reducing the version key and removing
+ // vats.terminated
+
+ t.is(kvStore.get('version'), '2');
+ kvStore.set(`version`, '1');
+ kvStore.delete('vats.terminated');
+ await commit();
+
+ // Now build a controller around this modified state, which should fail.
+ await t.throwsAsync(() => makeSwingsetController(kernelStorage), {
+ message: /kernel DB is too old/,
+ });
+});
+
+test('upgrade kernel state', async t => {
+ const { hostStorage, kernelStorage } = initSwingStore();
+ const { commit } = hostStorage;
+ const { kvStore } = kernelStorage;
+ const config = {
+ vats: {
+ one: {
+ sourceSpec: new URL(
+ 'files-vattp/bootstrap-test-vattp.js',
+ import.meta.url,
+ ).pathname,
+ },
+ },
+ };
+ await initializeSwingset(config, [], kernelStorage, t.context.data);
+ await commit();
+
+ // now doctor the initial state to make it look like the
+ // kernelkeeper v0 schema, with 'kernel.defaultReapInterval' instead
+ // of 'kernel.defaultReapDirtThreshold', and
+ // 'v1.reapCountdown`/`.reapInterval` . This is cribbed from "dirt
+ // upgrade" in test-state.js.
+ //
+ // our mainnet vats have data like:
+ // v5.options|{"workerOptions":{"type":"xsnap","bundleIDs":["b0-5c790a966210b78de758fb442af542714ed96da09db76e0b31d6a237e555fd62","b0-e0d2dafc7e981947b42118e8c950837109683bae56f7b4f5bffa1b67e5c1e768"]},"name":"timer","enableSetup":false,"enablePipelining":false,"enableDisavow":false,"useTranscript":true,"reapInterval":1000,"critical":false}
+ // v5.reapCountdown|181
+ // v5.reapInterval|1000
+ //
+ // This is a bit fragile.. there are probably ways to refactor
+ // kernelKeeper to make this better, or at least put all the
+ // manipulation/simulation code in the same place.
+
+ t.true(kvStore.has('kernel.defaultReapDirtThreshold'));
+
+ t.is(kvStore.get('version'), '2');
+ kvStore.delete('version'); // i.e. revert to v0
+ kvStore.set('initialized', 'true');
+ kvStore.delete('vats.terminated');
+ kvStore.delete(`kernel.defaultReapDirtThreshold`);
+ kvStore.set(`kernel.defaultReapInterval`, '300');
+
+ const vatIDs = {};
+ for (const name of JSON.parse(kvStore.get('vat.names'))) {
+ const vatID = kvStore.get(`vat.name.${name}`);
+ t.truthy(vatID, name);
+ vatIDs[name] = vatID;
+ t.true(kvStore.has(`${vatID}.reapDirt`));
+ kvStore.delete(`${vatID}.reapDirt`);
+ const options = JSON.parse(kvStore.get(`${vatID}.options`));
+ t.truthy(options);
+ t.truthy(options.reapDirtThreshold);
+ delete options.reapDirtThreshold;
+ options.reapInterval = 55; // ignored by upgrader, so make it bogus
+ kvStore.set(`${vatID}.options`, JSON.stringify(options));
+ if (name === 'comms') {
+ kvStore.set(`${vatID}.reapInterval`, 'never');
+ kvStore.set(`${vatID}.reapCountdown`, 'never');
+ } else {
+ kvStore.set(`${vatID}.reapInterval`, '100');
+ kvStore.set(`${vatID}.reapCountdown`, '70');
+ // 100-70 means the new state's dirt.deliveries should be 30
+ }
+ }
+
+ await commit();
+
+ // confirm that this state is too old for the kernel to use
+ await t.throwsAsync(() => makeSwingsetController(kernelStorage), {
+ message: /kernel DB is too old/,
+ });
+
+ // upgrade it
+ upgradeSwingset(kernelStorage);
+
+ // now we should be good to go
+ const _controller = await makeSwingsetController(kernelStorage);
+
+ t.true(kvStore.has('kernel.defaultReapDirtThreshold'));
+ // the kernel-wide threshold gets a .gcKrefs (to meet our upcoming
+ // slow-deletion goals)
+ t.deepEqual(JSON.parse(kvStore.get('kernel.defaultReapDirtThreshold')), {
+ computrons: 'never',
+ deliveries: 300,
+ gcKrefs: 20,
+ });
+
+ // normal vat has some (computed) accumulated dirt
+ t.deepEqual(JSON.parse(kvStore.get(`${vatIDs.one}.reapDirt`)), {
+ deliveries: 30,
+ });
+ // anywhere the vat's upgraded threshold differs from the
+ // kernel-wide threshold, .options gets an override value, in this
+ // case on deliveries (since 100 !== 300)
+ t.deepEqual(
+ JSON.parse(kvStore.get(`${vatIDs.one}.options`)).reapDirtThreshold,
+ { deliveries: 100 },
+ );
+
+ // comms doesn't reap, and doesn't count dirt, and gets a special
+ // 'never' marker
+ t.deepEqual(JSON.parse(kvStore.get(`${vatIDs.comms}.reapDirt`)), {});
+ t.deepEqual(
+ JSON.parse(kvStore.get(`${vatIDs.comms}.options`)).reapDirtThreshold,
+ { never: true },
+ );
+
+ // TODO examine the state, use it
+
+ // TODO check the export-data callbacks
+});
+
+test('upgrade non-reaping kernel state', async t => {
+ const { hostStorage, kernelStorage } = initSwingStore();
+ const { commit } = hostStorage;
+ const { kvStore } = kernelStorage;
+ const config = {};
+ await initializeSwingset(config, [], kernelStorage, t.context.data);
+ await commit();
+
+ // now doctor the initial state to make it look like the
+ // kernelkeeper v0 schema, with 'kernel.defaultReapInterval' of 'never'
+
+ t.true(kvStore.has('kernel.defaultReapDirtThreshold'));
+
+ t.is(kvStore.get('version'), '2');
+ kvStore.delete('version'); // i.e. revert to v0
+ kvStore.set('initialized', 'true');
+ kvStore.delete('vats.terminated');
+ kvStore.delete(`kernel.defaultReapDirtThreshold`);
+ kvStore.set(`kernel.defaultReapInterval`, 'never');
+
+ const vatIDs = {};
+ for (const name of JSON.parse(kvStore.get('vat.names'))) {
+ const vatID = kvStore.get(`vat.name.${name}`);
+ t.truthy(vatID, name);
+ vatIDs[name] = vatID;
+ t.true(kvStore.has(`${vatID}.reapDirt`));
+ kvStore.delete(`${vatID}.reapDirt`);
+ const options = JSON.parse(kvStore.get(`${vatID}.options`));
+ t.truthy(options);
+ t.truthy(options.reapDirtThreshold);
+ delete options.reapDirtThreshold;
+ options.reapInterval = 'never';
+ kvStore.set(`${vatID}.options`, JSON.stringify(options));
+ kvStore.set(`${vatID}.reapInterval`, 'never');
+ kvStore.set(`${vatID}.reapCountdown`, 'never');
+ }
+ await commit();
+
+ // confirm that this state is too old for the kernel to use
+ await t.throwsAsync(() => makeSwingsetController(kernelStorage), {
+ message: /kernel DB is too old/,
+ });
+
+ // upgrade it
+ upgradeSwingset(kernelStorage);
+
+ // now we should be good to go
+ const _controller = await makeSwingsetController(kernelStorage);
+
+ t.true(kvStore.has('kernel.defaultReapDirtThreshold'));
+ t.deepEqual(JSON.parse(kvStore.get('kernel.defaultReapDirtThreshold')), {
+ computrons: 'never',
+ deliveries: 'never',
+ gcKrefs: 'never',
+ });
+});
diff --git a/packages/SwingSet/test/upgrade/upgrade.test.js b/packages/SwingSet/test/upgrade/upgrade.test.js
index 77b7c781b87..aca1efbbd89 100644
--- a/packages/SwingSet/test/upgrade/upgrade.test.js
+++ b/packages/SwingSet/test/upgrade/upgrade.test.js
@@ -707,20 +707,11 @@ test('non-durable exports are abandoned by upgrade of non-liveslots vat', async
'1,1',
'strong observation of abandoned object retains ref counts',
);
- // TODO: Expect and verify observer receipt of dispatch.retireExports
- // and corresponding removal of weakKref ref counts.
- // https://github.com/Agoric/agoric-sdk/issues/7212
t.is(
kvStore.get(`${weakKref}.refCount`),
- '0,1',
- 'weak observation of abandoned object retains ref counts before #7212',
+ undefined,
+ 'unreachable abandoned object is forgotten',
);
- // t.is(
- // kvStore.get(`${weakKref}.refCount`),
- // undefined,
- // 'unreachable abandoned object is forgotten',
- // );
- // const observerLog = await messageToVat('observer', 'getDispatchLog');
});
// No longer valid as of removing stopVat per #6650
diff --git a/packages/SwingSet/test/vat-admin/bootstrap.js b/packages/SwingSet/test/vat-admin/bootstrap.js
index 5b1bcaa15ee..74bf050d9ac 100644
--- a/packages/SwingSet/test/vat-admin/bootstrap.js
+++ b/packages/SwingSet/test/vat-admin/bootstrap.js
@@ -25,6 +25,14 @@ export function buildRootObject() {
return n;
},
+ async byNameWithOptions(bundleName, opts) {
+ const { root } = await E(admin).createVatByName(bundleName, {
+ ...options,
+ ...opts,
+ });
+ return root;
+ },
+
async byNamedBundleCap(name) {
const bcap = await E(admin).getNamedBundleCap(name);
const { root } = await E(admin).createVat(bcap, options);
diff --git a/packages/SwingSet/test/vat-admin/create-vat.test.js b/packages/SwingSet/test/vat-admin/create-vat.test.js
index a23a686752e..40b3325cc58 100644
--- a/packages/SwingSet/test/vat-admin/create-vat.test.js
+++ b/packages/SwingSet/test/vat-admin/create-vat.test.js
@@ -444,3 +444,40 @@ test('createVat holds refcount', async t => {
await stepUntil(() => false);
t.deepEqual(kunser(c.kpResolution(kpid)), 0);
});
+
+test('createVat without options', async t => {
+ const printSlog = false;
+ const { c, kernelStorage } = await doTestSetup(t, false, printSlog);
+ const { kvStore } = kernelStorage;
+ const threshold = JSON.parse(kvStore.get('kernel.defaultReapDirtThreshold'));
+ t.deepEqual(threshold, { deliveries: 1, gcKrefs: 20, computrons: 'never' });
+
+ const kpid = c.queueToVatRoot('bootstrap', 'byNameWithOptions', [
+ 'new13',
+ {},
+ ]);
+ await c.run();
+ const kref = kunser(c.kpResolution(kpid)).getKref();
+ const vatID = kvStore.get(`${kref}.owner`);
+ const options = JSON.parse(kvStore.get(`${vatID}.options`));
+ t.deepEqual(options.reapDirtThreshold, {});
+});
+
+test('createVat with options', async t => {
+ const printSlog = false;
+ const { c, kernelStorage } = await doTestSetup(t, false, printSlog);
+ const { kvStore } = kernelStorage;
+ const threshold = JSON.parse(kvStore.get('kernel.defaultReapDirtThreshold'));
+ t.deepEqual(threshold, { deliveries: 1, gcKrefs: 20, computrons: 'never' });
+
+ const opts = { reapInterval: 123 };
+ const kpid = c.queueToVatRoot('bootstrap', 'byNameWithOptions', [
+ 'new13',
+ opts,
+ ]);
+ await c.run();
+ const kref = kunser(c.kpResolution(kpid)).getKref();
+ const vatID = kvStore.get(`${kref}.owner`);
+ const options = JSON.parse(kvStore.get(`${vatID}.options`));
+ t.deepEqual(options.reapDirtThreshold, { deliveries: 123 });
+});
diff --git a/packages/SwingSet/test/vat-admin/slow-termination/bootstrap-slow-terminate.js b/packages/SwingSet/test/vat-admin/slow-termination/bootstrap-slow-terminate.js
new file mode 100644
index 00000000000..135124209ef
--- /dev/null
+++ b/packages/SwingSet/test/vat-admin/slow-termination/bootstrap-slow-terminate.js
@@ -0,0 +1,55 @@
+import { Far, E } from '@endo/far';
+
+export function buildRootObject(_vatPowers) {
+ let root;
+ let adminNode;
+ const myImports = [];
+
+ const self = Far('root', {
+ async bootstrap(vats, devices) {
+ const svc = E(vats.vatAdmin).createVatAdminService(devices.vatAdmin);
+ // create a dynamic vat, send it a message and let it respond, to make
+ // sure everything is working
+ const dude = await E(svc).createVatByName('dude');
+ root = dude.root;
+ adminNode = dude.adminNode;
+ await E(root).alive();
+
+ // set up 20 "bootstrap exports, dude imports" c-list entries
+ for (let i = 0; i < 20; i += 1) {
+ await E(root).acceptImports(Far('bootstrap export', {}));
+ }
+
+ // set up 20 "dude exports, bootstrap imports" c-list entries
+
+ for (let i = 0; i < 20; i += 1) {
+ myImports.push(await E(root).sendExport());
+ }
+
+ // ask dude to creates 20 vatstore entries (in addition to the
+ // built-in liveslots stuff)
+ await E(root).makeVatstore(20);
+
+ return 'bootstrap done';
+ },
+
+ async kill(mode) {
+ switch (mode) {
+ case 'kill':
+ await E(adminNode).terminateWithFailure(mode);
+ break;
+ case 'dieHappy':
+ await E(root).dieHappy(mode);
+ break;
+ default:
+ console.log('something terrible has happened');
+ break;
+ }
+ // confirm the vat is dead, even though cleanup happens later
+ return E(root)
+ .ping()
+ .catch(err => `kill done, ${err}`);
+ },
+ });
+ return self;
+}
diff --git a/packages/SwingSet/test/vat-admin/slow-termination/slow-termination.test.js b/packages/SwingSet/test/vat-admin/slow-termination/slow-termination.test.js
new file mode 100644
index 00000000000..336176024c6
--- /dev/null
+++ b/packages/SwingSet/test/vat-admin/slow-termination/slow-termination.test.js
@@ -0,0 +1,294 @@
+// @ts-nocheck
+// eslint-disable-next-line import/order
+import { test } from '../../../tools/prepare-test-env-ava.js';
+
+import tmp from 'tmp';
+import sqlite3 from 'better-sqlite3';
+import path from 'path';
+
+import { kser } from '@agoric/kmarshal';
+import { initSwingStore } from '@agoric/swing-store';
+
+import { buildVatController, buildKernelBundles } from '../../../src/index.js';
+import { enumeratePrefixedKeys } from '../../../src/kernel/state/storageHelper.js';
+
+/**
+ * @param {string} [prefix]
+ * @returns {Promise<[string, () => void]>}
+ */
+export const tmpDir = prefix =>
+ new Promise((resolve, reject) => {
+ tmp.dir({ unsafeCleanup: true, prefix }, (err, name, removeCallback) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve([name, removeCallback]);
+ }
+ });
+ });
+
+test.before(async t => {
+ const kernelBundles = await buildKernelBundles();
+ t.context.data = { kernelBundles };
+});
+
+const makeCleanupPolicy = budget => {
+ let cleanups = 0;
+ const stop = () => false;
+ const policy = harden({
+ vatCreated: stop,
+ crankComplete: stop,
+ crankFailed: stop,
+ emptyCrank: stop,
+ allowCleanup() {
+ if (budget > 0) {
+ return { default: budget };
+ } else {
+ return false;
+ }
+ },
+ didCleanup(spent) {
+ budget -= spent.cleanups.total;
+ cleanups += spent.cleanups.total;
+ },
+ });
+ const getCleanups = () => cleanups;
+ return [policy, getCleanups];
+};
+
+const bfile = relpath => new URL(relpath, import.meta.url).pathname;
+
+async function doSlowTerminate(t, mode) {
+ const config = {
+ defaultManagerType: 'xsnap',
+ defaultReapInterval: 'never',
+ snapshotInitial: 2, // same as the default
+ snapshotInterval: 10, // ensure multiple spans+snapshots
+ bootstrap: 'bootstrap',
+ bundles: {
+ dude: {
+ sourceSpec: bfile('vat-slow-terminate.js'),
+ },
+ },
+ vats: {
+ bootstrap: {
+ sourceSpec: bfile('bootstrap-slow-terminate.js'),
+ },
+ },
+ };
+
+ let countCleanups = 0;
+ const noCleanupPolicy = {
+ allowCleanup: () => false,
+ vatCreated: () => true,
+ crankComplete: () => true,
+ crankFailed: () => true,
+ emptyCrank: () => true,
+ didCleanup: ({ cleanups }) => {
+ countCleanups += cleanups.total;
+ return true;
+ },
+ };
+
+ const [dbDir, cleanup] = await tmpDir('testdb');
+ t.teardown(cleanup);
+
+ const ss = initSwingStore(dbDir);
+ const { kernelStorage } = ss;
+ const { commit } = ss.hostStorage;
+ const { kvStore } = kernelStorage;
+ // look directly at DB to confirm changes
+ const db = sqlite3(path.join(dbDir, 'swingstore.sqlite'));
+
+ const controller = await buildVatController(config, [], {
+ ...t.context.data,
+ kernelStorage,
+ });
+ t.teardown(controller.shutdown);
+ t.is(controller.kpStatus(controller.bootstrapResult), 'unresolved');
+ controller.pinVatRoot('bootstrap');
+ await controller.run(noCleanupPolicy);
+ await commit();
+ t.is(controller.kpStatus(controller.bootstrapResult), 'fulfilled');
+ t.deepEqual(
+ controller.kpResolution(controller.bootstrapResult),
+ kser('bootstrap done'),
+ );
+ t.is(countCleanups, 0);
+
+ // bootstrap adds a fair amount of vat-dude state:
+ // * we have c-list entries for 20 imports and 20 exports, each of
+ // which need two kvStore entries, so 80 kvStore total
+ // * the vat has created 20 baggage entries, all of which go into
+ // the vatstore, adding 20 kvStore
+ // * an empty vat has about 29 kvStore entries just to track
+ // counters, the built-in collection types, baggage itself, etc
+ // * by sending 40-plus deliveries into an xsnap vat with
+ // snapInterval=5, we get 8-ish transcript spans (7 old, 1
+ // current), and each old span generates a heap snapshot record
+ // Slow vat termination means deleting these entries slowly.
+
+ const vatID = JSON.parse(kvStore.get('vat.dynamicIDs'))[0];
+ t.is(vatID, 'v6'); // change if necessary
+ const remainingKV = () =>
+ Array.from(enumeratePrefixedKeys(kvStore, `${vatID}.`));
+ const remainingSnapshots = () =>
+ db
+ .prepare('SELECT COUNT(*) FROM snapshots WHERE vatID=?')
+ .pluck()
+ .get(vatID);
+ const remainingTranscriptItems = () =>
+ db
+ .prepare('SELECT COUNT(*) FROM transcriptItems WHERE vatID=?')
+ .pluck()
+ .get(vatID);
+ const remainingTranscriptSpans = () =>
+ db
+ .prepare('SELECT COUNT(*) FROM transcriptSpans WHERE vatID=?')
+ .pluck()
+ .get(vatID);
+
+ // 20*2 for imports, 21*2 for exports, 20*1 for vatstore = 102.
+ // Plus 21 for the usual liveslots stuff, and 6 for kernel stuff
+ // like vNN.source/options
+
+ t.is(remainingKV().length, 129);
+ t.false(JSON.parse(kvStore.get('vats.terminated')).includes(vatID));
+ // we get one span for snapshotInitial (=2), then a span every
+ // snapshotInterval (=10). Each non-current span creates a
+ // snapshot.
+ t.is(remainingTranscriptSpans(), 6);
+ t.is(remainingTranscriptItems(), 59);
+ t.is(remainingSnapshots(), 5);
+ const remaining = () =>
+ remainingKV().length +
+ remainingSnapshots() +
+ remainingTranscriptItems() +
+ remainingTranscriptSpans();
+
+ // note: mode=dieHappy means we send one extra message to the vat,
+ // which adds a single transcript item (but this doesn't happen to trigger an extra span)
+
+ const kpid = controller.queueToVatRoot('bootstrap', 'kill', [mode]);
+ await controller.run(noCleanupPolicy);
+ await commit();
+ t.is(controller.kpStatus(kpid), 'fulfilled');
+ t.deepEqual(
+ controller.kpResolution(kpid),
+ kser('kill done, Error: vat terminated'),
+ );
+ t.is(countCleanups, 0);
+
+ t.true(JSON.parse(kvStore.get('vats.terminated')).includes(vatID));
+ // no cleanups were allowed, so nothing should be removed yet
+ t.truthy(kernelStorage.kvStore.get(`${vatID}.options`));
+ t.is(remainingKV().length, 129);
+
+ // now do a series of cleanup runs, each with budget=5
+ const clean = async (budget = 5) => {
+ const [policy, getCleanups] = makeCleanupPolicy(budget);
+ await controller.run(policy);
+ await commit();
+ return getCleanups();
+ };
+
+ // cleanup deletes c-list exports, then c-list imports, then all
+ // other kvStore entries, then snapshots, then transcripts
+
+ let leftKV = remainingKV().length;
+ const cleanKV = async (expectedKV, expectedCleanups) => {
+ const cleanups = await clean();
+ const newLeftKV = remainingKV().length;
+ t.is(leftKV - newLeftKV, expectedKV);
+ leftKV = newLeftKV;
+ t.is(cleanups, expectedCleanups);
+ };
+
+ // we have 21 c-list exports (1 vat root, plus 20 we added), we
+ // delete them 5 at a time (2 kv each, so 10kv per clean)
+ await cleanKV(10, 5); // 5 c-list exports
+ await cleanKV(10, 5); // 5 c-list exports
+ await cleanKV(10, 5); // 5 c-list exports
+ await cleanKV(10, 5); // 5 c-list exports
+
+ // now we have one export left, so this clean(budget.default=5) will
+ // delete the one export (= two kv), then the first five of our 20
+ // c-list imports (each of which also has 2 kv, so 12 kv total)
+
+ await cleanKV(12, 6); // 1 c-list exports, 5 c-list imports
+ await cleanKV(10, 5); // 5 c-list imports
+ await cleanKV(10, 5); // 5 c-list imports
+ await cleanKV(10, 5); // 5 c-list imports, leaving none
+
+ // the non-clist kvstore keys should still be present
+ t.truthy(kernelStorage.kvStore.get(`${vatID}.options`));
+
+ // there are no imports, so this clean(budget.default=5) will delete
+ // the first five of our 47 other kv entries (20 vatstore plus 27
+ // liveslots overhead
+
+ await cleanKV(5, 5); // 5 other kv
+ // now there are 42 other kv entries left
+ t.is(remainingKV().length, 42);
+
+ await cleanKV(5, 5); // 5 other kv
+ t.is(remainingKV().length, 37);
+ await cleanKV(5, 5); // 5 other kv
+ t.is(remainingKV().length, 32);
+ await cleanKV(5, 5); // 5 other kv
+ t.is(remainingKV().length, 27);
+ await cleanKV(5, 5); // 5 other kv
+ t.is(remainingKV().length, 22);
+ await cleanKV(5, 5); // 5 other kv
+ t.is(remainingKV().length, 17);
+ t.is(remainingSnapshots(), 5);
+ await cleanKV(5, 5); // 5 other kv
+ t.is(remainingKV().length, 12);
+ await cleanKV(5, 5); // 5 other kv
+ t.is(remainingKV().length, 7);
+ await cleanKV(5, 5); // 5 other kv
+ t.is(remainingKV().length, 2);
+ t.is(remainingSnapshots(), 5);
+
+ // there are two kv left, so this clean will delete those, then all 5 snapshots
+ await cleanKV(2, 7); // 2 final kv, and 5 snapshots
+ t.deepEqual(remainingKV(), []);
+ t.is(kernelStorage.kvStore.get(`${vatID}.options`), undefined);
+ t.is(remainingSnapshots(), 0);
+
+ t.is(remainingTranscriptSpans(), 6);
+ let ts = 59;
+ if (mode === 'dieHappy') {
+ ts = 60;
+ }
+ t.is(remainingTranscriptItems(), ts);
+
+ // the next clean (with the default budget of 5) will delete the
+ // five most recent transcript spans, starting with the isCurrent=1
+ // one (which had 9 or 10 items), leaving just the earliest (which
+ // had 4, due to `snapshotInitial`)
+ let cleanups = await clean();
+ t.is(cleanups, 5);
+ t.is(remainingTranscriptSpans(), 1);
+ t.is(remainingTranscriptItems(), 4);
+ // not quite done
+ t.true(JSON.parse(kvStore.get('vats.terminated')).includes(vatID));
+
+ // the final clean deletes the remaining span, and finishes by
+ // removing the "still being deleted" bookkeeping, and the .options
+
+ cleanups = await clean();
+ t.is(cleanups, 1);
+ t.is(remainingTranscriptSpans(), 0);
+ t.is(remainingTranscriptItems(), 0);
+ t.is(remaining(), 0);
+ t.false(JSON.parse(kvStore.get('vats.terminated')).includes(vatID));
+}
+
+test.serial('slow terminate (kill)', async t => {
+ await doSlowTerminate(t, 'kill');
+});
+
+test.serial('slow terminate (die happy)', async t => {
+ await doSlowTerminate(t, 'dieHappy');
+});
diff --git a/packages/SwingSet/test/vat-admin/slow-termination/vat-slow-terminate.js b/packages/SwingSet/test/vat-admin/slow-termination/vat-slow-terminate.js
new file mode 100644
index 00000000000..78ec9a74e47
--- /dev/null
+++ b/packages/SwingSet/test/vat-admin/slow-termination/vat-slow-terminate.js
@@ -0,0 +1,16 @@
+import { Far } from '@endo/far';
+
+export function buildRootObject(vatPowers, _vatParameters, baggage) {
+ const hold = [];
+ return Far('root', {
+ alive: () => true,
+ dieHappy: completion => vatPowers.exitVat(completion),
+ sendExport: () => Far('dude export', {}),
+ acceptImports: imports => hold.push(imports),
+ makeVatstore: count => {
+ for (let i = 0; i < count; i += 1) {
+ baggage.init(`key-${i}`, i);
+ }
+ },
+ });
+}
diff --git a/packages/SwingSet/test/vat-admin/terminate/terminate.test.js b/packages/SwingSet/test/vat-admin/terminate/terminate.test.js
index 750862e084b..a4759943e47 100644
--- a/packages/SwingSet/test/vat-admin/terminate/terminate.test.js
+++ b/packages/SwingSet/test/vat-admin/terminate/terminate.test.js
@@ -150,8 +150,12 @@ async function doTerminateCritical(
t.is(thrown.message, mode);
}
t.is(controller.kpStatus(kpid), dynamic ? 'unresolved' : 'fulfilled');
+ // the kernel is supposed to crash before deleting vNN.options,
+ // although strictly speaking it doesn't matter because the host is
+ // supposed to crash too, abandoning the uncommitted swingstore
+ // changes
const postProbe = kernelStorage.kvStore.get(`${deadVatID}.options`);
- t.is(postProbe, undefined);
+ t.truthy(postProbe);
}
test.serial('terminate (dynamic, non-critical)', async t => {
diff --git a/packages/SwingSet/test/vat-env.test.js b/packages/SwingSet/test/vat-env.test.js
index 0f1f29c9298..aed60fadfdd 100644
--- a/packages/SwingSet/test/vat-env.test.js
+++ b/packages/SwingSet/test/vat-env.test.js
@@ -1,7 +1,8 @@
// @ts-nocheck
+// eslint-disable-next-line import/order
import { test, VatData } from '../tools/prepare-test-env-ava.js';
-// eslint-disable-next-line import/order
+import bundleSource from '@endo/bundle-source';
import { initSwingStore } from '@agoric/swing-store';
import { buildVatController } from '../src/index.js';
@@ -75,8 +76,9 @@ async function testForExpectedGlobals(t, workerType) {
},
defaultManagerType: workerType,
};
+ const bundle = await bundleSource(config.vats.bootstrap.sourceSpec);
const kernelStorage = initSwingStore().kernelStorage;
- const c = await buildVatController(config, [], {
+ const c = await buildVatController(config, [bundle], {
kernelStorage,
});
t.teardown(c.shutdown);
@@ -97,6 +99,10 @@ async function testForExpectedGlobals(t, workerType) {
'VatData.makeScalarBigWeakMapStore: function',
'VatData.makeScalarBigSetStore: function',
'VatData.makeScalarBigWeakSetStore: function',
+ 'global has passStyleOf: true',
+ 'passStyleOf delegates to global: true',
+ 'child compartment has matching passStyleOf: true',
+ 'grandchild compartment has matching passStyleOf: true',
]);
}
diff --git a/packages/SwingSet/test/vat-envtest.js b/packages/SwingSet/test/vat-envtest.js
index e66efd4f9c0..0e750cde6f6 100644
--- a/packages/SwingSet/test/vat-envtest.js
+++ b/packages/SwingSet/test/vat-envtest.js
@@ -1,18 +1,55 @@
// @ts-nocheck
-/* global VatData */
+/* global VatData globalThis */
import { Far } from '@endo/far';
+import { passStyleOf } from '@endo/pass-style';
+import { PassStyleOfEndowmentSymbol } from '@endo/pass-style/endow.js';
+import { importBundle } from '@endo/import-bundle';
-export function buildRootObject(vatPowers) {
+export function meta() {
+ return { globalThis, passStyleOf };
+}
+
+const endowments = {
+ console,
+ // See https://github.com/Agoric/agoric-sdk/issues/9515
+ assert: globalThis.assert,
+ VatData: globalThis.VatData,
+};
+
+export async function recurse(bundle) {
+ return importBundle(bundle, { endowments });
+}
+
+export function buildRootObject(vatPowers, vatParameters) {
const log = vatPowers.testLog;
+ const { argv } = vatParameters;
+ const [bundle] = argv;
return Far('root', {
- bootstrap(_vats) {
+ async bootstrap(_vats) {
log(`control sample: ${typeof notThere}`);
log(`harden: ${typeof harden}`);
log(`VatData: ${typeof VatData}`);
for (const prop of Object.keys(VatData)) {
log(`VatData.${prop}: ${typeof VatData[prop]}`);
}
+ const globalPassStyleOf =
+ globalThis && globalThis[PassStyleOfEndowmentSymbol];
+ log(`global has passStyleOf: ${!!globalPassStyleOf}`);
+ // we expect globalPassStyleOf and passStyleOf to be the same
+ // thing, because @endo/pass-style delegates to the version it
+ // finds on globalThis
+ const d1 = globalPassStyleOf === passStyleOf;
+ log(`passStyleOf delegates to global: ${d1}`);
+
+ // make sure sub-compartments automatically get passStyleOf too
+ const c1 = await importBundle(bundle, { endowments });
+ const m1 = c1.meta().passStyleOf === passStyleOf;
+ log(`child compartment has matching passStyleOf: ${m1}`);
+
+ const c2 = await c1.recurse(bundle);
+ const m2 = c2.meta().passStyleOf === passStyleOf;
+ log(`grandchild compartment has matching passStyleOf: ${m2}`);
},
});
}
diff --git a/packages/agoric-cli/package.json b/packages/agoric-cli/package.json
index cbe25b768fa..6bcf1a914a7 100644
--- a/packages/agoric-cli/package.json
+++ b/packages/agoric-cli/package.json
@@ -37,7 +37,7 @@
},
"dependencies": {
"@agoric/access-token": "^0.4.21",
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/cache": "^0.3.2",
"@agoric/casting": "^0.4.2",
"@agoric/cosmic-proto": "^0.4.0",
@@ -58,17 +58,17 @@
"@cosmjs/math": "^0.32.3",
"@cosmjs/proto-signing": "^0.32.3",
"@cosmjs/stargate": "^0.32.3",
- "@endo/bundle-source": "^3.2.3",
- "@endo/captp": "^4.2.0",
- "@endo/compartment-mapper": "^1.1.5",
- "@endo/env-options": "^1.1.4",
- "@endo/far": "^1.1.2",
- "@endo/init": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/nat": "^5.0.7",
- "@endo/patterns": "^1.4.0",
- "@endo/promise-kit": "^1.1.2",
- "@endo/zip": "^1.0.5",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/captp": "^4.3.0",
+ "@endo/compartment-mapper": "^1.2.2",
+ "@endo/env-options": "^1.1.6",
+ "@endo/far": "^1.1.5",
+ "@endo/init": "^1.1.4",
+ "@endo/marshal": "^1.5.3",
+ "@endo/nat": "^5.0.10",
+ "@endo/patterns": "^1.4.3",
+ "@endo/promise-kit": "^1.1.5",
+ "@endo/zip": "^1.0.7",
"@iarna/toml": "^2.2.3",
"anylogger": "^0.21.0",
"chalk": "^5.2.0",
@@ -99,6 +99,6 @@
"workerThreads": false
},
"typeCoverage": {
- "atLeast": 77.36
+ "atLeast": 77.44
}
}
diff --git a/packages/agoric-cli/src/bin-agops.js b/packages/agoric-cli/src/bin-agops.js
index 7e9841e4c1b..445589a8cb1 100755
--- a/packages/agoric-cli/src/bin-agops.js
+++ b/packages/agoric-cli/src/bin-agops.js
@@ -6,7 +6,6 @@
import '@endo/init/pre.js';
-import '@agoric/casting/node-fetch-shim.js';
import '@endo/init';
import { E } from '@endo/far';
diff --git a/packages/agoric-cli/src/commands/auction.js b/packages/agoric-cli/src/commands/auction.js
index 0b33b7507da..99ffd43355c 100644
--- a/packages/agoric-cli/src/commands/auction.js
+++ b/packages/agoric-cli/src/commands/auction.js
@@ -130,6 +130,8 @@ export const makeAuctionCommand = (
};
if (Object.keys(params).length === 0) {
+ // InvalidArgumentError is a class constructor, and so
+ // must be invoked with `new`.
throw new InvalidArgumentError(`no parameters given`);
}
diff --git a/packages/agoric-cli/src/commands/gov.js b/packages/agoric-cli/src/commands/gov.js
index 26a2f111927..8a4b46d49e5 100644
--- a/packages/agoric-cli/src/commands/gov.js
+++ b/packages/agoric-cli/src/commands/gov.js
@@ -73,6 +73,8 @@ export const makeGovCommand = (_logger, io = {}) => {
const done = found.filter(it => it.instanceName === instanceName);
if (done.length > 0) {
console.warn(`invitation to ${instanceName} already accepted`, done);
+ // CommanderError is a class constructor, and so
+ // must be invoked with `new`.
throw new CommanderError(1, 'EALREADY', `already accepted`);
}
};
@@ -330,6 +332,8 @@ export const makeGovCommand = (_logger, io = {}) => {
const info = await readLatestHead(
`published.committees.${opts.pathname}.latestQuestion`,
).catch(err => {
+ // CommanderError is a class constructor, and so
+ // must be invoked with `new`.
throw new CommanderError(1, 'VSTORAGE_FAILURE', err.message);
});
@@ -346,6 +350,8 @@ export const makeGovCommand = (_logger, io = {}) => {
const votingRight = cont.find(it => it.instanceName === opts.instance);
if (!votingRight) {
console.debug('continuing ids', cont, 'for', current);
+ // CommanderError is a class constructor, and so
+ // must be invoked with `new`.
throw new CommanderError(
1,
'NO_INVITATION',
diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js
index f8353d41c8b..702b2ae0f48 100644
--- a/packages/agoric-cli/src/commands/inter.js
+++ b/packages/agoric-cli/src/commands/inter.js
@@ -218,6 +218,8 @@ export const makeInterCommand = (
try {
return rawExec(file, args, ...opts);
} catch (err) {
+ // InvalidArgumentError is a class constructor, and so
+ // must be invoked with `new`.
throw new InvalidArgumentError(
`${err.message}: is ${file} in your $PATH?`,
);
@@ -239,6 +241,8 @@ export const makeInterCommand = (
const networkConfig = await getNetworkConfig(env);
return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig);
} catch (err) {
+ // CommanderError is a class constructor, and so
+ // must be invoked with `new`.
throw new CommanderError(1, 'RPC_FAIL', err.message);
}
};
@@ -431,6 +435,8 @@ inter auction status
const parsePercent = v => {
const p = Number(v);
if (!(p >= -100 && p <= 100)) {
+ // InvalidArgumentError is a class constructor, and so
+ // must be invoked with `new`.
throw new InvalidArgumentError('must be between -100 and 100');
}
return p / 100;
@@ -498,6 +504,8 @@ inter auction status
const current = await getCurrent(from, { readLatestHead });
const liveIds = current.liveOffers.map(([i, _s]) => i);
if (!liveIds.includes(id)) {
+ // InvalidArgumentError is a class constructor, and so
+ // must be invoked with `new`.
throw new InvalidArgumentError(
`${id} not in live offer ids: ${liveIds}`,
);
diff --git a/packages/agoric-cli/src/commands/oracle.js b/packages/agoric-cli/src/commands/oracle.js
index af03aad0c21..d8f44b2159b 100644
--- a/packages/agoric-cli/src/commands/oracle.js
+++ b/packages/agoric-cli/src/commands/oracle.js
@@ -26,6 +26,8 @@ const COSMOS_UNIT = 1_000_000n;
const scaleDecimals = num => BigInt(num * Number(COSMOS_UNIT));
/**
+ * Prints JSON output to stdout and diagnostic info (like logs) to stderr
+ *
* @param {import('anylogger').Logger} logger
* @param {{
* delay?: (ms: number) => Promise,
@@ -271,14 +273,13 @@ export const makeOracleCommand = (logger, io = {}) => {
);
const unitPrice = scaleDecimals(price);
- console.error(`${pair[0]}-${pair[1]}_price_feed: before setPrice`);
+ const feedPath = `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`;
const readPrice = () =>
/** @type {Promise} */ (
- readLatestHead(
- `published.priceFeed.${pair[0]}-${pair[1]}_price_feed`,
- ).catch(err => {
- console.warn(`cannot get ${pair[0]}-${pair[1]}_price_feed`, err);
+ readLatestHead(feedPath).catch(() => {
+ const viewer = `https://vstorage.agoric.net/#${networkConfig.rpcAddrs[0]}|published,published.priceFeed|${feedPath}`;
+ console.warn(`no existing price data; see ${viewer}`);
return undefined;
})
);
@@ -297,43 +298,61 @@ export const makeOracleCommand = (logger, io = {}) => {
show(fmtFeed(before));
}
- console.error(
- 'Choose lead oracle operator order based on latestRound...',
- );
const keyOrder = keys.map(normalizeAddress);
- const latestRoundP = readLatestHead(
- `published.priceFeed.${pair[0]}-${pair[1]}_price_feed.latestRound`,
- );
- await Promise.race([
- delay(5000),
- latestRoundP.then(round => {
- // @ts-expect-error XXX get type from contract
- const { roundId, startedAt, startedBy } = round;
- show({
- startedAt: fmtSecs(startedAt.absValue),
- roundId,
- startedBy,
- });
- if (startedBy === keyOrder[0]) {
- keyOrder.reverse();
- }
- }),
- ]).catch(err => {
- console.warn(err);
- });
+ if (before) {
+ console.error(
+ 'Choose lead oracle operator order based on latestRound...',
+ );
- const instance = lookupPriceAggregatorInstance(pair);
+ const latestRoundP =
+ /** @type {Promise<{roundId: number, startedAt: import('@agoric/time').TimestampRecord, startedBy: string}>} */ (
+ readLatestHead(
+ `published.priceFeed.${pair[0]}-${pair[1]}_price_feed.latestRound`,
+ )
+ );
+ await Promise.race([
+ delay(5000),
+ latestRoundP.then(round => {
+ const { roundId, startedAt, startedBy } = round;
+ show({
+ startedAt: fmtSecs(startedAt.absValue),
+ roundId,
+ startedBy,
+ });
+ if (startedBy === keyOrder[0]) {
+ keyOrder.reverse();
+ }
+ }),
+ ]).catch(err => {
+ console.warn(err);
+ });
+ }
- console.error('pushPrice from each:', keyOrder);
+ const instance = lookupPriceAggregatorInstance(pair);
+ const adminOfferIds = {};
for await (const from of keyOrder) {
- const oracleAdminAcceptOfferId = await findOracleCap(
+ adminOfferIds[from] = await findOracleCap(
instance,
from,
readLatestHead,
);
- if (!oracleAdminAcceptOfferId) {
- throw Error(`no oracle invitation found: ${from}`);
+ if (!adminOfferIds[from]) {
+ console.error(
+ `Failed to find an offer accepting oracle invitation for ${from}. Accept and try again:`,
+ );
+ console.error(
+ ` agops oracle accept > accept.json; agoric wallet send --from ${from} --offer accept.json`,
+ );
}
+ }
+ assert(
+ Object.values(adminOfferIds).every(x => x),
+ 'Missing oracle admin offer ids',
+ );
+
+ console.error('pushPrice from each:', keyOrder);
+ for await (const from of keyOrder) {
+ const oracleAdminAcceptOfferId = adminOfferIds[from];
show({ from, oracleAdminAcceptOfferId });
const offerId = `pushPrice-${Date.now()}`;
const offer = Offers.fluxAggregator.PushPrice(
diff --git a/packages/agoric-cli/src/commands/test-upgrade.js b/packages/agoric-cli/src/commands/test-upgrade.js
index ca1aeda4a83..20223ee7bc5 100644
--- a/packages/agoric-cli/src/commands/test-upgrade.js
+++ b/packages/agoric-cli/src/commands/test-upgrade.js
@@ -41,6 +41,8 @@ export const makeTestCommand = (
const networkConfig = await getNetworkConfig(env);
return makeWalletUtils({ fetch, execFileSync, delay }, networkConfig);
} catch (err) {
+ // CommanderError is a class constructor, and so
+ // must be invoked with `new`.
throw new CommanderError(1, 'RPC_FAIL', err.message);
}
};
diff --git a/packages/agoric-cli/src/entrypoint.js b/packages/agoric-cli/src/entrypoint.js
index c90ac5f0406..f921a2340ac 100755
--- a/packages/agoric-cli/src/entrypoint.js
+++ b/packages/agoric-cli/src/entrypoint.js
@@ -5,7 +5,6 @@
import '@endo/init/pre.js';
import 'esm';
-import '@agoric/casting/node-fetch-shim.js';
import '@endo/init/legacy.js';
import path from 'path';
diff --git a/packages/agoric-cli/src/helpers.js b/packages/agoric-cli/src/helpers.js
index e8fcad990d1..e140e7eb5bf 100644
--- a/packages/agoric-cli/src/helpers.js
+++ b/packages/agoric-cli/src/helpers.js
@@ -45,6 +45,7 @@ export const makePspawn = ({
* @param {string | [string, string, string]} [param2.stdio] standard IO
* specification
* @param {Record} [param2.env] environment
+ * @param {boolean} [param2.detached] whether the child process should be detached
* @returns {Promise & { childProcess: ChildProcess }}} promise for
* exit status. The return result has a `childProcess` property to obtain
* control over the running process
diff --git a/packages/agoric-cli/src/init.js b/packages/agoric-cli/src/init.js
index a95177a6a33..251ef5c230e 100644
--- a/packages/agoric-cli/src/init.js
+++ b/packages/agoric-cli/src/init.js
@@ -1,8 +1,6 @@
import chalk from 'chalk';
import { makePspawn } from './helpers.js';
-///
-
// Use either an absolute template URL, or find it relative to DAPP_URL_BASE.
const gitURL = (relativeOrAbsoluteURL, base) => {
const url = new URL(relativeOrAbsoluteURL, base);
diff --git a/packages/agoric-cli/src/lib/bundles.js b/packages/agoric-cli/src/lib/bundles.js
index e41eb21ef02..d2feca36e72 100644
--- a/packages/agoric-cli/src/lib/bundles.js
+++ b/packages/agoric-cli/src/lib/bundles.js
@@ -28,7 +28,7 @@ export const PACKAGE_NAME_RE = /^(?:@[^/]+\/)?[^/]+/;
/** @param {Bundle} bundleObj*/
export const extractBundleInfo = async bundleObj => {
if (bundleObj.moduleFormat !== 'endoZipBase64') {
- throw new Error('only endoZipBase64 is supported');
+ throw Error('only endoZipBase64 is supported');
}
const contents = Buffer.from(bundleObj.endoZipBase64, 'base64');
diff --git a/packages/agoric-cli/src/lib/wallet.js b/packages/agoric-cli/src/lib/wallet.js
index c120db764e9..c8d3dc71e35 100644
--- a/packages/agoric-cli/src/lib/wallet.js
+++ b/packages/agoric-cli/src/lib/wallet.js
@@ -33,7 +33,7 @@ export const getCurrent = async (addr, { readLatestHead }) => {
await readLatestHead(`published.wallet.${addr}.current`)
);
if (current === undefined) {
- throw new Error(`undefined current node for ${addr}`);
+ throw Error(`undefined current node for ${addr}`);
}
// Repair a type misunderstanding seen in the wild.
diff --git a/packages/agoric-cli/src/scripts.js b/packages/agoric-cli/src/scripts.js
index 54857b5d7e3..c1781eacc12 100644
--- a/packages/agoric-cli/src/scripts.js
+++ b/packages/agoric-cli/src/scripts.js
@@ -161,8 +161,17 @@ export { bootPlugin } from ${JSON.stringify(absPath)};
const allEndowments = harden({
home: bootP,
- bundleSource: (file, options = undefined) =>
- bundleSource(pathResolve(file), options),
+ /**
+ * @template {import('@endo/bundle-source').ModuleFormat} ModuleFormat
+ * @param {string} file
+ * @param {import('@endo/bundle-source').BundleOptions} options
+ * @returns {Promise>}
+ */
+ bundleSource: (file, options = {}) =>
+ bundleSource(pathResolve(file), {
+ elideComments: true,
+ ...options,
+ }),
...endowments,
pathResolve,
installUnsafePlugin,
diff --git a/packages/agoric-cli/test/inter-cli.test.js b/packages/agoric-cli/test/inter-cli.test.js
index 3a80a27c26d..5d7bb758626 100644
--- a/packages/agoric-cli/test/inter-cli.test.js
+++ b/packages/agoric-cli/test/inter-cli.test.js
@@ -252,8 +252,6 @@ test('amount parsing', t => {
});
});
-test.todo('want as max collateral wanted');
-
/**
* @type {import('@agoric/smart-wallet/src/offers.js').OfferStatus &
* { offerArgs: import('@agoric/inter-protocol/src/auction/auctionBook.js').OfferSpec}}
@@ -358,8 +356,6 @@ test('diagnostic for agd ENOENT', async t => {
t.is(out.join('').trim(), '');
});
-test.todo('agd ENOENT clue outside normalizeAddress');
-
const usageTest = (words, blurb = 'Command usage:') => {
test(`Usage: ${words}`, async t => {
const argv = `node agops ${words} --help`.split(' ');
@@ -370,6 +366,8 @@ const usageTest = (words, blurb = 'Command usage:') => {
program.addCommand(cmd);
for (const c of subCommands(program)) {
c.exitOverride(() => {
+ // CommanderError is a class constructor, and so
+ // must be invoked with `new`.
throw new CommanderError(1, 'usage', '');
});
}
@@ -416,7 +414,6 @@ test('formatBid', t => {
}
});
-test.todo('fmtBid with error does not show result');
/*
_not_ like this:
@@ -607,7 +604,6 @@ test('README ex1: inter bid place by-price: printed offer is correct', async t =
t.deepEqual(txt, expected);
});
-test.todo('inter bid by-price shows tx, wallet status');
/*
$ agops inter bid by-price --price 0.81 --give 0.5 --maxBuy 3 --from gov2
2023-03-30T21:48:14.479332418Z not in block 49618 retrying...
@@ -617,12 +613,9 @@ first bid update:
{"id":"bid-1680212903989","price":"0.81 IST/ATOM","give":{"Bid":"0.5IST"},"want":"3ATOM","result":"Your bid has been accepted"}
*/
-test.todo('execSwingsetTransaction returns non-0 code');
-
-test.todo('already cancelled bid');
/*
$ agops inter bid cancel --from gov2 bid-1680211556497
bid-1680211556497 not in live offer ids: bid-1680211593489,bid-1680212903989,bid-1680213097499,bid-1680220217218,bid-1680220368714,bid-1680220406939
*/
-test.todo('--give without number');
+// TODO improve test coverage https://github.com/Agoric/agoric-sdk/issues/9965
diff --git a/packages/agoric-cli/test/main.test.js b/packages/agoric-cli/test/main.test.js
index 88219733fae..d2b17a170a5 100644
--- a/packages/agoric-cli/test/main.test.js
+++ b/packages/agoric-cli/test/main.test.js
@@ -1,5 +1,4 @@
/* global globalThis */
-import '@agoric/casting/node-fetch-shim.js';
import '@endo/init/pre.js';
import 'esm';
import '@endo/init/debug.js';
diff --git a/packages/agoric-cli/tools/getting-started.js b/packages/agoric-cli/tools/getting-started.js
index dae31eeb298..3dbbdf7a5a7 100644
--- a/packages/agoric-cli/tools/getting-started.js
+++ b/packages/agoric-cli/tools/getting-started.js
@@ -1,4 +1,5 @@
-/* global process setTimeout setInterval clearInterval */
+// @ts-check
+/* global process setTimeout setInterval clearInterval Buffer */
import fs from 'fs';
import path from 'path';
@@ -10,7 +11,13 @@ import { spawn } from 'child_process';
import { makePspawn } from '../src/helpers.js';
-const TIMEOUT_SECONDS = 3 * 60;
+const RETRY_BLOCKHEIGHT_SECONDS = 3;
+const SOCKET_TIMEOUT_SECONDS = 2;
+
+// TODO: Set this to `true` when `agoric install $DISTTAG` properly updates the
+// getting-started workflow's dependencies to current `@endo/*` and Agoric SDK
+// from the local registry.
+const AGORIC_INSTALL_DISTTAG = false;
const dirname = new URL('./', import.meta.url).pathname;
@@ -18,23 +25,59 @@ const dirname = new URL('./', import.meta.url).pathname;
// Note that we currently only test:
// agoric init dapp-foo
-// yarn install
+// yarn install (or agoric install $DISTTAG)
// yarn start:docker
// yarn start:contract
// yarn start:ui
+/**
+ * @param {string} url
+ * @returns {Promise}
+ */
+const getLatestBlockHeight = url =>
+ new Promise((resolve, reject) => {
+ const req = request(url, res => {
+ if (!res) {
+ reject(Error('no result'));
+ return;
+ }
+ const bodyChunks = [];
+ res
+ .on('data', chunk => bodyChunks.push(chunk))
+ .on('end', () => {
+ const body = Buffer.concat(bodyChunks).toString('utf8');
+ const { statusCode = 0 } = res;
+ if (statusCode >= 200 && statusCode < 300) {
+ const { result: { sync_info: sync = {} } = {} } = JSON.parse(body);
+ if (sync.catching_up === false) {
+ resolve(BigInt(sync.latest_block_height));
+ return;
+ }
+ }
+ reject(Error(`Cannot get block height: ${statusCode} ${body}`));
+ });
+ });
+ req.setTimeout(SOCKET_TIMEOUT_SECONDS * 1_000);
+ req.on('error', reject);
+ req.end();
+ });
+
export const gettingStartedWorkflowTest = async (t, options = {}) => {
- const { init: initOptions = [] } = options;
+ const { init: initOptions = [], install: installOptions = [] } = options;
const pspawn = makePspawn({ spawn });
// Kill an entire process group.
const pkill = (cp, signal = 'SIGINT') => process.kill(-cp.pid, signal);
+ /** @param {Parameters} args */
function pspawnStdout(...args) {
const ps = pspawn(...args);
- ps.childProcess.stdout.on('data', chunk => {
- process.stdout.write(chunk);
- });
+ const { stdout } = ps.childProcess;
+ if (stdout) {
+ stdout.on('data', chunk => {
+ process.stdout.write(chunk);
+ });
+ }
// ps.childProcess.unref();
return ps;
}
@@ -107,17 +150,51 @@ export const gettingStartedWorkflowTest = async (t, options = {}) => {
);
process.chdir('dapp-foo');
- // ==============
- // yarn install
- t.is(await yarn(['install']), 0, 'yarn install works');
+ if (AGORIC_INSTALL_DISTTAG && process.env.AGORIC_INSTALL_OPTIONS) {
+ // ==============
+ // agoric install $DISTTAG
+ const opts = JSON.parse(process.env.AGORIC_INSTALL_OPTIONS);
+ installOptions.push(...opts);
+ t.is(
+ await myMain(['install', ...installOptions]),
+ 0,
+ 'agoric install works',
+ );
+ } else {
+ // ==============
+ // yarn install
+ t.is(await yarn(['install', ...installOptions]), 0, 'yarn install works');
+ }
// ==============
// yarn start:docker
t.is(await yarn(['start:docker']), 0, 'yarn start:docker works');
- // XXX: use abci_info endpoint to get block height
- // sleep to let contract start
- await new Promise(resolve => setTimeout(resolve, TIMEOUT_SECONDS));
+ // ==============
+ // wait for the chain to start
+ let lastKnownBlockHeight = 0n;
+ for (;;) {
+ try {
+ const currentHeight = await getLatestBlockHeight(
+ 'http://localhost:26657/status',
+ );
+ if (currentHeight > lastKnownBlockHeight) {
+ const earlierHeight = lastKnownBlockHeight;
+ lastKnownBlockHeight = currentHeight;
+ if (earlierHeight > 0n && currentHeight > earlierHeight) {
+ // We've had at least one block produced.
+ break;
+ }
+ }
+ } catch (e) {
+ console.error((e && e.message) || e);
+ }
+
+ // Wait a bit and try again.
+ await new Promise(resolve =>
+ setTimeout(resolve, RETRY_BLOCKHEIGHT_SECONDS * 1_000),
+ );
+ }
// ==============
// yarn start:contract
@@ -145,9 +222,9 @@ export const gettingStartedWorkflowTest = async (t, options = {}) => {
const req = request('http://localhost:5173/', _res => {
resolve('listening');
});
- req.setTimeout(2000);
+ req.setTimeout(SOCKET_TIMEOUT_SECONDS * 1_000);
req.on('error', err => {
- if (err.code !== 'ECONNREFUSED') {
+ if (!('code' in err) || err.code !== 'ECONNREFUSED') {
resolve(`Cannot connect to UI server: ${err}`);
}
});
diff --git a/packages/async-flow/index.js b/packages/async-flow/index.js
index 7c6e499a9c0..9ea1e5a6f19 100644
--- a/packages/async-flow/index.js
+++ b/packages/async-flow/index.js
@@ -1,3 +1,3 @@
export * from './src/async-flow.js';
export * from './src/types.js';
-export { makeStateRecord } from './src/endowments.js';
+export { makeSharedStateRecord } from './src/endowments.js';
diff --git a/packages/async-flow/package.json b/packages/async-flow/package.json
index eeb9ae506de..e7fadad8be8 100644
--- a/packages/async-flow/package.json
+++ b/packages/async-flow/package.json
@@ -8,7 +8,7 @@
"scripts": {
"build": "exit 0",
"prepack": "tsc --build tsconfig.build.json",
- "postpack": "git clean -f '*.d.ts*'",
+ "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
"test": "ava",
"test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
"test:xs": "exit 0",
@@ -28,19 +28,19 @@
"@agoric/internal": "^0.3.2",
"@agoric/store": "^0.9.2",
"@agoric/vow": "^0.1.0",
- "@endo/common": "^1.2.2",
- "@endo/errors": "^1.2.2",
- "@endo/eventual-send": "^1.2.2",
- "@endo/marshal": "^1.5.0",
- "@endo/pass-style": "^1.4.0",
- "@endo/patterns": "^1.4.0",
- "@endo/promise-kit": "^1.1.2"
+ "@endo/common": "^1.2.5",
+ "@endo/errors": "^1.2.5",
+ "@endo/eventual-send": "^1.2.5",
+ "@endo/marshal": "^1.5.3",
+ "@endo/pass-style": "^1.4.3",
+ "@endo/patterns": "^1.4.3",
+ "@endo/promise-kit": "^1.1.5"
},
"devDependencies": {
"@agoric/swingset-liveslots": "^0.10.2",
"@agoric/zone": "^0.2.2",
- "@endo/env-options": "^1.1.4",
- "@endo/ses-ava": "^1.2.2",
+ "@endo/env-options": "^1.1.6",
+ "@endo/ses-ava": "^1.2.5",
"ava": "^5.3.0",
"tsd": "^0.31.1"
},
@@ -61,6 +61,6 @@
"workerThreads": false
},
"typeCoverage": {
- "atLeast": 77.01
+ "atLeast": 77.29
}
}
diff --git a/packages/async-flow/src/endowments.js b/packages/async-flow/src/endowments.js
index 209eae0c8f2..1aba97efaaf 100644
--- a/packages/async-flow/src/endowments.js
+++ b/packages/async-flow/src/endowments.js
@@ -64,7 +64,7 @@ export const forwardingMethods = rem => {
* @param {R} dataRecord
* @returns {R}
*/
-export const makeStateRecord = dataRecord =>
+export const makeSharedStateRecord = dataRecord =>
harden(
create(
objectPrototype,
diff --git a/packages/async-flow/src/types.d.ts b/packages/async-flow/src/types.d.ts
index 114ae65aa51..5541611961c 100644
--- a/packages/async-flow/src/types.d.ts
+++ b/packages/async-flow/src/types.d.ts
@@ -46,11 +46,18 @@ export type GuestOf = F extends (
? (...args: A) => Promise
: F;
+// from https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts
+type Simplify = { [KeyType in keyof T]: T[KeyType] } & {};
+
/**
* Convert an entire Guest interface into what the host will implement.
*/
type HostInterface = {
- [K in keyof T]: HostOf;
+ [K in keyof T]: T[K] extends CallableFunction
+ ? HostOf
+ : T[K] extends Record
+ ? Simplify>
+ : T[K];
};
/**
@@ -61,9 +68,11 @@ export type GuestInterface = {
? (...args: Parameters) => Promise
: T[K] extends HostAsyncFuncWrapper
? GuestOf
- : T[K] extends object
- ? GuestInterface
- : T[K];
+ : T[K] extends (...args: any[]) => infer R
+ ? T[K]
+ : T[K] extends object
+ ? GuestInterface
+ : T[K];
};
/**
@@ -71,8 +80,12 @@ export type GuestInterface = {
*
* Specifically, Promise return values are converted to Vows.
*/
-export type HostOf = F extends (...args: infer A) => Promise
- ? (...args: A) => Vow>
+export type HostOf = F extends (
+ ...args: infer A
+) => infer R
+ ? R extends Promise
+ ? (...args: A) => Vow>
+ : (...args: A) => HostInterface
: F;
export type HostArgs = { [K in keyof GA]: HostOf };
diff --git a/packages/async-flow/test/types.test-d.ts b/packages/async-flow/test/types.test-d.ts
index 9c393769464..399a766743d 100644
--- a/packages/async-flow/test/types.test-d.ts
+++ b/packages/async-flow/test/types.test-d.ts
@@ -1,8 +1,13 @@
import { expectType } from 'tsd';
-import type { Zone } from '@agoric/base-zone';
import type { Vow, VowTools } from '@agoric/vow';
-import type { HostOf, GuestOf } from '../src/types.js';
+import type {
+ HostOf,
+ GuestOf,
+ HostInterface,
+ GuestInterface,
+} from '../src/types.js';
+const castable: unknown = null;
const vt: VowTools = null as any;
const sumVow = (a: number, b: number) => vt.asVow(() => a + b);
@@ -10,13 +15,59 @@ const sumVow = (a: number, b: number) => vt.asVow(() => a + b);
const sumPromise = (a: number, b: number) => Promise.resolve(a + b);
expectType<(p1: number, p2: number) => Promise>(
- null as unknown as GuestOf,
+ castable as GuestOf,
);
expectType<(p1: number, p2: number) => Vow>(
- null as unknown as HostOf,
+ castable as HostOf,
);
expectType<(p1: number, p2: number) => Vow>(
// @ts-expect-error incompatible return type
- null as unknown as HostOf,
+ castable as HostOf,
+);
+
+// Test HostInterface and GuestInterface with an exoClass object
+type ExoAPIBase = {
+ getValue: () => number;
+ setValue: (value: number) => void;
+ getCopyData: () => Record[];
+ // TODO include `getRemote() => Guarded<...>`, since durable exos are passable
+};
+type ExoGuestAPI = ExoAPIBase & {
+ getValueAsync: () => Promise;
+};
+
+type ExoHostAPI = ExoAPIBase & {
+ getValueAsync: () => Vow;
+};
+
+expectType<
+ ExoAPIBase & {
+ getValueAsync: () => Vow;
+ }
+>(castable as HostInterface);
+expectType<
+ ExoAPIBase & {
+ getValueAsync: () => Promise;
+ }
+>(castable as GuestInterface);
+
+// Test HostInterface and GuestInterface with classKit (nested) objects
+expectType<{
+ facet: ExoAPIBase & {
+ getValueAsync: () => Vow;
+ };
+}>(
+ castable as HostInterface<{
+ facet: ExoGuestAPI;
+ }>,
+);
+expectType<{
+ facet: ExoAPIBase & {
+ getValueAsync: () => Promise;
+ };
+}>(
+ castable as GuestInterface<{
+ facet: ExoHostAPI;
+ }>,
);
diff --git a/packages/base-zone/package.json b/packages/base-zone/package.json
index c6821f2ec18..5ab76eac728 100644
--- a/packages/base-zone/package.json
+++ b/packages/base-zone/package.json
@@ -8,7 +8,7 @@
"scripts": {
"build": "exit 0",
"prepack": "tsc --build tsconfig.build.json",
- "postpack": "git clean -f '*.d.ts*'",
+ "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
"test": "ava",
"test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
"test:xs": "exit 0",
@@ -28,16 +28,16 @@
"license": "Apache-2.0",
"dependencies": {
"@agoric/store": "^0.9.2",
- "@endo/common": "^1.2.2",
- "@endo/errors": "^1.2.2",
- "@endo/exo": "^1.5.0",
- "@endo/far": "^1.1.2",
- "@endo/pass-style": "^1.4.0",
- "@endo/patterns": "^1.4.0"
+ "@endo/common": "^1.2.5",
+ "@endo/errors": "^1.2.5",
+ "@endo/exo": "^1.5.3",
+ "@endo/far": "^1.1.5",
+ "@endo/pass-style": "^1.4.3",
+ "@endo/patterns": "^1.4.3"
},
"devDependencies": {
- "@endo/init": "^1.1.2",
- "@endo/ses-ava": "^1.2.2",
+ "@endo/init": "^1.1.4",
+ "@endo/ses-ava": "^1.2.5",
"ava": "^5.3.0"
},
"publishConfig": {
diff --git a/packages/base-zone/src/make-once.js b/packages/base-zone/src/make-once.js
index adb01b70cb2..fbefd6e9d17 100644
--- a/packages/base-zone/src/make-once.js
+++ b/packages/base-zone/src/make-once.js
@@ -35,7 +35,7 @@ export const makeOnceKit = (debugName, stores, backingStore = undefined) => {
* Ensure the wrapped function is only called once per incarnation. It is
* expected to update the backing store directly.
*
- * @template {(key: string, ...rest: unknown[]) => any} T
+ * @template {(key: string, ...rest: any[]) => any} T
* @param {T} provider
* @param {(label: string) => string[]} [labelToKeys]
* @returns {T}
diff --git a/packages/benchmark/benchmark/benchmark-liquidation.js b/packages/benchmark/benchmark/benchmark-liquidation.js
index bfeb0da0a17..7cef5032417 100644
--- a/packages/benchmark/benchmark/benchmark-liquidation.js
+++ b/packages/benchmark/benchmark/benchmark-liquidation.js
@@ -2,7 +2,7 @@
import { bench } from '../src/benchmarkerator.js';
import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
-import { scale6 } from '@agoric/boot/tools/liquidation.ts';
+import { scale6 } from '@agoric/boot/tools/liquidation.js';
const setupData = {
vaults: [
diff --git a/packages/benchmark/package.json b/packages/benchmark/package.json
index d9046f8b175..5f484e77f87 100644
--- a/packages/benchmark/package.json
+++ b/packages/benchmark/package.json
@@ -22,14 +22,14 @@
"author": "Agoric",
"license": "Apache-2.0",
"dependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/boot": "^0.1.0",
"@agoric/cosmic-swingset": "^0.41.3",
"@agoric/internal": "^0.3.2",
"@agoric/inter-protocol": "^0.16.1",
"@agoric/vats": "^0.15.1",
"@agoric/zoe": "^0.26.2",
- "@endo/init": "^1.1.2"
+ "@endo/init": "^1.1.4"
},
"devDependencies": {},
"files": [
diff --git a/packages/benchmark/src/benchmarkerator.js b/packages/benchmark/src/benchmarkerator.js
index 2e40b37b493..623fb0cc7c6 100644
--- a/packages/benchmark/src/benchmarkerator.js
+++ b/packages/benchmark/src/benchmarkerator.js
@@ -9,12 +9,12 @@ import '@agoric/cosmic-swingset/src/launch-chain.js';
import { Fail } from '@endo/errors';
import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
import { makeAgoricNamesRemotesFromFakeStorage } from '@agoric/vats/tools/board-utils.js';
-import { makeSwingsetTestKit } from '@agoric/boot/tools/supports.ts';
+import { makeSwingsetTestKit } from '@agoric/boot/tools/supports.js';
import {
makeWalletFactoryDriver,
makeGovernanceDriver,
-} from '@agoric/boot/tools/drivers.ts';
-import { makeLiquidationTestKit } from '@agoric/boot/tools/liquidation.ts';
+} from '@agoric/boot/tools/drivers.js';
+import { makeLiquidationTestKit } from '@agoric/boot/tools/liquidation.js';
// When I was a child my family took a lot of roadtrips around California to go
// camping and backpacking and so on. It was not uncommon in those days (nor is
diff --git a/packages/benchmark/tsconfig.json b/packages/benchmark/tsconfig.json
index 537a877842a..372b9311313 100644
--- a/packages/benchmark/tsconfig.json
+++ b/packages/benchmark/tsconfig.json
@@ -1,7 +1,6 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
- "allowImportingTsExtensions": true,
"checkJs": true,
},
"include": [
@@ -13,5 +12,6 @@
"test/**/*.js",
"test/**/*.ts",
"tools/**/*.js",
+ "tools/**/*.ts",
],
}
diff --git a/packages/boot/package.json b/packages/boot/package.json
index 076b4254f77..647fb2a0160 100644
--- a/packages/boot/package.json
+++ b/packages/boot/package.json
@@ -18,7 +18,7 @@
"author": "Agoric",
"license": "Apache-2.0",
"dependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/builders": "^0.1.0",
"@agoric/cosmic-proto": "^0.4.0",
"@agoric/cosmic-swingset": "^0.41.3",
@@ -38,14 +38,14 @@
"@agoric/vow": "^0.1.0",
"@agoric/zoe": "^0.26.2",
"@agoric/zone": "^0.2.2",
- "@endo/bundle-source": "^3.2.3",
- "@endo/captp": "^4.2.0",
- "@endo/eventual-send": "^1.2.2",
- "@endo/far": "^1.1.2",
- "@endo/init": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/promise-kit": "^1.1.2",
- "@endo/stream": "^1.2.2",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/captp": "^4.3.0",
+ "@endo/eventual-send": "^1.2.5",
+ "@endo/far": "^1.1.5",
+ "@endo/init": "^1.1.4",
+ "@endo/marshal": "^1.5.3",
+ "@endo/promise-kit": "^1.1.5",
+ "@endo/stream": "^1.2.5",
"import-meta-resolve": "^2.2.1"
},
"devDependencies": {
@@ -53,8 +53,8 @@
"@agoric/governance": "^0.10.3",
"@agoric/store": "^0.9.2",
"@agoric/swingset-liveslots": "^0.10.2",
- "@endo/base64": "^1.0.5",
- "@endo/patterns": "^1.4.0",
+ "@endo/base64": "^1.0.7",
+ "@endo/patterns": "^1.4.3",
"ava": "^5.3.0",
"c8": "^9.1.0",
"tsx": "3.12.8"
@@ -90,6 +90,6 @@
"workerThreads": false
},
"typeCoverage": {
- "atLeast": 86.64
+ "atLeast": 90.31
}
}
diff --git a/packages/boot/test/bootstrapTests/addAssets.test.ts b/packages/boot/test/bootstrapTests/addAssets.test.ts
index 9cdaea18c6d..90190890b22 100644
--- a/packages/boot/test/bootstrapTests/addAssets.test.ts
+++ b/packages/boot/test/bootstrapTests/addAssets.test.ts
@@ -1,3 +1,7 @@
+/**
+ * @file tests of adding an asset to the vaultFactory.
+ * Checks that auctions update correctly.
+ */
import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';
import type { TestFn } from 'ava';
@@ -6,8 +10,8 @@ import { TimeMath } from '@agoric/time';
import {
LiquidationTestContext,
makeLiquidationTestContext,
-} from '../../tools/liquidation.ts';
-import { makeProposalExtractor } from '../../tools/supports.ts';
+} from '../../tools/liquidation.js';
+import { makeProposalExtractor } from '../../tools/supports.js';
const test = anyTest as TestFn<
LiquidationTestContext & {
@@ -15,6 +19,7 @@ const test = anyTest as TestFn<
name: string,
id: string,
) => Awaited>>;
+ getNumAuctionBooks: () => number;
}
>;
@@ -34,23 +39,28 @@ test.before(async t => {
.replaceAll('ibc/987C17B1', `ibc/987C17B1${id}`);
return JSON.parse(proposalMod);
};
+
+ const getNumAuctionBooks = () =>
+ Array.from(context.storage.data.keys()).filter(k =>
+ k.startsWith(`${auctioneerPath}.book`),
+ ).length;
+
t.context = {
...context,
getCollateralProposal,
+ getNumAuctionBooks,
};
});
test.after.always(t => {
- // This will fail if a subset of tests are run. It detects that three
- // collaterals were added to the auction after ATOM.
- t.like(t.context.readLatest(`${auctioneerPath}.book3`), {
- currentPriceLevel: null,
- });
return t.context.shutdown && t.context.shutdown();
});
-test('addAsset to quiescent auction', async t => {
- const { advanceTimeTo, evalProposal, readLatest } = t.context;
+test.serial('addAsset to quiescent auction', async t => {
+ const { advanceTimeTo, evalProposal, getNumAuctionBooks, readLatest } =
+ t.context;
+
+ const booksBefore = getNumAuctionBooks();
await evalProposal(t.context.getCollateralProposal('COMETS', 'A'));
@@ -61,7 +71,7 @@ test('addAsset to quiescent auction', async t => {
const { liveAuctionSchedule, nextAuctionSchedule } = schedules;
const nextEndTime = liveAuctionSchedule
? liveAuctionSchedule.endTime
- : nextAuctionSchedule.endTime;
+ : nextAuctionSchedule!.endTime;
const fiveMinutes = harden({
relValue: 5n * 60n,
timerBrand: nextEndTime.timerBrand,
@@ -69,21 +79,36 @@ test('addAsset to quiescent auction', async t => {
const nextQuiescentTime = TimeMath.addAbsRel(nextEndTime, fiveMinutes);
await advanceTimeTo(nextQuiescentTime);
- t.like(readLatest(`${auctioneerPath}.book1`), {
- currentPriceLevel: null,
- });
+ const booksAfter = getNumAuctionBooks();
+ t.is(booksAfter, booksBefore + 1);
+
+ t.like(
+ readLatest(`${auctioneerPath}.book${booksAfter - 1}`),
+ {
+ currentPriceLevel: null,
+ },
+ 'quiescent',
+ );
});
-test('addAsset to active auction', async t => {
- const { advanceTimeTo, readLatest } = t.context;
+test.serial('addAsset to active auction', async t => {
+ const { advanceTimeTo, getNumAuctionBooks, readLatest } = t.context;
const { EV } = t.context.runUtils;
- t.like(readLatest(`${auctioneerPath}.book0`), { startPrice: null });
+ const booksBefore = getNumAuctionBooks();
+
+ t.like(
+ readLatest(`${auctioneerPath}.book${booksBefore - 1}`),
+ {
+ startPrice: null,
+ },
+ 'active',
+ );
const auctioneerKit = await EV.vat('bootstrap').consumeItem('auctioneerKit');
const schedules = await EV(auctioneerKit.creatorFacet).getSchedule();
const { nextAuctionSchedule } = schedules;
- t.truthy(nextAuctionSchedule);
+ assert(nextAuctionSchedule);
const nextStartTime = nextAuctionSchedule.startTime;
const fiveMinutes = harden({
relValue: 5n * 60n,
@@ -105,9 +130,10 @@ test('addAsset to active auction', async t => {
const coreEvalBridgeHandler = await EV.vat('bootstrap').consumeItem(
'coreEvalBridgeHandler',
);
- EV(coreEvalBridgeHandler).fromBridge(bridgeMessage);
+ // XXX races with the following lines
+ void EV(coreEvalBridgeHandler).fromBridge(bridgeMessage);
- const nextEndTime = nextAuctionSchedule.endTime;
+ const nextEndTime = nextAuctionSchedule!.endTime;
const afterEndTime = TimeMath.addAbsRel(nextEndTime, fiveMinutes);
await advanceTimeTo(afterEndTime);
t.log('proposal executed');
@@ -115,21 +141,23 @@ test('addAsset to active auction', async t => {
const schedulesAfter = await EV(auctioneerKit.creatorFacet).getSchedule();
// TimeMath.compareAbs() can't handle brands processed by kmarshall
t.truthy(
- schedules.nextAuctionSchedule.endTime.absValue <
- schedulesAfter.nextAuctionSchedule.endTime.absValue,
+ schedules.nextAuctionSchedule!.endTime.absValue <
+ schedulesAfter.nextAuctionSchedule!.endTime.absValue,
);
- t.like(readLatest(`${auctioneerPath}.book1`), { currentPriceLevel: null });
+ const booksAfter = getNumAuctionBooks();
+ t.is(booksAfter, booksBefore + 1);
});
-test('addAsset to auction starting soon', async t => {
- const { advanceTimeTo, readLatest } = t.context;
+test.serial('addAsset to auction starting soon', async t => {
+ const { advanceTimeTo, getNumAuctionBooks } = t.context;
const { EV } = t.context.runUtils;
+ const booksBefore = getNumAuctionBooks();
const auctioneerKit = await EV.vat('bootstrap').consumeItem('auctioneerKit');
const schedules = await EV(auctioneerKit.creatorFacet).getSchedule();
const { nextAuctionSchedule } = schedules;
- t.truthy(nextAuctionSchedule);
+ assert(nextAuctionSchedule);
const nextStartTime = nextAuctionSchedule.startTime;
const fiveMinutes = harden({
relValue: 5n * 60n,
@@ -150,7 +178,8 @@ test('addAsset to auction starting soon', async t => {
const coreEvalBridgeHandler = await EV.vat('bootstrap').consumeItem(
'coreEvalBridgeHandler',
);
- EV(coreEvalBridgeHandler).fromBridge(bridgeMessage);
+ // XXX races with the following lines
+ void EV(coreEvalBridgeHandler).fromBridge(bridgeMessage);
const nextEndTime = nextAuctionSchedule.endTime;
const afterEndTime = TimeMath.addAbsRel(nextEndTime, fiveMinutes);
@@ -160,8 +189,10 @@ test('addAsset to auction starting soon', async t => {
const schedulesAfter = await EV(auctioneerKit.creatorFacet).getSchedule();
t.truthy(
- schedules.nextAuctionSchedule.endTime.absValue <
- schedulesAfter.nextAuctionSchedule.endTime.absValue,
+ schedules.nextAuctionSchedule!.endTime.absValue <
+ schedulesAfter.nextAuctionSchedule!.endTime.absValue,
);
- t.like(readLatest(`${auctioneerPath}.book1`), { currentPriceLevel: null });
+
+ const booksAfter = getNumAuctionBooks();
+ t.is(booksAfter, booksBefore + 1);
});
diff --git a/packages/boot/test/bootstrapTests/demo-config.test.ts b/packages/boot/test/bootstrapTests/demo-config.test.ts
index 28d29eacf1c..af87839e678 100644
--- a/packages/boot/test/bootstrapTests/demo-config.test.ts
+++ b/packages/boot/test/bootstrapTests/demo-config.test.ts
@@ -4,7 +4,7 @@ import { PowerFlags } from '@agoric/vats/src/walletFlags.js';
import type { TestFn } from 'ava';
-import { keyArrayEqual, makeSwingsetTestKit } from '../../tools/supports.ts';
+import { keyArrayEqual, makeSwingsetTestKit } from '../../tools/supports.js';
const { keys } = Object;
diff --git a/packages/boot/test/bootstrapTests/lca.test.ts b/packages/boot/test/bootstrapTests/lca.test.ts
index adb0d727e33..df475d8a484 100644
--- a/packages/boot/test/bootstrapTests/lca.test.ts
+++ b/packages/boot/test/bootstrapTests/lca.test.ts
@@ -3,12 +3,13 @@ import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';
import type { TestFn } from 'ava';
import { Fail } from '@endo/errors';
-import type { start as stakeBldStart } from '@agoric/orchestration/src/examples/stakeBld.contract.js';
+import type { start as stakeBldStart } from '@agoric/orchestration/src/examples/stake-bld.contract.js';
import type { Instance } from '@agoric/zoe/src/zoeService/utils.js';
+import { SIMULATED_ERRORS } from '@agoric/vats/tools/fake-bridge.js';
import {
makeWalletFactoryContext,
type WalletFactoryTestContext,
-} from './walletFactory.ts';
+} from './walletFactory.js';
const test: TestFn = anyTest;
@@ -100,12 +101,15 @@ test.serial('stakeBld', async t => {
source: 'continuing',
previousOffer: 'request-stake',
invitationMakerName: 'Delegate',
- invitationArgs: ['agoric1validator1', { brand: BLD, value: 504n }],
+ invitationArgs: [
+ 'agoric1validator1',
+ { brand: BLD, value: SIMULATED_ERRORS.TIMEOUT },
+ ],
},
proposal: {
give: {
// @ts-expect-error XXX BoardRemote
- In: { brand: BLD, value: 504n },
+ In: { brand: BLD, value: SIMULATED_ERRORS.TIMEOUT },
},
},
}),
@@ -113,4 +117,72 @@ test.serial('stakeBld', async t => {
// FIXME should receive "simulated packet timeout" error
// { message: 'simulated packet timeout' },
);
+
+ await wd.executeOffer({
+ id: 'bank-send',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-stake',
+ invitationMakerName: 'Send',
+ },
+ proposal: {},
+ offerArgs: {
+ toAccount: {
+ value: 'agoric1EOAAccAddress',
+ chainId: 'agoriclocal',
+ encoding: 'bech32',
+ },
+ amount: { denom: 'ibc/1234', value: 10n },
+ },
+ });
+ t.like(wd.getLatestUpdateRecord(), {
+ status: { id: 'bank-send', numWantsSatisfied: 1 },
+ });
+
+ await wd.executeOffer({
+ id: 'bank-sendAll',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-stake',
+ invitationMakerName: 'SendAll',
+ },
+ proposal: {},
+ offerArgs: {
+ toAccount: {
+ value: 'agoric1EOAAccAddress',
+ chainId: 'agoriclocal',
+ encoding: 'bech32',
+ },
+ amounts: [
+ { denom: 'uatom', value: 10n },
+ { denom: 'ibc/1234', value: 10n },
+ ],
+ },
+ });
+ t.like(wd.getLatestUpdateRecord(), {
+ status: { id: 'bank-sendAll', numWantsSatisfied: 1 },
+ });
+
+ await t.throwsAsync(
+ wd.executeOffer({
+ id: 'bank-send-fail',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-stake',
+ invitationMakerName: 'Send',
+ },
+ proposal: {},
+ offerArgs: {
+ toAccount: {
+ value: 'agoric1EOAAccAddress',
+ chainId: 'agoriclocal',
+ encoding: 'bech32',
+ },
+ amount: {
+ denom: 'ibc/1234',
+ value: SIMULATED_ERRORS.BAD_REQUEST,
+ },
+ },
+ }),
+ );
});
diff --git a/packages/boot/test/bootstrapTests/liquidation-1.test.ts b/packages/boot/test/bootstrapTests/liquidation-1.test.ts
index d25bec16d8d..d25f8e871b8 100644
--- a/packages/boot/test/bootstrapTests/liquidation-1.test.ts
+++ b/packages/boot/test/bootstrapTests/liquidation-1.test.ts
@@ -12,7 +12,7 @@ import {
makeLiquidationTestContext,
scale6,
LiquidationSetup,
-} from '../../tools/liquidation.ts';
+} from '../../tools/liquidation.js';
const test = anyTest as TestFn;
diff --git a/packages/boot/test/bootstrapTests/liquidation-2b.test.ts b/packages/boot/test/bootstrapTests/liquidation-2b.test.ts
index 09996a313f9..3a9d48e555c 100644
--- a/packages/boot/test/bootstrapTests/liquidation-2b.test.ts
+++ b/packages/boot/test/bootstrapTests/liquidation-2b.test.ts
@@ -17,7 +17,7 @@ import {
LiquidationTestContext,
makeLiquidationTestContext,
scale6,
-} from '../../tools/liquidation.ts';
+} from '../../tools/liquidation.js';
const test = anyTest as TestFn;
diff --git a/packages/boot/test/bootstrapTests/liquidation-concurrent-1.test.ts b/packages/boot/test/bootstrapTests/liquidation-concurrent-1.test.ts
index 1a7fa875e0c..514d0df9323 100644
--- a/packages/boot/test/bootstrapTests/liquidation-concurrent-1.test.ts
+++ b/packages/boot/test/bootstrapTests/liquidation-concurrent-1.test.ts
@@ -12,7 +12,7 @@ import {
likePayouts,
makeLiquidationTestContext,
scale6,
-} from '../../tools/liquidation.ts';
+} from '../../tools/liquidation.js';
const test = anyTest as TestFn;
diff --git a/packages/boot/test/bootstrapTests/liquidation-concurrent-2b.test.ts b/packages/boot/test/bootstrapTests/liquidation-concurrent-2b.test.ts
index 21f8f7bf394..4798cf96ae2 100644
--- a/packages/boot/test/bootstrapTests/liquidation-concurrent-2b.test.ts
+++ b/packages/boot/test/bootstrapTests/liquidation-concurrent-2b.test.ts
@@ -15,7 +15,7 @@ import {
ensureVaultCollateral,
makeLiquidationTestContext,
scale6,
-} from '../../tools/liquidation.ts';
+} from '../../tools/liquidation.js';
const test = anyTest as TestFn;
diff --git a/packages/boot/test/bootstrapTests/net-ibc-upgrade.test.ts b/packages/boot/test/bootstrapTests/net-ibc-upgrade.test.ts
index 0c5eb68dc4e..53a1a1ebc98 100644
--- a/packages/boot/test/bootstrapTests/net-ibc-upgrade.test.ts
+++ b/packages/boot/test/bootstrapTests/net-ibc-upgrade.test.ts
@@ -7,7 +7,7 @@ import { createRequire } from 'module';
import type { Baggage } from '@agoric/swingset-liveslots';
import { M, makeScalarBigMapStore } from '@agoric/vat-data';
import { makeDurableZone } from '@agoric/zone/durable.js';
-import { makeSwingsetTestKit } from '../../tools/supports.ts';
+import { makeSwingsetTestKit } from '../../tools/supports.js';
const { entries, assign } = Object;
diff --git a/packages/boot/test/bootstrapTests/orchestration.test.ts b/packages/boot/test/bootstrapTests/orchestration.test.ts
index c73b3073b87..ba56accaabe 100644
--- a/packages/boot/test/bootstrapTests/orchestration.test.ts
+++ b/packages/boot/test/bootstrapTests/orchestration.test.ts
@@ -3,13 +3,14 @@ import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';
import { Fail } from '@endo/errors';
import { documentStorageSchema } from '@agoric/internal/src/storage-test-utils.js';
import type { CosmosValidatorAddress } from '@agoric/orchestration';
-import type { start as startStakeIca } from '@agoric/orchestration/src/examples/stakeIca.contract.js';
+import type { start as startStakeIca } from '@agoric/orchestration/src/examples/stake-ica.contract.js';
import type { Instance } from '@agoric/zoe/src/zoeService/utils.js';
import type { TestFn } from 'ava';
+import { SIMULATED_ERRORS } from '@agoric/vats/tools/fake-bridge.js';
import {
makeWalletFactoryContext,
type WalletFactoryTestContext,
-} from './walletFactory.ts';
+} from './walletFactory.js';
const test: TestFn = anyTest;
@@ -19,6 +20,8 @@ const validatorAddress: CosmosValidatorAddress = {
encoding: 'bech32',
};
+const ATOM_DENOM = 'uatom';
+
test.before(async t => {
t.context = await makeWalletFactoryContext(
t,
@@ -43,7 +46,7 @@ test.serial('config', async t => {
const cosmosChainInfo = await EV(agoricNames).lookup('chain', 'cosmoshub');
t.like(cosmosChainInfo, {
chainId: 'cosmoshub-4',
- stakingTokens: [{ denom: 'uatom' }],
+ stakingTokens: [{ denom: ATOM_DENOM }],
});
t.deepEqual(
readLatest(`published.agoricNames.chain.cosmoshub`),
@@ -120,8 +123,8 @@ test.skip('stakeOsmo - queries', async t => {
t.log('account', account);
t.truthy(account, 'makeAccount returns an account on OSMO connection');
- const queryRes = await EV(account).getBalance('uatom');
- t.deepEqual(queryRes, { value: 0n, denom: 'uatom' });
+ const queryRes = await EV(account).getBalance(ATOM_DENOM);
+ t.deepEqual(queryRes, { value: 0n, denom: ATOM_DENOM });
const queryUnknownDenom = await EV(account).getBalance('some-invalid-denom');
t.deepEqual(
@@ -132,8 +135,13 @@ test.skip('stakeOsmo - queries', async t => {
});
test.serial('stakeAtom - smart wallet', async t => {
- const { buildProposal, evalProposal, agoricNamesRemotes, readLatest } =
- t.context;
+ const {
+ buildProposal,
+ evalProposal,
+ agoricNamesRemotes,
+ bridgeUtils: { flushInboundQueue },
+ readLatest,
+ } = t.context;
await evalProposal(
buildProposal('@agoric/builders/scripts/orchestration/init-stakeAtom.js'),
@@ -143,7 +151,7 @@ test.serial('stakeAtom - smart wallet', async t => {
'agoric1testStakAtom',
);
- await wd.executeOffer({
+ await wd.sendOffer({
id: 'request-account',
invitationSpec: {
source: 'agoricContract',
@@ -152,6 +160,7 @@ test.serial('stakeAtom - smart wallet', async t => {
},
proposal: {},
});
+ await flushInboundQueue();
t.like(wd.getCurrentWalletRecord(), {
offerToPublicSubscriberPaths: [
[
@@ -165,23 +174,28 @@ test.serial('stakeAtom - smart wallet', async t => {
t.like(wd.getLatestUpdateRecord(), {
status: { id: 'request-account', numWantsSatisfied: 1 },
});
- t.is(readLatest('published.stakeAtom.accounts.cosmos1test'), '');
+ t.deepEqual(readLatest('published.stakeAtom.accounts.cosmos1test'), {
+ localAddress:
+ '/ibc-port/icacontroller-1/ordered/{"version":"ics27-1","controllerConnectionId":"connection-8","hostConnectionId":"connection-649","address":"cosmos1test","encoding":"proto3","txType":"sdk_multi_msg"}/ibc-channel/channel-1',
+ remoteAddress:
+ '/ibc-hop/connection-8/ibc-port/icahost/ordered/{"version":"ics27-1","controllerConnectionId":"connection-8","hostConnectionId":"connection-649","address":"cosmos1test","encoding":"proto3","txType":"sdk_multi_msg"}/ibc-channel/channel-1',
+ });
const { ATOM } = agoricNamesRemotes.brand;
ATOM || Fail`ATOM missing from agoricNames`;
- await t.notThrowsAsync(
- wd.executeOffer({
- id: 'request-delegate-success',
- invitationSpec: {
- source: 'continuing',
- previousOffer: 'request-account',
- invitationMakerName: 'Delegate',
- invitationArgs: [validatorAddress, { brand: ATOM, value: 10n }],
- },
- proposal: {},
- }),
- );
+ // Cannot await executeOffer because the offer won't resolve until after the bridge's inbound queue is flushed.
+ // But this test doesn't require that.
+ await wd.sendOffer({
+ id: 'request-delegate-success',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-account',
+ invitationMakerName: 'Delegate',
+ invitationArgs: [validatorAddress, { denom: ATOM_DENOM, value: 10n }],
+ },
+ proposal: {},
+ });
t.like(wd.getLatestUpdateRecord(), {
status: { id: 'request-delegate-success', numWantsSatisfied: 1 },
});
@@ -192,6 +206,7 @@ test.serial('stakeAtom - smart wallet', async t => {
encoding: 'bech32',
};
+ // This will trigger the immediate ack of the mock bridge
await t.throwsAsync(
wd.executeOffer({
id: 'request-delegate-fail',
@@ -199,7 +214,10 @@ test.serial('stakeAtom - smart wallet', async t => {
source: 'continuing',
previousOffer: 'request-account',
invitationMakerName: 'Delegate',
- invitationArgs: [validatorAddressFail, { brand: ATOM, value: 10n }],
+ invitationArgs: [
+ validatorAddressFail,
+ { denom: ATOM_DENOM, value: 10n },
+ ],
},
proposal: {},
}),
@@ -208,6 +226,23 @@ test.serial('stakeAtom - smart wallet', async t => {
},
'delegate fails with invalid validator',
);
+
+ // This will trigger the immediate ack of the mock bridge
+ await t.throwsAsync(
+ wd.executeOffer({
+ id: 'request-delegate-brand',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-account',
+ invitationMakerName: 'Delegate',
+ invitationArgs: [validatorAddress, { brand: ATOM, value: 10n }],
+ },
+ proposal: {},
+ }),
+ {
+ message: 'No denom for brand [object Alleged: ATOM brand]',
+ },
+ );
});
test.todo('undelegate wallet offer');
@@ -248,8 +283,13 @@ test.serial('revise chain info', async t => {
});
test('basic-flows', async t => {
- const { buildProposal, evalProposal, agoricNamesRemotes, readLatest } =
- t.context;
+ const {
+ buildProposal,
+ evalProposal,
+ agoricNamesRemotes,
+ readLatest,
+ bridgeUtils: { flushInboundQueue },
+ } = t.context;
await evalProposal(
buildProposal('@agoric/builders/scripts/orchestration/init-basic-flows.js'),
@@ -259,7 +299,7 @@ test('basic-flows', async t => {
await t.context.walletFactoryDriver.provideSmartWallet('agoric1test');
// create a cosmos orchestration account
- await wd.executeOffer({
+ await wd.sendOffer({
id: 'request-coa',
invitationSpec: {
source: 'agoricContract',
@@ -271,6 +311,7 @@ test('basic-flows', async t => {
},
proposal: {},
});
+ await flushInboundQueue();
t.like(wd.getCurrentWalletRecord(), {
offerToPublicSubscriberPaths: [
[
@@ -284,7 +325,12 @@ test('basic-flows', async t => {
t.like(wd.getLatestUpdateRecord(), {
status: { id: 'request-coa', numWantsSatisfied: 1 },
});
- t.is(readLatest('published.basicFlows.cosmos1test'), '');
+ t.deepEqual(readLatest('published.basicFlows.cosmos1test'), {
+ localAddress:
+ '/ibc-port/icacontroller-4/ordered/{"version":"ics27-1","controllerConnectionId":"connection-8","hostConnectionId":"connection-649","address":"cosmos1test","encoding":"proto3","txType":"sdk_multi_msg"}/ibc-channel/channel-4',
+ remoteAddress:
+ '/ibc-hop/connection-8/ibc-port/icahost/ordered/{"version":"ics27-1","controllerConnectionId":"connection-8","hostConnectionId":"connection-649","address":"cosmos1test","encoding":"proto3","txType":"sdk_multi_msg"}/ibc-channel/channel-4',
+ });
// create a local orchestration account
await wd.executeOffer({
@@ -304,12 +350,105 @@ test('basic-flows', async t => {
wd.getCurrentWalletRecord().offerToPublicSubscriberPaths,
);
t.deepEqual(publicSubscriberPaths['request-loa'], {
- account: 'published.basicFlows.agoric1mockVlocalchainAddress',
+ account: 'published.basicFlows.agoric1fakeLCAAddress1',
});
t.like(wd.getLatestUpdateRecord(), {
status: { id: 'request-loa', numWantsSatisfied: 1 },
});
- t.is(readLatest('published.basicFlows.agoric1mockVlocalchainAddress'), '');
+ t.is(readLatest('published.basicFlows.agoric1fakeLCAAddress'), '');
+
+ await wd.sendOffer({
+ id: 'transfer-to-noble-from-cosmos',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-coa',
+ invitationMakerName: 'Transfer',
+ },
+ proposal: {},
+ offerArgs: {
+ amount: { denom: 'ibc/uusdchash', value: 10n },
+ destination: {
+ chainId: 'noble-1',
+ value: 'noble1test',
+ encoding: 'bech32,',
+ },
+ },
+ });
+ t.like(wd.getLatestUpdateRecord(), {
+ status: {
+ id: 'transfer-to-noble-from-cosmos',
+ error: undefined,
+ },
+ });
+
+ await wd.sendOffer({
+ id: 'transfer-to-noble-from-cosmos-timeout',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-coa',
+ invitationMakerName: 'Transfer',
+ },
+ proposal: {},
+ offerArgs: {
+ amount: { denom: 'ibc/uusdchash', value: SIMULATED_ERRORS.TIMEOUT },
+ destination: {
+ chainId: 'noble-1',
+ value: 'noble1test',
+ encoding: 'bech32,',
+ },
+ },
+ });
+ t.like(wd.getLatestUpdateRecord(), {
+ status: {
+ id: 'transfer-to-noble-from-cosmos-timeout',
+ error:
+ 'Error: ABCI code: 5: error handling packet: see events for details',
+ },
+ });
+
+ await wd.sendOffer({
+ id: 'transfer-to-noble-from-agoric',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-loa',
+ invitationMakerName: 'Transfer',
+ },
+ proposal: {},
+ offerArgs: {
+ amount: { denom: 'ibc/uusdchash', value: 10n },
+ destination: {
+ chainId: 'noble-1',
+ value: 'noble1test',
+ encoding: 'bech32,',
+ },
+ },
+ });
+ t.like(wd.getLatestUpdateRecord(), {
+ status: {
+ id: 'transfer-to-noble-from-agoric',
+ error: undefined,
+ },
+ });
+
+ await t.throwsAsync(
+ wd.executeOffer({
+ id: 'transfer-to-noble-from-agoric-timeout',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-loa',
+ invitationMakerName: 'Transfer',
+ },
+ proposal: {},
+ offerArgs: {
+ amount: { denom: 'ibc/uusdchash', value: SIMULATED_ERRORS.TIMEOUT },
+ destination: {
+ chainId: 'noble-1',
+ value: 'noble1test',
+ encoding: 'bech32,',
+ },
+ },
+ }),
+ );
});
test.serial('auto-stake-it - proposal', async t => {
@@ -323,8 +462,13 @@ test.serial('auto-stake-it - proposal', async t => {
});
test.serial('basic-flows - portfolio holder', async t => {
- const { buildProposal, evalProposal, readLatest, agoricNamesRemotes } =
- t.context;
+ const {
+ buildProposal,
+ evalProposal,
+ readLatest,
+ agoricNamesRemotes,
+ bridgeUtils: { flushInboundQueue },
+ } = t.context;
await evalProposal(
buildProposal('@agoric/builders/scripts/orchestration/init-basic-flows.js'),
@@ -334,7 +478,7 @@ test.serial('basic-flows - portfolio holder', async t => {
await t.context.walletFactoryDriver.provideSmartWallet('agoric1test2');
// create a cosmos orchestration account
- await wd.executeOffer({
+ await wd.sendOffer({
id: 'request-portfolio-acct',
invitationSpec: {
source: 'agoricContract',
@@ -346,12 +490,20 @@ test.serial('basic-flows - portfolio holder', async t => {
},
proposal: {},
});
+ t.like(
+ wd.getLatestUpdateRecord(),
+ {
+ status: { id: 'request-portfolio-acct', numWantsSatisfied: 1 },
+ },
+ 'trivially satisfied',
+ );
+ await flushInboundQueue();
t.like(wd.getCurrentWalletRecord(), {
offerToPublicSubscriberPaths: [
[
'request-portfolio-acct',
{
- agoric: 'published.basicFlows.agoric1mockVlocalchainAddress',
+ agoric: 'published.basicFlows.agoric1fakeLCAAddress',
cosmoshub: 'published.basicFlows.cosmos1test',
// XXX support multiple chain addresses in ibc mocks
osmosis: 'published.basicFlows.cosmos1test',
@@ -363,51 +515,51 @@ test.serial('basic-flows - portfolio holder', async t => {
status: { id: 'request-portfolio-acct', numWantsSatisfied: 1 },
});
// XXX this overrides a previous account, since mocks only provide one address
- t.is(readLatest('published.basicFlows.cosmos1test'), '');
+ t.deepEqual(readLatest('published.basicFlows.cosmos1test'), {
+ localAddress:
+ '/ibc-port/icacontroller-3/ordered/{"version":"ics27-1","controllerConnectionId":"connection-1","hostConnectionId":"connection-1649","address":"cosmos1test","encoding":"proto3","txType":"sdk_multi_msg"}/ibc-channel/channel-3',
+ remoteAddress:
+ '/ibc-hop/connection-1/ibc-port/icahost/ordered/{"version":"ics27-1","controllerConnectionId":"connection-1","hostConnectionId":"connection-1649","address":"cosmos1test","encoding":"proto3","txType":"sdk_multi_msg"}/ibc-channel/channel-3',
+ });
// XXX this overrides a previous account, since mocks only provide one address
- t.is(readLatest('published.basicFlows.agoric1mockVlocalchainAddress'), '');
+ t.is(readLatest('published.basicFlows.agoric1fakeLCAAddress'), '');
- const { ATOM, BLD } = agoricNamesRemotes.brand;
- ATOM || Fail`ATOM missing from agoricNames`;
+ const { BLD } = agoricNamesRemotes.brand;
BLD || Fail`BLD missing from agoricNames`;
- await t.notThrowsAsync(
- wd.executeOffer({
- id: 'delegate-cosmoshub',
- invitationSpec: {
- source: 'continuing',
- previousOffer: 'request-portfolio-acct',
- invitationMakerName: 'MakeInvitation',
- invitationArgs: [
- 'cosmoshub',
- 'Delegate',
- [validatorAddress, { brand: ATOM, value: 10n }],
- ],
- },
- proposal: {},
- }),
- );
+ await wd.sendOffer({
+ id: 'delegate-cosmoshub',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-portfolio-acct',
+ invitationMakerName: 'Proxying',
+ invitationArgs: [
+ 'cosmoshub',
+ 'Delegate',
+ [validatorAddress, { denom: ATOM_DENOM, value: 10n }],
+ ],
+ },
+ proposal: {},
+ });
t.like(wd.getLatestUpdateRecord(), {
status: { id: 'delegate-cosmoshub', numWantsSatisfied: 1 },
});
- await t.notThrowsAsync(
- wd.executeOffer({
- id: 'delegate-agoric',
- invitationSpec: {
- source: 'continuing',
- previousOffer: 'request-portfolio-acct',
- invitationMakerName: 'MakeInvitation',
- invitationArgs: [
- 'agoric',
- 'Delegate',
- // XXX use ChainAddress for LocalOrchAccount
- ['agoric1validator1', { brand: BLD, value: 10n }],
- ],
- },
- proposal: {},
- }),
- );
+ await wd.sendOffer({
+ id: 'delegate-agoric',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-portfolio-acct',
+ invitationMakerName: 'Proxying',
+ invitationArgs: [
+ 'agoric',
+ 'Delegate',
+ // XXX use ChainAddress for LocalOrchAccount
+ ['agoric1validator1', { brand: BLD, value: 10n }],
+ ],
+ },
+ proposal: {},
+ });
t.like(wd.getLatestUpdateRecord(), {
status: { id: 'delegate-agoric', numWantsSatisfied: 1 },
});
@@ -418,11 +570,14 @@ test.serial('basic-flows - portfolio holder', async t => {
invitationSpec: {
source: 'continuing',
previousOffer: 'request-portfolio-acct',
- invitationMakerName: 'MakeInvitation',
+ invitationMakerName: 'Proxying',
invitationArgs: [
'cosmoshub',
'Delegate',
- [validatorAddress, { brand: ATOM, value: 504n }],
+ [
+ validatorAddress,
+ { denom: ATOM_DENOM, value: SIMULATED_ERRORS.TIMEOUT },
+ ],
],
},
proposal: {},
@@ -435,11 +590,14 @@ test.serial('basic-flows - portfolio holder', async t => {
invitationSpec: {
source: 'continuing',
previousOffer: 'request-portfolio-acct',
- invitationMakerName: 'MakeInvitation',
+ invitationMakerName: 'Proxying',
invitationArgs: [
'agoric',
'Delegate',
- ['agoric1validator1', { brand: BLD, value: 504n }],
+ [
+ 'agoric1validator1',
+ { brand: BLD, value: SIMULATED_ERRORS.TIMEOUT },
+ ],
],
},
proposal: {},
diff --git a/packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.md b/packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.md
index 9128d9e1512..720d6075dc2 100644
--- a/packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.md
+++ b/packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.md
@@ -16,10 +16,6 @@ Generated by [AVA](https://avajs.dev).
'published.agoricNames.chain.agoric',
'{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"chainId\\\\\\":\\\\\\"agoric-3\\\\\\",\\\\\\"icqEnabled\\\\\\":false,\\\\\\"stakingTokens\\\\\\":[{\\\\\\"denom\\\\\\":\\\\\\"ubld\\\\\\"}]}\\",\\"slots\\":[]}"]}',
],
- [
- 'published.agoricNames.chain.agoriclocal',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"chainId\\\\\\":\\\\\\"agoriclocal\\\\\\"}\\",\\"slots\\":[]}"]}',
- ],
[
'published.agoricNames.chain.celestia',
'{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"chainId\\\\\\":\\\\\\"celestia\\\\\\",\\\\\\"icqEnabled\\\\\\":false,\\\\\\"stakingTokens\\\\\\":[{\\\\\\"denom\\\\\\":\\\\\\"utia\\\\\\"}]}\\",\\"slots\\":[]}"]}',
@@ -42,7 +38,7 @@ Generated by [AVA](https://avajs.dev).
],
[
'published.agoricNames.chain.noble',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"chainId\\\\\\":\\\\\\"noble-1\\\\\\",\\\\\\"icqEnabled\\\\\\":false,\\\\\\"stakingTokens\\\\\\":[{\\\\\\"denom\\\\\\":\\\\\\"ustake\\\\\\"}]}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"chainId\\\\\\":\\\\\\"noble-1\\\\\\",\\\\\\"icqEnabled\\\\\\":false}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chain.omniflixhub',
@@ -70,215 +66,207 @@ Generated by [AVA](https://avajs.dev).
],
[
'published.agoricNames.chainConnection.agoric-3_cosmoshub-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-6\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-927\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-649\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-405\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-6\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-927\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-649\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-405\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-77\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-32\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-40\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-72\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-62\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-21\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-77\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-32\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-40\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-72\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-62\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-21\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_omniflixhub-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-73\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-47\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-40\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-67\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-58\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-30\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-73\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-47\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-40\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-67\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-58\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-30\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2109\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1649\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-320\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2109\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1649\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-320\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-17\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-111\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-80\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-17\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-10\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-51\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-17\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-111\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-80\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-17\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-10\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-51\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-74\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-129\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-118\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-68\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-59\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-148\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-74\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-129\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-118\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-68\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-59\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-148\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-18\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-152\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-101\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-42\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
- ],
- [
- 'published.agoricNames.chainConnection.agoriclocal_cosmoshub-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":1,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
- ],
- [
- 'published.agoricNames.chainConnection.agoriclocal_osmosislocal',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":1,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-18\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-152\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-101\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-42\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_neutron-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-29\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-48\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-36\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-7\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-35\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-29\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-48\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-36\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-7\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-35\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-10\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3012\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2503\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-2\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-6994\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-10\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3012\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2503\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-2\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-6994\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-52\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-174\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-131\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-15\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-14\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-91\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-52\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-174\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-131\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-15\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-14\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-91\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-86\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-359\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-296\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-56\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-33\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-291\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-86\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-359\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-296\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-56\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-33\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-291\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-137\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-125\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-4\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-4\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-162\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-137\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-125\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-4\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-4\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-162\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_juno-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-439\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-372\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-207\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-439\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-372\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-207\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_neutron-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1119\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-809\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-569\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1119\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-809\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-569\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1116\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-4\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-12\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-790\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-536\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-4\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1116\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-4\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-12\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-790\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-536\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-4\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_omniflixhub-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-656\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-23\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-19\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-501\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-306\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-12\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-656\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-23\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-19\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-501\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-306\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-12\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-259\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-257\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-141\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-259\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-257\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-141\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-492\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-401\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-235\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-492\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-401\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-235\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1188\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-320\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-256\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-918\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-730\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-239\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1188\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-320\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-256\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-918\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-730\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-239\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-913\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-635\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-391\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-913\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-635\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-391\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_neutron-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-11\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-72\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-51\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-17\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-11\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-72\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-51\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-17\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-59\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-57\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-33\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-59\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-57\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-33\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3009\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2500\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-7\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-3\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-6787\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3009\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2500\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-7\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-3\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-6787\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-133\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-123\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-160\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-133\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-123\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-160\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-8\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-244\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-208\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-13\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-118\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-8\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-244\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-208\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-13\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-118\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_neutron-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-557\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-97\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-71\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-524\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-548\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-4328\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-557\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-97\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-71\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-524\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-548\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-4328\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-334\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-322\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-224\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-3\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-334\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-8\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-322\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-224\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-3\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1457\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1142\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-42\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1457\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1142\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-42\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-108\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-23\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-9\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-68\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-108\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-23\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-9\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-68\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-44\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-13\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-11\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-30\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-20\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-44\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-13\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-11\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-30\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-20\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-263\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-31\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-19\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-205\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-139\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-24\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-263\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-31\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-19\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-205\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-139\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-24\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-40\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-25\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-34\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-31\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-30\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-18\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-40\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-25\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-34\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-31\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-30\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-18\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-19\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2823\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2338\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-10\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-874\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-19\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2823\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2338\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-10\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-874\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-85\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-199\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-192\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-63\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1551\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-144\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-85\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-199\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-192\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-63\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1551\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-144\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-31\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-283\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-211\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-23\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-18\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-191\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-31\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-283\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-211\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-23\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-18\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-191\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-18\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-125\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-113\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-15\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-123\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-18\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-125\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-113\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-15\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-123\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_omniflixhub-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-68\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-51\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-49\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-65\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-44\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-38\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-68\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-51\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-49\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-65\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-44\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-38\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2704\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2241\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-750\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2704\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2241\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-750\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-24\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-170\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-127\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-33\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-17\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-88\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-24\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-170\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-127\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-33\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-17\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-88\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-16\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-287\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-214\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-204\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-16\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-287\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-214\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-204\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-73\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-248\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-210\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-74\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-51\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-120\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-73\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-248\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-210\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-74\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-51\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-120\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.omniflixhub-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-8\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1829\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1431\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-199\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-8\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1829\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1431\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-199\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.osmosis-1_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1588\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1244\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-88\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1588\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1244\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-88\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.osmosis-1_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1562\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1223\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-75\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1562\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1223\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-75\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.osmosis-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2119\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1657\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-326\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2119\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1657\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-326\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.osmosis-1_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1805\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-6\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1410\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-184\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1805\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-6\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1410\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-184\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.secret-4_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-43\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-177\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-110\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-19\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-43\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-177\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-110\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-19\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.secret-4_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-75\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-37\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-40\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-37\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-40\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-75\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-37\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-25\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-40\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-37\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-40\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.secret-4_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-193\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-249\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-213\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-188\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-126\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-123\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-193\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-249\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-213\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-188\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-126\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-123\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.stargaze-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-195\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-30\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-128\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-106\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-19\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-195\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-30\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-18\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-128\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-106\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-19\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.stride-1_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-32\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-64\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-45\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-20\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-29\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-34\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-32\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-64\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-45\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-20\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-29\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-34\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
]
@@ -290,214 +278,206 @@ Generated by [AVA](https://avajs.dev).
[
[
'published.agoricNames.chainConnection.agoric-3_cosmoshub-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-6\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-927\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-649\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-405\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-6\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-927\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-649\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-405\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-77\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-32\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-40\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-72\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-62\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-21\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-77\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-32\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-40\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-72\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-62\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-21\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_omniflixhub-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-73\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-47\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-40\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-67\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-58\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-30\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-73\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-47\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-40\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-67\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-58\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-30\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2109\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1649\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-320\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2109\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1649\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-320\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-17\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-111\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-80\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-17\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-10\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-51\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-17\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-111\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-80\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-17\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-10\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-51\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-74\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-129\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-118\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-68\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-59\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-148\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-74\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-129\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-118\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-68\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-59\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-148\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.agoric-3_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-18\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-152\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-101\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-42\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
- ],
- [
- 'published.agoricNames.chainConnection.agoriclocal_cosmoshub-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":1,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
- ],
- [
- 'published.agoricNames.chainConnection.agoriclocal_osmosislocal',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":1,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-18\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-152\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-101\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-42\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_neutron-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-29\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-48\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-36\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-7\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-35\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-29\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-48\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-36\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-7\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-35\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-10\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3012\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2503\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-2\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-6994\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-10\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3012\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2503\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-2\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-6994\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-52\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-174\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-131\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-15\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-14\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-91\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-52\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-174\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-131\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-15\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-14\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-91\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-86\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-359\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-296\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-56\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-33\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-291\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-86\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-359\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-296\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-56\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-33\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-291\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.celestia_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-137\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-125\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-4\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-4\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-162\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-137\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-125\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-4\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-4\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-162\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_juno-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-439\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-372\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-207\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-439\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-372\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-207\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_neutron-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1119\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-809\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-569\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1119\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-809\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-569\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1116\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-4\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-12\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-790\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-536\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-4\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1116\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-4\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-12\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-790\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-536\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-4\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_omniflixhub-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-656\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-23\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-19\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-501\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-306\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-12\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-656\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-23\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-19\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-501\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-306\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-12\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-259\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-257\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-141\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-259\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-257\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-141\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-492\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-401\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-235\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-492\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-401\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-235\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1188\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-320\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-256\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-918\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-730\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-239\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1188\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-320\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-256\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-918\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-730\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-239\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.cosmoshub-4_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-913\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-635\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-391\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-913\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-635\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-391\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_neutron-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-11\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-72\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-51\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-17\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-11\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-72\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-51\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-17\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-59\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-57\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-33\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-59\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-57\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-33\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3009\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2500\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-7\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-3\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-6787\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3009\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2500\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-7\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-3\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-6787\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-133\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-123\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-160\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-133\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-123\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-160\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.dydx-mainnet-1_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-8\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-244\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-208\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-13\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-118\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-8\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-244\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-208\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-13\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-118\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_neutron-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-557\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-97\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-71\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-524\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-548\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-4328\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-557\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-97\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-71\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-524\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-548\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-4328\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-334\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-322\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-224\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-3\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-334\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-3\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-8\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-322\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-224\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-3\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1457\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1142\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-42\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1457\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1142\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-42\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-108\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-23\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-9\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-68\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-108\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-23\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-9\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-68\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-44\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-13\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-11\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-30\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-20\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-44\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-13\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-11\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-30\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-20\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.juno-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-263\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-31\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-19\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-205\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-139\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-24\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-263\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-31\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-19\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-205\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-139\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-24\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_noble-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-40\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-25\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-34\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-31\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-30\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-18\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-40\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-25\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-34\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-31\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-30\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-18\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-19\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2823\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2338\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-10\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-874\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-19\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2823\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2338\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-10\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-874\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-85\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-199\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-192\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-63\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1551\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-144\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-85\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-199\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-192\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-63\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1551\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-144\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-31\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-283\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-211\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-23\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-18\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-191\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-31\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-283\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-211\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-23\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-18\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-191\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.neutron-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-18\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-125\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-113\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-15\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-123\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-18\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-125\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-113\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-15\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-8\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-123\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_omniflixhub-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-68\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-51\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-49\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-65\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-44\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-38\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-68\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-51\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-49\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-65\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-44\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-38\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2704\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2241\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-750\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2704\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2241\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-750\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-24\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-170\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-127\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-33\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-17\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-88\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-24\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-170\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-127\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-33\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-17\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-88\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-16\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-287\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-214\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-204\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-16\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-287\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-214\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-11\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-204\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.noble-1_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-73\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-248\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-210\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-74\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-51\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-120\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-73\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-248\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-210\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-74\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-51\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-120\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.omniflixhub-1_osmosis-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-8\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1829\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1431\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-199\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-8\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1829\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1431\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-199\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.osmosis-1_secret-4',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1588\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1244\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-88\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1588\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-1\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1244\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-88\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-1\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.osmosis-1_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1562\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1223\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-75\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1562\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-0\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1223\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-75\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.osmosis-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2119\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1657\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-326\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-2119\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-2\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1657\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-326\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-5\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.osmosis-1_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1805\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-6\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-1410\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-184\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-1805\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-6\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-0\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-1410\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-184\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-0\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.secret-4_stargaze-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-43\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-177\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-110\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-19\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-43\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-177\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-110\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-19\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-48\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.secret-4_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-75\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-37\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-25\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-40\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-37\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-40\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-75\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-37\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-25\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-40\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-37\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-40\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.secret-4_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-193\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-249\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-213\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-188\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-126\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-123\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-193\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-249\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-213\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-188\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-126\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-123\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.stargaze-1_stride-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-195\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-30\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-18\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-128\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-106\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-19\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-195\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-30\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-18\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-128\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-106\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-19\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
[
'published.agoricNames.chainConnection.stride-1_umee-1',
- '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-32\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-64\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-45\\\\\\",\\\\\\"prefix\\\\\\":{\\\\\\"key_prefix\\\\\\":\\\\\\"FIXME\\\\\\"}},\\\\\\"id\\\\\\":\\\\\\"connection-20\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-29\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-34\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
+ '{"blockHeight":"0","values":["{\\"body\\":\\"{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-32\\\\\\",\\\\\\"counterparty\\\\\\":{\\\\\\"client_id\\\\\\":\\\\\\"07-tendermint-64\\\\\\",\\\\\\"connection_id\\\\\\":\\\\\\"connection-45\\\\\\"},\\\\\\"id\\\\\\":\\\\\\"connection-20\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"transferChannel\\\\\\":{\\\\\\"channelId\\\\\\":\\\\\\"channel-29\\\\\\",\\\\\\"counterPartyChannelId\\\\\\":\\\\\\"channel-34\\\\\\",\\\\\\"counterPartyPortId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"ordering\\\\\\":0,\\\\\\"portId\\\\\\":\\\\\\"transfer\\\\\\",\\\\\\"state\\\\\\":3,\\\\\\"version\\\\\\":\\\\\\"ics20-1\\\\\\"}}\\",\\"slots\\":[]}"]}',
],
]
diff --git a/packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.snap b/packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.snap
index 5ef2c1ede43..53aefbf2f9c 100644
Binary files a/packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.snap and b/packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.snap differ
diff --git a/packages/boot/test/bootstrapTests/vat-orchestration.test.ts b/packages/boot/test/bootstrapTests/vat-orchestration.test.ts
index da8ba3187a3..22781f38ac1 100644
--- a/packages/boot/test/bootstrapTests/vat-orchestration.test.ts
+++ b/packages/boot/test/bootstrapTests/vat-orchestration.test.ts
@@ -17,14 +17,14 @@ import { M, matches } from '@endo/patterns';
import {
makeWalletFactoryContext,
type WalletFactoryTestContext,
-} from './walletFactory.ts';
+} from './walletFactory.js';
const test: TestFn = anyTest;
/**
* To update, pass the message into `makeTxPacket` or `makeQueryPacket` from
* `@agoric/orchestration`, and paste the resulting `data` key into `protoMsgMocks`
- * in [mocks.js](../../tools/ibc/mocks.js).
+ * in [mocks.ts](../../tools/ibc/mocks.ts).
* If adding a new msg, reference the mock in the `sendPacket` switch statement
* in [supports.ts](../../tools/supports.ts).
*/
@@ -55,6 +55,11 @@ test.before(async t => {
await evalProposal(
buildProposal('@agoric/builders/scripts/vats/init-orchestration.js'),
);
+ await evalProposal(
+ buildProposal(
+ '@agoric/builders/scripts/orchestration/write-chain-info.js',
+ ),
+ );
const vatStore = await EV.vat('bootstrap').consumeItem('vatStore');
t.true(await EV(vatStore).has('ibc'), 'ibc');
t.true(await EV(vatStore).has('network'), 'network');
diff --git a/packages/boot/test/bootstrapTests/vats-restart.test.ts b/packages/boot/test/bootstrapTests/vats-restart.test.ts
index 0655b96ec2c..0d33fb55a9f 100644
--- a/packages/boot/test/bootstrapTests/vats-restart.test.ts
+++ b/packages/boot/test/bootstrapTests/vats-restart.test.ts
@@ -2,20 +2,13 @@
import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';
import { TestFn } from 'ava';
-import processAmbient from 'child_process';
-import { promises as fsAmbientPromises } from 'fs';
-
import { Fail } from '@endo/errors';
import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
import { makeAgoricNamesRemotesFromFakeStorage } from '@agoric/vats/tools/board-utils.js';
import { BridgeHandler, ScopedBridgeManager } from '@agoric/vats';
-import type { EconomyBootstrapSpace } from '@agoric/inter-protocol/src/proposals/econ-behaviors.js';
-import {
- makeProposalExtractor,
- makeSwingsetTestKit,
-} from '../../tools/supports.ts';
-import { makeWalletFactoryDriver } from '../../tools/drivers.ts';
+import { makeSwingsetTestKit } from '../../tools/supports.js';
+import { makeWalletFactoryDriver } from '../../tools/drivers.js';
// main/production config doesn't have initialPrice, upon which 'open vaults' depends
const PLATFORM_CONFIG = '@agoric/vm-config/decentral-itest-vaults-config.json';
@@ -132,9 +125,8 @@ test.serial('use IBC callbacks after upgrade', async t => {
test.serial('read metrics', async t => {
const { EV } = t.context.runUtils;
- const vaultFactoryKit: Awaited<
- EconomyBootstrapSpace['consume']['vaultFactoryKit']
- > = await EV.vat('bootstrap').consumeItem('vaultFactoryKit');
+ const vaultFactoryKit =
+ await EV.vat('bootstrap').consumeItem('vaultFactoryKit');
const vfTopics = await EV(vaultFactoryKit.publicFacet).getPublicTopics();
diff --git a/packages/boot/test/bootstrapTests/vaults-integration.test.ts b/packages/boot/test/bootstrapTests/vaults-integration.test.ts
index fa51746b355..94aa48c3cc2 100644
--- a/packages/boot/test/bootstrapTests/vaults-integration.test.ts
+++ b/packages/boot/test/bootstrapTests/vaults-integration.test.ts
@@ -14,8 +14,8 @@ import {
import type { TestFn } from 'ava';
import { ParamChangesOfferArgs } from '@agoric/inter-protocol/src/econCommitteeCharter.js';
-import { makeSwingsetTestKit } from '../../tools/supports.ts';
-import { makeWalletFactoryDriver } from '../../tools/drivers.ts';
+import { makeSwingsetTestKit } from '../../tools/supports.js';
+import { makeWalletFactoryDriver } from '../../tools/drivers.js';
// presently all these tests use one collateral manager
const collateralBrandKey = 'ATOM';
diff --git a/packages/boot/test/bootstrapTests/vaults-upgrade.test.ts b/packages/boot/test/bootstrapTests/vaults-upgrade.test.ts
index d1f8c29429d..4af94865058 100644
--- a/packages/boot/test/bootstrapTests/vaults-upgrade.test.ts
+++ b/packages/boot/test/bootstrapTests/vaults-upgrade.test.ts
@@ -15,9 +15,8 @@ import { SECONDS_PER_YEAR } from '@agoric/inter-protocol/src/interest.js';
import { makeAgoricNamesRemotesFromFakeStorage } from '@agoric/vats/tools/board-utils.js';
import { ExecutionContext, TestFn } from 'ava';
import { FakeStorageKit } from '@agoric/internal/src/storage-test-utils.js';
-import { EconomyBootstrapSpace } from '@agoric/inter-protocol/src/proposals/econ-behaviors.js';
-import { makeSwingsetTestKit } from '../../tools/supports.ts';
-import { makeWalletFactoryDriver } from '../../tools/drivers.ts';
+import { makeSwingsetTestKit } from '../../tools/supports.js';
+import { makeWalletFactoryDriver } from '../../tools/drivers.js';
// presently all these tests use one collateral manager
const collateralBrandKey = 'ATOM';
@@ -284,17 +283,14 @@ test.serial('open vault', async t => {
test.serial('restart vaultFactory', async t => {
const { runUtils, readCollateralMetrics } = t.context.shared;
const { EV } = runUtils;
- const vaultFactoryKit = await (EV.vat('bootstrap').consumeItem(
- 'vaultFactoryKit',
- ) as EconomyBootstrapSpace['consume']['vaultFactoryKit']);
+ const vaultFactoryKit =
+ await EV.vat('bootstrap').consumeItem('vaultFactoryKit');
- const reserveKit = await (EV.vat('bootstrap').consumeItem(
- 'reserveKit',
- ) as EconomyBootstrapSpace['consume']['reserveKit']);
+ const reserveKit = await EV.vat('bootstrap').consumeItem('reserveKit');
const bootstrapVat = EV.vat('bootstrap');
- const electorateCreatorFacet = await (bootstrapVat.consumeItem(
+ const electorateCreatorFacet = await bootstrapVat.consumeItem(
'economicCommitteeCreatorFacet',
- ) as EconomyBootstrapSpace['consume']['economicCommitteeCreatorFacet']);
+ );
const poserInvitation = await EV(electorateCreatorFacet).getPoserInvitation();
const creatorFacet1 = await EV.get(reserveKit).creatorFacet;
@@ -327,9 +323,8 @@ test.serial('restart vaultFactory', async t => {
test.serial('restart contractGovernor', async t => {
const { EV } = t.context.shared.runUtils;
- const vaultFactoryKit = await (EV.vat('bootstrap').consumeItem(
- 'vaultFactoryKit',
- ) as EconomyBootstrapSpace['consume']['vaultFactoryKit']);
+ const vaultFactoryKit =
+ await EV.vat('bootstrap').consumeItem('vaultFactoryKit');
const { governorAdminFacet } = vaultFactoryKit;
// has no privateArgs of its own. the privateArgs.governed is only for the
@@ -498,9 +493,10 @@ test.serial(
await EV.vat('bootstrap').consumeItem('powerStore');
const getStoreSnapshot = async (name: string) =>
- EV.vat('bootstrap').snapshotStore(
- await EV(powerStore).get(name),
- ) as Promise<[any, any][]>;
+ EV.vat('bootstrap').snapshotStore(await EV(powerStore).get(name)) as [
+ any,
+ any,
+ ][];
const contractKits = await getStoreSnapshot('contractKits');
// TODO refactor the entries to go into governedContractKits too (so the latter is sufficient to test)
diff --git a/packages/boot/test/bootstrapTests/vow-offer-results.test.ts b/packages/boot/test/bootstrapTests/vow-offer-results.test.ts
index bc0b35b5619..27a448f7d89 100644
--- a/packages/boot/test/bootstrapTests/vow-offer-results.test.ts
+++ b/packages/boot/test/bootstrapTests/vow-offer-results.test.ts
@@ -5,7 +5,7 @@ import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
import {
makeWalletFactoryContext,
type WalletFactoryTestContext,
-} from './walletFactory.ts';
+} from './walletFactory.js';
const test: TestFn = anyTest;
diff --git a/packages/boot/test/bootstrapTests/vtransfer.test.ts b/packages/boot/test/bootstrapTests/vtransfer.test.ts
index 5e6221a2e14..fd0bec558ac 100644
--- a/packages/boot/test/bootstrapTests/vtransfer.test.ts
+++ b/packages/boot/test/bootstrapTests/vtransfer.test.ts
@@ -8,7 +8,7 @@ import type { TransferMiddleware } from '@agoric/vats/src/transfer.js';
import type { TransferVat } from '@agoric/vats/src/vat-transfer.js';
import { BridgeId } from '@agoric/internal';
import { VTRANSFER_IBC_EVENT } from '@agoric/internal/src/action-types.js';
-import { makeSwingsetTestKit } from '../../tools/supports.ts';
+import { makeSwingsetTestKit } from '../../tools/supports.js';
const makeDefaultTestContext = async t => {
const swingsetTestKit = await makeSwingsetTestKit(t.log, undefined, {
@@ -24,8 +24,12 @@ test.before(async t => (t.context = await makeDefaultTestContext(t)));
test.after.always(t => t.context.shutdown?.());
test('vtransfer', async t => {
- const { buildProposal, evalProposal, getOutboundMessages, runUtils } =
- t.context;
+ const {
+ buildProposal,
+ evalProposal,
+ bridgeUtils: { getOutboundMessages },
+ runUtils,
+ } = t.context;
const { EV } = runUtils;
// Pull what transfer-proposal produced into local scope
diff --git a/packages/boot/test/bootstrapTests/walletFactory.ts b/packages/boot/test/bootstrapTests/walletFactory.ts
index 2fa6f4c3d5e..e00e5a6adc5 100644
--- a/packages/boot/test/bootstrapTests/walletFactory.ts
+++ b/packages/boot/test/bootstrapTests/walletFactory.ts
@@ -3,8 +3,8 @@ import {
AgoricNamesRemotes,
makeAgoricNamesRemotesFromFakeStorage,
} from '@agoric/vats/tools/board-utils.js';
-import { makeSwingsetTestKit } from '../../tools/supports.ts';
-import { makeWalletFactoryDriver } from '../../tools/drivers.ts';
+import { makeSwingsetTestKit } from '../../tools/supports.js';
+import { makeWalletFactoryDriver } from '../../tools/drivers.js';
export const makeWalletFactoryContext = async (
t,
diff --git a/packages/boot/test/bootstrapTests/walletSurvivesZoeRestart.test.ts b/packages/boot/test/bootstrapTests/walletSurvivesZoeRestart.test.ts
index 7fbddc26492..43eda7d55a2 100644
--- a/packages/boot/test/bootstrapTests/walletSurvivesZoeRestart.test.ts
+++ b/packages/boot/test/bootstrapTests/walletSurvivesZoeRestart.test.ts
@@ -10,7 +10,7 @@ import {
LiquidationTestContext,
makeLiquidationTestContext,
LiquidationSetup,
-} from '../../tools/liquidation.ts';
+} from '../../tools/liquidation.js';
const test = anyTest as TestFn;
diff --git a/packages/boot/test/bootstrapTests/zcf-upgrade.test.ts b/packages/boot/test/bootstrapTests/zcf-upgrade.test.ts
index e08b5a0ed9e..0e1ed083e13 100644
--- a/packages/boot/test/bootstrapTests/zcf-upgrade.test.ts
+++ b/packages/boot/test/bootstrapTests/zcf-upgrade.test.ts
@@ -6,12 +6,12 @@ import path from 'path';
import { makeAgoricNamesRemotesFromFakeStorage } from '@agoric/vats/tools/board-utils.js';
import { TestFn } from 'ava';
-import { matchAmount, makeSwingsetTestKit } from '../../tools/supports.ts';
-import { makeZoeDriver } from '../../tools/drivers.ts';
+import { matchAmount, makeSwingsetTestKit } from '../../tools/supports.js';
+import { makeZoeDriver } from '../../tools/drivers.js';
const dirname = path.dirname(new URL(import.meta.url).pathname);
-const ZCF_PROBE_SRC = './zcfProbe.js';
+const ZCF_PROBE_SRC = './zcfProbe.contract.js';
/**
* @file Bootstrap test of upgrading ZCF to support atomicRearrange internally.
@@ -85,7 +85,7 @@ test('run restart-vats proposal', async t => {
await controller.validateAndInstallBundle(zcfProbeBundle);
// This test self-sufficiently builds all the artifacts it needs. The test in
// .../packages/deployment/upgradeTest/upgrade-test-scripts/unreleased-upgrade/zoe-upgrade/
- // needs a bundled copy of ./zcfProbe.js as of the final commit that will be
+ // needs a bundled copy of ./zcfProbe.contract.js as of the final commit that will be
// installed on-chain. Uncomment the following line and add
// `import fs from "fs";` to generate a bundle of the contract.
// fs.writeFileSync('bundles/prober-contract-bundle.json', JSON.stringify(zcfProbeBundle));
diff --git a/packages/boot/test/bootstrapTests/zcfProbe.js b/packages/boot/test/bootstrapTests/zcfProbe.contract.js
similarity index 99%
rename from packages/boot/test/bootstrapTests/zcfProbe.js
rename to packages/boot/test/bootstrapTests/zcfProbe.contract.js
index bec8d63684c..326cb73ef5f 100644
--- a/packages/boot/test/bootstrapTests/zcfProbe.js
+++ b/packages/boot/test/bootstrapTests/zcfProbe.contract.js
@@ -151,3 +151,4 @@ export const start = async (zcf, privateArgs, baggage) => {
creatorFacet: probe,
});
};
+harden(start);
diff --git a/packages/boot/test/orchestration/restart-contracts.test.ts b/packages/boot/test/orchestration/restart-contracts.test.ts
new file mode 100644
index 00000000000..25e7d881268
--- /dev/null
+++ b/packages/boot/test/orchestration/restart-contracts.test.ts
@@ -0,0 +1,281 @@
+/** @file Bootstrap test of restarting contracts using orchestration */
+import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';
+import { TestFn } from 'ava';
+
+import type { CosmosValidatorAddress } from '@agoric/orchestration';
+import type { UpdateRecord } from '@agoric/smart-wallet/src/smartWallet.js';
+import {
+ makeWalletFactoryContext,
+ type WalletFactoryTestContext,
+} from '../bootstrapTests/walletFactory.js';
+
+const test: TestFn = anyTest;
+test.before(async t => {
+ t.context = await makeWalletFactoryContext(
+ t,
+ '@agoric/vm-config/decentral-itest-orchestration-config.json',
+ );
+});
+test.after.always(t => t.context.shutdown?.());
+
+// FIXME the test needs to be able to send the acknowledgementPacket ack
+// so that the transfer vow resolves.
+test.serial.failing('send-anywhere', async t => {
+ const {
+ walletFactoryDriver,
+ buildProposal,
+ evalProposal,
+ bridgeUtils: { flushInboundQueue },
+ } = t.context;
+
+ const { IST } = t.context.agoricNamesRemotes.brand;
+
+ t.log('start send-anywhere');
+ await evalProposal(
+ buildProposal('@agoric/builders/scripts/testing/start-send-anywhere.js'),
+ );
+
+ t.log('making offer');
+ const wallet = await walletFactoryDriver.provideSmartWallet('agoric1test');
+ // no money in wallet to actually send
+ const zero = { brand: IST, value: 0n };
+ // send because it won't resolve
+ await wallet.sendOffer({
+ id: 'send-somewhere',
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: ['sendAnywhere'],
+ callPipe: [['makeSendInvitation']],
+ },
+ proposal: {
+ // @ts-expect-error XXX BoardRemote
+ give: { Send: zero },
+ },
+ offerArgs: {
+ // meaningless address
+ destAddr: 'cosmos1qy352eufjjmc9c',
+ chainName: 'cosmoshub',
+ },
+ });
+ // no errors and no resolution
+ const beforeFlush = wallet.getLatestUpdateRecord();
+ t.like(wallet.getLatestUpdateRecord(), {
+ updated: 'offerStatus',
+ status: {
+ id: 'send-somewhere',
+ error: undefined,
+ },
+ numWantsSatisfied: undefined,
+ payouts: undefined,
+ result: undefined,
+ });
+
+ t.is(await flushInboundQueue(), 0);
+ t.deepEqual(wallet.getLatestUpdateRecord(), beforeFlush);
+
+ t.log('restart send-anywhere');
+ await evalProposal(
+ buildProposal('@agoric/builders/scripts/testing/restart-send-anywhere.js'),
+ );
+
+ const conclusion = wallet.getLatestUpdateRecord();
+ console.log('conclusion', conclusion);
+ t.like(conclusion, {
+ updated: 'offerStatus',
+ status: {
+ id: 'send-somewhere',
+ error: undefined,
+ },
+ numWantsSatisfied: undefined,
+ payouts: undefined,
+ result: undefined,
+ });
+
+ await flushInboundQueue();
+
+ // Nothing interesting to confirm here.
+});
+
+const validatorAddress: CosmosValidatorAddress = {
+ value: 'cosmosvaloper1test',
+ chainId: 'gaiatest',
+ encoding: 'bech32',
+};
+const ATOM_DENOM = 'uatom';
+
+// check for key because the value will be 'undefined' when the result is provided
+// TODO should it be something truthy?
+const hasResult = (r: UpdateRecord) => {
+ assert(r.updated === 'offerStatus');
+ return 'result' in r.status;
+};
+
+// Tests restart but not of an orchestration() flow
+test.serial('stakeAtom', async t => {
+ const {
+ buildProposal,
+ evalProposal,
+ agoricNamesRemotes,
+ bridgeUtils: { flushInboundQueue },
+ readLatest,
+ } = t.context;
+
+ await evalProposal(
+ buildProposal('@agoric/builders/scripts/orchestration/init-stakeAtom.js'),
+ );
+
+ const wd = await t.context.walletFactoryDriver.provideSmartWallet(
+ 'agoric1testStakAtom',
+ );
+
+ await wd.sendOffer({
+ id: 'request-account',
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: ['stakeAtom'],
+ callPipe: [['makeAccountInvitationMaker']],
+ },
+ proposal: {},
+ });
+ // cosmos1test is from ibc/mocks.js
+ const accountPath = 'published.stakeAtom.accounts.cosmos1test';
+ t.throws(() => readLatest(accountPath));
+ t.is(await flushInboundQueue(), 1);
+ t.deepEqual(readLatest(accountPath), {
+ localAddress:
+ '/ibc-port/icacontroller-1/ordered/{"version":"ics27-1","controllerConnectionId":"connection-8","hostConnectionId":"connection-649","address":"cosmos1test","encoding":"proto3","txType":"sdk_multi_msg"}/ibc-channel/channel-1',
+ remoteAddress:
+ '/ibc-hop/connection-8/ibc-port/icahost/ordered/{"version":"ics27-1","controllerConnectionId":"connection-8","hostConnectionId":"connection-649","address":"cosmos1test","encoding":"proto3","txType":"sdk_multi_msg"}/ibc-channel/channel-1',
+ });
+ // request-account is complete
+
+ const { ATOM } = agoricNamesRemotes.brand;
+ assert(ATOM);
+
+ await wd.sendOffer({
+ id: 'request-delegate',
+ invitationSpec: {
+ source: 'continuing',
+ previousOffer: 'request-account',
+ invitationMakerName: 'Delegate',
+ invitationArgs: [validatorAddress, { denom: ATOM_DENOM, value: 10n }],
+ },
+ proposal: {},
+ });
+ // no result yet because the IBC incoming messages haven't arrived
+ // and won't until we flush.
+ t.false(hasResult(wd.getLatestUpdateRecord()));
+
+ t.log('restart stakeAtom');
+ await evalProposal(
+ buildProposal('@agoric/builders/scripts/testing/restart-stakeAtom.js'),
+ );
+
+ t.is(await flushInboundQueue(), 1);
+ t.true(hasResult(wd.getLatestUpdateRecord()));
+});
+
+// Tests restart of an orchestration() flow while an IBC response is pending.
+//
+// TODO consider testing this pausing during any pending IBC message. It'll need
+// to fresh contract state on each iteration, and since this is a bootstrap test
+// that means either restarting bootstrap or starting a new contract and
+// restarting that one. For them to share bootstrap they'll each need a unique
+// instance name, which will require paramatizing the the two builders scripts
+// and the two core-eval functions.
+test.serial('basicFlows', async t => {
+ const {
+ walletFactoryDriver,
+ buildProposal,
+ evalProposal,
+ bridgeUtils: { getInboundQueueLength, flushInboundQueue },
+ } = t.context;
+
+ t.log('start basicFlows');
+ await evalProposal(
+ buildProposal('@agoric/builders/scripts/orchestration/init-basic-flows.js'),
+ );
+
+ t.log('making offer');
+ const wallet = await walletFactoryDriver.provideSmartWallet('agoric1test');
+ const id1 = 'make-orch-account';
+ // send because it won't resolve
+ await wallet.sendOffer({
+ id: id1,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: ['basicFlows'],
+ callPipe: [['makeOrchAccountInvitation']],
+ },
+ proposal: {},
+ offerArgs: {
+ chainName: 'cosmoshub',
+ },
+ });
+ // no errors and no result yet
+ t.like(wallet.getLatestUpdateRecord(), {
+ status: {
+ id: id1,
+ error: undefined,
+ numWantsSatisfied: 1,
+ payouts: {},
+ result: undefined, // no property
+ },
+ });
+ t.is(getInboundQueueLength(), 1);
+
+ const id2 = 'makePortfolio';
+ await wallet.sendOffer({
+ id: id2,
+ invitationSpec: {
+ source: 'agoricContract',
+ instancePath: ['basicFlows'],
+ callPipe: [['makePortfolioAccountInvitation']],
+ },
+ proposal: {},
+ offerArgs: {
+ chainNames: ['agoric', 'cosmoshub', 'osmosis'],
+ },
+ });
+ // no errors and no result yet
+ t.like(wallet.getLatestUpdateRecord(), {
+ status: {
+ id: id2,
+ error: undefined,
+ numWantsSatisfied: 1,
+ payouts: {},
+ result: undefined, // no property
+ },
+ });
+ // 3x ICA Channel Opens, 1x ICQ Channel Open
+ t.is(getInboundQueueLength(), 4);
+
+ t.log('restart basicFlows');
+ await evalProposal(
+ buildProposal('@agoric/builders/scripts/testing/restart-basic-flows.js'),
+ );
+
+ t.log('flush and verify results');
+ const beforeFlush = wallet.getLatestUpdateRecord();
+ t.like(beforeFlush, {
+ status: {
+ result: undefined,
+ },
+ });
+ t.is(await flushInboundQueue(1), 1);
+ t.like(wallet.getLatestUpdateRecord(), {
+ status: {
+ id: id1,
+ error: undefined,
+ result: 'UNPUBLISHED',
+ },
+ });
+ t.is(await flushInboundQueue(3), 3);
+ t.like(wallet.getLatestUpdateRecord(), {
+ status: {
+ id: id2,
+ error: undefined,
+ result: 'UNPUBLISHED',
+ },
+ });
+});
diff --git a/packages/boot/test/tools/ibc/mocks.test.js b/packages/boot/test/tools/ibc/mocks.test.ts
similarity index 100%
rename from packages/boot/test/tools/ibc/mocks.test.js
rename to packages/boot/test/tools/ibc/mocks.test.ts
diff --git a/packages/boot/test/upgrading/upgrade-vats.test.js b/packages/boot/test/upgrading/upgrade-vats.test.ts
similarity index 93%
rename from packages/boot/test/upgrading/upgrade-vats.test.js
rename to packages/boot/test/upgrading/upgrade-vats.test.ts
index 4685dd8228f..ed1647e1303 100644
--- a/packages/boot/test/upgrading/upgrade-vats.test.js
+++ b/packages/boot/test/upgrading/upgrade-vats.test.ts
@@ -1,18 +1,16 @@
-// @ts-check
-import { test as anyTest } from '@agoric/swingset-vat/tools/prepare-test-env-ava.js';
+/* eslint-disable @jessie.js/safe-await-separator -- test */
+import { test } from '@agoric/swingset-vat/tools/prepare-test-env-ava.js';
-import { Fail } from '@endo/errors';
-import { makeTagged } from '@endo/marshal';
import { BridgeId } from '@agoric/internal';
import { buildVatController } from '@agoric/swingset-vat';
import { makeRunUtils } from '@agoric/swingset-vat/tools/run-utils.js';
+import { Fail } from '@endo/errors';
+import { makeTagged } from '@endo/marshal';
import { resolve as importMetaResolve } from 'import-meta-resolve';
-import { matchAmount, matchIter, matchRef } from '../../tools/supports.ts';
+import type { IssuerKit } from '@agoric/ertp/src/types.js';
+import { matchAmount, matchIter, matchRef } from '../../tools/supports.js';
-/**
- * @type {import('ava').TestFn<{}>}
- */
-const test = anyTest;
+import type { buildRootObject as buildTestMintVat } from './vat-mint.js';
const bfile = name => new URL(name, import.meta.url).pathname;
const importSpec = spec =>
@@ -23,19 +21,12 @@ const makeCallOutbound = t => (srcID, obj) => {
return obj;
};
-/**
- * @param {any} t
- * @param {Partial} [kernelConfigOverrides]
- * @param {Record} [deviceEndowments]
- * @returns {Promise>}
- */
const makeScenario = async (
- t,
- kernelConfigOverrides = {},
- deviceEndowments,
+ t: any,
+ kernelConfigOverrides: Partial = {},
+ deviceEndowments: Record = {},
) => {
- /** @type {SwingSetConfig} */
- const config = {
+ const config: SwingSetConfig = {
includeDevDependencies: true, // for vat-data
bootstrap: 'bootstrap',
defaultReapInterval: 'never',
@@ -274,18 +265,17 @@ test('upgrade vat-bank', async t => {
bundleCapName: 'mint',
};
const bridgeRoot = await EV.vat('bootstrap').createVat(bridgeVatConfig);
- const bankRoot = await EV.vat('bootstrap').createVat(bankVatConfig);
- const mintRoot = await EV.vat('bootstrap').createVat(mintVatConfig);
+ const bankRoot: BankVat = await EV.vat('bootstrap').createVat(bankVatConfig);
+ const mintRoot: ReturnType =
+ await EV.vat('bootstrap').createVat(mintVatConfig);
t.log(`create a non-bridged bank manager`);
- /** @type {ERef} */
const noBridgeMgr = await EV(bankRoot).makeBankManager();
t.log(`create a bridged bank manager`);
const dev = await EV.vat('bootstrap').getDevice('bridge');
const bridge1 = await EV(bridgeRoot).provideManagerForBridge(dev);
const bankBridge = await EV(bridge1).register(BridgeId.BANK);
- /** @type {ERef} */
const bridgedMgr = await EV(bankRoot).makeBankManager(bankBridge);
t.log('subscribe to no bridge asset lists');
@@ -293,8 +283,8 @@ test('upgrade vat-bank', async t => {
const noBridgeIterator = await EV(noBridgeAssetSub1)[Symbol.asyncIterator]();
t.log('add an asset to both');
- const abcKit = await EV(mintRoot).makeIssuerKit('ABC');
- const defKit = await EV(mintRoot).makeIssuerKit('DEF');
+ const abcKit = (await EV(mintRoot).makeIssuerKit('ABC')) as IssuerKit<'nat'>;
+ const defKit = (await EV(mintRoot).makeIssuerKit('DEF')) as IssuerKit<'nat'>;
await EV(noBridgeMgr).addAsset('uabc', 'ABC', 'A Bank Coin', abcKit);
await EV(bridgedMgr).addAsset('uabc', 'ABC', 'A Bank Coin', abcKit);
await EV(bridgedMgr).addAsset('udef', 'DEF', 'Definitely a coin', defKit);
@@ -420,11 +410,10 @@ test('upgrade vat-priceAuthority', async t => {
name: 'priceAuthority',
bundleCapName: 'priceAuthority',
};
- const priceAuthorityRoot = await EV.vat('bootstrap').createVat(
- priceAuthorityVatConfig,
- );
+ const priceAuthorityRoot: PriceAuthorityVat = await EV.vat(
+ 'bootstrap',
+ ).createVat(priceAuthorityVatConfig);
- /** @type {import('@agoric/vats/src/priceAuthorityRegistry.js').PriceAuthorityRegistry} */
const registry = await EV(priceAuthorityRoot).getRegistry();
// Ideally we'd also test registering a PA and verifying the same one comes out the def end.
@@ -476,12 +465,11 @@ test('upgrade vat-vow', async t => {
};
t.log('test incarnation 0');
- /** @type {Record} */
const localPromises = {
promiseForever: [],
promiseFulfilled: ['hello'],
promiseRejected: ['goodbye', true],
- };
+ } as Record;
const promiseKit = await EV.vat('bootstrap').makePromiseKit();
const fakeVowKit = await makeFakeVowKit();
const localVows = {
diff --git a/packages/boot/tools/drivers.ts b/packages/boot/tools/drivers.ts
index b9f0c8bb207..6f36e56aeb7 100644
--- a/packages/boot/tools/drivers.ts
+++ b/packages/boot/tools/drivers.ts
@@ -24,7 +24,7 @@ import type { OfferSpec } from '@agoric/smart-wallet/src/offers.js';
import type { TimerService } from '@agoric/time';
import type { OfferMaker } from '@agoric/smart-wallet/src/types.js';
import type { RunUtils } from '@agoric/swingset-vat/tools/run-utils.js';
-import type { SwingsetTestKit } from './supports.ts';
+import type { SwingsetTestKit } from './supports.js';
export const makeWalletFactoryDriver = async (
runUtils: RunUtils,
@@ -324,7 +324,7 @@ export const makeZoeDriver = async (testKit: SwingsetTestKit) => {
const { EV } = testKit.runUtils;
const zoe = await EV.vat('bootstrap').consumeItem('zoe');
const chainStorage = await EV.vat('bootstrap').consumeItem('chainStorage');
- const storageNode = await EV(chainStorage).makeChildNode('prober-asid9a');
+ const storageNode = await EV(chainStorage!).makeChildNode('prober-asid9a');
let creatorFacet;
let adminFacet;
let brand;
diff --git a/packages/boot/tools/ibc/README.md b/packages/boot/tools/ibc/README.md
index 23119e8acf1..e74876c2301 100644
--- a/packages/boot/tools/ibc/README.md
+++ b/packages/boot/tools/ibc/README.md
@@ -73,6 +73,42 @@ sequenceDiagram
Mock Testing:
- on `SendPacket`, return `onAcknowledgePacket`
+### ICA Channel Closing (from Controller)
+
+```mermaid
+sequenceDiagram
+ participant CC as Controller Chain
+ participant R as Relayer
+ participant HC as Host Chain
+
+ CC->>R: ChanCloseInit(PortID, ChannelID)
+ R->>HC: ChanCloseConfirm(PortID, ChannelID)
+ HC->>HC: OnChanCloseConfirm(portID, channelID)
+ HC-->>R: Success
+ R->>CC: ChanCloseConfirm
+ CC->>CC: CloseChannel(PortID, ChannelID)
+```
+Mock Testing:
+ - on `ChanCloseInit`, return `ChanCloseConfirm`
+
+### ICA Channel Closing (from Host - Unexpected closure)
+
+```mermaid
+sequenceDiagram
+ participant CC as Controller Chain
+ participant R as Relayer
+ participant HC as Host Chain
+
+ HC-->>R: Channel closed unexpectedly
+ R->>CC: ChanCloseConfirm(PortID, ChannelID)
+ CC->>CC: OnChanCloseConfirm
+ CC-->>R: Acknowledge closure
+
+ Note over CC: Handle unexpected closure
+ Note over HC: Unexpected channel closure (e.g., timeout in ORDERED channel)
+```
+Mock Testing:
+ - `ChanCloseConfirm` event is emitted
### ICA Channel Reactivation
diff --git a/packages/boot/tools/ibc/mocks.js b/packages/boot/tools/ibc/mocks.ts
similarity index 88%
rename from packages/boot/tools/ibc/mocks.js
rename to packages/boot/tools/ibc/mocks.ts
index 72cbcee4b65..824768df9d6 100644
--- a/packages/boot/tools/ibc/mocks.js
+++ b/packages/boot/tools/ibc/mocks.ts
@@ -1,4 +1,5 @@
// @ts-check
+import { createMockAckMap } from '@agoric/orchestration/tools/ibc-mocks.js';
/** @import { IBCChannelID, IBCMethod, IBCEvent } from '@agoric/vats'; */
@@ -16,6 +17,9 @@ const responses = {
// eyJkYXRhIjoiQ2hzeUdRb1hDaEp6YjIxbExXbHVkbUZzYVdRdFpHVnViMjBTQVRBPSJ9
queryBalanceUnknownDenom:
'eyJyZXN1bHQiOiJleUprWVhSaElqb2lRMmh6ZVVkUmIxaERhRXA2WWpJeGJFeFhiSFZrYlVaellWZFJkRnBIVm5WaU1qQlRRVlJCUFNKOSJ9',
+ // /ibc.applications.transfer.v1.MsgTransferResponse - sequence 0n
+ ibcTransfer:
+ 'eyJyZXN1bHQiOiJFak1LTVM5cFltTXVZWEJ3YkdsallYUnBiMjV6TG5SeVlXNXpabVZ5TG5ZeExrMXpaMVJ5WVc1elptVnlVbVZ6Y0c5dWMyVT0ifQ==',
// {"error":"ABCI code: 4: error handling packet: see events for details"}
error4:
'eyJlcnJvciI6IkFCQ0kgY29kZTogNDogZXJyb3IgaGFuZGxpbmcgcGFja2V0OiBzZWUgZXZlbnRzIGZvciBkZXRhaWxzIn0=',
@@ -56,11 +60,19 @@ export const protoMsgMocks = {
msg: 'eyJ0eXBlIjoxLCJkYXRhIjoiQ2xVS0l5OWpiM050YjNNdWMzUmhhMmx1Wnk1Mk1XSmxkR0V4TGsxelowUmxiR1ZuWVhSbEVpNEtDMk52YzIxdmN6RjBaWE4wRWhKamIzTnRiM04yWVd4dmNHVnlNWFJsYzNRYUN3b0ZkV0YwYjIwU0FqRXdFZ2RVUlZOVVNVNUhHSUNVNjl3RCIsIm1lbW8iOiIifQ==',
ack: responses.delegate,
},
+ // MsgTransfer 10 ibc/uusdchash from cosmos1test to noble1test through channel-536
+ ibcTransfer: {
+ msg: 'eyJ0eXBlIjoxLCJkYXRhIjoiQ25zS0tTOXBZbU11WVhCd2JHbGpZWFJwYjI1ekxuUnlZVzV6Wm1WeUxuWXhMazF6WjFSeVlXNXpabVZ5RWs0S0NIUnlZVzV6Wm1WeUVndGphR0Z1Ym1Wc0xUVXpOaG9UQ2cxcFltTXZkWFZ6WkdOb1lYTm9FZ0l4TUNJTFkyOXpiVzl6TVhSbGMzUXFDbTV2WW14bE1YUmxjM1F5QURpQThKTEwzUWc9IiwibWVtbyI6IiJ9',
+ ack: responses.ibcTransfer,
+ },
error: {
+ msg: '',
ack: responses.error5,
},
};
+export const protoMsgMockMap = createMockAckMap(protoMsgMocks);
+
/**
* Adds parameters to IBC version string if it's JSON
* @param {string} version version or JSON version string
@@ -130,7 +142,7 @@ export const icaMocks = {
* @param {string} acknowledgement acknowledgement response as base64 encoded bytes
* @returns {IBCEvent<'acknowledgementPacket'>}
*/
- ackPacket: (obj, sequence = 1, acknowledgement) => {
+ ackPacketEvent: (obj, sequence = 1, acknowledgement) => {
return {
acknowledgement,
blockHeight: 289,
diff --git a/packages/boot/tools/supports.ts b/packages/boot/tools/supports.ts
index ac9db683abe..36af57d01cc 100644
--- a/packages/boot/tools/supports.ts
+++ b/packages/boot/tools/supports.ts
@@ -7,13 +7,14 @@ import { resolve as importMetaResolve } from 'import-meta-resolve';
import { basename, join } from 'path';
import { inspect } from 'util';
-import { Fail } from '@endo/errors';
import { buildSwingset } from '@agoric/cosmic-swingset/src/launch-chain.js';
import {
BridgeId,
NonNullish,
VBankAccount,
makeTracer,
+ type BridgeIdValue,
+ type Remote,
} from '@agoric/internal';
import { unmarshalFromVstorage } from '@agoric/internal/src/marshal.js';
import { makeFakeStorageKit } from '@agoric/internal/src/storage-test-utils.js';
@@ -22,21 +23,59 @@ import { initSwingStore } from '@agoric/swing-store';
import { loadSwingsetConfigFile } from '@agoric/swingset-vat';
import { makeSlogSender } from '@agoric/telemetry';
import { TimeMath, Timestamp } from '@agoric/time';
+import { Fail } from '@endo/errors';
+import {
+ fakeLocalChainBridgeTxMsgHandler,
+ LOCALCHAIN_DEFAULT_ADDRESS,
+} from '@agoric/vats/tools/fake-bridge.js';
+import {
+ makeRunUtils,
+ type RunUtils,
+} from '@agoric/swingset-vat/tools/run-utils.js';
import {
boardSlottingMarshaller,
slotToBoardRemote,
} from '@agoric/vats/tools/board-utils.js';
-import { makeRunUtils } from '@agoric/swingset-vat/tools/run-utils.js';
import type { ExecutionContext as AvaT } from 'ava';
import type { CoreEvalSDKType } from '@agoric/cosmic-proto/swingset/swingset.js';
-import type { BridgeHandler, IBCMethod } from '@agoric/vats';
-import { icaMocks, protoMsgMocks } from './ibc/mocks.js';
+import type { EconomyBootstrapPowers } from '@agoric/inter-protocol/src/proposals/econ-behaviors.js';
+import type { SwingsetController } from '@agoric/swingset-vat/src/controller/controller.js';
+import type { BridgeHandler, IBCMethod, IBCPacket } from '@agoric/vats';
+import type { BootstrapRootObject } from '@agoric/vats/src/core/lib-boot.js';
+import type { EProxy } from '@endo/eventual-send';
+import { icaMocks, protoMsgMockMap, protoMsgMocks } from './ibc/mocks.js';
const trace = makeTracer('BSTSupport', false);
+type ConsumeBootrapItem = (
+ name: N,
+) => N extends keyof EconomyBootstrapPowers['consume']
+ ? EconomyBootstrapPowers['consume'][N]
+ : unknown;
+
+// XXX should satisfy EVProxy from run-utils.js but that's failing to import
+/**
+ * Elaboration of EVProxy with knowledge of bootstrap space in these tests.
+ */
+type BootstrapEV = EProxy & {
+ sendOnly: (presence: unknown) => Record void>;
+ vat: (
+ name: N,
+ ) => N extends 'bootstrap'
+ ? Omit & {
+ // XXX not really local
+ consumeItem: ConsumeBootrapItem;
+ } & Remote<{ consumeItem: ConsumeBootrapItem }>
+ : Record Promise>;
+};
+
+const makeBootstrapRunUtils = makeRunUtils as (
+ controller: SwingsetController,
+) => Omit & { EV: BootstrapEV };
+
const keysToObject = (
keys: K[],
valueMaker: (key: K, i: number) => V,
@@ -284,19 +323,55 @@ export const makeSwingsetTestKit = async (
return data;
};
- let lastNonce = 0n;
+ let lastBankNonce = 0n;
+ let ibcSequenceNonce = 0;
+ let lcaSequenceNonce = 0;
+ let lcaAccountsCreated = 0;
const outboundMessages = new Map();
- let inbound;
- let ibcSequenceNonce = 0;
+ const inbound: Awaited>['bridgeInbound'] = (
+ ...args
+ ) => {
+ console.log('inbound', ...args);
+ // eslint-disable-next-line no-use-before-define
+ bridgeInbound!(...args);
+ };
+
+ /**
+ * Adds the sequence so the bridge knows what response to connect it to.
+ * Then queue it send it over the bridge over this returns.
+ * Finally return the packet that will be sent.
+ */
+ const ackImmediately = (obj: IBCMethod<'sendPacket'>, ack: string) => {
+ ibcSequenceNonce += 1;
+ const msg = icaMocks.ackPacketEvent(obj, ibcSequenceNonce, ack);
+ setTimeout(() => {
+ /**
+ * Mock when Agoric receives the ack from another chain over DIBC. Always
+ * happens after the packet is returned.
+ */
+ inbound(BridgeId.DIBC, msg);
+ });
+ return msg.packet;
+ };
- const makeAckEvent = (obj: IBCMethod<'sendPacket'>, ack: string) => {
+ const inboundQueue: [bridgeId: BridgeIdValue, arg1: unknown][] = [];
+ /** Add a message that will be sent to the bridge by flushInboundQueue. */
+ const pushInbound = (bridgeId: BridgeIdValue, arg1: unknown) => {
+ inboundQueue.push([bridgeId, arg1]);
+ };
+ /**
+ * Like ackImmediately but defers in the inbound receiverAck
+ * until `bridgeQueue()` is awaited.
+ */
+ const ackLater = (obj: IBCMethod<'sendPacket'>, ack: string) => {
ibcSequenceNonce += 1;
- const msg = icaMocks.ackPacket(obj, ibcSequenceNonce, ack);
- inbound(BridgeId.DIBC, msg);
+ const msg = icaMocks.ackPacketEvent(obj, ibcSequenceNonce, ack);
+ pushInbound(BridgeId.DIBC, msg);
return msg.packet;
};
+
/**
* Mock the bridge outbound handler. The real one is implemented in Golang so
* changes there will sometimes require changes here.
@@ -311,138 +386,104 @@ export const makeSwingsetTestKit = async (
switch (bridgeId) {
case BridgeId.BANK: {
trace(
- 'bridgeOutbound BANK',
+ 'bridgeOutbound bank',
obj.type,
obj.recipient,
obj.amount,
obj.denom,
);
+ break;
+ }
+ case BridgeId.STORAGE:
+ return storage.toStorage(obj);
+ case BridgeId.PROVISION:
+ case BridgeId.PROVISION_SMART_WALLET:
+ case BridgeId.WALLET:
+ console.warn('Bridge returning undefined for', bridgeId, ':', obj);
+ return undefined;
+ default:
+ break;
+ }
+
+ const bridgeTargetRegistered = new Set();
+ const bridgeType = `${bridgeId}:${obj.type}`;
+ switch (bridgeType) {
+ case `${BridgeId.BANK}:VBANK_GET_MODULE_ACCOUNT_ADDRESS`: {
// bridgeOutbound bank : {
// moduleName: 'vbank/reserve',
// type: 'VBANK_GET_MODULE_ACCOUNT_ADDRESS'
// }
- switch (obj.type) {
- case 'VBANK_GET_MODULE_ACCOUNT_ADDRESS': {
- const { moduleName } = obj;
- const moduleDescriptor = Object.values(VBankAccount).find(
- ({ module }) => module === moduleName,
- );
- if (!moduleDescriptor) {
- return 'undefined';
- }
- return moduleDescriptor.address;
- }
-
- // Observed message:
- // address: 'agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346',
- // denom: 'ibc/toyatom',
- // type: 'VBANK_GET_BALANCE'
- case 'VBANK_GET_BALANCE': {
- // TODO consider letting config specify vbank assets
- // empty balances for test.
- return '0';
- }
+ const { moduleName } = obj;
+ const moduleDescriptor = Object.values(VBankAccount).find(
+ ({ module }) => module === moduleName,
+ );
+ if (!moduleDescriptor) {
+ return 'undefined';
+ }
+ return moduleDescriptor.address;
+ }
- case 'VBANK_GRAB':
- case 'VBANK_GIVE': {
- lastNonce += 1n;
- // Also empty balances.
- return harden({
- type: 'VBANK_BALANCE_UPDATE',
- nonce: `${lastNonce}`,
- updated: [],
- });
- }
+ // Observed message:
+ // address: 'agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346',
+ // denom: 'ibc/toyatom',
+ // type: 'VBANK_GET_BALANCE'
+ case `${BridgeId.BANK}:VBANK_GET_BALANCE`: {
+ // TODO consider letting config specify vbank assets
+ // empty balances for test.
+ return '0';
+ }
- default: {
- return 'undefined';
- }
- }
+ case `${BridgeId.BANK}:VBANK_GRAB`:
+ case `${BridgeId.BANK}:VBANK_GIVE`: {
+ lastBankNonce += 1n;
+ // Also empty balances.
+ return harden({
+ type: 'VBANK_BALANCE_UPDATE',
+ nonce: `${lastBankNonce}`,
+ updated: [],
+ });
}
- case BridgeId.CORE:
- case BridgeId.DIBC:
- switch (obj.type) {
- case 'IBC_METHOD':
- switch (obj.method) {
- case 'startChannelOpenInit':
- inbound(BridgeId.DIBC, icaMocks.channelOpenAck(obj));
- return undefined;
- case 'sendPacket':
- switch (obj.packet.data) {
- case protoMsgMocks.delegate.msg: {
- return makeAckEvent(obj, protoMsgMocks.delegate.ack);
- }
- case protoMsgMocks.delegateWithOpts.msg: {
- return makeAckEvent(
- obj,
- protoMsgMocks.delegateWithOpts.ack,
- );
- }
- case protoMsgMocks.queryBalance.msg: {
- return makeAckEvent(obj, protoMsgMocks.queryBalance.ack);
- }
- case protoMsgMocks.queryUnknownPath.msg: {
- return makeAckEvent(
- obj,
- protoMsgMocks.queryUnknownPath.ack,
- );
- }
- case protoMsgMocks.queryBalanceMulti.msg: {
- return makeAckEvent(
- obj,
- protoMsgMocks.queryBalanceMulti.ack,
- );
- }
- case protoMsgMocks.queryBalanceUnknownDenom.msg: {
- return makeAckEvent(
- obj,
- protoMsgMocks.queryBalanceUnknownDenom.ack,
- );
- }
- default: {
- return makeAckEvent(obj, protoMsgMocks.error.ack);
- }
- }
- default:
- return undefined;
+
+ case `${BridgeId.CORE}:IBC_METHOD`:
+ case `${BridgeId.DIBC}:IBC_METHOD`:
+ case `${BridgeId.VTRANSFER}:IBC_METHOD`: {
+ switch (obj.method) {
+ case 'startChannelOpenInit':
+ pushInbound(BridgeId.DIBC, icaMocks.channelOpenAck(obj));
+ return undefined;
+ case 'sendPacket': {
+ if (protoMsgMockMap[obj.packet.data]) {
+ return ackLater(obj, protoMsgMockMap[obj.packet.data]);
}
+ // An error that would be triggered before reception on another chain
+ return ackImmediately(obj, protoMsgMocks.error.ack);
+ }
default:
return undefined;
}
- case BridgeId.PROVISION:
- case BridgeId.PROVISION_SMART_WALLET:
- case BridgeId.VTRANSFER:
- case BridgeId.WALLET:
- console.warn('Bridge returning undefined for', bridgeId, ':', obj);
+ }
+ case `${BridgeId.VTRANSFER}:BRIDGE_TARGET_REGISTER`: {
+ bridgeTargetRegistered.add(obj.target);
return undefined;
- case BridgeId.STORAGE:
- return storage.toStorage(obj);
- case BridgeId.VLOCALCHAIN:
- switch (obj.type) {
- case 'VLOCALCHAIN_ALLOCATE_ADDRESS':
- return 'agoric1mockVlocalchainAddress';
- case 'VLOCALCHAIN_EXECUTE_TX': {
- return obj.messages.map(message => {
- switch (message['@type']) {
- case '/cosmos.staking.v1beta1.MsgDelegate': {
- if (message.amount.amount === '504') {
- // FIXME - how can we propagate the error?
- // this results in `syscall.callNow failed: device.invoke failed, see logs for details`
- throw Error('simulated packet timeout');
- }
- return /** @type {JsonSafe} */ {};
- }
- // returns one empty object per message unless specified
- default:
- return {};
- }
- });
- }
- default:
- throw Error(`VLOCALCHAIN message of unknown type ${obj.type}`);
- }
- default:
- throw Error(`unknown bridgeId ${bridgeId}`);
+ }
+ case `${BridgeId.VTRANSFER}:BRIDGE_TARGET_UNREGISTER`: {
+ bridgeTargetRegistered.delete(obj.target);
+ return undefined;
+ }
+ case `${BridgeId.VLOCALCHAIN}:VLOCALCHAIN_ALLOCATE_ADDRESS`: {
+ const address = `${LOCALCHAIN_DEFAULT_ADDRESS}${lcaAccountsCreated || ''}`;
+ lcaAccountsCreated += 1;
+ return address;
+ }
+ case `${BridgeId.VLOCALCHAIN}:VLOCALCHAIN_EXECUTE_TX`: {
+ lcaSequenceNonce += 1;
+ return obj.messages.map(message =>
+ fakeLocalChainBridgeTxMsgHandler(message, lcaSequenceNonce),
+ );
+ }
+ default: {
+ throw Error(`FIXME missing support for ${bridgeId}: ${obj.type}`);
+ }
}
};
@@ -473,11 +514,10 @@ export const makeSwingsetTestKit = async (
debugVats,
},
);
- inbound = bridgeInbound;
console.timeLog('makeBaseSwingsetTestKit', 'buildSwingset');
- const runUtils = makeRunUtils(controller);
+ const runUtils = makeBootstrapRunUtils(controller);
const buildProposal = makeProposalExtractor({
childProcess: childProcessAmbient,
@@ -553,18 +593,38 @@ export const makeSwingsetTestKit = async (
const getCrankNumber = () => Number(kernelStorage.kvStore.get('crankNumber'));
- const getOutboundMessages = (bridgeId: string) =>
- harden([...outboundMessages.get(bridgeId)]);
+ const bridgeUtils = {
+ /** Immediately handle the inbound message */
+ inbound: bridgeInbound,
+ getOutboundMessages: (bridgeId: string) =>
+ harden([...outboundMessages.get(bridgeId)]),
+ getInboundQueueLength: () => inboundQueue.length,
+ /**
+ * @param {number} max the max number of messages to flush
+ * @returns {Promise} the number of messages flushed
+ */
+ async flushInboundQueue(max: number = Number.POSITIVE_INFINITY) {
+ console.log('🚽');
+ let i = 0;
+ for (i = 0; i < max; i += 1) {
+ const args = inboundQueue.shift();
+ if (!args) break;
+
+ await runUtils.queueAndRun(() => inbound(...args), true);
+ }
+ console.log('🧻');
+ return i;
+ },
+ };
return {
advanceTimeBy,
advanceTimeTo,
+ bridgeUtils,
buildProposal,
- bridgeInbound,
controller,
evalProposal,
getCrankNumber,
- getOutboundMessages,
jumpTimeTo,
readLatest,
runUtils,
diff --git a/packages/boot/tsconfig.json b/packages/boot/tsconfig.json
index 1287d783ae1..fa0055be5c3 100644
--- a/packages/boot/tsconfig.json
+++ b/packages/boot/tsconfig.json
@@ -1,7 +1,6 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
- "allowImportingTsExtensions": true,
"checkJs": true,
},
"include": [
@@ -11,5 +10,6 @@
"test/**/*.js",
"test/**/*.ts",
"tools/**/*.js",
+ "tools/**/*.ts",
],
}
diff --git a/packages/builders/package.json b/packages/builders/package.json
index 3cb3ff12678..a444755dc70 100644
--- a/packages/builders/package.json
+++ b/packages/builders/package.json
@@ -11,7 +11,7 @@
"build:restart-vats-proposal": "echo This command has been deprecated. Please run this instead: agoric run scripts/vats/restart-vats.js",
"build:zcf-proposal": "echo This command has been deprecated. Please run this instead: agoric run scripts/vats/replace-zoe.js",
"prepack": "tsc --build tsconfig.build.json",
- "postpack": "git clean -f '*.d.ts*'",
+ "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
"test": "ava",
"test:xs": "exit 0",
"lint-fix": "yarn lint:eslint --fix",
@@ -30,18 +30,18 @@
"@agoric/vat-data": "^0.5.2",
"@agoric/vats": "^0.15.1",
"@agoric/zoe": "^0.26.2",
- "@endo/bundle-source": "^3.2.3",
- "@endo/captp": "^4.2.0",
- "@endo/eventual-send": "^1.2.2",
- "@endo/far": "^1.1.2",
- "@endo/init": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/promise-kit": "^1.1.2",
- "@endo/stream": "^1.2.2",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/captp": "^4.3.0",
+ "@endo/eventual-send": "^1.2.5",
+ "@endo/far": "^1.1.5",
+ "@endo/init": "^1.1.4",
+ "@endo/marshal": "^1.5.3",
+ "@endo/promise-kit": "^1.1.5",
+ "@endo/stream": "^1.2.5",
"import-meta-resolve": "^2.2.1"
},
"devDependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/deploy-script-support": "^0.10.3",
"@agoric/governance": "^0.10.3",
"@agoric/inter-protocol": "^0.16.1",
@@ -79,6 +79,6 @@
"workerThreads": false
},
"typeCoverage": {
- "atLeast": 76.03
+ "atLeast": 81.8
}
}
diff --git a/packages/builders/scripts/inter-protocol/manual-price-feed.js b/packages/builders/scripts/inter-protocol/manual-price-feed.js
index 502b9bd6743..b8e5ff8237f 100644
--- a/packages/builders/scripts/inter-protocol/manual-price-feed.js
+++ b/packages/builders/scripts/inter-protocol/manual-price-feed.js
@@ -48,6 +48,7 @@ export default async function priceAuthorityFromNotifier(
if (!aggregatorInstance) {
console.log('Autodetecting aggregator instance...');
+ // @ts-expect-error inspecific Home type
const purse = E(home.wallet).getPurse('Default Zoe invite purse');
const { value } = await E(purse).getCurrentAmount();
const invitations = value.filter(
@@ -81,6 +82,7 @@ export default async function priceAuthorityFromNotifier(
};
console.log('Getting wallet bridge...');
+ // @ts-expect-error inspecific Home type
const bridge = await E(home.wallet).getBridge();
// Consume an aggregator invitation for this instance.
@@ -94,6 +96,7 @@ export default async function priceAuthorityFromNotifier(
() => {},
);
+ // @ts-expect-error inspecific Home type
const walletAdmin = E(home.wallet).getAdminFacet();
console.log('=====================================================');
@@ -111,6 +114,7 @@ export default async function priceAuthorityFromNotifier(
const orKey = `offerResult ${id}`;
await E(home.scratch).set(
orKey,
+ // @ts-expect-error inspecific Home type
E(home.wallet).lookup('offerResult', id),
);
console.log(
diff --git a/packages/builders/scripts/orchestration/init-stakeAtom.js b/packages/builders/scripts/orchestration/init-stakeAtom.js
index da1ea661073..3d5f6e1454d 100644
--- a/packages/builders/scripts/orchestration/init-stakeAtom.js
+++ b/packages/builders/scripts/orchestration/init-stakeAtom.js
@@ -9,7 +9,7 @@ export const defaultProposalBuilder = async ({ publishRef, install }) => {
{
installKeys: {
stakeIca: publishRef(
- install('@agoric/orchestration/src/examples/stakeIca.contract.js'),
+ install('@agoric/orchestration/src/examples/stake-ica.contract.js'),
),
},
},
diff --git a/packages/builders/scripts/orchestration/init-stakeBld.js b/packages/builders/scripts/orchestration/init-stakeBld.js
index 992c10d0a91..f3db614e777 100644
--- a/packages/builders/scripts/orchestration/init-stakeBld.js
+++ b/packages/builders/scripts/orchestration/init-stakeBld.js
@@ -10,7 +10,7 @@ export const defaultProposalBuilder = async ({ publishRef, install }) =>
{
installKeys: {
stakeBld: publishRef(
- install('@agoric/orchestration/src/examples/stakeBld.contract.js'),
+ install('@agoric/orchestration/src/examples/stake-bld.contract.js'),
),
},
},
diff --git a/packages/builders/scripts/orchestration/init-stakeOsmo.js b/packages/builders/scripts/orchestration/init-stakeOsmo.js
index 7374d3d59a6..a0cb295364e 100644
--- a/packages/builders/scripts/orchestration/init-stakeOsmo.js
+++ b/packages/builders/scripts/orchestration/init-stakeOsmo.js
@@ -9,7 +9,7 @@ export const defaultProposalBuilder = async ({ publishRef, install }) => {
{
installKeys: {
stakeIca: publishRef(
- install('@agoric/orchestration/src/examples/stakeIca.contract.js'),
+ install('@agoric/orchestration/src/examples/stake-ica.contract.js'),
),
},
},
diff --git a/packages/builders/scripts/orchestration/write-chain-info.js b/packages/builders/scripts/orchestration/write-chain-info.js
new file mode 100644
index 00000000000..10e8e9abad3
--- /dev/null
+++ b/packages/builders/scripts/orchestration/write-chain-info.js
@@ -0,0 +1,13 @@
+import { makeHelpers } from '@agoric/deploy-script-support';
+
+/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
+export const defaultProposalBuilder = async () =>
+ harden({
+ sourceSpec: '@agoric/orchestration/src/proposals/init-chain-info.js',
+ getManifestCall: ['getManifestForChainInfo'],
+ });
+
+export default async (homeP, endowments) => {
+ const { writeCoreEval } = await makeHelpers(homeP, endowments);
+ await writeCoreEval('gov-orchestration', defaultProposalBuilder);
+};
diff --git a/packages/builders/scripts/testing/append-chain-info.js b/packages/builders/scripts/testing/append-chain-info.js
index f141fe49074..4c4b7f6692c 100644
--- a/packages/builders/scripts/testing/append-chain-info.js
+++ b/packages/builders/scripts/testing/append-chain-info.js
@@ -13,9 +13,6 @@ const chainInfo = {
counterparty: {
client_id: '07-tendermint-2',
connection_id: 'connection-1',
- prefix: {
- key_prefix: '',
- },
},
state: 3 /* IBCConnectionState.STATE_OPEN */,
transferChannel: {
diff --git a/packages/builders/scripts/testing/restart-basic-flows.js b/packages/builders/scripts/testing/restart-basic-flows.js
new file mode 100644
index 00000000000..ac4c7b3f02f
--- /dev/null
+++ b/packages/builders/scripts/testing/restart-basic-flows.js
@@ -0,0 +1,100 @@
+/**
+ * @file This is for use in tests.
+ * Unlike most builder scripts, this one includes the proposal exports as well.
+ */
+import {
+ deeplyFulfilledObject,
+ makeTracer,
+ NonNullish,
+} from '@agoric/internal';
+import { E } from '@endo/far';
+
+///
+
+const trace = makeTracer('RestartBasicFlows', true);
+
+/**
+ * @import {start as StartFn} from '@agoric/orchestration/src/examples/basic-flows.contract.js';
+ */
+
+/**
+ * @param {BootstrapPowers} powers
+ */
+export const restartBasicFlows = async ({
+ consume: {
+ agoricNames,
+ board,
+ chainStorage,
+ chainTimerService,
+ cosmosInterchainService,
+ localchain,
+
+ contractKits,
+ },
+ instance: instances,
+}) => {
+ trace(restartBasicFlows.name);
+
+ // @ts-expect-error unknown instance
+ const instance = await instances.consume.basicFlows;
+ trace('instance', instance);
+ /** @type {StartedInstanceKit} */
+ const kit = /** @type {any} */ (await E(contractKits).get(instance));
+
+ const marshaller = await E(board).getReadonlyMarshaller();
+
+ const privateArgs = await deeplyFulfilledObject(
+ harden({
+ agoricNames,
+ localchain,
+ marshaller,
+ orchestrationService: cosmosInterchainService,
+ storageNode: E(NonNullish(await chainStorage)).makeChildNode(
+ 'basicFlows',
+ ),
+ timerService: chainTimerService,
+ }),
+ );
+
+ await E(kit.adminFacet).restartContract(privateArgs);
+ trace('done');
+};
+harden(restartBasicFlows);
+
+export const getManifest = () => {
+ return {
+ manifest: {
+ [restartBasicFlows.name]: {
+ consume: {
+ agoricNames: true,
+ board: true,
+ chainStorage: true,
+ chainTimerService: true,
+ cosmosInterchainService: true,
+ localchain: true,
+
+ contractKits: true,
+ },
+ instance: {
+ consume: { basicFlows: true },
+ },
+ },
+ },
+ };
+};
+
+/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
+export const defaultProposalBuilder = async () =>
+ harden({
+ // Somewhat unorthodox, source the exports from this builder module
+ sourceSpec: '@agoric/builders/scripts/testing/restart-basic-flows.js',
+ getManifestCall: [getManifest.name],
+ });
+
+export default async (homeP, endowments) => {
+ // import dynamically so the module can work in CoreEval environment
+ const dspModule = await import('@agoric/deploy-script-support');
+ const { makeHelpers } = dspModule;
+ const { writeCoreEval } = await makeHelpers(homeP, endowments);
+ await writeCoreEval(restartBasicFlows.name, defaultProposalBuilder);
+};
diff --git a/packages/builders/scripts/testing/restart-send-anywhere.js b/packages/builders/scripts/testing/restart-send-anywhere.js
new file mode 100644
index 00000000000..95b682248cc
--- /dev/null
+++ b/packages/builders/scripts/testing/restart-send-anywhere.js
@@ -0,0 +1,100 @@
+/**
+ * @file This is for use in tests in a3p-integration
+ * Unlike most builder scripts, this one includes the proposal exports as well.
+ */
+import {
+ deeplyFulfilledObject,
+ makeTracer,
+ NonNullish,
+} from '@agoric/internal';
+import { E } from '@endo/far';
+
+///
+
+const trace = makeTracer('StartSA', true);
+
+/**
+ * @import {start as StartFn} from '@agoric/orchestration/src/examples/send-anywhere.contract.js';
+ */
+
+/**
+ * @param {BootstrapPowers} powers
+ */
+export const restartSendAnywhere = async ({
+ consume: {
+ agoricNames,
+ board,
+ chainStorage,
+ chainTimerService,
+ cosmosInterchainService,
+ localchain,
+
+ contractKits,
+ },
+ instance: instances,
+}) => {
+ trace(restartSendAnywhere.name);
+
+ // @ts-expect-error unknown instance
+ const instance = await instances.consume.sendAnywhere;
+ trace('instance', instance);
+ /** @type {StartedInstanceKit} */
+ const kit = /** @type {any} */ (await E(contractKits).get(instance));
+
+ const marshaller = await E(board).getReadonlyMarshaller();
+
+ const privateArgs = await deeplyFulfilledObject(
+ harden({
+ agoricNames,
+ localchain,
+ marshaller,
+ orchestrationService: cosmosInterchainService,
+ storageNode: E(NonNullish(await chainStorage)).makeChildNode(
+ 'sendAnywhere',
+ ),
+ timerService: chainTimerService,
+ }),
+ );
+
+ await E(kit.adminFacet).restartContract(privateArgs);
+ trace('done');
+};
+harden(restartSendAnywhere);
+
+export const getManifest = () => {
+ return {
+ manifest: {
+ [restartSendAnywhere.name]: {
+ consume: {
+ agoricNames: true,
+ board: true,
+ chainStorage: true,
+ chainTimerService: true,
+ cosmosInterchainService: true,
+ localchain: true,
+
+ contractKits: true,
+ },
+ instance: {
+ consume: { sendAnywhere: true },
+ },
+ },
+ },
+ };
+};
+
+/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
+export const defaultProposalBuilder = async () =>
+ harden({
+ // Somewhat unorthodox, source the exports from this builder module
+ sourceSpec: '@agoric/builders/scripts/testing/restart-send-anywhere.js',
+ getManifestCall: [getManifest.name],
+ });
+
+export default async (homeP, endowments) => {
+ // import dynamically so the module can work in CoreEval environment
+ const dspModule = await import('@agoric/deploy-script-support');
+ const { makeHelpers } = dspModule;
+ const { writeCoreEval } = await makeHelpers(homeP, endowments);
+ await writeCoreEval(restartSendAnywhere.name, defaultProposalBuilder);
+};
diff --git a/packages/builders/scripts/testing/restart-stakeAtom.js b/packages/builders/scripts/testing/restart-stakeAtom.js
new file mode 100644
index 00000000000..7568d0048e2
--- /dev/null
+++ b/packages/builders/scripts/testing/restart-stakeAtom.js
@@ -0,0 +1,90 @@
+/**
+ * @file This is for use in tests in a3p-integration
+ * Unlike most builder scripts, this one includes the proposal exports as well.
+ */
+import { deeplyFulfilledObject, makeTracer } from '@agoric/internal';
+import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js';
+import { E } from '@endo/far';
+
+///
+
+const trace = makeTracer('RestartSA', true);
+
+/**
+ * @import {start as StartFn} from '@agoric/orchestration/src/examples/stake-ica.contract.js';
+ */
+
+/**
+ * @param {BootstrapPowers} powers
+ */
+export const restartStakeAtom = async ({
+ consume: {
+ agoricNames,
+ board,
+ chainStorage,
+ chainTimerService,
+ cosmosInterchainService,
+ contractKits,
+ },
+ instance: instances,
+}) => {
+ trace(restartStakeAtom.name);
+
+ const instance = await instances.consume.stakeAtom;
+ trace('instance', instance);
+
+ /** @type {StartedInstanceKit} */
+ const kit = /** @type {any} */ (await E(contractKits).get(instance));
+
+ const marshaller = await E(board).getReadonlyMarshaller();
+
+ const privateArgs = await deeplyFulfilledObject(
+ harden({
+ agoricNames,
+ cosmosInterchainService,
+ storageNode: makeStorageNodeChild(chainStorage, 'stakeAtom'),
+ marshaller,
+ timer: chainTimerService,
+ }),
+ );
+
+ await E(kit.adminFacet).restartContract(privateArgs);
+ trace('done');
+};
+harden(restartStakeAtom);
+
+export const getManifest = () => {
+ return {
+ manifest: {
+ [restartStakeAtom.name]: {
+ consume: {
+ agoricNames: true,
+ board: true,
+ chainStorage: true,
+ chainTimerService: true,
+ cosmosInterchainService: true,
+ contractKits: true,
+ },
+ instance: {
+ consume: { stakeAtom: true },
+ },
+ },
+ },
+ };
+};
+
+/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
+export const defaultProposalBuilder = async () =>
+ harden({
+ // Somewhat unorthodox, source the exports from this builder module
+ sourceSpec: '@agoric/builders/scripts/testing/restart-stakeAtom.js',
+ getManifestCall: [getManifest.name],
+ });
+
+export default async (homeP, endowments) => {
+ // import dynamically so the module can work in CoreEval environment
+ const dspModule = await import('@agoric/deploy-script-support');
+ const { makeHelpers } = dspModule;
+ const { writeCoreEval } = await makeHelpers(homeP, endowments);
+ await writeCoreEval(restartStakeAtom.name, defaultProposalBuilder);
+};
diff --git a/packages/builders/scripts/testing/start-auto-stake-it.js b/packages/builders/scripts/testing/start-auto-stake-it.js
index 38e810dfcb9..e7c495228b0 100644
--- a/packages/builders/scripts/testing/start-auto-stake-it.js
+++ b/packages/builders/scripts/testing/start-auto-stake-it.js
@@ -50,6 +50,7 @@ export const startAutoStakeIt = async ({
installation,
terms: undefined,
privateArgs: await deeplyFulfilled(
+ // @ts-expect-error
harden({
agoricNames,
orchestrationService: cosmosInterchainService,
diff --git a/packages/builders/scripts/testing/start-query-flows.js b/packages/builders/scripts/testing/start-query-flows.js
new file mode 100644
index 00000000000..fc7e947bb7e
--- /dev/null
+++ b/packages/builders/scripts/testing/start-query-flows.js
@@ -0,0 +1,134 @@
+/**
+ * @file A proposal to start the query-flows contract.
+ *
+ * QueryFlows is a testing fixture that publishes query results to vstorage.
+ * It's purpose is to support E2E testing.
+ */
+import { deeplyFulfilledObject, makeTracer } from '@agoric/internal';
+import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js';
+import { E } from '@endo/far';
+
+/**
+ * @import {QueryFlowsSF as StartFn} from '@agoric/orchestration/src/fixtures/query-flows.contract.js';
+ */
+
+const contractName = 'queryFlows';
+const trace = makeTracer(contractName, true);
+
+/**
+ * See `@agoric/builders/builders/scripts/orchestration/init-query-flows.js` for
+ * the accompanying proposal builder. Run `agoric run
+ * packages/builders/scripts/orchestration/init-query-flows.js` to build the
+ * contract and proposal files.
+ *
+ * @param {BootstrapPowers & {
+ * installation: {
+ * consume: {
+ * queryFlows: Installation;
+ * };
+ * };
+ * }} powers
+ */
+export const startQueryFlows = async ({
+ consume: {
+ agoricNames,
+ board,
+ chainStorage,
+ chainTimerService,
+ cosmosInterchainService,
+ localchain,
+ startUpgradable,
+ },
+ installation: {
+ consume: { [contractName]: installation },
+ },
+ instance: {
+ // @ts-expect-error unknown instance
+ produce: { [contractName]: produceInstance },
+ },
+}) => {
+ trace(`start ${contractName}`);
+
+ const storageNode = await makeStorageNodeChild(chainStorage, contractName);
+ const marshaller = await E(board).getPublishingMarshaller();
+
+ /** @type {StartUpgradableOpts} */
+ const startOpts = {
+ label: 'queryFlows',
+ installation,
+ terms: undefined,
+ privateArgs: await deeplyFulfilledObject(
+ harden({
+ agoricNames,
+ orchestrationService: cosmosInterchainService,
+ localchain,
+ storageNode,
+ marshaller,
+ timerService: chainTimerService,
+ }),
+ ),
+ };
+
+ const { instance } = await E(startUpgradable)(startOpts);
+ produceInstance.resolve(instance);
+};
+harden(startQueryFlows);
+
+export const getManifestForContract = (
+ { restoreRef },
+ { installKeys, ...options },
+) => {
+ return {
+ manifest: {
+ [startQueryFlows.name]: {
+ consume: {
+ agoricNames: true,
+ board: true,
+ chainStorage: true,
+ chainTimerService: true,
+ cosmosInterchainService: true,
+ localchain: true,
+ startUpgradable: true,
+ },
+ installation: {
+ consume: { [contractName]: true },
+ },
+ instance: {
+ produce: { [contractName]: true },
+ },
+ },
+ },
+ installations: {
+ [contractName]: restoreRef(installKeys[contractName]),
+ },
+ options,
+ };
+};
+
+/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
+export const defaultProposalBuilder = async ({ publishRef, install }) => {
+ return harden({
+ // Somewhat unorthodox, source the exports from this builder module
+ sourceSpec: '@agoric/builders/scripts/testing/start-query-flows.js',
+ getManifestCall: [
+ 'getManifestForContract',
+ {
+ installKeys: {
+ queryFlows: publishRef(
+ install(
+ '@agoric/orchestration/src/fixtures/query-flows.contract.js',
+ ),
+ ),
+ },
+ },
+ ],
+ });
+};
+
+export default async (homeP, endowments) => {
+ // import dynamically so the module can work in CoreEval environment
+ const dspModule = await import('@agoric/deploy-script-support');
+ const { makeHelpers } = dspModule;
+ const { writeCoreEval } = await makeHelpers(homeP, endowments);
+ await writeCoreEval(startQueryFlows.name, defaultProposalBuilder);
+};
diff --git a/packages/builders/scripts/testing/start-send-anywhere.js b/packages/builders/scripts/testing/start-send-anywhere.js
new file mode 100644
index 00000000000..71efef5df54
--- /dev/null
+++ b/packages/builders/scripts/testing/start-send-anywhere.js
@@ -0,0 +1,135 @@
+/**
+ * @file This is for use in tests in a3p-integration
+ * Unlike most builder scripts, this one includes the proposal exports as well.
+ */
+import {
+ deeplyFulfilledObject,
+ makeTracer,
+ NonNullish,
+} from '@agoric/internal';
+import { E } from '@endo/far';
+
+///
+/**
+ * @import {Installation} from '@agoric/zoe/src/zoeService/utils.js';
+ */
+
+const trace = makeTracer('StartSA', true);
+
+/**
+ * @import {start as StartFn} from '@agoric/orchestration/src/examples/send-anywhere.contract.js';
+ */
+
+/**
+ * @param {BootstrapPowers & {
+ * installation: {
+ * consume: {
+ * sendAnywhere: Installation;
+ * };
+ * };
+ * }} powers
+ */
+export const startSendAnywhere = async ({
+ consume: {
+ agoricNames,
+ board,
+ chainStorage,
+ chainTimerService,
+ cosmosInterchainService,
+ localchain,
+ startUpgradable,
+ },
+ installation: {
+ consume: { sendAnywhere },
+ },
+ instance: {
+ // @ts-expect-error unknown instance
+ produce: { sendAnywhere: produceInstance },
+ },
+ issuer: {
+ consume: { IST },
+ },
+}) => {
+ trace(startSendAnywhere.name);
+
+ const marshaller = await E(board).getReadonlyMarshaller();
+
+ const privateArgs = await deeplyFulfilledObject(
+ harden({
+ agoricNames,
+ localchain,
+ marshaller,
+ orchestrationService: cosmosInterchainService,
+ storageNode: E(NonNullish(await chainStorage)).makeChildNode(
+ 'send-anywhere',
+ ),
+ timerService: chainTimerService,
+ }),
+ );
+
+ const { instance } = await E(startUpgradable)({
+ label: 'send-anywhere',
+ installation: sendAnywhere,
+ issuerKeywordRecord: { Stable: await IST },
+ privateArgs,
+ });
+ produceInstance.resolve(instance);
+ trace('done');
+};
+harden(startSendAnywhere);
+
+export const getManifest = ({ restoreRef }, { installationRef }) => {
+ return {
+ manifest: {
+ [startSendAnywhere.name]: {
+ consume: {
+ agoricNames: true,
+ board: true,
+ chainStorage: true,
+ chainTimerService: true,
+ cosmosInterchainService: true,
+ localchain: true,
+
+ startUpgradable: true,
+ },
+ installation: {
+ consume: { sendAnywhere: true },
+ },
+ instance: {
+ produce: { sendAnywhere: true },
+ },
+ issuer: {
+ consume: { IST: true },
+ },
+ },
+ },
+ installations: {
+ sendAnywhere: restoreRef(installationRef),
+ },
+ };
+};
+
+/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
+export const defaultProposalBuilder = async ({ publishRef, install }) =>
+ harden({
+ // Somewhat unorthodox, source the exports from this builder module
+ sourceSpec: '@agoric/builders/scripts/testing/start-send-anywhere.js',
+ getManifestCall: [
+ getManifest.name,
+ {
+ installationRef: publishRef(
+ install(
+ '@agoric/orchestration/src/examples/send-anywhere.contract.js',
+ ),
+ ),
+ },
+ ],
+ });
+
+export default async (homeP, endowments) => {
+ // import dynamically so the module can work in CoreEval environment
+ const dspModule = await import('@agoric/deploy-script-support');
+ const { makeHelpers } = dspModule;
+ const { writeCoreEval } = await makeHelpers(homeP, endowments);
+ await writeCoreEval(startSendAnywhere.name, defaultProposalBuilder);
+};
diff --git a/packages/builders/scripts/testing/tweak-chain-info.js b/packages/builders/scripts/testing/tweak-chain-info.js
index 922300ea7c0..ee5ce2da41a 100644
--- a/packages/builders/scripts/testing/tweak-chain-info.js
+++ b/packages/builders/scripts/testing/tweak-chain-info.js
@@ -16,9 +16,6 @@ const chainInfo = {
counterparty: {
client_id: '07-tendermint-2',
connection_id: 'connection-1',
- prefix: {
- key_prefix: '',
- },
},
state: 3 /* IBCConnectionState.STATE_OPEN */,
transferChannel: {
diff --git a/packages/builders/scripts/vats/add-auction.js b/packages/builders/scripts/vats/add-auction.js
index 2f7a2fd12c7..e98d10ef39e 100644
--- a/packages/builders/scripts/vats/add-auction.js
+++ b/packages/builders/scripts/vats/add-auction.js
@@ -1,10 +1,20 @@
import { makeHelpers } from '@agoric/deploy-script-support';
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
-export const defaultProposalBuilder = async () => {
+export const defaultProposalBuilder = async ({ publishRef, install }) => {
return harden({
sourceSpec: '@agoric/inter-protocol/src/proposals/add-auction.js',
- getManifestCall: ['getManifestForAddAuction'],
+ getManifestCall: [
+ 'getManifestForAddAuction',
+ {
+ auctionsRef: publishRef(
+ install(
+ '@agoric/inter-protocol/src/auction/auctioneer.js',
+ '../../inter-protocol/bundles/bundle-auctioneer.js',
+ ),
+ ),
+ },
+ ],
});
};
diff --git a/packages/builders/scripts/vats/upgrade-orch-core.js b/packages/builders/scripts/vats/upgrade-orch-core.js
new file mode 100644
index 00000000000..a4d8a21087b
--- /dev/null
+++ b/packages/builders/scripts/vats/upgrade-orch-core.js
@@ -0,0 +1,23 @@
+import { makeHelpers } from '@agoric/deploy-script-support';
+
+/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
+export const defaultProposalBuilder = async ({ publishRef, install }) =>
+ harden({
+ sourceSpec: '@agoric/vats/src/proposals/upgrade-orch-core-proposal.js',
+ getManifestCall: [
+ 'getManifestForUpgradingOrchCore',
+ {
+ bundleRefs: {
+ ibc: publishRef(install('@agoric/vats/src/vat-ibc.js')),
+ network: publishRef(install('@agoric/vats/src/vat-network.js')),
+ localchain: publishRef(install('@agoric/vats/src/vat-localchain.js')),
+ transfer: publishRef(install('@agoric/vats/src/vat-transfer.js')),
+ },
+ },
+ ],
+ });
+
+export default async (homeP, endowments) => {
+ const { writeCoreProposal } = await makeHelpers(homeP, endowments);
+ await writeCoreProposal('upgrade-network', defaultProposalBuilder);
+};
diff --git a/packages/cache/package.json b/packages/cache/package.json
index 5a0fc6115c0..e1cf95eb3e0 100644
--- a/packages/cache/package.json
+++ b/packages/cache/package.json
@@ -23,8 +23,8 @@
"@agoric/notifier": "^0.6.2",
"@agoric/store": "^0.9.2",
"@agoric/vat-data": "^0.5.2",
- "@endo/far": "^1.1.2",
- "@endo/marshal": "^1.5.0"
+ "@endo/far": "^1.1.5",
+ "@endo/marshal": "^1.5.3"
},
"devDependencies": {
"@agoric/zoe": "^0.26.2",
diff --git a/packages/casting/README.md b/packages/casting/README.md
index a04be102d63..6f7fa9e5f42 100644
--- a/packages/casting/README.md
+++ b/packages/casting/README.md
@@ -13,7 +13,6 @@ An example of following an on-chain mailbox in code (using this package) is:
```js
// First, obtain a Hardened JS environment via Endo.
import '@endo/init/pre-remoting.js'; // needed only for the next line
-import '@agoric/casting/node-fetch-shim.js'; // needed for Node.js
import '@endo/init';
import {
diff --git a/packages/casting/node-fetch-shim.js b/packages/casting/node-fetch-shim.js
deleted file mode 100644
index 73636b7b9b7..00000000000
--- a/packages/casting/node-fetch-shim.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// @jessie-check
-
-/* global globalThis */
-import fetch from 'node-fetch';
-
-// @ts-expect-error node-fetch does not exactly match W3C Fetch
-globalThis.fetch = fetch;
diff --git a/packages/casting/package.json b/packages/casting/package.json
index b21961e462c..6edf3fb70bb 100644
--- a/packages/casting/package.json
+++ b/packages/casting/package.json
@@ -8,7 +8,7 @@
"scripts": {
"build": "exit 0",
"prepack": "tsc --build tsconfig.build.json",
- "postpack": "git clean -f '*.d.ts*'",
+ "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
"demo": "node -e 'import(\"./test/fake-rpc-server.js\").then(ns => ns.develop())'",
"test": "ava",
"test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
@@ -29,18 +29,16 @@
"@cosmjs/proto-signing": "^0.32.3",
"@cosmjs/stargate": "^0.32.3",
"@cosmjs/tendermint-rpc": "^0.32.3",
- "@endo/errors": "^1.2.2",
- "@endo/far": "^1.1.2",
- "@endo/init": "^1.1.2",
- "@endo/lockdown": "^1.0.7",
- "@endo/marshal": "^1.5.0",
- "@endo/promise-kit": "^1.1.2",
- "node-fetch": "^2.6.0"
+ "@endo/errors": "^1.2.5",
+ "@endo/far": "^1.1.5",
+ "@endo/init": "^1.1.4",
+ "@endo/lockdown": "^1.0.10",
+ "@endo/marshal": "^1.5.3",
+ "@endo/promise-kit": "^1.1.5"
},
"devDependencies": {
"@agoric/cosmic-proto": "^0.4.0",
- "@endo/ses-ava": "^1.2.2",
- "@types/node-fetch": "^2.6.2",
+ "@endo/ses-ava": "^1.2.5",
"ava": "^5.3.0",
"c8": "^9.1.0",
"express": "^4.17.1",
diff --git a/packages/casting/src/makeHttpClient.js b/packages/casting/src/makeHttpClient.js
index 834c50c40e2..e6fe7c1ec7e 100644
--- a/packages/casting/src/makeHttpClient.js
+++ b/packages/casting/src/makeHttpClient.js
@@ -4,7 +4,7 @@ const { freeze } = Object;
const filterBadStatus = res => {
if (res.status >= 400) {
- throw new Error(`Bad status on response: ${res.status}`);
+ throw Error(`Bad status on response: ${res.status}`);
}
return res;
};
diff --git a/packages/casting/test/lockdown.js b/packages/casting/test/lockdown.js
index f597abccf3d..a072eab0b40 100644
--- a/packages/casting/test/lockdown.js
+++ b/packages/casting/test/lockdown.js
@@ -1,3 +1,2 @@
import '@endo/init/pre-remoting.js';
-import '../node-fetch-shim.js';
import '@endo/init';
diff --git a/packages/casting/test/mvp.test.js b/packages/casting/test/mvp.test.js
index 123ba4eda5e..3a05b6abb73 100644
--- a/packages/casting/test/mvp.test.js
+++ b/packages/casting/test/mvp.test.js
@@ -155,7 +155,7 @@ test('missing rpc server', async t => {
jitter: null,
}),
{
- message: /^invalid json response body/,
+ message: /^Unexpected token/,
},
);
});
diff --git a/packages/cosmic-proto/README.md b/packages/cosmic-proto/README.md
index 57da42b9d3e..e46015a25b1 100644
--- a/packages/cosmic-proto/README.md
+++ b/packages/cosmic-proto/README.md
@@ -27,21 +27,14 @@ npm install @agoric/cosmic-proto
## Usage
### RPC Clients
-```js
-import { agoric } from '@agoric/cosmic-proto';
-
-const { createRPCQueryClient } = agoric.ClientFactory;
-const client = await createRPCQueryClient({ rpcEndpoint: RPC_ENDPOINT });
-
-const swingsetParams = await client.agoric.swingset.params()
-```
+TODO #9200
### Composing Messages
-Import the `agoric` object from `@agoric/cosmic-proto`.
+Import the `agoric` object from the Agoric bundle.
```js
-import { agoric } from '@agoric/cosmic-proto';
+import { agoric } from '@agoric/cosmic-proto/agoric/bundle.js';
const {
installBundle,
@@ -54,18 +47,7 @@ const {
Here are the docs on [creating signers](https://github.com/cosmology-tech/cosmos-kit/tree/main/packages/react#signing-clients) in cosmos-kit that can be used with Keplr and other wallets.
-### Initializing the Stargate Client
-
-Use `getSigningAgoricClient` to get your `SigningStargateClient`, with the proto/amino messages full-loaded. No need to manually add amino types, just require and initialize the client:
-```js
-import { getSigningAgoricClient } from '@agoric/cosmic-proto';
-
-const stargateClient = await getSigningAgoricClient({
- rpcEndpoint,
- signer // OfflineSigner
-});
-```
### Creating Signers
To broadcast messages, you can create signers with a variety of options:
diff --git a/packages/cosmic-proto/package.json b/packages/cosmic-proto/package.json
index 1a492ea4bef..1cb06d9f84f 100644
--- a/packages/cosmic-proto/package.json
+++ b/packages/cosmic-proto/package.json
@@ -19,10 +19,6 @@
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
- "./vatsafe": {
- "types": "./dist/vatsafe.d.ts",
- "default": "./dist/vatsafe.js"
- },
"./package.json": "./package.json",
"./agoric/*.js": {
"types": "./dist/codegen/agoric/*.d.ts",
@@ -36,10 +32,22 @@
"types": "./dist/codegen/cosmos/bank/v1beta1/query.d.ts",
"default": "./dist/codegen/cosmos/bank/v1beta1/query.js"
},
+ "./cosmos/bank/v1beta1/tx.js": {
+ "types": "./dist/codegen/cosmos/bank/v1beta1/tx.d.ts",
+ "default": "./dist/codegen/cosmos/bank/v1beta1/tx.js"
+ },
+ "./cosmos/distribution/v1beta1/query.js": {
+ "types": "./dist/codegen/cosmos/distribution/v1beta1/query.d.ts",
+ "default": "./dist/codegen/cosmos/distribution/v1beta1/query.js"
+ },
"./cosmos/distribution/v1beta1/tx.js": {
"types": "./dist/codegen/cosmos/distribution/v1beta1/tx.d.ts",
"default": "./dist/codegen/cosmos/distribution/v1beta1/tx.js"
},
+ "./cosmos/staking/v1beta1/query.js": {
+ "types": "./dist/codegen/cosmos/staking/v1beta1/query.d.ts",
+ "default": "./dist/codegen/cosmos/staking/v1beta1/query.js"
+ },
"./cosmos/staking/v1beta1/tx.js": {
"types": "./dist/codegen/cosmos/staking/v1beta1/tx.d.ts",
"default": "./dist/codegen/cosmos/staking/v1beta1/tx.js"
@@ -64,6 +72,10 @@
"types": "./dist/codegen/ibc/applications/interchain_accounts/v1/packet.d.ts",
"default": "./dist/codegen/ibc/applications/interchain_accounts/v1/packet.js"
},
+ "./ibc/applications/transfer/v1/tx.js": {
+ "types": "./dist/codegen/ibc/applications/transfer/v1/tx.d.ts",
+ "default": "./dist/codegen/ibc/applications/transfer/v1/tx.js"
+ },
"./ibc/core/channel/v1/channel.js": {
"types": "./dist/codegen/ibc/core/channel/v1/channel.d.ts",
"default": "./dist/codegen/ibc/core/channel/v1/channel.js"
@@ -132,18 +144,18 @@
"devDependencies": {
"@agoric/cosmos": "^0.34.1",
"@ava/typescript": "^4.1.0",
- "@cosmology/telescope": "^1.7.1",
- "@endo/bundle-source": "^3.2.3",
- "@endo/import-bundle": "^1.1.2",
+ "@cosmology/telescope": "https://gitpkg.vercel.app/agoric-labs/telescope/packages/telescope?8d2c2f6ba637a5578eead09a7368dc41c262a9d0",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/import-bundle": "^1.2.2",
"ava": "^5.3.1",
"rimraf": "^5.0.0",
"tsd": "^0.31.1",
"tsimp": "^2.0.11",
- "typescript": "^5.5.3"
+ "typescript": "~5.6.2"
},
"dependencies": {
- "@endo/base64": "^1.0.5",
- "@endo/init": "^1.1.2"
+ "@endo/base64": "^1.0.7",
+ "@endo/init": "^1.1.4"
},
"resolutions": {
"**/axios": "^1.6.7",
diff --git a/packages/cosmic-proto/src/codegen/binary.ts b/packages/cosmic-proto/src/codegen/binary.ts
index 524eb36d273..22d542844d2 100644
--- a/packages/cosmic-proto/src/codegen/binary.ts
+++ b/packages/cosmic-proto/src/codegen/binary.ts
@@ -1,6 +1,6 @@
//@ts-nocheck
/**
- * This file and any referenced files were automatically generated by @cosmology/telescope@1.7.1
+ * This file and any referenced files were automatically generated by @cosmology/telescope@1.8.3
* DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain
* and run the transpile command or npm scripts command that is used to regenerate this bundle.
*/
diff --git a/packages/cosmic-proto/src/codegen/google/protobuf/descriptor.ts b/packages/cosmic-proto/src/codegen/google/protobuf/descriptor.ts
index 3ec3b438f39..a381d00927f 100644
--- a/packages/cosmic-proto/src/codegen/google/protobuf/descriptor.ts
+++ b/packages/cosmic-proto/src/codegen/google/protobuf/descriptor.ts
@@ -31,6 +31,7 @@ export enum FieldDescriptorProto_Type {
* treat group fields as unknown fields.
*/
TYPE_GROUP = 10,
+ /** TYPE_MESSAGE - Length-delimited aggregate. */
TYPE_MESSAGE = 11,
/** TYPE_BYTES - New in version 2. */
TYPE_BYTES = 12,
@@ -198,12 +199,9 @@ export function fieldDescriptorProto_LabelToJSON(
}
/** Generated classes can be optimized for speed or code size. */
export enum FileOptions_OptimizeMode {
- /**
- * SPEED - Generate complete code for parsing, serialization,
- * etc.
- */
+ /** SPEED - Generate complete code for parsing, serialization, */
SPEED = 1,
- /** CODE_SIZE - Use ReflectionOps to implement these methods. */
+ /** CODE_SIZE - etc. */
CODE_SIZE = 2,
/** LITE_RUNTIME - Generate code using MessageLite and the lite runtime. */
LITE_RUNTIME = 3,
@@ -393,6 +391,7 @@ export interface FileDescriptorSetSDKType {
export interface FileDescriptorProto {
/** file name, relative to root of source tree */
name: string;
+ /** e.g. "foo", "foo.bar", etc. */
package: string;
/** Names of files imported by this file. */
dependency: string[];
diff --git a/packages/cosmic-proto/src/codegen/helpers.ts b/packages/cosmic-proto/src/codegen/helpers.ts
index ebdafe89353..e9674426df1 100644
--- a/packages/cosmic-proto/src/codegen/helpers.ts
+++ b/packages/cosmic-proto/src/codegen/helpers.ts
@@ -1,6 +1,6 @@
//@ts-nocheck
/**
- * This file and any referenced files were automatically generated by @cosmology/telescope@1.7.1
+ * This file and any referenced files were automatically generated by @cosmology/telescope@1.8.3
* DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain
* and run the transpile command or npm scripts command that is used to regenerate this bundle.
*/
@@ -223,9 +223,10 @@ function numberToLong(number: number) {
return BigInt(Math.trunc(number));
}
+// START agoric-sdk patch
// The largest value we need is 18 (Ether).
const maxFractionalDigits = 30;
-// Subset of Decimal in @cosmjs/math
+
/**
* A type for arbitrary precision, non-negative decimals.
*
@@ -252,7 +253,7 @@ export class Decimal {
if (input === '') {
whole = '0';
fractional = '';
- } else if (input.search(/./) === -1) {
+ } else if (input.search(/\./) === -1) {
// integer format, no separator
whole = input;
fractional = '';
@@ -302,4 +303,47 @@ export class Decimal {
);
}
}
+
+ public get atomics(): string {
+ return this.data.atomics.toString();
+ }
+
+ public get fractionalDigits(): number {
+ return this.data.fractionalDigits;
+ }
+
+ private readonly data: {
+ readonly atomics: bigint;
+ readonly fractionalDigits: number;
+ };
+
+ private constructor(atomics: string, fractionalDigits: number) {
+ if (!atomics.match(/^[0-9]+$/)) {
+ throw new Error(
+ 'Invalid string format. Only non-negative integers in decimal representation supported.',
+ );
+ }
+
+ this.data = {
+ atomics: BigInt(atomics),
+ fractionalDigits: fractionalDigits,
+ };
+ }
+
+ public toString(): string {
+ const factor = BigInt(10) ** BigInt(this.data.fractionalDigits);
+ const whole = this.data.atomics / factor;
+ const fractional = this.data.atomics % factor;
+
+ if (fractional === 0n) {
+ return whole.toString();
+ } else {
+ const fullFractionalPart = fractional
+ .toString()
+ .padStart(this.data.fractionalDigits, '0');
+ const trimmedFractionalPart = fullFractionalPart.replace(/0+$/, '');
+ return `${whole.toString()}.${trimmedFractionalPart}`;
+ }
+ }
}
+// END agoric-sdk patch
diff --git a/packages/cosmic-proto/src/codegen/index.ts b/packages/cosmic-proto/src/codegen/index.ts
index 80dd20e32b1..e6e4d93d04b 100644
--- a/packages/cosmic-proto/src/codegen/index.ts
+++ b/packages/cosmic-proto/src/codegen/index.ts
@@ -1,6 +1,6 @@
//@ts-nocheck
/**
- * This file and any referenced files were automatically generated by @cosmology/telescope@1.7.1
+ * This file and any referenced files were automatically generated by @cosmology/telescope@1.8.3
* DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain
* and run the transpile command or npm scripts command that is used to regenerate this bundle.
*/
diff --git a/packages/cosmic-proto/src/codegen/json-safe.ts b/packages/cosmic-proto/src/codegen/json-safe.ts
index a026dbef565..b35e037fe21 100644
--- a/packages/cosmic-proto/src/codegen/json-safe.ts
+++ b/packages/cosmic-proto/src/codegen/json-safe.ts
@@ -1,12 +1,14 @@
//@ts-nocheck
/**
- * This file and any referenced files were automatically generated by @cosmology/telescope@1.7.1
+ * This file and any referenced files were automatically generated by @cosmology/telescope@1.8.3
* DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain
* and run the transpile command or npm scripts command that is used to regenerate this bundle.
*/
-export type JsonSafe = {
- [Prop in keyof T]: T[Prop] extends Uint8Array | bigint | Date
- ? string
- : T[Prop];
-};
+export type JsonSafe = T extends Uint8Array | bigint | Date
+ ? string
+ : T extends Array
+ ? Array>
+ : T extends object
+ ? { [K in keyof T]: JsonSafe }
+ : T;
diff --git a/packages/cosmic-proto/src/codegen/tendermint/abci/types.ts b/packages/cosmic-proto/src/codegen/tendermint/abci/types.ts
index 913c9ee017f..8d1fd3f6eb9 100644
--- a/packages/cosmic-proto/src/codegen/tendermint/abci/types.ts
+++ b/packages/cosmic-proto/src/codegen/tendermint/abci/types.ts
@@ -849,12 +849,9 @@ export interface TxResultSDKType {
}
/** Validator */
export interface Validator {
- /**
- * The first 20 bytes of SHA256(public key)
- * PubKey pub_key = 2 [(gogoproto.nullable)=false];
- */
+ /** The first 20 bytes of SHA256(public key) */
address: Uint8Array;
- /** The voting power */
+ /** PubKey pub_key = 2 [(gogoproto.nullable)=false]; */
power: bigint;
}
export interface ValidatorProtoMsg {
diff --git a/packages/cosmic-proto/src/codegen/tendermint/types/types.ts b/packages/cosmic-proto/src/codegen/tendermint/types/types.ts
index 52eba4662ac..e34af751bbc 100644
--- a/packages/cosmic-proto/src/codegen/tendermint/types/types.ts
+++ b/packages/cosmic-proto/src/codegen/tendermint/types/types.ts
@@ -158,6 +158,7 @@ export interface Header {
lastBlockId: BlockID;
/** hashes of block data */
lastCommitHash: Uint8Array;
+ /** transactions */
dataHash: Uint8Array;
/** hashes from the app output from the prev block */
validatorsHash: Uint8Array;
@@ -167,6 +168,7 @@ export interface Header {
consensusHash: Uint8Array;
/** state after txs from the previous block */
appHash: Uint8Array;
+ /** root hash of all results from the txs from the previous block */
lastResultsHash: Uint8Array;
/** consensus info */
evidenceHash: Uint8Array;
diff --git a/packages/cosmic-proto/src/codegen/utf8.ts b/packages/cosmic-proto/src/codegen/utf8.ts
index f2d864a1976..d0412e27b6c 100644
--- a/packages/cosmic-proto/src/codegen/utf8.ts
+++ b/packages/cosmic-proto/src/codegen/utf8.ts
@@ -1,6 +1,6 @@
//@ts-nocheck
/**
- * This file and any referenced files were automatically generated by @cosmology/telescope@1.7.1
+ * This file and any referenced files were automatically generated by @cosmology/telescope@1.8.3
* DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain
* and run the transpile command or npm scripts command that is used to regenerate this bundle.
*/
diff --git a/packages/cosmic-proto/src/codegen/varint.ts b/packages/cosmic-proto/src/codegen/varint.ts
index e379c6dcef1..dd800ff82d9 100644
--- a/packages/cosmic-proto/src/codegen/varint.ts
+++ b/packages/cosmic-proto/src/codegen/varint.ts
@@ -1,6 +1,6 @@
//@ts-nocheck
/**
- * This file and any referenced files were automatically generated by @cosmology/telescope@1.7.1
+ * This file and any referenced files were automatically generated by @cosmology/telescope@1.8.3
* DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain
* and run the transpile command or npm scripts command that is used to regenerate this bundle.
*/
diff --git a/packages/cosmic-proto/src/helpers.ts b/packages/cosmic-proto/src/helpers.ts
index f25f093c68a..5e2cb864cd6 100644
--- a/packages/cosmic-proto/src/helpers.ts
+++ b/packages/cosmic-proto/src/helpers.ts
@@ -7,7 +7,9 @@ import type {
import type {
QueryAllBalancesRequest,
QueryAllBalancesResponse,
+ QueryBalanceRequest,
QueryBalanceRequestProtoMsg,
+ QueryBalanceResponse,
} from './codegen/cosmos/bank/v1beta1/query.js';
import type {
MsgSend,
@@ -38,6 +40,8 @@ export type Proto3Shape = {
'/cosmos.bank.v1beta1.MsgSendResponse': MsgSendResponse;
'/cosmos.bank.v1beta1.QueryAllBalancesRequest': QueryAllBalancesRequest;
'/cosmos.bank.v1beta1.QueryAllBalancesResponse': QueryAllBalancesResponse;
+ '/cosmos.bank.v1beta1.QueryBalanceRequest': QueryBalanceRequest;
+ '/cosmos.bank.v1beta1.QueryBalanceResponse': QueryBalanceResponse;
'/cosmos.staking.v1beta1.MsgDelegate': MsgDelegate;
'/cosmos.staking.v1beta1.MsgDelegateResponse': MsgDelegateResponse;
'/cosmos.staking.v1beta1.MsgUndelegate': MsgUndelegate;
@@ -93,9 +97,7 @@ const QUERY_REQ_TYPEURL_RE =
export const typeUrlToGrpcPath = (typeUrl: Any['typeUrl']) => {
const match = typeUrl.match(QUERY_REQ_TYPEURL_RE);
if (!(match && match.groups)) {
- throw new TypeError(
- `Invalid typeUrl: ${typeUrl}. Must be a Query Request.`,
- );
+ throw TypeError(`Invalid typeUrl: ${typeUrl}. Must be a Query Request.`);
}
const { serviceName, methodName } = match.groups;
return `/${serviceName}.Query/${methodName}`;
diff --git a/packages/cosmic-proto/src/index.ts b/packages/cosmic-proto/src/index.ts
index 8643097653e..c3a5f798955 100644
--- a/packages/cosmic-proto/src/index.ts
+++ b/packages/cosmic-proto/src/index.ts
@@ -1,3 +1,6 @@
-export * from './codegen/index.js';
+// Do not export codegen/index.js because it entrains multiple megabytes of module imports.
+// Instead we have the top level be relatively conservative, just things that are safe to import into a vat.
+// This can include all the types because those are free (never included in a JS bundle).
+export * from './codegen/json-safe.js';
export * from './helpers.js';
diff --git a/packages/cosmic-proto/src/vatsafe.ts b/packages/cosmic-proto/src/vatsafe.ts
deleted file mode 100644
index 780f0c00ce3..00000000000
--- a/packages/cosmic-proto/src/vatsafe.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/** @file top level export (similar to index.js) but only with modules that can load from within a vat */
-export * from './helpers.js';
diff --git a/packages/cosmic-proto/test/exports.test.js b/packages/cosmic-proto/test/exports.test.js
index 88f31c13f05..d5e9ba3db8d 100644
--- a/packages/cosmic-proto/test/exports.test.js
+++ b/packages/cosmic-proto/test/exports.test.js
@@ -1,10 +1,14 @@
-// @ts-check
/* eslint-disable import/no-extraneous-dependencies -- requiring the package itself to check exports map */
+// @ts-check
+
import test from 'ava';
import '@endo/init';
import * as index from '@agoric/cosmic-proto';
+import { agoric } from '@agoric/cosmic-proto/agoric/bundle.js';
+import { cosmos } from '@agoric/cosmic-proto/cosmos/bundle.js';
+import { ibc } from '@agoric/cosmic-proto/ibc/bundle.js';
import * as swingsetMsgs from '@agoric/cosmic-proto/swingset/msgs.js';
import * as swingsetQuery from '@agoric/cosmic-proto/swingset/query.js';
import * as vstorageQuery from '@agoric/cosmic-proto/vstorage/query.js';
@@ -26,13 +30,13 @@ test('vstorage/query', t => {
});
test('agoric', t => {
- t.snapshot(Object.keys(index.agoric).sort());
+ t.snapshot(Object.keys(agoric).sort());
});
test('cosmos', t => {
- t.snapshot(Object.keys(index.cosmos).sort());
+ t.snapshot(Object.keys(cosmos).sort());
});
test('ibc', t => {
- t.snapshot(Object.keys(index.ibc).sort());
+ t.snapshot(Object.keys(ibc).sort());
});
diff --git a/packages/cosmic-proto/test/helpers.test-d.ts b/packages/cosmic-proto/test/helpers.test-d.ts
index 0ad74d4846e..dbeafd4af4b 100644
--- a/packages/cosmic-proto/test/helpers.test-d.ts
+++ b/packages/cosmic-proto/test/helpers.test-d.ts
@@ -1,6 +1,6 @@
import { expectType } from 'tsd';
import { typedJson } from '../src/helpers.js';
-import type { ResponseTo, TypedJson } from '../src/helpers.ts';
+import type { ResponseTo, TypedJson } from '../src/helpers.js';
import type { JsonSafe } from '../src/codegen/json-safe.js';
import type { Timestamp } from '../src/codegen/google/protobuf/timestamp.js';
@@ -69,6 +69,5 @@ import type { Timestamp } from '../src/codegen/google/protobuf/timestamp.js';
null as any;
expectType(response.completionTime);
const responseJson: JsonSafe = null as any;
- // FIXME: should be a string. UNTIL: github.com/cosmology-tech/telescope/pull/632
- expectType(responseJson.completionTime.seconds);
+ expectType(responseJson.completionTime.seconds);
}
diff --git a/packages/cosmic-proto/test/readme.test.js b/packages/cosmic-proto/test/readme.test.js
index 945afa643cc..83dfdf35b0c 100644
--- a/packages/cosmic-proto/test/readme.test.js
+++ b/packages/cosmic-proto/test/readme.test.js
@@ -1,21 +1,9 @@
// @ts-check
/** @file snippets from the README */
-/* eslint-disable import/no-extraneous-dependencies -- requiring the package itself to check exports map */
-import test from 'ava';
-
-import { agoric } from '../dist/index.js';
-
-const RPC_ENDPOINT = '';
-// Skip because we don't have a real endpoint, still tests the types
-test.skip('RPC Clients', async t => {
- // @ts-expect-error
- const { createRPCQueryClient } = agoric.ClientFactory;
- const client = await createRPCQueryClient({ rpcEndpoint: RPC_ENDPOINT });
+import test from 'ava';
- const swingsetParams = await client.agoric.swingset.params();
- t.truthy(swingsetParams);
-});
+import { agoric } from '../dist/codegen/agoric/bundle.js';
test.failing('Composing Messages', t => {
// @ts-expect-error
diff --git a/packages/cosmic-proto/test/snapshots/exports.test.js.md b/packages/cosmic-proto/test/snapshots/exports.test.js.md
index 5241414b882..8faf119bf32 100644
--- a/packages/cosmic-proto/test/snapshots/exports.test.js.md
+++ b/packages/cosmic-proto/test/snapshots/exports.test.js.md
@@ -9,41 +9,9 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 1
[
- 'BinaryReader',
- 'BinaryWriter',
- 'WireType',
- 'agoric',
- 'amino',
- 'cosmos',
- 'cosmos_proto',
- 'gogoproto',
- 'google',
- 'ibc',
- 'icq',
- 'ics23',
- 'int64FromString',
- 'int64Length',
- 'int64ToString',
- 'readInt32',
- 'readUInt32',
- 'tendermint',
'toRequestQueryJson',
'typeUrlToGrpcPath',
'typedJson',
- 'uInt64ToString',
- 'utf8Length',
- 'utf8Read',
- 'utf8Write',
- 'varint32read',
- 'varint32write',
- 'varint64read',
- 'varint64write',
- 'writeByte',
- 'writeFixed32',
- 'writeVarint32',
- 'writeVarint64',
- 'zzDecode',
- 'zzEncode',
]
## swingset/msgs
diff --git a/packages/cosmic-proto/test/snapshots/exports.test.js.snap b/packages/cosmic-proto/test/snapshots/exports.test.js.snap
index 5594cf1f2c4..306b4ec09e8 100644
Binary files a/packages/cosmic-proto/test/snapshots/exports.test.js.snap and b/packages/cosmic-proto/test/snapshots/exports.test.js.snap differ
diff --git a/packages/cosmic-proto/test/vatsafe.test.js b/packages/cosmic-proto/test/vatsafe.test.js
index db0d5175951..a184176e27d 100644
--- a/packages/cosmic-proto/test/vatsafe.test.js
+++ b/packages/cosmic-proto/test/vatsafe.test.js
@@ -1,31 +1,9 @@
// @ts-check
/* eslint-disable import/no-extraneous-dependencies -- requiring the package itself to check exports map */
import test from '@endo/ses-ava/prepare-endo.js';
-import { cosmos } from '@agoric/cosmic-proto';
import { MsgDelegate } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js';
-// @ts-expect-error
-cosmos.staking.v1beta1.MsgDelegate.missing;
-// @ts-expect-error
-MsgDelegate.missing;
-
-test('imports', t => {
- t.is(MsgDelegate, cosmos.staking.v1beta1.MsgDelegate);
-
- t.deepEqual(cosmos.staking.v1beta1.MsgDelegate.fromPartial({}), {
- amount: undefined,
- delegatorAddress: '',
- validatorAddress: '',
- });
-
- t.deepEqual(MsgDelegate.fromPartial({}), {
- amount: undefined,
- delegatorAddress: '',
- validatorAddress: '',
- });
-});
-
test('proto encoding', t => {
const contents = {
delegatorAddress:
diff --git a/packages/cosmic-proto/update-protos.sh b/packages/cosmic-proto/update-protos.sh
index 3e73512067f..2c65c328070 100755
--- a/packages/cosmic-proto/update-protos.sh
+++ b/packages/cosmic-proto/update-protos.sh
@@ -7,7 +7,7 @@ AG_SDK=$(readlink -f "$(dirname -- "$(readlink -f -- "$0")")/../..")
# go ensure fresh build
cd "$AG_SDK"/golang/cosmos
-make go-mod-cache
+SKIP_MOD_VERIFY=1 make go.sum
COSMOS_SDK=$(go list -m -f '{{ .Dir }}' github.com/cosmos/cosmos-sdk)
IBC_GO=$(go list -m -f '{{ .Dir }}' github.com/cosmos/ibc-go/v6)
cd -
diff --git a/packages/cosmic-swingset/.gitignore b/packages/cosmic-swingset/.gitignore
index fd4c7ab84c2..c54a14d5162 100644
--- a/packages/cosmic-swingset/.gitignore
+++ b/packages/cosmic-swingset/.gitignore
@@ -87,3 +87,6 @@ typings/
# next.js build output
.next
+
+# rosetta-cli executable
+bin/rosetta-cli
\ No newline at end of file
diff --git a/packages/cosmic-swingset/package.json b/packages/cosmic-swingset/package.json
index 09d3a7056d6..fa2309d970a 100644
--- a/packages/cosmic-swingset/package.json
+++ b/packages/cosmic-swingset/package.json
@@ -22,7 +22,6 @@
"author": "Agoric",
"license": "Apache-2.0",
"dependencies": {
- "@endo/errors": "^1.2.2",
"@agoric/builders": "^0.1.0",
"@agoric/cosmos": "^0.34.1",
"@agoric/deploy-script-support": "^0.10.3",
@@ -32,17 +31,19 @@
"@agoric/swingset-vat": "^0.32.2",
"@agoric/telemetry": "^0.6.2",
"@agoric/vm-config": "^0.1.0",
- "@endo/bundle-source": "^3.2.3",
- "@endo/env-options": "^1.1.4",
- "@endo/far": "^1.1.2",
- "@endo/import-bundle": "^1.1.2",
- "@endo/init": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/nat": "^5.0.7",
- "@endo/promise-kit": "^1.1.2",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/env-options": "^1.1.6",
+ "@endo/errors": "^1.2.5",
+ "@endo/import-bundle": "^1.2.2",
+ "@endo/init": "^1.1.4",
+ "@endo/far": "^1.1.5",
+ "@endo/marshal": "^1.5.3",
+ "@endo/nat": "^5.0.10",
+ "@endo/patterns": "^1.4.3",
+ "@endo/promise-kit": "^1.1.5",
"@iarna/toml": "^2.2.3",
- "@opentelemetry/sdk-metrics": "~1.9.0",
"@opentelemetry/api": "~1.3.0",
+ "@opentelemetry/sdk-metrics": "~1.9.0",
"anylogger": "^0.21.0",
"deterministic-json": "^1.0.5",
"import-meta-resolve": "^2.2.1",
@@ -68,6 +69,6 @@
"timeout": "20m"
},
"typeCoverage": {
- "atLeast": 80.6
+ "atLeast": 80.55
}
}
diff --git a/packages/cosmic-swingset/src/chain-main.js b/packages/cosmic-swingset/src/chain-main.js
index 466ed83d1f0..83f38f2aa6a 100644
--- a/packages/cosmic-swingset/src/chain-main.js
+++ b/packages/cosmic-swingset/src/chain-main.js
@@ -1,17 +1,20 @@
// @ts-check
-import { resolve as pathResolve } from 'path';
+import path from 'node:path';
import v8 from 'node:v8';
import process from 'node:process';
import fs from 'node:fs';
import fsPromises from 'node:fs/promises';
-import { performance } from 'perf_hooks';
-import { resolve as importMetaResolve } from 'import-meta-resolve';
-import tmpfs from 'tmp';
+import { performance } from 'node:perf_hooks';
import { fork } from 'node:child_process';
+import { resolve as importMetaResolve } from 'import-meta-resolve';
+import tmp from 'tmp';
import { Fail, q } from '@endo/errors';
import { E } from '@endo/far';
+import { makeMarshal } from '@endo/marshal';
+import { isNat } from '@endo/nat';
+import { M, mustMatch } from '@endo/patterns';
import engineGC from '@agoric/internal/src/lib-nodejs/engine-gc.js';
import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
import {
@@ -25,12 +28,15 @@ import {
makeChainStorageRoot,
makeSerializeToStorage,
} from '@agoric/internal/src/lib-chainStorage.js';
-import { makeMarshal } from '@endo/marshal';
import { makeShutdown } from '@agoric/internal/src/node/shutdown.js';
import * as STORAGE_PATH from '@agoric/internal/src/chain-storage-paths.js';
import * as ActionType from '@agoric/internal/src/action-types.js';
import { BridgeId, CosmosInitKeyToBridgeId } from '@agoric/internal';
+import {
+ makeArchiveSnapshot,
+ makeArchiveTranscript,
+} from '@agoric/swing-store';
import {
makeBufferedStorage,
makeReadCachingStorage,
@@ -48,6 +54,8 @@ import {
validateImporterOptions,
} from './import-kernel-db.js';
+const ignore = () => {};
+
// eslint-disable-next-line no-unused-vars
let whenHellFreezesOver = null;
@@ -62,6 +70,66 @@ const toNumber = specimen => {
return number;
};
+/**
+ * The swingset config object parsed and resolved by cosmos in
+ * `golang/cosmos/x/swingset/config.go`. The shape should be kept in sync
+ * with `SwingsetConfig` defined there.
+ *
+ * @typedef {object} CosmosSwingsetConfig
+ * @property {string} [slogfile]
+ * @property {number} [maxVatsOnline]
+ * @property {'debug' | 'operational'} [vatSnapshotRetention]
+ * @property {'archival' | 'operational'} [vatTranscriptRetention]
+ * @property {string} [vatSnapshotArchiveDir]
+ * @property {string} [vatTranscriptArchiveDir]
+ */
+const SwingsetConfigShape = M.splitRecord(
+ // All known properties are optional, but unknown properties are not allowed.
+ {},
+ {
+ slogfile: M.string(),
+ maxVatsOnline: M.number(),
+ vatSnapshotRetention: M.or('debug', 'operational'),
+ vatTranscriptRetention: M.or('archival', 'operational'),
+ vatSnapshotArchiveDir: M.string(),
+ vatTranscriptArchiveDir: M.string(),
+ },
+ {},
+);
+const validateSwingsetConfig = swingsetConfig => {
+ mustMatch(swingsetConfig, SwingsetConfigShape);
+ const { maxVatsOnline } = swingsetConfig;
+ maxVatsOnline === undefined ||
+ (isNat(maxVatsOnline) && maxVatsOnline > 0) ||
+ Fail`maxVatsOnline must be a positive integer`;
+};
+
+/**
+ * A boot message consists of cosmosInitAction fields that are subject to
+ * consensus. See cosmosInitAction in {@link ../../../golang/cosmos/app/app.go}.
+ *
+ * @param {any} initAction
+ */
+const makeBootMsg = initAction => {
+ const {
+ type,
+ blockTime,
+ blockHeight,
+ chainID,
+ params,
+ // NB: resolvedConfig is independent of consensus and MUST NOT be included
+ supplyCoins,
+ } = initAction;
+ return {
+ type,
+ blockTime,
+ blockHeight,
+ chainID,
+ params,
+ supplyCoins,
+ };
+};
+
/**
* @template {unknown} [T=unknown]
* @param {(req: string) => string} call
@@ -99,8 +167,8 @@ const makePrefixedBridgeStorage = (
return fromBridgeStringValue(ret);
},
set: (key, value) => {
- const path = `${prefix}${key}`;
- const entry = [path, toBridgeStringValue(value)];
+ const fullPath = `${prefix}${key}`;
+ const entry = [fullPath, toBridgeStringValue(value)];
call(
stringify({
method: setterMethod,
@@ -109,8 +177,8 @@ const makePrefixedBridgeStorage = (
);
},
delete: key => {
- const path = `${prefix}${key}`;
- const entry = [path];
+ const fullPath = `${prefix}${key}`;
+ const entry = [fullPath];
call(
stringify({
method: setterMethod,
@@ -214,7 +282,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
const clearChainSends = async () => {
// Cosmos should have blocked before calling commit, but wait just in case
- await stateSyncExport?.exporter?.onStarted().catch(() => {});
+ await stateSyncExport?.exporter?.onStarted().catch(ignore);
const chainSends = savedChainSends;
savedChainSends = [];
@@ -246,10 +314,33 @@ export default async function main(progname, args, { env, homedir, agcc }) {
/** @type {((obj: object) => void) | undefined} */
let writeSlogObject;
- // the storagePort used to change for every single message. It's defined out
+ // In the past, storagePort could change with every message. It's defined out
// here so 'sendToChainStorage' can close over the single mutable instance,
// when we updated the 'portNums.storage' value each time toSwingSet was called.
- async function launchAndInitializeSwingSet(bootMsg) {
+ async function launchAndInitializeSwingSet(initAction) {
+ const { XSNAP_KEEP_SNAPSHOTS, NODE_HEAP_SNAPSHOTS = -1 } = env;
+
+ /** @type {CosmosSwingsetConfig} */
+ const swingsetConfig = harden(initAction.resolvedConfig || {});
+ validateSwingsetConfig(swingsetConfig);
+ const {
+ slogfile,
+ vatSnapshotRetention,
+ vatTranscriptRetention,
+ vatSnapshotArchiveDir,
+ vatTranscriptArchiveDir,
+ } = swingsetConfig;
+ const keepSnapshots = vatSnapshotRetention
+ ? vatSnapshotRetention !== 'operational'
+ : ['1', 'true'].includes(XSNAP_KEEP_SNAPSHOTS);
+ const keepTranscripts = vatTranscriptRetention
+ ? vatTranscriptRetention !== 'operational'
+ : false;
+
+ // As a kludge, back-propagate selected configuration into environment variables.
+ // eslint-disable-next-line dot-notation
+ if (slogfile) env['SLOGFILE'] = slogfile;
+
const sendToChainStorage = msg => chainSend(portNums.storage, msg);
// this object is used to store the mailbox state.
const fromBridgeMailbox = data => {
@@ -363,7 +454,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
};
const argv = {
- bootMsg,
+ bootMsg: makeBootMsg(initAction),
};
const getVatConfig = async () => {
const vatHref = await importMetaResolve(
@@ -384,7 +475,6 @@ export default async function main(progname, args, { env, homedir, agcc }) {
serviceName: TELEMETRY_SERVICE_NAME,
});
- const { XSNAP_KEEP_SNAPSHOTS, NODE_HEAP_SNAPSHOTS = -1 } = env;
const slogSender = await makeSlogSender({
stateDir: stateDBDir,
env,
@@ -394,17 +484,14 @@ export default async function main(progname, args, { env, homedir, agcc }) {
const swingStoreTraceFile = processValue.getPath({
envName: 'SWING_STORE_TRACE',
flagName: 'trace-store',
- trueValue: pathResolve(stateDBDir, 'store-trace.log'),
+ trueValue: path.resolve(stateDBDir, 'store-trace.log'),
});
- const keepSnapshots =
- XSNAP_KEEP_SNAPSHOTS === '1' || XSNAP_KEEP_SNAPSHOTS === 'true';
-
const nodeHeapSnapshots = Number.parseInt(NODE_HEAP_SNAPSHOTS, 10);
let lastCommitTime = 0;
let commitCallsSinceLastSnapshot = NaN;
- const snapshotBaseDir = pathResolve(stateDBDir, 'node-heap-snapshots');
+ const snapshotBaseDir = path.resolve(stateDBDir, 'node-heap-snapshots');
if (nodeHeapSnapshots >= 0) {
fs.mkdirSync(snapshotBaseDir, { recursive: true });
@@ -440,7 +527,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
) {
commitCallsSinceLastSnapshot = 0;
heapSnapshot = `Heap-${process.pid}-${Date.now()}.heapsnapshot`;
- const snapshotPath = pathResolve(snapshotBaseDir, heapSnapshot);
+ const snapshotPath = path.resolve(snapshotBaseDir, heapSnapshot);
v8.writeHeapSnapshot(snapshotPath);
heapSnapshotTime = performance.now() - t3;
}
@@ -463,6 +550,14 @@ export default async function main(progname, args, { env, homedir, agcc }) {
}
};
+ const fsPowers = { fs, path, tmp };
+ const archiveSnapshot = vatSnapshotArchiveDir
+ ? makeArchiveSnapshot(vatSnapshotArchiveDir, fsPowers)
+ : undefined;
+ const archiveTranscript = vatTranscriptArchiveDir
+ ? makeArchiveTranscript(vatTranscriptArchiveDir, fsPowers)
+ : undefined;
+
const s = await launch({
actionQueueStorage,
highPriorityQueueStorage,
@@ -481,7 +576,11 @@ export default async function main(progname, args, { env, homedir, agcc }) {
swingStoreExportCallback,
swingStoreTraceFile,
keepSnapshots,
+ keepTranscripts,
+ archiveSnapshot,
+ archiveTranscript,
afterCommitCallback,
+ swingsetConfig,
});
const { blockingSend, shutdown } = s;
@@ -489,21 +588,19 @@ export default async function main(progname, args, { env, homedir, agcc }) {
let pendingBlockingSend = Promise.resolve();
- registerShutdown(async interrupted =>
- Promise.all([
+ registerShutdown(async interrupted => {
+ await Promise.all([
interrupted && pendingBlockingSend.then(shutdown),
discardStateSyncExport(),
- ]).then(() => {}),
- );
+ ]);
+ });
- return async action => {
+ const blockingSendSpy = async action => {
const result = blockingSend(action);
- pendingBlockingSend = Promise.resolve(result).then(
- () => {},
- () => {},
- );
+ pendingBlockingSend = Promise.resolve(result).then(ignore, ignore);
return result;
};
+ return blockingSendSpy;
}
/** @type {Awaited>['blockingSend'] | undefined} */
@@ -534,7 +631,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
);
return performStateSyncImport(options, {
fs: { ...fs, ...fsPromises },
- pathResolve,
+ pathResolve: path.resolve,
log: null,
});
}
@@ -558,7 +655,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
stateSyncExport = exportData;
await new Promise((resolve, reject) => {
- tmpfs.dir(
+ tmp.dir(
{
prefix: `agd-state-sync-${blockHeight}-`,
unsafeCleanup: true,
@@ -658,6 +755,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
!blockingSend || Fail`Swingset already initialized`;
+ // Capture "port numbers" for communicating with cosmos modules.
for (const [key, value] of Object.entries(action)) {
const portAlias = CosmosInitKeyToBridgeId[key];
if (portAlias) {
diff --git a/packages/cosmic-swingset/src/launch-chain.js b/packages/cosmic-swingset/src/launch-chain.js
index 430b531d1cf..ac4ce65dd7d 100644
--- a/packages/cosmic-swingset/src/launch-chain.js
+++ b/packages/cosmic-swingset/src/launch-chain.js
@@ -21,6 +21,7 @@ import {
makeSwingsetController,
loadBasedir,
loadSwingsetConfigFile,
+ upgradeSwingset,
} from '@agoric/swingset-vat';
import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
import { openSwingStore } from '@agoric/swing-store';
@@ -96,7 +97,7 @@ const getHostKey = path => `host.${path}`;
/**
* @param {Map<*, *>} mailboxStorage
- * @param {undefined | ((dstID: string, obj: any) => any)} bridgeOutbound
+ * @param {((dstID: string, obj: any) => any)} bridgeOutbound
* @param {SwingStoreKernelStorage} kernelStorage
* @param {string | (() => string | Promise)} vatconfig absolute path or thunk
* @param {unknown} bootstrapArgs JSON-serializable data
@@ -118,22 +119,21 @@ export async function buildSwingset(
verbose,
profileVats,
debugVats,
+ warehousePolicy,
},
) {
const debugPrefix = debugName === undefined ? '' : `${debugName}:`;
const mbs = buildMailboxStateMap(mailboxStorage);
- const bridgeDevice = bridgeOutbound && buildBridge(bridgeOutbound);
+ const bridgeDevice = buildBridge(bridgeOutbound);
const mailboxDevice = buildMailbox(mbs);
const timerDevice = buildTimer();
const deviceEndowments = {
mailbox: { ...mailboxDevice.endowments },
timer: { ...timerDevice.endowments },
+ bridge: { ...bridgeDevice.endowments },
};
- if (bridgeDevice) {
- deviceEndowments.bridge = { ...bridgeDevice.endowments };
- }
async function ensureSwingsetInitialized() {
if (swingsetIsInitialized(kernelStorage)) {
@@ -175,18 +175,16 @@ export async function buildSwingset(
const bootVat =
swingsetConfig.vats[swingsetConfig.bootstrap || 'bootstrap'];
- if (bridgeOutbound) {
- const batchChainStorage = (method, args) =>
- bridgeOutbound(BRIDGE_ID.STORAGE, { method, args });
+ const batchChainStorage = (method, args) =>
+ bridgeOutbound(BRIDGE_ID.STORAGE, { method, args });
- // Extract data from chain storage as [path, value?] pairs.
- const chainStorageEntries = exportStorage(
- batchChainStorage,
- exportStorageSubtrees,
- clearStorageSubtrees,
- );
- bootVat.parameters = { ...bootVat.parameters, chainStorageEntries };
- }
+ // Extract data from chain storage as [path, value?] pairs.
+ const chainStorageEntries = exportStorage(
+ batchChainStorage,
+ exportStorageSubtrees,
+ clearStorageSubtrees,
+ );
+ bootVat.parameters = { ...bootVat.parameters, chainStorageEntries };
// Since only on-chain swingsets like `agd` have a bridge (and thereby
// `CORE_EVAL` support), things like `ag-solo` will need to do the
@@ -217,7 +215,8 @@ export async function buildSwingset(
return bridgedCoreProposals;
}
- const coreProposals = await ensureSwingsetInitialized();
+ const pendingCoreProposals = await ensureSwingsetInitialized();
+ upgradeSwingset(kernelStorage);
const controller = await makeSwingsetController(
kernelStorage,
deviceEndowments,
@@ -228,6 +227,7 @@ export async function buildSwingset(
verbose,
profileVats,
debugVats,
+ warehousePolicy,
},
);
@@ -235,10 +235,10 @@ export async function buildSwingset(
// (either on bootstrap block (0) or in endBlock).
return {
- coreProposals,
+ coreProposals: pendingCoreProposals,
controller,
mb: mailboxDevice,
- bridgeInbound: bridgeDevice && bridgeDevice.deliverInbound,
+ bridgeInbound: bridgeDevice.deliverInbound,
timer: timerDevice,
};
}
@@ -331,10 +331,33 @@ export async function launch({
swingStoreTraceFile,
swingStoreExportCallback,
keepSnapshots,
+ keepTranscripts,
+ archiveSnapshot,
+ archiveTranscript,
afterCommitCallback = async () => ({}),
+ swingsetConfig,
}) {
console.info('Launching SwingSet kernel');
+ // The swingstore export-data callback gives us export-data records,
+ // which must be written into IAVL by sending them over to the
+ // golang side with swingStoreExportCallback . However, that
+ // callback isn't ready right away, so if e.g. openSwingStore() were
+ // to invoke it, we might lose those records. Likewise
+ // saveOutsideState() gathers the chainSends just before calling
+ // commit, so if the callback were invoked during commit(), those
+ // records would be left for a subsequent block, which would break
+ // consensus if the node crashed before the next commit. So this
+ // `allowExportCallback` flag serves to catch these two cases.
+ //
+ // Note that swingstore is within its rights to call exportCallback
+ // during openSwingStore() or commit(), it just happens to not do so
+ // right now. If that changes under maintenance, this guard should
+ // turn a corruption bug into a crash bug. See
+ // https://github.com/Agoric/agoric-sdk/issues/9655 for details
+
+ let allowExportCallback = false;
+
// The swingStore's exportCallback is synchronous, however we allow the
// callback provided to launch-chain to be asynchronous. The callbacks are
// invoked sequentially like if they were awaited, and the block manager
@@ -345,6 +368,7 @@ export async function launch({
const swingStoreExportSyncCallback =
swingStoreExportCallback &&
(updates => {
+ assert(allowExportCallback, 'export-data callback called at bad time');
pendingSwingStoreExport = swingStoreExportCallbackWithQueue(updates);
});
@@ -352,6 +376,9 @@ export async function launch({
traceFile: swingStoreTraceFile,
exportCallback: swingStoreExportSyncCallback,
keepSnapshots,
+ keepTranscripts,
+ archiveSnapshot,
+ archiveTranscript,
});
const { kvStore, commit } = hostStorage;
@@ -376,6 +403,9 @@ export async function launch({
});
console.debug(`buildSwingset`);
+ const warehousePolicy = {
+ maxVatsOnline: swingsetConfig.maxVatsOnline,
+ };
const {
coreProposals: bootstrapCoreProposals,
controller,
@@ -393,6 +423,7 @@ export async function launch({
debugName,
slogCallbacks,
slogSender,
+ warehousePolicy,
},
);
@@ -472,6 +503,7 @@ export async function launch({
}
async function saveOutsideState(blockHeight) {
+ allowExportCallback = false;
const chainSends = await clearChainSends();
kvStore.set(getHostKey('height'), `${blockHeight}`);
kvStore.set(getHostKey('chainSends'), JSON.stringify(chainSends));
@@ -549,8 +581,15 @@ export async function launch({
let savedBeginHeight = Number(
kvStore.get(getHostKey('beginHeight')) || savedHeight,
);
+ /**
+ * duration of the latest swingset execution in either END_BLOCK or
+ * once-per-chain bootstrap (the latter excluding "bridged" core proposals
+ * that run outside the bootstrap vat)
+ */
let runTime = 0;
+ /** duration of the latest saveChainState(), which commits mailbox data to chain storage */
let chainTime;
+ /** duration of the latest saveOutsideState(), which commits to swing-store host storage */
let saveTime = 0;
let endBlockFinish = 0;
let blockParams;
@@ -705,33 +744,16 @@ export async function launch({
/**
* @template T
- * @param {string} type
+ * @param {string} label
* @param {() => Promise} fn
+ * @param {() => void} onSettled
*/
- async function processAction(type, fn) {
- const start = Date.now();
- const finish = res => {
- // blockManagerConsole.error(
- // 'Action',
- // action.type,
- // action.blockHeight,
- // 'is done!',
- // );
- runTime += Date.now() - start;
- return res;
- };
-
+ function withErrorLogging(label, fn, onSettled) {
const p = fn();
- // Just attach some callbacks, but don't use the resulting neutered result
- // promise.
- void E.when(p, finish, e => {
- // None of these must fail, and if they do, log them verbosely before
- // returning to the chain.
- blockManagerConsole.error(type, 'error:', e);
- finish();
+ void E.when(p, onSettled, err => {
+ blockManagerConsole.error(label, 'error:', err);
+ onSettled();
});
- // Return the original promise so that the caller gets the original
- // resolution or rejection.
return p;
}
@@ -802,8 +824,13 @@ export async function launch({
// Start a block transaction, but without changing state
// for the upcoming begin block check
saveBeginHeight(savedBeginHeight);
- await processAction(action.type, async () =>
- bootstrapBlock(blockHeight, blockTime, bootstrapBlockParams),
+ const start = Date.now();
+ await withErrorLogging(
+ action.type,
+ () => bootstrapBlock(blockHeight, blockTime, bootstrapBlockParams),
+ () => {
+ runTime += Date.now() - start;
+ },
);
} finally {
controller.writeSlogObject({
@@ -891,6 +918,7 @@ export async function launch({
// );
switch (action.type) {
case ActionType.AG_COSMOS_INIT: {
+ allowExportCallback = true; // cleared by saveOutsideState in COMMIT_BLOCK
const { blockHeight, isBootstrap, upgradeDetails } = action;
if (!blockNeedsExecution(blockHeight)) {
@@ -907,17 +935,16 @@ export async function launch({
await doBootstrap(action);
}
- // Merge the core proposals from the bootstrap block with the
- // ones from the upgrade.
+ // Concatenate together any pending core proposals from chain bootstrap
+ // with any from this inbound init action, then execute them all.
const coreProposals = mergeCoreProposals(
bootstrapCoreProposals,
softwareUpgradeCoreProposals,
upgradeInfoCoreProposals,
);
-
if (coreProposals.steps.length) {
- upgradeDetails ||
- isBootstrap ||
+ isBootstrap ||
+ upgradeDetails ||
Fail`Unexpected core proposals outside of consensus start`;
await doCoreProposals(action, coreProposals);
}
@@ -944,9 +971,9 @@ export async function launch({
});
// Save the kernel's computed state just before the chain commits.
- const start2 = Date.now();
+ const start = Date.now();
await saveOutsideState(savedHeight);
- saveTime = Date.now() - start2;
+ saveTime = Date.now() - start;
blockParams = undefined;
@@ -977,6 +1004,7 @@ export async function launch({
}
case ActionType.BEGIN_BLOCK: {
+ allowExportCallback = true; // cleared by saveOutsideState in COMMIT_BLOCK
const { blockHeight, blockTime, params } = action;
blockParams = parseParams(params);
verboseBlocks &&
@@ -1043,14 +1071,19 @@ export async function launch({
provideInstallationPublisher();
- await processAction(action.type, async () =>
- endBlock(blockHeight, blockTime, blockParams),
+ const start = Date.now();
+ await withErrorLogging(
+ action.type,
+ () => endBlock(blockHeight, blockTime, blockParams),
+ () => {
+ runTime += Date.now() - start;
+ },
);
// We write out our on-chain state as a number of chainSends.
- const start = Date.now();
+ const start2 = Date.now();
await saveChainState();
- chainTime = Date.now() - start;
+ chainTime = Date.now() - start2;
// Advance our saved state variables.
savedHeight = blockHeight;
diff --git a/packages/create-dapp/test/sanity.test.js b/packages/create-dapp/test/sanity.test.js
index f4424d58768..4e6395a683a 100644
--- a/packages/create-dapp/test/sanity.test.js
+++ b/packages/create-dapp/test/sanity.test.js
@@ -15,4 +15,5 @@ test('sanity', async t => {
t.is(await myMain(['--help']), 0, '--help exits zero');
t.is(await myMain(['--version']), 0, '--version exits zero');
t.is(await myMain(['--zorgar']), 1, 'unknown flag fails');
+ t.is(await myMain(['demo']), 0, 'create-dapp demo exits 0');
});
diff --git a/packages/deploy-script-support/README.md b/packages/deploy-script-support/README.md
index 3be02f0d117..048cff205fa 100644
--- a/packages/deploy-script-support/README.md
+++ b/packages/deploy-script-support/README.md
@@ -70,8 +70,7 @@ objects.
The script describes how to build the core proposal. For
`agoric-3-proposals` and uploading to the chain, the script must be named in the
-`CoreProposalSteps` section in
-[`app.go`](https://github.com/Agoric/agoric-sdk/blob/b13743a2cccf0cb63a412b54384435596d4e81ea/golang/cosmos/app/app.go#L881),
+`CoreProposalSteps` section in [`upgrade.go`](../../golang/cosmos/app/upgrade.go),
and its `defaultProposalBuilder` will be invoked directly.
Script files should export `defaultProposalBuilder` and a `default` function
diff --git a/packages/deploy-script-support/package.json b/packages/deploy-script-support/package.json
index 3f3f5a6c927..81d37b649b7 100644
--- a/packages/deploy-script-support/package.json
+++ b/packages/deploy-script-support/package.json
@@ -34,7 +34,7 @@
},
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
"dependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/ertp": "^0.16.2",
"@agoric/import-manager": "^0.3.11",
"@agoric/internal": "^0.3.2",
@@ -42,17 +42,17 @@
"@agoric/store": "^0.9.2",
"@agoric/time": "^0.3.2",
"@agoric/zoe": "^0.26.2",
- "@endo/base64": "^1.0.5",
- "@endo/bundle-source": "^3.2.3",
- "@endo/far": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/nat": "^5.0.7",
- "@endo/promise-kit": "^1.1.2",
- "@endo/zip": "^1.0.5"
+ "@endo/base64": "^1.0.7",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/far": "^1.1.5",
+ "@endo/marshal": "^1.5.3",
+ "@endo/nat": "^5.0.10",
+ "@endo/promise-kit": "^1.1.5",
+ "@endo/zip": "^1.0.7"
},
"devDependencies": {
"@agoric/vats": "^0.15.1",
- "@endo/init": "^1.1.2",
+ "@endo/init": "^1.1.4",
"ava": "^5.3.0",
"import-meta-resolve": "^2.2.1"
},
@@ -72,6 +72,6 @@
"access": "public"
},
"typeCoverage": {
- "atLeast": 82.44
+ "atLeast": 82.6
}
}
diff --git a/packages/deployment/package.json b/packages/deployment/package.json
index 818744b2ce0..1e9c88687f7 100644
--- a/packages/deployment/package.json
+++ b/packages/deployment/package.json
@@ -19,15 +19,14 @@
"author": "Agoric",
"license": "Apache-2.0",
"dependencies": {
- "@endo/errors": "^1.2.2",
- "@endo/init": "^1.1.2",
- "@endo/marshal": "^1.5.0",
+ "@endo/errors": "^1.2.5",
+ "@endo/init": "^1.1.4",
+ "@endo/marshal": "^1.5.3",
"better-sqlite3": "^9.1.1",
"chalk": "^5.2.0",
"deterministic-json": "^1.0.5",
"inquirer": "^8.2.2",
"minimist": "^1.2.0",
- "node-fetch": "^2.6.0",
"temp": "^0.9.0"
},
"publishConfig": {
diff --git a/packages/deployment/src/entrypoint.js b/packages/deployment/src/entrypoint.js
index 2df1b243c84..c5ab08dfd4d 100755
--- a/packages/deployment/src/entrypoint.js
+++ b/packages/deployment/src/entrypoint.js
@@ -1,5 +1,5 @@
#! /usr/bin/env node
-/* global setInterval */
+/* eslint-env node */
import '@endo/init';
@@ -9,7 +9,6 @@ import temp from 'temp';
import process from 'process';
import { exec, spawn } from 'child_process';
import inquirer from 'inquirer';
-import fetch from 'node-fetch';
import { running } from './run.js';
import { setup } from './setup.js';
@@ -22,7 +21,7 @@ deploy(process.argv[1], process.argv.splice(2), {
rd: files.reading(fs, path),
wr: files.writing(fs, path, temp),
setup: setup({ resolve: path.resolve, env: process.env, setInterval }),
- running: running(process, { exec, process, spawn }),
+ running: running(process, { exec, spawn }),
inquirer,
fetch,
}).then(
diff --git a/packages/eslint-config/eslint-config.cjs b/packages/eslint-config/eslint-config.cjs
index ade8bf3c55c..eb184802d50 100644
--- a/packages/eslint-config/eslint-config.cjs
+++ b/packages/eslint-config/eslint-config.cjs
@@ -107,11 +107,19 @@ module.exports = {
'no-unused-vars': 'off',
},
},
+ {
+ // Zoe contract module
+ files: ['**/*.contract.js'],
+ rules: {
+ '@endo/harden-exports': 'error',
+ },
+ },
{
// Orchestration flows
files: ['**/*.flows.js'],
rules: {
'no-restricted-syntax': ['error', ...orchestrationFlowRestrictions],
+ '@endo/harden-exports': 'error',
},
},
],
diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json
index 58e20dc2d11..90485c9ce1f 100644
--- a/packages/eslint-config/package.json
+++ b/packages/eslint-config/package.json
@@ -25,7 +25,7 @@
"eslint-config.*"
],
"peerDependencies": {
- "@endo/eslint-plugin": "^2.1.3",
+ "@endo/eslint-plugin": "^2.2.1",
"@jessie.js/eslint-plugin": "^0.4.1",
"typescript-eslint": "^7.13.1",
"eslint": "^8.57.0",
diff --git a/packages/governance/package.json b/packages/governance/package.json
index 0a2bed98035..e7cc46d9e4b 100644
--- a/packages/governance/package.json
+++ b/packages/governance/package.json
@@ -11,7 +11,7 @@
"build": "yarn build:bundles",
"build:bundles": "node ./scripts/build-bundles.js",
"prepack": "tsc --build tsconfig.build.json",
- "postpack": "git clean -f '*.d.ts*'",
+ "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
"test": "ava",
"test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
"test:xs": "exit 0",
@@ -31,7 +31,7 @@
},
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
"dependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/ertp": "^0.16.2",
"@agoric/internal": "^0.3.2",
"@agoric/notifier": "^0.6.2",
@@ -39,19 +39,19 @@
"@agoric/time": "^0.3.2",
"@agoric/vat-data": "^0.5.2",
"@agoric/zoe": "^0.26.2",
- "@endo/bundle-source": "^3.2.3",
- "@endo/captp": "^4.2.0",
- "@endo/eventual-send": "^1.2.2",
- "@endo/far": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/nat": "^5.0.7",
- "@endo/promise-kit": "^1.1.2",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/captp": "^4.3.0",
+ "@endo/eventual-send": "^1.2.5",
+ "@endo/far": "^1.1.5",
+ "@endo/marshal": "^1.5.3",
+ "@endo/nat": "^5.0.10",
+ "@endo/promise-kit": "^1.1.5",
"import-meta-resolve": "^2.2.1"
},
"devDependencies": {
"@agoric/swingset-vat": "^0.32.2",
- "@endo/bundle-source": "^3.2.3",
- "@endo/init": "^1.1.2",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/init": "^1.1.4",
"ava": "^5.3.0",
"c8": "^9.1.0"
},
diff --git a/packages/governance/src/contractGovernance/typedParamManager.js b/packages/governance/src/contractGovernance/typedParamManager.js
index cc6f82e732c..ecd80d844f4 100644
--- a/packages/governance/src/contractGovernance/typedParamManager.js
+++ b/packages/governance/src/contractGovernance/typedParamManager.js
@@ -141,6 +141,7 @@ harden(makeParamManagerSync);
* @param {ZCF>} zcf
* @param {I} invitations invitation objects, which must come from privateArgs
* @param {M} paramTypesMap
+ * @param {object} [overrides]
* @returns {TypedParamManager}
*/
export const makeParamManagerFromTerms = (
@@ -148,17 +149,23 @@ export const makeParamManagerFromTerms = (
zcf,
invitations,
paramTypesMap,
+ overrides,
) => {
+ if (overrides) {
+ console.log('TPM ', { overrides });
+ }
+
const { governedParams } = zcf.getTerms();
- /** @type {Array<[Keyword, SyncSpecTuple | AsyncSpecTuple]>} */
+ /** @type {Array<[Keyword, (SyncSpecTuple | AsyncSpecTuple)]>} */
const makerSpecEntries = Object.entries(paramTypesMap).map(
- ([paramKey, paramType]) => [
- paramKey,
- /** @type {SyncSpecTuple} */ ([
- paramType,
- governedParams[paramKey].value,
- ]),
- ],
+ ([paramKey, paramType]) => {
+ const value =
+ overrides && overrides[paramKey]
+ ? overrides[paramKey]
+ : governedParams[paramKey].value;
+
+ return [paramKey, /** @type {SyncSpecTuple} */ ([paramType, value])];
+ },
);
// Every governed contract has an Electorate param that starts as `initialPoserInvitation` private arg
for (const [name, invitation] of Object.entries(invitations)) {
diff --git a/packages/governance/test/unitTests/typedParamManager.test.js b/packages/governance/test/unitTests/typedParamManager.test.js
index a4ef53487db..fcc4255bdbb 100644
--- a/packages/governance/test/unitTests/typedParamManager.test.js
+++ b/packages/governance/test/unitTests/typedParamManager.test.js
@@ -361,3 +361,27 @@ test('Unknown', async t => {
await paramManager.updateParams({ Surprise: ['gift', 'party'] });
t.deepEqual(paramManager.getSurprise(), ['gift', 'party']);
});
+
+test('makeParamManagerFromTerms overrides', async t => {
+ const terms = harden({
+ governedParams: {
+ Mmr: { type: 'nat', value: makeRatio(150n, drachmaKit.brand) },
+ },
+ });
+ const issuerKeywordRecord = harden({
+ Ignore: drachmaKit.issuer,
+ });
+ const { zcf } = await setupZCFTest(issuerKeywordRecord, terms);
+
+ const paramManager = await makeParamManagerFromTerms(
+ makeStoredPublisherKit(),
+ // @ts-expect-error missing governance terms
+ zcf,
+ { Electorate: zcf.makeInvitation(() => null, 'mock poser invitation') },
+ {
+ Mmr: 'ratio',
+ },
+ { Mmr: makeRatio(100n, drachmaKit.brand) },
+ );
+ t.deepEqual(paramManager.getMmr().numerator.value, 100n);
+});
diff --git a/packages/inter-protocol/package.json b/packages/inter-protocol/package.json
index 5ff3f8f43ef..59f4140da00 100644
--- a/packages/inter-protocol/package.json
+++ b/packages/inter-protocol/package.json
@@ -11,7 +11,7 @@
"build": "yarn build:bundles",
"build:bundles": "node ./scripts/build-bundles.js",
"prepack": "tsc --build tsconfig.build.json",
- "postpack": "git clean -f '*.d.ts*'",
+ "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
"test": "ava",
"test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
"test:xs": "exit 0",
@@ -31,7 +31,7 @@
},
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
"dependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/ertp": "^0.16.2",
"@agoric/governance": "^0.10.3",
"@agoric/internal": "^0.3.2",
@@ -41,12 +41,12 @@
"@agoric/vat-data": "^0.5.2",
"@agoric/vats": "^0.15.1",
"@agoric/zoe": "^0.26.2",
- "@endo/captp": "^4.2.0",
- "@endo/eventual-send": "^1.2.2",
- "@endo/far": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/nat": "^5.0.7",
- "@endo/promise-kit": "^1.1.2",
+ "@endo/captp": "^4.3.0",
+ "@endo/eventual-send": "^1.2.5",
+ "@endo/far": "^1.1.5",
+ "@endo/marshal": "^1.5.3",
+ "@endo/nat": "^5.0.10",
+ "@endo/promise-kit": "^1.1.5",
"jessie.js": "^0.3.4"
},
"devDependencies": {
@@ -54,9 +54,9 @@
"@agoric/swingset-liveslots": "^0.10.2",
"@agoric/swingset-vat": "^0.32.2",
"@agoric/zone": "^0.2.2",
- "@endo/bundle-source": "^3.2.3",
- "@endo/init": "^1.1.2",
- "@endo/promise-kit": "^1.1.2",
+ "@endo/bundle-source": "^3.4.0",
+ "@endo/init": "^1.1.4",
+ "@endo/promise-kit": "^1.1.5",
"@fast-check/ava": "^1.1.5",
"ava": "^5.3.0",
"c8": "^9.1.0",
@@ -82,6 +82,6 @@
"access": "public"
},
"typeCoverage": {
- "atLeast": 95.81
+ "atLeast": 95.8
}
}
diff --git a/packages/inter-protocol/src/auction/auctionBook.js b/packages/inter-protocol/src/auction/auctionBook.js
index 11b0da04228..d5536768e8a 100644
--- a/packages/inter-protocol/src/auction/auctionBook.js
+++ b/packages/inter-protocol/src/auction/auctionBook.js
@@ -10,9 +10,7 @@ import { M, prepareExoClassKit } from '@agoric/vat-data';
import { assertAllDefined, makeTracer } from '@agoric/internal';
import {
- atomicRearrange,
ceilMultiplyBy,
- floorDivideBy,
makeRatioFromAmounts,
makeRecorderTopic,
multiplyRatios,
@@ -21,6 +19,7 @@ import {
import { observeNotifier } from '@agoric/notifier';
import { makeNatAmountShape } from '../contractSupport.js';
+import { amountsToSettle } from './auctionMath.js';
import { preparePriceBook, prepareScaledBidBook } from './offerBook.js';
import {
isScaledBidPriceHigher,
@@ -282,46 +281,36 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
return makeEmpty(collateralBrand);
}
- /** @type {Amount<'nat'>} */
- const initialCollateralTarget = AmountMath.min(
- collateralWanted,
- collateralAvailable,
- );
-
const { curAuctionPrice, bidHoldingSeat, remainingProceedsGoal } =
this.state;
curAuctionPrice !== null ||
Fail`auctionPrice must be set before each round`;
assert(curAuctionPrice);
- const proceedsNeeded = ceilMultiplyBy(
- initialCollateralTarget,
- curAuctionPrice,
- );
- if (AmountMath.isEmpty(proceedsNeeded)) {
+ const { proceedsExpected, proceedsTarget, collateralTarget } =
+ amountsToSettle(
+ {
+ bidAlloc,
+ collateralWanted,
+ collateralAvailable,
+ curAuctionPrice,
+ remainingProceedsGoal,
+ },
+ trace,
+ );
+
+ if (proceedsExpected === null) {
seat.fail(Error('price fell to zero'));
return makeEmpty(collateralBrand);
}
- const minProceedsTarget = AmountMath.min(proceedsNeeded, bidAlloc);
- const proceedsLimit = remainingProceedsGoal
- ? AmountMath.min(remainingProceedsGoal, minProceedsTarget)
- : minProceedsTarget;
- const isRaiseLimited =
- remainingProceedsGoal ||
- !AmountMath.isGTE(proceedsLimit, proceedsNeeded);
-
- const [proceedsTarget, collateralTarget] = isRaiseLimited
- ? [proceedsLimit, floorDivideBy(proceedsLimit, curAuctionPrice)]
- : [minProceedsTarget, initialCollateralTarget];
-
+ // check that the requested amount could be satisfied
const { Collateral } = seat.getProposal().want;
if (Collateral && AmountMath.isGTE(Collateral, collateralTarget)) {
seat.exit('unable to satisfy want');
}
- atomicRearrange(
- zcf,
+ zcf.atomicRearrange(
harden([
[collateralSeat, seat, { Collateral: collateralTarget }],
[seat, bidHoldingSeat, { Bid: proceedsTarget }],
@@ -335,7 +324,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
);
}
- trace('settle', {
+ trace('settled', {
collateralTarget,
proceedsTarget,
remainingProceedsGoal: this.state.remainingProceedsGoal,
@@ -578,8 +567,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
state.startProceedsGoal = nextProceedsGoal;
}
- atomicRearrange(
- zcf,
+ zcf.atomicRearrange(
harden([[sourceSeat, collateralSeat, { Collateral: assetAmount }]]),
);
@@ -611,20 +599,14 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
const pricedOffers = priceBook.offersAbove(curAuctionPrice);
const scaledBidOffers = scaledBidBook.offersAbove(reduction);
- const compareValues = (v1, v2) => {
- if (v1 < v2) {
- return -1;
- } else if (v1 === v2) {
- return 0;
- } else {
- return 1;
- }
- };
- trace(`settling`, pricedOffers.length, scaledBidOffers.length);
// requested price or BidScaling gives no priority beyond specifying which
// round the order will be serviced in.
const prioritizedOffers = [...pricedOffers, ...scaledBidOffers].sort(
- (a, b) => compareValues(a[1].seqNum, b[1].seqNum),
+ (a, b) => Number(a[1].seqNum - b[1].seqNum),
+ );
+
+ trace(
+ `settling ${prioritizedOffers.length} offers at ${curAuctionPrice} (priced ${pricedOffers.length}, scaled ${scaledBidOffers.length}) `,
);
const { remainingProceedsGoal } = state;
diff --git a/packages/inter-protocol/src/auction/auctionMath.js b/packages/inter-protocol/src/auction/auctionMath.js
new file mode 100644
index 00000000000..33a7875c1a7
--- /dev/null
+++ b/packages/inter-protocol/src/auction/auctionMath.js
@@ -0,0 +1,81 @@
+import { AmountMath } from '@agoric/ertp';
+import {
+ ceilMultiplyBy,
+ floorDivideBy,
+} from '@agoric/zoe/src/contractSupport/index.js';
+
+/**
+ * @import {Amount} from '@agoric/ertp/src/types.js';
+ */
+
+/**
+ * @param {object} p
+ * @param {Amount<'nat'>} p.bidAlloc current allocation of the bidding seat
+ * @param {Amount<'nat'>} p.collateralWanted want of the offer
+ * @param {Amount<'nat'>} p.collateralAvailable available to auction
+ * @param {Ratio} p.curAuctionPrice current auction price
+ * @param {Amount<'nat'> | null} p.remainingProceedsGoal amount still needing
+ * liquidating over multiple rounds; null indicates no limit
+ * @param {(...msgs: any[]) => void} [log]
+ */
+export const amountsToSettle = (
+ {
+ bidAlloc,
+ collateralWanted,
+ collateralAvailable,
+ curAuctionPrice,
+ remainingProceedsGoal,
+ },
+ log = () => {},
+) => {
+ log('amountsToSettle', {
+ bidAlloc,
+ collateralWanted,
+ collateralAvailable,
+ curAuctionPrice,
+ remainingProceedsGoal,
+ });
+ const initialCollateralTarget = AmountMath.min(
+ collateralWanted,
+ collateralAvailable,
+ );
+
+ const proceedsExpected = ceilMultiplyBy(
+ initialCollateralTarget,
+ curAuctionPrice,
+ );
+ if (AmountMath.isEmpty(proceedsExpected)) {
+ return { proceedsExpected: null };
+ }
+
+ const targetByProceeds = proceedsLimit =>
+ AmountMath.min(
+ collateralAvailable,
+ floorDivideBy(proceedsLimit, curAuctionPrice),
+ );
+
+ const [proceedsTarget, collateralTarget] = (() => {
+ // proceeds cannot exceed what is needed or being offered
+ const proceedsBidded = AmountMath.min(proceedsExpected, bidAlloc);
+ if (remainingProceedsGoal) {
+ const goalProceeds = AmountMath.min(
+ remainingProceedsGoal,
+ proceedsBidded,
+ );
+ return [goalProceeds, targetByProceeds(goalProceeds)];
+ } else if (AmountMath.isGTE(proceedsBidded, proceedsExpected)) {
+ // initial collateral suffices
+ return [proceedsBidded, initialCollateralTarget];
+ } else {
+ return [proceedsBidded, targetByProceeds(proceedsBidded)];
+ }
+ })();
+
+ assert(
+ AmountMath.isGTE(collateralAvailable, collateralTarget),
+ 'target cannot exceed available',
+ );
+
+ return { proceedsExpected, proceedsTarget, collateralTarget };
+};
+harden(amountsToSettle);
diff --git a/packages/inter-protocol/src/auction/auctioneer.js b/packages/inter-protocol/src/auction/auctioneer.js
index 3b475137f5c..1eed4c9d48a 100644
--- a/packages/inter-protocol/src/auction/auctioneer.js
+++ b/packages/inter-protocol/src/auction/auctioneer.js
@@ -12,7 +12,6 @@ import { mustMatch } from '@agoric/store';
import { appendToStoredArray } from '@agoric/store/src/stores/store-utils.js';
import { M, provideDurableMapStore } from '@agoric/vat-data';
import {
- atomicRearrange,
ceilDivideBy,
ceilMultiplyBy,
defineERecorderKit,
@@ -490,8 +489,7 @@ export const start = async (zcf, privateArgs, baggage) => {
// send it all to the one
const liqSeat = depositsForBrand[0].seat;
- atomicRearrange(
- zcf,
+ zcf.atomicRearrange(
harden([
[collateralSeat, liqSeat, collateralSeat.getCurrentAllocation()],
[bidHoldingSeat, liqSeat, bidHoldingSeat.getCurrentAllocation()],
@@ -514,7 +512,7 @@ export const start = async (zcf, privateArgs, baggage) => {
reserveSeat,
brand,
);
- atomicRearrange(zcf, harden(transfers));
+ zcf.atomicRearrange(harden(transfers));
for (const { seat } of depositsForBrand) {
seat.exit();
diff --git a/packages/inter-protocol/src/contractSupport.js b/packages/inter-protocol/src/contractSupport.js
index bc1941561a0..119f819fc89 100644
--- a/packages/inter-protocol/src/contractSupport.js
+++ b/packages/inter-protocol/src/contractSupport.js
@@ -67,8 +67,13 @@ export const allEmpty = amounts => {
* @param {Amount<'nat'>} totalDebt
* @param {Amount<'nat'>} toMint
* @throws if minting would exceed total debt
+ *
+ * Note: Succeeds regardless of debtLimit if toMint is empty.
*/
export const checkDebtLimit = (debtLimit, totalDebt, toMint) => {
+ if (AmountMath.isEmpty(toMint)) {
+ return;
+ }
const debtPost = AmountMath.add(totalDebt, toMint);
AmountMath.isGTE(debtLimit, debtPost) ||
Fail`Minting ${q(toMint)} past ${q(
diff --git a/packages/inter-protocol/src/interest.js b/packages/inter-protocol/src/interest.js
index 688c4e67d2d..7faf77615df 100644
--- a/packages/inter-protocol/src/interest.js
+++ b/packages/inter-protocol/src/interest.js
@@ -197,7 +197,7 @@ export const chargeInterest = (powers, params, prior, accruedUntil) => {
}
// NB: This method of inferring the compounded rate from the ratio of debts
- // acrrued suffers slightly from the integer nature of debts. However in
+ // accrued suffers slightly from the integer nature of debts. However in
// testing with small numbers there's 5 digits of precision, and with large
// numbers the ratios tend towards ample precision.
// TODO adopt banker's rounding https://github.com/Agoric/agoric-sdk/issues/4573
diff --git a/packages/inter-protocol/src/proposals/add-auction.js b/packages/inter-protocol/src/proposals/add-auction.js
index 38657e53ef2..ca5bb004759 100644
--- a/packages/inter-protocol/src/proposals/add-auction.js
+++ b/packages/inter-protocol/src/proposals/add-auction.js
@@ -6,35 +6,59 @@ import { makeGovernedTerms as makeGovernedATerms } from '../auction/params.js';
const trace = makeTracer('NewAuction', true);
-/** @param {import('./econ-behaviors.js').EconomyBootstrapPowers} powers */
-export const addAuction = async ({
- consume: {
- zoe,
- board,
- chainTimerService,
- priceAuthority,
- chainStorage,
- economicCommitteeCreatorFacet: electorateCreatorFacet,
- auctioneerKit: legacyKitP,
- },
- produce: { newAuctioneerKit },
- instance: {
- consume: { reserve: reserveInstance },
- },
- installation: {
+/**
+ * @typedef {PromiseSpaceOf<{
+ * auctionUpgradeNewInstance: Instance;
+ * }>} interlockPowers
+ */
+
+/**
+ * @param {import('./econ-behaviors.js').EconomyBootstrapPowers &
+ * interlockPowers} powers
+ * @param {{ options: { auctionsRef: { bundleID: string } } }} options
+ */
+export const addAuction = async (
+ {
consume: {
- auctioneer: auctionInstallation,
- contractGovernor: contractGovernorInstallation,
+ agoricNamesAdmin,
+ auctioneerKit: legacyKitP,
+ board,
+ chainStorage,
+ chainTimerService,
+ economicCommitteeCreatorFacet: electorateCreatorFacet,
+ econCharterKit,
+ priceAuthority,
+ zoe,
+ },
+ produce: { auctioneerKit: produceAuctioneerKit, auctionUpgradeNewInstance },
+ instance: {
+ consume: { reserve: reserveInstance },
+ produce: { auctioneer: auctionInstance },
+ },
+ installation: {
+ consume: { contractGovernor: contractGovernorInstallation },
+ produce: { auctioneer: produceInstallation },
+ },
+ issuer: {
+ consume: { [Stable.symbol]: stableIssuerP },
},
},
- issuer: {
- consume: { [Stable.symbol]: stableIssuerP },
- },
-}) => {
- trace('addAuction start');
+ { options },
+) => {
+ trace('addAuction start', options);
const STORAGE_PATH = 'auction';
+ const { auctionsRef } = options;
const poserInvitationP = E(electorateCreatorFacet).getPoserInvitation();
+ const bundleID = auctionsRef.bundleID;
+ /**
+ * @type {Promise<
+ * Installation
+ * >}
+ */
+ const installationP = E(zoe).installBundleID(bundleID);
+ produceInstallation.reset();
+ produceInstallation.resolve(installationP);
const [
initialPoserInvitation,
@@ -80,10 +104,12 @@ export const addAuction = async ({
},
);
+ const installation = await installationP;
+
const governorTerms = await deeplyFulfilledObject(
harden({
timer: chainTimerService,
- governedContractInstallation: auctionInstallation,
+ governedContractInstallation: installation,
governed: {
terms: auctionTerms,
issuerKeywordRecord: { Bid: stableIssuer },
@@ -94,7 +120,7 @@ export const addAuction = async ({
}),
);
- /** @type {GovernorStartedInstallationKit} */
+ /** @type {GovernorStartedInstallationKit} */
const governorStartResult = await E(zoe).startInstance(
contractGovernorInstallation,
undefined,
@@ -128,45 +154,65 @@ export const addAuction = async ({
),
);
- newAuctioneerKit.resolve(
- harden({
- label: 'auctioneer',
- creatorFacet: governedCreatorFacet,
- adminFacet: governorStartResult.adminFacet,
- publicFacet: governedPublicFacet,
- instance: governedInstance,
-
- governor: governorStartResult.instance,
- governorCreatorFacet: governorStartResult.creatorFacet,
- governorAdminFacet: governorStartResult.adminFacet,
- }),
+ const kit = harden({
+ label: 'auctioneer',
+ creatorFacet: governedCreatorFacet,
+ adminFacet: governorStartResult.adminFacet,
+ publicFacet: governedPublicFacet,
+ instance: governedInstance,
+
+ governor: governorStartResult.instance,
+ governorCreatorFacet: governorStartResult.creatorFacet,
+ governorAdminFacet: governorStartResult.adminFacet,
+ });
+ produceAuctioneerKit.reset();
+ produceAuctioneerKit.resolve(kit);
+
+ // introduce economic committee charter to new auctioneer
+ // cf addGovernorsToEconCharter() in committee-proposal.js
+ await E(E.get(econCharterKit).creatorFacet).addInstance(
+ kit.instance,
+ kit.governorCreatorFacet,
+ kit.label,
+ );
+
+ auctionInstance.reset();
+ await auctionInstance.resolve(governedInstance);
+ // belt and suspenders; the above is supposed to also do this
+ await E(E(agoricNamesAdmin).lookupAdmin('instance')).update(
+ 'auctioneer',
+ governedInstance,
);
- // don't overwrite auctioneerKit or auction instance yet. Wait until
- // upgrade-vault.js
+
+ auctionUpgradeNewInstance.resolve(governedInstance);
};
export const ADD_AUCTION_MANIFEST = harden({
[addAuction.name]: {
consume: {
- zoe: true,
+ agoricNamesAdmin: true,
+ auctioneerKit: true,
board: true,
- chainTimerService: true,
- priceAuthority: true,
chainStorage: true,
+ chainTimerService: true,
+ econCharterKit: true,
economicCommitteeCreatorFacet: true,
- auctioneerKit: true,
+ priceAuthority: true,
+ zoe: true,
},
produce: {
- newAuctioneerKit: true,
+ auctioneerKit: true,
+ auctionUpgradeNewInstance: true,
},
instance: {
consume: { reserve: true },
+ produce: { auctioneer: true },
},
installation: {
consume: {
- auctioneer: true,
contractGovernor: true,
},
+ produce: { auctioneer: true },
},
issuer: {
consume: { [Stable.symbol]: true },
@@ -174,7 +220,15 @@ export const ADD_AUCTION_MANIFEST = harden({
},
});
-/* Add a new auction to a chain that already has one. */
-export const getManifestForAddAuction = async () => {
- return { manifest: ADD_AUCTION_MANIFEST };
+/**
+ * Add a new auction to a chain that already has one.
+ *
+ * @param {object} _ign
+ * @param {any} addAuctionOptions
+ */
+export const getManifestForAddAuction = async (_ign, addAuctionOptions) => {
+ return {
+ manifest: ADD_AUCTION_MANIFEST,
+ options: addAuctionOptions,
+ };
};
diff --git a/packages/inter-protocol/src/proposals/startPSM.js b/packages/inter-protocol/src/proposals/startPSM.js
index 8a6e0bd5daa..9c00cdcf9d9 100644
--- a/packages/inter-protocol/src/proposals/startPSM.js
+++ b/packages/inter-protocol/src/proposals/startPSM.js
@@ -347,18 +347,22 @@ export const makeAnchorAsset = async (
}),
);
- const { creatorFacet: mint, publicFacet: issuer } = /**
- * @type {{
+ /**
+ * @typedef {{
* creatorFacet: ERef>;
* publicFacet: ERef>;
- * }}
- */ (
- await E(startUpgradable)({
- installation: mintHolder,
- label: keyword,
- terms,
- })
- );
+ * }} PsmKit
+ */
+
+ const { creatorFacet: mint, publicFacet: issuer } =
+ /** @type {PsmKit} */
+ (
+ await E(startUpgradable)({
+ installation: mintHolder,
+ label: keyword,
+ terms,
+ })
+ );
const brand = await E(issuer).getBrand();
const kit = harden({ mint, issuer, brand });
diff --git a/packages/inter-protocol/src/proposals/upgrade-vaults.js b/packages/inter-protocol/src/proposals/upgrade-vaults.js
index 7c8547bf2c6..2088aac9e67 100644
--- a/packages/inter-protocol/src/proposals/upgrade-vaults.js
+++ b/packages/inter-protocol/src/proposals/upgrade-vaults.js
@@ -2,63 +2,47 @@ import { E } from '@endo/far';
import { makeNotifierFromAsyncIterable } from '@agoric/notifier';
import { AmountMath } from '@agoric/ertp/src/index.js';
import { makeTracer } from '@agoric/internal/src/index.js';
-import { isUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
+import { Fail } from '@endo/errors';
+import { TimeMath } from '@agoric/time';
const trace = makeTracer('upgrade Vaults proposal');
-// stand-in for Promise.any() which isn't available at this point.
-/** @param {Promise[]} promises */
-const any = promises =>
- new Promise((resolve, reject) => {
- for (const promise of promises) {
- void promise.then(resolve, () => {});
- }
- void Promise.allSettled(promises).then(results => {
- const rejects = /** @type {PromiseRejectedResult[]} */ (
- results.filter(({ status }) => status === 'rejected')
- );
- if (rejects.length === results.length) {
- const messages = rejects.map(
- ({ reason: { message } }) => message || 'no error message',
- );
- const aggregate = new Error(messages.join(';'));
- /** @type {any} */ (aggregate).errors = rejects.map(
- ({ reason }) => reason,
- );
- reject(aggregate);
- }
- });
- });
+/**
+ * @typedef {PromiseSpaceOf<{
+ * auctionUpgradeNewInstance: Instance;
+ * }>} interlockPowers
+ */
/**
- * @param {import('../../src/proposals/econ-behaviors').EconomyBootstrapPowers} powers
+ * @param {import('../../src/proposals/econ-behaviors').EconomyBootstrapPowers &
+ * interlockPowers} powers
* @param {{ options: { vaultsRef: { bundleID: string } } }} options
*/
-export const upgradeVaults = async (powers, { options }) => {
- const {
+export const upgradeVaults = async (
+ {
consume: {
- agoricNamesAdmin,
- newAuctioneerKit: auctioneerKitP,
- priceAuthority,
- vaultFactoryKit,
- zoe,
+ auctionUpgradeNewInstance,
+ chainTimerService,
economicCommitteeCreatorFacet: electorateCreatorFacet,
reserveKit,
+ vaultFactoryKit,
+ zoe,
},
- produce: {
- auctioneerKit: auctioneerKitProducer,
- newAuctioneerKit: tempAuctioneerKit,
+ produce: { auctionUpgradeNewInstance: auctionUpgradeNewInstanceProducer },
+ installation: {
+ produce: { VaultFactory: produceVaultInstallation },
},
instance: {
- produce: { auctioneer: auctioneerProducer },
+ consume: { auctioneer: auctioneerInstanceP },
},
- } = powers;
+ },
+ { options },
+) => {
const { vaultsRef } = options;
const kit = await vaultFactoryKit;
- const auctioneerKit = await auctioneerKitP;
const { instance: directorInstance } = kit;
const allBrands = await E(zoe).getBrands(directorInstance);
- const { Minted: istBrand, ...vaultBrands } = allBrands;
+ const { Minted: _istBrand, ...vaultBrands } = allBrands;
const bundleID = vaultsRef.bundleID;
console.log(`upgradeVaults: bundleId`, bundleID);
@@ -67,23 +51,50 @@ export const upgradeVaults = async (powers, { options }) => {
* Installation
* >}
*/
- let installationP;
- await null;
- if (vaultsRef) {
- if (bundleID) {
- installationP = E(zoe).installBundleID(bundleID);
- await E.when(
- installationP,
- installation =>
- E(E(agoricNamesAdmin).lookupAdmin('installation')).update(
- 'vaultFactory',
- installation,
- ),
- err =>
- console.error(`🚨 failed to update vaultFactory installation`, err),
+ const installationP = E(zoe).installBundleID(bundleID);
+ produceVaultInstallation.reset();
+ produceVaultInstallation.resolve(installationP);
+
+ const [auctionOldInstance, auctionNewInstance] = await Promise.all([
+ auctioneerInstanceP,
+ auctionUpgradeNewInstance,
+ ]);
+ auctionOldInstance !== auctionNewInstance ||
+ Fail`Auction instance didn't change`;
+ auctionUpgradeNewInstanceProducer.reset();
+ const publicFacet = E(zoe).getPublicFacet(auctionNewInstance);
+ /** @type {import('@agoric/inter-protocol/src/auction/scheduler.js').FullSchedule} */
+ const schedules = await E(publicFacet).getSchedules();
+ const now = await E(chainTimerService).getCurrentTimestamp();
+ (schedules.nextAuctionSchedule &&
+ TimeMath.compareAbs(schedules.nextAuctionSchedule.startTime, now) > 0) ||
+ Fail`Expected next start time in the future ${schedules.nextAuctionSchedule?.startTime}`;
+
+ const readCurrentDirectorParams = async () => {
+ const { publicFacet: directorPF } = kit;
+
+ await null;
+
+ const subscription = E(directorPF).getElectorateSubscription();
+ const notifier = makeNotifierFromAsyncIterable(subscription);
+ let { value, updateCount } = await notifier.getUpdateSince(0n);
+ // @ts-expect-error It's an amount.
+ while (AmountMath.isEmpty(value.current.MinInitialDebt.value)) {
+ ({ value, updateCount } = await notifier.getUpdateSince(updateCount));
+ trace(
+ `minInitialDebt was empty, retried`,
+ value.current.MinInitialDebt.value,
);
}
- }
+
+ return harden({
+ MinInitialDebt: value.current.MinInitialDebt.value,
+ ReferencedUI: value.current.ReferencedUI.value,
+ RecordingPeriod: value.current.RecordingPeriod.value,
+ ChargingPeriod: value.current.ChargingPeriod.value,
+ });
+ };
+ const directorParamOverrides = await readCurrentDirectorParams();
const readManagerParams = async () => {
const { publicFacet: directorPF } = kit;
@@ -99,9 +110,17 @@ export const upgradeVaults = async (powers, { options }) => {
const notifier = makeNotifierFromAsyncIterable(subscription);
let { value, updateCount } = await notifier.getUpdateSince(0n);
// @ts-expect-error It's an amount.
- while (AmountMath.isEmpty(value.current.DebtLimit.value)) {
+ if (AmountMath.isEmpty(value.current.DebtLimit.value)) {
+ // The parameters might have been empty at start, and the notifier might
+ // give the first state before the current state.
+ trace(`debtLimit was empty, retrying`, value.current.DebtLimit.value);
({ value, updateCount } = await notifier.getUpdateSince(updateCount));
- trace(`debtLimit was empty, retried`, value.current.DebtLimit.value);
+
+ // @ts-expect-error It's an amount.
+ if (AmountMath.isEmpty(value.current.DebtLimit.value)) {
+ trace('debtLimit was empty after retrying');
+ throw Error('🚨Governed parameters empty after retry, Giving up');
+ }
}
trace(kwd, 'params at', updateCount, 'are', value.current);
params[kwd] = harden({
@@ -130,14 +149,15 @@ export const upgradeVaults = async (powers, { options }) => {
const poserInvitation = await E(
electorateCreatorFacet,
).getPoserInvitation();
+
/** @type {import('../../src/vaultFactory/vaultFactory').VaultFactoryContract['privateArgs']} */
const newPrivateArgs = harden({
...privateArgs,
- // @ts-expect-error It has a value until reset after the upgrade
- auctioneerInstance: auctioneerKit.instance,
+ auctioneerInstance: auctionNewInstance,
initialPoserInvitation: poserInvitation,
initialShortfallInvitation: shortfallInvitation,
managerParams: managerParamValues,
+ directorParamOverrides,
});
const upgradeResult = await E(kit.adminFacet).upgradeContract(
@@ -148,60 +168,22 @@ export const upgradeVaults = async (powers, { options }) => {
trace('upgraded vaultFactory.', upgradeResult);
};
- // Wait for at least one new price feed to be ready before upgrading Vaults
- void E.when(
- any(
- Object.values(vaultBrands).map(async brand => {
- const getQuote = async lastRejectionReason => {
- await null;
- try {
- return await E(priceAuthority).quoteGiven(
- AmountMath.make(brand, 10n),
- istBrand,
- );
- } catch (reason) {
- if (
- isUpgradeDisconnection(reason) &&
- (!lastRejectionReason ||
- reason.incarnationNumber >
- lastRejectionReason.incarnationNumber)
- ) {
- return getQuote(reason);
- }
- throw reason;
- }
- };
- return getQuote(null);
- }),
- ),
- async price => {
- trace(`upgrading after delay`, price);
- await upgradeVaultFactory();
- auctioneerKitProducer.reset();
- // @ts-expect-error auctioneerKit is non-null except between auctioneerKitProducer.reset() and auctioneerKitProducer.resolve()
- auctioneerKitProducer.resolve(auctioneerKit);
- auctioneerProducer.reset();
- // @ts-expect-error auctioneerKit is non-null except between auctioneerKitProducer.reset() and auctioneerKitProducer.resolve()
- auctioneerProducer.resolve(auctioneerKit.instance);
- // We wanted it to be valid for only a short while.
- tempAuctioneerKit.reset();
- await E(E(agoricNamesAdmin).lookupAdmin('instance')).update(
- 'auctioneer',
- // @ts-expect-error auctioneerKit is non-null except between auctioneerKitProducer.reset() and auctioneerKitProducer.resolve()
- auctioneerKit.instance,
- );
- trace(`upgrading complete`, price);
- },
- error => {
- console.error(
- 'Failed to upgrade vaultFactory',
- error.message,
- ...(error.errors || []),
- );
- },
+ await upgradeVaultFactory();
+
+ // @ts-expect-error It's saved in econ-behaviors.js:startVaultFactory()
+ const vaultFactoryPrivateArgs = kit.privateArgs;
+ console.log('UPGV upgraded vaults, restarting governor');
+
+ const ecf = await electorateCreatorFacet;
+ // restart vaultFactory governor
+ await E(kit.governorAdminFacet).restartContract(
+ harden({
+ electorateCreatorFacet: ecf,
+ governed: vaultFactoryPrivateArgs,
+ }),
);
- console.log(`upgradeVaults scheduled; waiting for priceFeeds`);
+ console.log('UPGV restarted governor');
};
const uV = 'upgradeVaults';
@@ -218,17 +200,18 @@ export const getManifestForUpgradeVaults = async (
manifest: {
[upgradeVaults.name]: {
consume: {
- agoricNamesAdmin: uV,
- newAuctioneerKit: uV,
+ auctionUpgradeNewInstance: uV,
+ chainTimerService: uV,
economicCommitteeCreatorFacet: uV,
- priceAuthority: uV,
reserveKit: uV,
vaultFactoryKit: uV,
- board: uV,
zoe: uV,
},
- produce: { auctioneerKit: uV, newAuctioneerKit: uV },
- instance: { produce: { auctioneer: uV, newAuctioneerKit: uV } },
+ produce: { auctionUpgradeNewInstance: uV },
+ installation: {
+ produce: { VaultFactory: true },
+ },
+ instance: { consume: { auctioneer: true } },
},
},
options: { ...vaultUpgradeOptions },
diff --git a/packages/inter-protocol/src/vaultFactory/liquidation.js b/packages/inter-protocol/src/vaultFactory/liquidation.js
index 2c992d15086..cd378d2989c 100644
--- a/packages/inter-protocol/src/vaultFactory/liquidation.js
+++ b/packages/inter-protocol/src/vaultFactory/liquidation.js
@@ -5,7 +5,6 @@ import { makeTracer } from '@agoric/internal';
import { observeIteration, subscribeEach } from '@agoric/notifier';
import { makeScalarMapStore } from '@agoric/store';
import { TimeMath } from '@agoric/time';
-import { atomicRearrange } from '@agoric/zoe/src/contractSupport/index.js';
import { E } from '@endo/eventual-send';
import { AUCTION_START_DELAY, PRICE_LOCK_PERIOD } from '../auction/params.js';
@@ -302,7 +301,7 @@ export const getLiquidatableVaults = (
}
if (transfers.length > 0) {
- atomicRearrange(zcf, harden(transfers));
+ zcf.atomicRearrange(harden(transfers));
}
return { vaultData, totalDebt, totalCollateral, liqSeat };
diff --git a/packages/inter-protocol/src/vaultFactory/vaultDirector.js b/packages/inter-protocol/src/vaultFactory/vaultDirector.js
index 7eccd809648..fdfa8d2f9d9 100644
--- a/packages/inter-protocol/src/vaultFactory/vaultDirector.js
+++ b/packages/inter-protocol/src/vaultFactory/vaultDirector.js
@@ -18,7 +18,6 @@ import {
} from '@agoric/vat-data';
import { assertKeywordName } from '@agoric/zoe/src/cleanProposal.js';
import {
- atomicRearrange,
makeRecorderTopic,
provideEmptySeat,
SubscriberShape,
@@ -82,6 +81,21 @@ const trace = makeTracer('VD', true);
const shortfallInvitationKey = 'shortfallInvitation';
+// If one manager/token fails, we don't want that to block possible success for
+// others, so we .catch() and log separately.
+//
+// exported for testing
+export const makeAllManagersDo = (collateralManagers, vaultManagers) => {
+ /** @param {(vm: VaultManager) => void} fn */
+ return fn => {
+ for (const managerIndex of collateralManagers.values()) {
+ Promise.resolve(vaultManagers.get(managerIndex).self)
+ .then(vm => fn(vm))
+ .catch(e => trace('🚨ERROR: allManagersDo', e));
+ }
+ };
+};
+
/**
* @param {import('@agoric/swingset-liveslots').Baggage} baggage
* @param {import('./vaultFactory.js').VaultFactoryZCF} zcf
@@ -93,7 +107,7 @@ const shortfallInvitationKey = 'shortfallInvitation';
* @param {ERef} marshaller
* @param {import('@agoric/zoe/src/contractSupport/recorder.js').MakeRecorderKit} makeRecorderKit
* @param {import('@agoric/zoe/src/contractSupport/recorder.js').MakeERecorderKit} makeERecorderKit
- * @param managerParams
+ * @param {Record} managerParams
*/
const prepareVaultDirector = (
baggage,
@@ -216,7 +230,7 @@ const prepareVaultDirector = (
[mintSeat, mintReceiver, { Minted: kept }],
];
try {
- atomicRearrange(zcf, harden(transfers));
+ zcf.atomicRearrange(harden(transfers));
} catch (e) {
console.error('mintAndTransfer failed to rearrange', e);
// If the rearrange fails, burn the newly minted tokens.
@@ -263,13 +277,7 @@ const prepareVaultDirector = (
metrics: makeRecorderTopic('Vault Factory metrics', metricsKit),
});
- /** @param {(vm: VaultManager) => void} fn */
- const allManagersDo = fn => {
- for (const managerIndex of collateralManagers.values()) {
- const vm = vaultManagers.get(managerIndex).self;
- fn(vm);
- }
- };
+ const allManagersDo = makeAllManagersDo(collateralManagers, vaultManagers);
const makeWaker = (name, func) => {
return Far(name, {
diff --git a/packages/inter-protocol/src/vaultFactory/vaultFactory.js b/packages/inter-protocol/src/vaultFactory/vaultFactory.js
index 595fdc84e20..b2d27dca2f6 100644
--- a/packages/inter-protocol/src/vaultFactory/vaultFactory.js
+++ b/packages/inter-protocol/src/vaultFactory/vaultFactory.js
@@ -74,6 +74,7 @@ harden(meta);
* string,
* import('./params.js').VaultManagerParamOverrides
* >;
+ * directorParamOverrides: [object];
* }} privateArgs
* @param {import('@agoric/swingset-liveslots').Baggage} baggage
*/
@@ -86,6 +87,7 @@ export const start = async (zcf, privateArgs, baggage) => {
storageNode,
auctioneerInstance,
managerParams,
+ directorParamOverrides,
} = privateArgs;
trace('awaiting debtMint');
@@ -117,7 +119,6 @@ export const start = async (zcf, privateArgs, baggage) => {
marshaller,
);
/** a powerful object; can modify the invitation */
- trace('awaiting makeParamManagerFromTerms');
const vaultDirectorParamManager = await makeParamManagerFromTerms(
{
publisher: governanceSubscriptionKit.publication,
@@ -129,6 +130,7 @@ export const start = async (zcf, privateArgs, baggage) => {
[SHORTFALL_INVITATION_KEY]: initialShortfallInvitation,
},
vaultDirectorParamTypes,
+ directorParamOverrides,
);
const director = provideDirector(
diff --git a/packages/inter-protocol/src/vaultFactory/vaultManager.js b/packages/inter-protocol/src/vaultFactory/vaultManager.js
index ad5cffc37ed..20ffb29ab71 100644
--- a/packages/inter-protocol/src/vaultFactory/vaultManager.js
+++ b/packages/inter-protocol/src/vaultFactory/vaultManager.js
@@ -39,7 +39,6 @@ import {
} from '@agoric/vat-data';
import { TransferPartShape } from '@agoric/zoe/src/contractSupport/atomicTransfer.js';
import {
- atomicRearrange,
ceilMultiplyBy,
floorDivideBy,
getAmountIn,
@@ -52,6 +51,7 @@ import {
TopicsRecordShape,
} from '@agoric/zoe/src/contractSupport/index.js';
import { PriceQuoteShape, SeatShape } from '@agoric/zoe/src/typeGuards.js';
+import { multiplyBy } from '@agoric/zoe/src/contractSupport/ratio.js';
import {
checkDebtLimit,
makeNatAmountShape,
@@ -756,7 +756,7 @@ export const prepareVaultManagerKit = (
amounts,
]),
);
- atomicRearrange(zcf, harden(transfers));
+ zcf.atomicRearrange(harden(transfers));
}
const { prioritizedVaults } = collateralEphemera(
@@ -993,8 +993,9 @@ export const prepareVaultManagerKit = (
);
state.totalDebt = AmountMath.subtract(
AmountMath.add(state.totalDebt, vault.getCurrentDebt()),
- oldDebtNormalized,
+ multiplyBy(oldDebtNormalized, state.compoundedInterest),
);
+
void facets.helper.writeMetrics();
},
},
diff --git a/packages/inter-protocol/test/auction/auctionMath.test.js b/packages/inter-protocol/test/auction/auctionMath.test.js
new file mode 100644
index 00000000000..337c2d36dfe
--- /dev/null
+++ b/packages/inter-protocol/test/auction/auctionMath.test.js
@@ -0,0 +1,204 @@
+import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';
+
+import { AmountMath } from '@agoric/ertp';
+import { makeRatioFromAmounts } from '@agoric/zoe/src/contractSupport/ratio.js';
+import { Far } from '@endo/far';
+import { amountsToSettle } from '../../src/auction/auctionMath.js';
+
+/**
+ * @import {Amount, Brand} from '@agoric/ertp/src/types.js';
+ */
+
+const brand = /** @type {any} */ (Far('fungible brand', {}));
+
+const testAmounts = test.macro(
+ /**
+ * @type {(
+ * t: import('ava').ExecutionContext,
+ * input: any,
+ * output: any,
+ * ) => Promise}
+ */
+ async (
+ t,
+ { bid, want, avail, price, goal },
+ { expected, procTarget, collTarget },
+ ) => {
+ /** @type {(n: number) => Amount<'nat'>} */
+ const amt = n => AmountMath.make(brand, BigInt(n));
+
+ const result = amountsToSettle({
+ bidAlloc: amt(bid),
+ collateralWanted: amt(want),
+ collateralAvailable: amt(avail),
+ curAuctionPrice: makeRatioFromAmounts(amt(price[0]), amt(price[1])),
+ remainingProceedsGoal: goal ? amt(goal) : null,
+ });
+
+ t.deepEqual(result, {
+ proceedsExpected: amt(expected),
+ proceedsTarget: amt(procTarget),
+ collateralTarget: amt(collTarget),
+ });
+ },
+);
+
+// These were observed in other tests
+test(
+ 'observed 1',
+ testAmounts,
+ { bid: 578, want: 500, avail: 1000, price: [1155, 1000] },
+ {
+ expected: 578,
+ procTarget: 578,
+ collTarget: 500,
+ },
+);
+
+test(
+ 'observed 2 - with remaining proceeds goal',
+ testAmounts,
+ { bid: 125, want: 100, avail: 400, price: [525, 1000], goal: 200 },
+ {
+ expected: 53,
+ procTarget: 53,
+ collTarget: 100,
+ },
+);
+
+test(
+ 'observed 3',
+ testAmounts,
+ { bid: 231, want: 200, avail: 1000, price: [1155, 1000] },
+ {
+ expected: 231,
+ procTarget: 231,
+ collTarget: 200,
+ },
+);
+
+test(
+ 'observed 4',
+ testAmounts,
+ { bid: 232, want: 200, avail: 100, price: [1155, 1000] },
+ {
+ expected: 116,
+ procTarget: 116,
+ collTarget: 100,
+ },
+);
+
+test(
+ 'observed 5',
+ testAmounts,
+ { bid: 19, want: 300, avail: 300, price: [625, 10000] },
+ {
+ expected: 19,
+ procTarget: 19,
+ collTarget: 300,
+ },
+);
+
+test(
+ 'observed 6',
+ testAmounts,
+ { bid: 23, want: 200, avail: 500, price: [1125, 10000] },
+ {
+ expected: 23,
+ procTarget: 23,
+ collTarget: 200,
+ },
+);
+
+test(
+ 'observed 7',
+ testAmounts,
+ { bid: 500, want: 2000, avail: 717, price: [715, 1000] },
+ {
+ expected: 513,
+ procTarget: 500,
+ collTarget: 699,
+ },
+);
+
+test(
+ 'observed 8',
+ testAmounts,
+ { bid: 240, want: 200, avail: 20, price: [1155, 1000] },
+ {
+ expected: 24,
+ procTarget: 24,
+ collTarget: 20,
+ },
+);
+
+test(
+ 'observed 9',
+ testAmounts,
+ { bid: 2000, want: 200, avail: 1000, price: [1155, 1000] },
+ {
+ expected: 231,
+ procTarget: 231,
+ collTarget: 200,
+ },
+);
+
+test(
+ 'observed 10',
+ testAmounts,
+ { bid: 2240, want: 200, avail: 1000, price: [1155, 1000] },
+ {
+ expected: 231,
+ procTarget: 231,
+ collTarget: 200,
+ },
+);
+
+test(
+ 'want exceeeds avail',
+ testAmounts,
+ { bid: 2000, want: 2000, avail: 1000, price: [1, 1] },
+ {
+ expected: 1000,
+ procTarget: 1000,
+ collTarget: 1000,
+ },
+);
+
+test(
+ 'want exceeeds avail at half price',
+ testAmounts,
+ { bid: 1999, want: 2000, avail: 1000, price: [201, 1] },
+ {
+ expected: 201000,
+ procTarget: 1999,
+ collTarget: 9,
+ },
+);
+test(
+ 'want exceeeds avail at half price with goal',
+ testAmounts,
+ { bid: 1999, want: 2000, avail: 1000, price: [201, 1], goal: 301 },
+ {
+ expected: 201000,
+ procTarget: 301,
+ collTarget: 1,
+ },
+);
+
+test(
+ 'observed in production',
+ testAmounts,
+ {
+ bid: 3000,
+ want: 2000,
+ avail: 1000,
+ price: [4914, 10000], // "currentPriceLevel": "0.4914 IST/stOSMO",
+ goal: 1254_886835, // "remainingProceedsGoal": "1254.886835 IST",
+ },
+ {
+ expected: 492,
+ procTarget: 492,
+ collTarget: 1000,
+ },
+);
diff --git a/packages/inter-protocol/test/auction/sortedOffers.test.js b/packages/inter-protocol/test/auction/sortedOffers.test.js
index 260aac80850..7dc908b617e 100644
--- a/packages/inter-protocol/test/auction/sortedOffers.test.js
+++ b/packages/inter-protocol/test/auction/sortedOffers.test.js
@@ -4,8 +4,10 @@ import {
ratiosSame,
makeRatioFromAmounts,
quantize,
+ subtractRatios,
} from '@agoric/zoe/src/contractSupport/index.js';
import { setup } from '@agoric/zoe/test/unitTests/setupBasicMints.js';
+import { AmountMath } from '@agoric/ertp';
import {
fromPriceOfferKey,
toPriceOfferKey,
@@ -65,6 +67,10 @@ test('toKey discount', t => {
t.true(keyD26 > keyD25);
});
+const ratiosEqual = (t, left, right) => {
+ t.true(AmountMath.isEmpty(subtractRatios(left, right).numerator));
+};
+
test('fromKey Price', t => {
const { moola, moolaKit, simoleans, simoleanKit } = setup();
const { brand: moolaBrand } = moolaKit;
@@ -81,12 +87,7 @@ test('fromKey Price', t => {
t.true(
ratiosSame(priceAOut, makeRatioFromAmounts(moola(40n * N), simoleans(N))),
);
- t.true(
- ratiosSame(
- priceBOut,
- quantize(makeRatioFromAmounts(moola(40n), simoleans(1000n)), N),
- ),
- );
+ ratiosEqual(t, priceBOut, makeRatioFromAmounts(moola(40n), simoleans(1000n)));
t.is(timeA, DEC25);
t.is(timeB, DEC25);
});
@@ -104,8 +105,9 @@ test('fromKey discount', t => {
const [discountAOut, timeA] = fromScaledRateOfferKey(keyA25, moolaBrand, 9);
const [discountBOut, timeB] = fromScaledRateOfferKey(keyB25, moolaBrand, 9);
- t.deepEqual(quantize(discountAOut, 10000n), quantize(fivePercent, 10000n));
- t.deepEqual(
+ ratiosEqual(t, discountAOut, fivePercent);
+ ratiosEqual(
+ t,
quantize(discountBOut, 10000n),
quantize(fivePointFivePercent, 10000n),
);
diff --git a/packages/inter-protocol/test/contractSupport.test.js b/packages/inter-protocol/test/contractSupport.test.js
index c7a43bab1aa..cbea5608a91 100644
--- a/packages/inter-protocol/test/contractSupport.test.js
+++ b/packages/inter-protocol/test/contractSupport.test.js
@@ -20,3 +20,8 @@ test('checkDebtLimit allows at limit', t => {
test('checkDebtLimit throws above', t => {
t.throws(() => checkDebtLimit(limit, prior, debt.make(3n)));
});
+
+test('checkDebtLimit always succeeds if there is nothing to mint', t => {
+ const bigPrior = debt.make(5n);
+ t.notThrows(() => checkDebtLimit(limit, bigPrior, debt.make(0n)));
+});
diff --git a/packages/inter-protocol/test/supports.js b/packages/inter-protocol/test/supports.js
index 34f645c3e2d..de0e179b0dc 100644
--- a/packages/inter-protocol/test/supports.js
+++ b/packages/inter-protocol/test/supports.js
@@ -59,11 +59,8 @@ harden(setUpZoeForTest);
*/
export const setupBootstrap = async (t, optTimer) => {
const trace = makeTracer('PromiseSpace', false);
- const space = /** @type {any} */ (makePromiseSpace(trace));
- const { produce, consume } = /**
- * @type {import('../src/proposals/econ-behaviors.js').EconomyBootstrapPowers &
- * BootstrapPowers}
- */ (space);
+ const space = /** @type {Space} */ (makePromiseSpace(trace));
+ const { produce, consume } = space;
await produceDiagnostics(space);
diff --git a/packages/inter-protocol/test/vaultFactory/director-allMgrsDo.test.js b/packages/inter-protocol/test/vaultFactory/director-allMgrsDo.test.js
new file mode 100644
index 00000000000..6720436e94b
--- /dev/null
+++ b/packages/inter-protocol/test/vaultFactory/director-allMgrsDo.test.js
@@ -0,0 +1,63 @@
+import { Far } from '@endo/marshal';
+import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';
+
+import { waitUntilQuiescent } from '@agoric/swingset-liveslots/test/waitUntilQuiescent.js';
+import { makeAllManagersDo } from '../../src/vaultFactory/vaultDirector.js';
+
+const makeFakeVM = (name, thrower) => {
+ let okay = true;
+ const fakeVM = Far('fakeVM', {
+ doIt: () => {
+ if (thrower) {
+ okay = false;
+ throw Error('whatever', name);
+ }
+ return name;
+ },
+ okay: () => okay,
+ });
+ return { self: fakeVM };
+};
+
+const makeFakeVMgrKits = () => {
+ const kits = [];
+ return {
+ add: k => kits.push(k),
+ get: i => kits[i],
+ };
+};
+
+test(`AllManagersDo no throw`, async t => {
+ const collMgr = [0, 1, 2];
+ const kits = makeFakeVMgrKits();
+ kits.add(makeFakeVM('A', false));
+ kits.add(makeFakeVM('B', false));
+ kits.add(makeFakeVM('C', false));
+
+ const allManagersDo = makeAllManagersDo(collMgr, kits);
+ // @ts-expect-error It's a fake
+ const result = allManagersDo(vm => vm.doIt());
+ t.is(result, undefined);
+ t.true(kits.get(0).self.okay());
+ t.true(kits.get(1).self.okay());
+ t.true(kits.get(2).self.okay());
+});
+
+test(`AllManagersDo throw`, async t => {
+ const collMgr = [0, 1, 2];
+ const kits = makeFakeVMgrKits();
+ kits.add(makeFakeVM('A', false));
+ kits.add(makeFakeVM('B', true));
+ kits.add(makeFakeVM('C', false));
+
+ const allManagersDo = makeAllManagersDo(collMgr, kits);
+ // @ts-expect-error It's a fake
+ const result = allManagersDo(vm => vm.doIt());
+ t.is(result, undefined);
+
+ await waitUntilQuiescent();
+
+ t.true(kits.get(0).self.okay());
+ t.false(kits.get(1).self.okay());
+ t.true(kits.get(2).self.okay());
+});
diff --git a/packages/inter-protocol/test/vaultFactory/driver.js b/packages/inter-protocol/test/vaultFactory/driver.js
index 7c486fd4ea2..d203afcd8b1 100644
--- a/packages/inter-protocol/test/vaultFactory/driver.js
+++ b/packages/inter-protocol/test/vaultFactory/driver.js
@@ -142,7 +142,10 @@ export const makeDriverContext = async ({
aethInitialLiquidity: AmountMath.make(aeth.brand, 900_000_000n),
};
const frozenCtx = await deeplyFulfilled(harden(contextPs));
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
+ // @ts-ignore Local tsc sees this as an error but typedoc does not
return { ...frozenCtx, bundleCache, run, aeth };
+ /* eslint-enable @typescript-eslint/ban-ts-comment */
};
/** @param {import('ava').ExecutionContext} t */
@@ -210,7 +213,7 @@ const getRunFromFaucet = async (t, amt) => {
* @param {Amount} priceBase
*/
const setupServices = async (t, initialPrice, priceBase) => {
- const timer = buildZoeManualTimer(t.log);
+ const timer = buildZoeManualTimer(t.log, 0n, { timeStep: 60n * 60n });
const { zoe, run, aeth, interestTiming, minInitialDebt, rates } = t.context;
t.context.timer = timer;
@@ -333,6 +336,10 @@ export const makeManagerDriver = async (
publicTopics.asset.subscriber,
);
let managerNotification = await E(managerNotifier).getUpdateSince();
+ const metricsNotifier = await makeNotifierFromSubscriber(
+ publicTopics.metrics.subscriber,
+ );
+ let metricsNotification = await E(metricsNotifier).getUpdateSince();
/** @type {UserSeat} */
let currentSeat;
@@ -556,6 +563,21 @@ export const makeManagerDriver = async (
}
return managerNotification;
},
+ /**
+ * @param {object} [likeExpected]
+ * @param {AT_NEXT | number} [optSince] AT_NEXT is an alias for updateCount
+ * of the last update, forcing to wait for another
+ */
+ metricsNotified: async (likeExpected, optSince) => {
+ metricsNotification = await E(metricsNotifier).getUpdateSince(
+ optSince === AT_NEXT ? metricsNotification.updateCount : optSince,
+ );
+ trace(t, 'metrics notifier', metricsNotification);
+ if (likeExpected) {
+ t.like(metricsNotification.value, likeExpected);
+ }
+ return managerNotification;
+ },
checkReserveAllocation: async stableValue => {
const { reserveCreatorFacet } = t.context;
const reserveAllocations = await E(reserveCreatorFacet).getAllocations();
diff --git a/packages/inter-protocol/test/vaultFactory/snapshots/vaultFactory.test.js.md b/packages/inter-protocol/test/vaultFactory/snapshots/vaultFactory.test.js.md
index 615561a83dc..d814867d411 100644
--- a/packages/inter-protocol/test/vaultFactory/snapshots/vaultFactory.test.js.md
+++ b/packages/inter-protocol/test/vaultFactory/snapshots/vaultFactory.test.js.md
@@ -72,11 +72,11 @@ Generated by [AVA](https://avajs.dev).
compoundedInterest: {
denominator: {
brand: Object @Alleged: IST brand {},
- value: 100000000000000000000n,
+ value: 857701650301172500n,
},
numerator: {
brand: Object @Alleged: IST brand {},
- value: 101967213114754098360n,
+ value: 874574469651359500n,
},
},
interestRate: {
@@ -204,7 +204,7 @@ Generated by [AVA](https://avajs.dev).
},
totalDebt: {
brand: Object @Alleged: IST brand {},
- value: 1634n,
+ value: 1608n,
},
totalOverageReceived: {
brand: Object @Alleged: IST brand {},
@@ -387,11 +387,11 @@ Generated by [AVA](https://avajs.dev).
interest: {
denominator: {
brand: Object @Alleged: IST brand {},
- value: 100000000000000000000n,
+ value: 857701650301172500n,
},
numerator: {
brand: Object @Alleged: IST brand {},
- value: 101967213114754098360n,
+ value: 874574469651359500n,
},
},
},
@@ -413,11 +413,11 @@ Generated by [AVA](https://avajs.dev).
interest: {
denominator: {
brand: Object @Alleged: IST brand {},
- value: 100000000000000000000n,
+ value: 857701650301172500n,
},
numerator: {
brand: Object @Alleged: IST brand {},
- value: 101967213114754098360n,
+ value: 874574469651359500n,
},
},
},
diff --git a/packages/inter-protocol/test/vaultFactory/snapshots/vaultFactory.test.js.snap b/packages/inter-protocol/test/vaultFactory/snapshots/vaultFactory.test.js.snap
index 21a5482e71a..a5a84851905 100644
Binary files a/packages/inter-protocol/test/vaultFactory/snapshots/vaultFactory.test.js.snap and b/packages/inter-protocol/test/vaultFactory/snapshots/vaultFactory.test.js.snap differ
diff --git a/packages/inter-protocol/test/vaultFactory/vault-collateralization.test.js b/packages/inter-protocol/test/vaultFactory/vault-collateralization.test.js
index 7157de31682..5f3a912872f 100644
--- a/packages/inter-protocol/test/vaultFactory/vault-collateralization.test.js
+++ b/packages/inter-protocol/test/vaultFactory/vault-collateralization.test.js
@@ -2,7 +2,8 @@ import { test as unknownTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';
import { makeTracer } from '@agoric/internal';
import { E } from '@endo/eventual-send';
-import { makeDriverContext, makeManagerDriver } from './driver.js';
+import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
+import { AT_NEXT, makeDriverContext, makeManagerDriver } from './driver.js';
/** @typedef {import('./driver.js').DriverContext & {}} Context */
/** @type {import('ava').TestFn} */
@@ -15,14 +16,52 @@ test.before(async t => {
trace(t, 'CONTEXT');
});
+test('totalDebt calculation includes compoundedInterest', async t => {
+ const { aeth, run } = t.context;
+ const md = await makeManagerDriver(t);
+ const timer = md.timer();
+
+ t.log('charge 2% per day to simulate lower rates over longer times');
+ const aethKey = { collateralBrand: aeth.brand };
+ const twoPctPerDay = run.makeRatio(2n * 360n, 100n);
+ await md.setGovernedParam('InterestRate', twoPctPerDay, { key: aethKey });
+ const plausibleDebtLimit = run.units(500000);
+ await md.setGovernedParam('DebtLimit', plausibleDebtLimit, { key: aethKey });
+
+ t.log('mint 100 IST against 25 AETH');
+ const vd = await md.makeVaultDriver(aeth.units(25), run.units(100));
+ const v1debtAfterMint = await E(vd.vault()).getCurrentDebt();
+ t.deepEqual(v1debtAfterMint, run.units(100 + 5));
+ // totalDebt is debit of this 1 vault
+ await md.metricsNotified({ totalDebt: v1debtAfterMint }, AT_NEXT);
+
+ await E(timer).tickN(40, 'interest accumulates over 40hrs');
+ await eventLoopIteration(); // let all timer-induced promises settle
+ const v1debtAfterDay = await E(vd.vault()).getCurrentDebt();
+ t.deepEqual(v1debtAfterDay, run.make(106_008_000n));
+
+ // Checking that totalDebt here matches v1debtAfterDay would be handy,
+ // but totalDebt isn't updated when calculating interest.
+ const expectedCompoundedInterest = {
+ denominator: { value: 100000000000000000000n },
+ numerator: { value: 100960000000000000000n },
+ };
+ await md.managerNotified({ compoundedInterest: expectedCompoundedInterest });
+
+ t.log('give some collateral (adjustBalances); no change to debt');
+ await E(vd).giveCollateral(50n, aeth);
+ const v1debtAfterGive = await E(vd.vault()).getCurrentDebt();
+ t.deepEqual(v1debtAfterGive, v1debtAfterDay, 'no debt change');
+
+ await md.metricsNotified({ totalDebt: v1debtAfterDay }, AT_NEXT);
+});
+
test('excessive loan', async t => {
const { aeth, run } = t.context;
const md = await makeManagerDriver(t);
const threshold = 453n;
- await t.notThrowsAsync(
- md.makeVaultDriver(aeth.make(100n), run.make(threshold)),
- );
+ await md.makeVaultDriver(aeth.make(100n), run.make(threshold));
await t.throwsAsync(
md.makeVaultDriver(aeth.make(100n), run.make(threshold + 1n)),
@@ -32,6 +71,28 @@ test('excessive loan', async t => {
);
});
+test('repay works regardless of debtLimit', async t => {
+ const { aeth, run } = t.context;
+ const md = await makeManagerDriver(t);
+
+ // take debt that comes just shy of max
+ const vd = await md.makeVaultDriver(aeth.make(1000n), run.make(4500n));
+ t.deepEqual(await E(vd.vault()).getCurrentDebt(), run.make(4725n));
+
+ const MARGIN_HOP = 20n;
+
+ // we can take a loan and pay it back
+ await vd.giveCollateral(100n, aeth, MARGIN_HOP);
+ await vd.giveMinted(MARGIN_HOP, aeth, 100n);
+
+ // EC lowers mint limit
+ await md.setGovernedParam('DebtLimit', run.make(1000n), {
+ key: { collateralBrand: aeth.brand },
+ });
+ // we can still repay debt
+ await vd.giveMinted(MARGIN_HOP, aeth);
+});
+
test('add debt to vault under LiquidationMarging + LiquidationPadding', async t => {
const { aeth, run } = t.context;
const md = await makeManagerDriver(t);
diff --git a/packages/inter-protocol/test/vaultFactory/vaultFactory.test.js b/packages/inter-protocol/test/vaultFactory/vaultFactory.test.js
index 6d68f610c03..f285b00bd00 100644
--- a/packages/inter-protocol/test/vaultFactory/vaultFactory.test.js
+++ b/packages/inter-protocol/test/vaultFactory/vaultFactory.test.js
@@ -1838,6 +1838,13 @@ test('manager notifiers, with snapshot', async t => {
}),
);
({ vault } = await E(vaultSeat).getOfferResult());
+ totalCollateral += ENOUGH;
+ totalDebt += DEBT2;
+ await m.assertChange({
+ numActiveVaults: 4,
+ totalCollateral: { value: totalCollateral },
+ totalDebt: { value: totalDebt },
+ });
trace('6. Loan interest');
vaultSeat = await E(services.zoe).offer(
@@ -1851,18 +1858,21 @@ test('manager notifiers, with snapshot', async t => {
}),
);
({ vault } = await E(vaultSeat).getOfferResult());
- totalCollateral += ENOUGH;
- totalDebt += DEBT2;
+ totalCollateral += AMPLE;
+ totalDebt += DEBT1;
await m.assertChange({
- numActiveVaults: 4,
+ numActiveVaults: 5,
totalCollateral: { value: totalCollateral },
totalDebt: { value: totalDebt },
});
- m.addDebt(DEBT2);
+
await manualTimer.tickN(5);
+ // This is interest for a single vault.
const interestAccrued = (await E(vault).getCurrentDebt()).value - DEBT1;
m.addDebt(interestAccrued);
- t.is(interestAccrued, 9n);
+
+ t.is(interestAccrued, 9n); // interest on OPEN1 for 5 periods
+ totalDebt += 30n; // interest on 270_000 for 5 periods
trace('7. make another loan to trigger a publish');
vaultSeat = await E(services.zoe).offer(
@@ -1876,10 +1886,10 @@ test('manager notifiers, with snapshot', async t => {
}),
);
({ vault } = await E(vaultSeat).getOfferResult());
- totalCollateral += AMPLE;
- totalDebt += DEBT1;
+ totalCollateral += ENOUGH;
+ totalDebt += DEBT2;
await m.assertChange({
- numActiveVaults: 5,
+ numActiveVaults: 6,
totalCollateral: { value: totalCollateral },
totalDebt: { value: totalDebt },
});
@@ -1898,11 +1908,10 @@ test('manager notifiers, with snapshot', async t => {
}),
);
({ vault } = await E(vaultSeat).getOfferResult());
- totalCollateral += ENOUGH;
- totalDebt += DEBT2 + 30n; // XXX ??
- m.addDebt(DEBT2);
+ totalCollateral += AMPLE;
+ totalDebt += DEBT1;
await m.assertChange({
- numActiveVaults: 6,
+ numActiveVaults: 7,
totalCollateral: { value: totalCollateral },
totalDebt: { value: totalDebt },
});
@@ -1925,20 +1934,11 @@ test('manager notifiers, with snapshot', async t => {
}),
);
await E(vaultOpSeat).getOfferResult();
- totalCollateral += AMPLE;
- totalDebt += DEBT1;
- await m.assertChange({
- numActiveVaults: 7,
- totalDebt: { value: totalDebt },
- totalCollateral: { value: totalCollateral },
- });
-
totalCollateral += given.value;
- totalDebt += WANT_EXTRA + 29n; // magic number is fees
-
+ totalDebt += WANT_EXTRA + 20n;
await m.assertChange({
- totalCollateral: { value: totalCollateral },
totalDebt: { value: totalDebt },
+ totalCollateral: { value: totalCollateral },
});
trace('10. Close vault');
@@ -1955,7 +1955,7 @@ test('manager notifiers, with snapshot', async t => {
await E(vaultOpSeat).getOfferResult();
totalCollateral -= AMPLE + given.value;
- totalDebt -= DEBT1_EXTRA - 17n; // magic number is fees
+ totalDebt -= DEBT1_EXTRA;
await m.assertChange({
numActiveVaults: 6,
totalCollateral: { value: totalCollateral },
diff --git a/packages/internal/package.json b/packages/internal/package.json
index 9e94cf3ff18..ad31590ee43 100755
--- a/packages/internal/package.json
+++ b/packages/internal/package.json
@@ -10,7 +10,7 @@
"scripts": {
"build": "exit 0",
"prepack": "tsc --build tsconfig.build.json",
- "postpack": "git clean -f '*.d.ts*'",
+ "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
"test": "ava",
"test:nyc": "exit 0",
"test:xs": "exit 0",
@@ -20,22 +20,22 @@
"lint:types": "tsc"
},
"dependencies": {
- "@endo/errors": "^1.2.2",
+ "@endo/errors": "^1.2.5",
"@agoric/base-zone": "^0.1.0",
- "@endo/common": "^1.2.2",
- "@endo/far": "^1.1.2",
- "@endo/init": "^1.1.2",
- "@endo/marshal": "^1.5.0",
- "@endo/pass-style": "^1.4.0",
- "@endo/patterns": "^1.4.0",
- "@endo/promise-kit": "^1.1.2",
- "@endo/stream": "^1.2.2",
+ "@endo/common": "^1.2.5",
+ "@endo/far": "^1.1.5",
+ "@endo/init": "^1.1.4",
+ "@endo/marshal": "^1.5.3",
+ "@endo/pass-style": "^1.4.3",
+ "@endo/patterns": "^1.4.3",
+ "@endo/promise-kit": "^1.1.5",
+ "@endo/stream": "^1.2.5",
"anylogger": "^0.21.0",
"jessie.js": "^0.3.4"
},
"devDependencies": {
- "@endo/exo": "^1.5.0",
- "@endo/init": "^1.1.2",
+ "@endo/exo": "^1.5.3",
+ "@endo/init": "^1.1.4",
"ava": "^5.3.0",
"tsd": "^0.31.1"
},
@@ -57,6 +57,6 @@
"access": "public"
},
"typeCoverage": {
- "atLeast": 93.82
+ "atLeast": 93.42
}
}
diff --git a/packages/internal/src/callback.js b/packages/internal/src/callback.js
index 01350acfa58..a8400ae90c5 100644
--- a/packages/internal/src/callback.js
+++ b/packages/internal/src/callback.js
@@ -41,7 +41,7 @@ const isPropertyKey = key => {
/**
* Synchronously call a callback.
*
- * @template {(...args: unknown[]) => any} I
+ * @template {(...args: any[]) => any} I
* @param {SyncCallback} callback
* @param {Parameters} args
* @returns {ReturnType}
@@ -58,7 +58,7 @@ harden(callSync);
/**
* Eventual send to a callback.
*
- * @template {(...args: unknown[]) => any} I
+ * @template {(...args: any[]) => any} I
* @param {Callback} callback
* @param {Parameters} args
* @returns {Promise>>}
@@ -75,9 +75,9 @@ harden(callE);
/**
* Create a callback from a near function.
*
- * @template {(...args: unknown[]) => any} I
+ * @template {(...args: any[]) => any} I
* @template {(...args: [...B, ...Parameters]) => ReturnType} [T=I]
- * @template {unknown[]} [B=[]]
+ * @template {any[]} [B=[]]
* @param {T} target
* @param {B} bound
* @returns {SyncCallback}
@@ -94,9 +94,9 @@ harden(makeSyncFunctionCallback);
/**
* Create a callback from a potentially far function.
*
- * @template {(...args: unknown[]) => any} I
+ * @template {(...args: any[]) => any} I
* @template {ERef<(...args: [...B, ...Parameters]) => ReturnType>} [T=ERef]
- * @template {unknown[]} [B=[]]
+ * @template {any[]} [B=[]]
* @param {T} target
* @param {B} bound
* @returns {Callback}
@@ -113,12 +113,12 @@ harden(makeFunctionCallback);
/**
* Create a callback from a near method.
*
- * @template {(...args: unknown[]) => any} I
+ * @template {(...args: any[]) => any} I
* @template {PropertyKey} P
* @template {{
* [x in P]: (...args: [...B, ...Parameters]) => ReturnType;
* }} [T={ [x in P]: I }]
- * @template {unknown[]} [B=[]]
+ * @template {any[]} [B=[]]
* @param {T} target
* @param {P} methodName
* @param {B} bound
@@ -139,12 +139,12 @@ harden(makeSyncMethodCallback);
/**
* Create a callback from a potentially far method.
*
- * @template {(...args: unknown[]) => any} I
+ * @template {(...args: any[]) => any} I
* @template {PropertyKey} P
* @template {ERef<{
* [x in P]: (...args: [...B, ...Parameters]) => ReturnType;
* }>} [T=ERef<{ [x in P]: I }>]
- * @template {unknown[]} [B=[]]
+ * @template {any[]} [B=[]]
* @param {T} target
* @param {P} methodName
* @param {B} bound
@@ -200,11 +200,11 @@ export const prepareAttenuator = (
{ interfaceGuard, tag = 'Attenuator' } = {},
) => {
/**
- * @typedef {(this: any, ...args: unknown[]) => any} Method
+ * @typedef {(this: any, ...args: any[]) => any} Method
*
* @typedef {{ [K in M]?: Callback | null }} Overrides
*
- * @typedef {{ [K in M]: (this: any, ...args: unknown[]) => any }} Methods
+ * @typedef {{ [K in M]: (this: any, ...args: any[]) => any }} Methods
*/
const methods = /** @type {Methods} */ (
fromEntries(
diff --git a/packages/internal/src/index.js b/packages/internal/src/index.js
index 28e9139d3f3..536d8ffa125 100644
--- a/packages/internal/src/index.js
+++ b/packages/internal/src/index.js
@@ -14,4 +14,5 @@ export * from './typeGuards.js';
export * from './types.js';
export { objectMap } from '@endo/common/object-map.js';
+export { objectMetaMap } from '@endo/common/object-meta-map.js';
export { fromUniqueEntries } from '@endo/common/from-unique-entries.js';
diff --git a/packages/internal/src/node/createBundles.js b/packages/internal/src/node/createBundles.js
index 9b78839e0ac..116eca402cb 100644
--- a/packages/internal/src/node/createBundles.js
+++ b/packages/internal/src/node/createBundles.js
@@ -25,6 +25,7 @@ export const createBundlesFromAbsolute = async sourceBundles => {
const bundle = match[1];
const args = cacheToArgs.get(cache) || ['--cache-js', cache];
+ args.push('--elide-comments');
args.push(srcPath, bundle);
cacheToArgs.set(cache, args);
}
diff --git a/packages/internal/src/node/utils.js b/packages/internal/src/node/utils.js
deleted file mode 100644
index ba4995c3798..00000000000
--- a/packages/internal/src/node/utils.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// @ts-check
-// @jessie-check
-
-// These tools seem cross platform, but they rely on AggregateError in the error
-// handling path, which is currently not available in xsnap
-import 'node:process';
-
-/**
- * @template T
- * @param {readonly (T | PromiseLike)[]} items
- * @returns {Promise}
- */
-export const PromiseAllOrErrors = async items => {
- return Promise.allSettled(items).then(results => {
- const errors = /** @type {PromiseRejectedResult[]} */ (
- results.filter(({ status }) => status === 'rejected')
- ).map(result => result.reason);
- if (!errors.length) {
- return /** @type {PromiseFulfilledResult[]} */ (results).map(
- result => result.value,
- );
- } else if (errors.length === 1) {
- throw errors[0];
- } else {
- throw AggregateError(errors);
- }
- });
-};
-
-/**
- * @type {(
- * trier: () => Promise,
- * finalizer: (error?: unknown) => Promise,
- * ) => Promise}
- */
-export const aggregateTryFinally = async (trier, finalizer) =>
- trier().then(
- async result => finalizer().then(() => result),
- async tryError =>
- finalizer(tryError)
- .then(
- () => tryError,
- finalizeError => AggregateError([tryError, finalizeError]),
- )
- .then(error => Promise.reject(error)),
- );
diff --git a/packages/internal/src/storage-test-utils.js b/packages/internal/src/storage-test-utils.js
index 9da583ab10a..b1ce51b2cdc 100644
--- a/packages/internal/src/storage-test-utils.js
+++ b/packages/internal/src/storage-test-utils.js
@@ -9,25 +9,12 @@ import { bindAllMethods } from './method-tools.js';
import { eventLoopIteration } from './testing-utils.js';
/**
+ * @import {TotalMap} from './types.js';
* @import {Marshaller, StorageEntry, StorageMessage, StorageNode} from './lib-chainStorage.js';
*/
const trace = makeTracer('StorTU', false);
-/**
- * A map corresponding with a total function such that `get(key)` is assumed to
- * always succeed.
- *
- * @template K, V
- * @typedef {{ [k in Exclude, 'get'>]: Map[k] } & {
- * get: (key: K) => V;
- * }} TotalMap
- */
-/**
- * @template T
- * @typedef {T extends Map ? TotalMap : never} TotalMapFrom
- */
-
/**
* A convertSlotToVal function that produces basic Remotables. Assumes that all
* slots are Remotables (i.e. none are Promises).
diff --git a/packages/internal/src/types.d.ts b/packages/internal/src/types.d.ts
index 806e5882cf5..a91602bf1f4 100644
--- a/packages/internal/src/types.d.ts
+++ b/packages/internal/src/types.d.ts
@@ -3,7 +3,18 @@ import type { ERef, RemotableBrand } from '@endo/eventual-send';
import type { Primitive } from '@endo/pass-style';
import type { Callable } from './utils.js';
-export declare class Callback any> {
+/**
+ * A map corresponding with a total function such that `get(key)` is assumed to
+ * always succeed.
+ */
+export type TotalMap = Omit