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, 'get'> & { + /** Returns the element associated with the specified key in the TotalMap. */ + get: (key: K) => V; +}; +export type TotalMapFrom = + M extends Map ? TotalMap : never; + +export declare class Callback any> { private iface: I; public target: any; diff --git a/packages/internal/src/utils.js b/packages/internal/src/utils.js index ed82db385b6..bd69cdfabb9 100644 --- a/packages/internal/src/utils.js +++ b/packages/internal/src/utils.js @@ -52,6 +52,138 @@ export const deeplyFulfilledObject = async obj => { return deeplyFulfilled(obj); }; +/** + * @param {any} value + * @param {string | undefined} name + * @param {object | undefined} container + * @param {(value: any, name: string, record: object) => any} mapper + * @returns {any} + */ +const deepMapObjectInternal = (value, name, container, mapper) => { + if (container && typeof name === 'string') { + const mapped = mapper(value, name, container); + if (mapped !== value) { + return mapped; + } + } + + if (typeof value !== 'object' || !value) { + return value; + } + + let wasMapped = false; + const mappedEntries = Object.entries(value).map(([innerName, innerValue]) => { + const mappedInnerValue = deepMapObjectInternal( + innerValue, + innerName, + value, + mapper, + ); + wasMapped ||= mappedInnerValue !== innerValue; + return [innerName, mappedInnerValue]; + }); + + return wasMapped ? Object.fromEntries(mappedEntries) : value; +}; + +/** + * Traverses a record object structure deeply, calling a replacer for each + * enumerable string property values of an object. If none of the values are + * changed, the original object is used as-is, maintaining its identity. + * + * When an object is found as a property value, the replacer is first called on + * it. If not replaced, the object is then traversed. + * + * @param {object} obj + * @param {(value: any, name: string, record: object) => any} mapper + * @returns {object} + */ +export const deepMapObject = (obj, mapper) => + deepMapObjectInternal(obj, undefined, undefined, mapper); + +/** + * Tolerate absence of AggregateError in e.g. xsnap. + * + * @type {(errors: Error[], message?: string, options?: object) => Error} + */ +const makeAggregateError = + typeof AggregateError === 'function' + ? (errors, message, options) => AggregateError(errors, message, options) + : (errors, message, options) => { + return makeError(message ?? 'multiple errors', undefined, { + ...options, + errors, + }); + }; + +/** + * @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 makeAggregateError(errors); + } + }); +}; + +/** + * @template T + * @param {() => Promise} trier + * @param {(error?: unknown) => Promise} finalizer + * @returns {ReturnType} + */ +export const aggregateTryFinally = async (trier, finalizer) => + trier().then( + async result => finalizer().then(() => result), + async tryError => + finalizer(tryError) + .then( + () => tryError, + finalizeError => makeAggregateError([tryError, finalizeError]), + ) + .then(error => Promise.reject(error)), + ); + +/** + * Run a function with the ability to defer last-in-first-out cleanup callbacks. + * + * @template T + * @param {( + * addCleanup: (fn: (err?: unknown) => Promise) => void, + * ) => Promise} fn + * @returns {ReturnType} + */ +export const withDeferredCleanup = async fn => { + /** @type {((err?: unknown) => unknown)[]} */ + const cleanupsLIFO = []; + /** @type {(cleanup: (err?: unknown) => unknown) => void} */ + const addCleanup = cleanup => { + cleanupsLIFO.unshift(cleanup); + }; + /** @type {(err?: unknown) => Promise} */ + const finalizer = async err => { + // Run each cleanup in its own isolated stack. + const cleanupResults = cleanupsLIFO.map(async cleanup => { + await null; + return cleanup(err); + }); + await PromiseAllOrErrors(cleanupResults); + }; + return aggregateTryFinally(() => fn(addCleanup), finalizer); +}; + /** * Returns a function that uses a millisecond-based time-since-epoch capability * (such as `performance.now`) to measure execution time of an async function @@ -269,6 +401,10 @@ export const synchronizedTee = (sourceStream, readerCount) => { [Symbol.asyncIterator]() { return reader; }, + // eslint-disable-next-line no-restricted-globals + async [Symbol.asyncDispose]() { + await reader.return(); + }, }); return reader; }); diff --git a/packages/internal/test/utils.test.js b/packages/internal/test/utils.test.js index 27d391ca488..7d1b9ba5092 100644 --- a/packages/internal/test/utils.test.js +++ b/packages/internal/test/utils.test.js @@ -9,6 +9,7 @@ import { untilTrue, forever, deeplyFulfilledObject, + deepMapObject, synchronizedTee, } from '../src/utils.js'; @@ -30,6 +31,98 @@ test('deeplyFulfilledObject', async t => { }); }); +/** + * @typedef {object} DeepMapObjectTestParams + * @property {any} input + * @property {[any, any][]} replacements + * @property {string[][]} unchangedPaths + * @property {any} [expectedOutput] + */ + +/** @type {import('ava').Macro<[DeepMapObjectTestParams]>} */ +const deepMapObjectTest = test.macro({ + title(providedTitle, { input }) { + return `deepMapObject - ${providedTitle || JSON.stringify(input)}`; + }, + exec(t, { input, replacements, unchangedPaths, expectedOutput }) { + const replacementMap = new Map(replacements); + const output = deepMapObject(input, val => + replacementMap.has(val) ? replacementMap.get(val) : val, + ); + + for (const unchangedPath of unchangedPaths) { + /** @type {any} */ + let inputVal = input; + /** @type {any} */ + let outputVal = output; + for (const pathPart of unchangedPath) { + inputVal = inputVal[pathPart]; + outputVal = outputVal[pathPart]; + } + t.is( + outputVal, + inputVal, + `${['obj', ...unchangedPath].join('.')} is unchanged`, + ); + } + + if (expectedOutput) { + t.deepEqual(output, expectedOutput); + } + }, +}); + +test('identity', deepMapObjectTest, { + input: { foo: 42 }, + replacements: [], + unchangedPaths: [[]], +}); +test('non object', deepMapObjectTest, { + input: 'not an object', + replacements: [['not an object', 'not replaced']], + unchangedPaths: [[]], + expectedOutput: 'not an object', +}); +test('one level deep', deepMapObjectTest, { + input: { replace: 'replace me', notChanged: {} }, + replacements: [['replace me', 'replaced']], + unchangedPaths: [['notChanged']], + expectedOutput: { replace: 'replaced', notChanged: {} }, +}); + +const testRecord = { maybeReplace: 'replace me' }; +test('replace first before deep map', deepMapObjectTest, { + input: { replace: testRecord, notChanged: {} }, + replacements: [ + [testRecord, { different: 'something new' }], + ['replace me', 'should not be replaced'], + ], + unchangedPaths: [['notChanged']], + expectedOutput: { replace: { different: 'something new' }, notChanged: {} }, +}); + +test('not mapping top level container', deepMapObjectTest, { + input: testRecord, + replacements: [ + [testRecord, { different: 'should not be different' }], + ['replace me', 'replaced'], + ], + unchangedPaths: [], + expectedOutput: { maybeReplace: 'replaced' }, +}); +test('deep mapping', deepMapObjectTest, { + input: { + one: { two: { three: 'replace me' }, notChanged: {} }, + another: 'replace me', + }, + replacements: [['replace me', 'replaced']], + unchangedPaths: [['one', 'notChanged']], + expectedOutput: { + one: { two: { three: 'replaced' }, notChanged: {} }, + another: 'replaced', + }, +}); + test('makeMeasureSeconds', async t => { const times = [1000.25, 2000.75, NaN]; /** @type {() => number} */ diff --git a/packages/internal/tools/ava-assertions.js b/packages/internal/tools/ava-assertions.js new file mode 100644 index 00000000000..d53b36fbf57 --- /dev/null +++ b/packages/internal/tools/ava-assertions.js @@ -0,0 +1,26 @@ +/** + * Assert that the contents of `array` are + * [like]{@link https://github.com/avajs/ava/blob/main/docs/03-assertions.md#likeactual-selector-message} + * those of `expected`, including having matching lengths, with pretty diffs in + * case of mismatch. + * + * @param {import('ava').ExecutionContext} t + * @param {unknown[]} array + * @param {unknown[]} expected + * @param {string} [message] + */ +export const arrayIsLike = (t, array, expected, message) => { + const actualLength = array.length; + const expectedLength = expected.length; + const actualExcess = actualLength - expectedLength; + const comparable = + actualExcess > 0 + ? [...expected, ...Array.from({ length: actualExcess })] + : expected; + t.like(array, comparable, message); + + if (actualLength === expectedLength) return; + + const extended = [...array, ...Array.from({ length: -actualExcess })]; + t.deepEqual(extended, array, message); +}; diff --git a/packages/kmarshal/package.json b/packages/kmarshal/package.json index 6d0c4cb1bf6..5e134ebe2d7 100644 --- a/packages/kmarshal/package.json +++ b/packages/kmarshal/package.json @@ -21,9 +21,9 @@ "lint:eslint": "eslint ." }, "dependencies": { - "@endo/far": "^1.1.2", - "@endo/marshal": "^1.5.0", - "@endo/errors": "^1.2.2" + "@endo/far": "^1.1.5", + "@endo/marshal": "^1.5.3", + "@endo/errors": "^1.2.5" }, "devDependencies": { "ava": "^5.3.0" diff --git a/packages/network/package.json b/packages/network/package.json index 6f9fea25ed6..c1e3fefacdd 100644 --- a/packages/network/package.json +++ b/packages/network/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", "test:xs": "exit 0", @@ -21,22 +21,22 @@ "author": "Agoric", "license": "Apache-2.0", "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/internal": "^0.3.2", "@agoric/store": "^0.9.2", "@agoric/vat-data": "^0.5.2", - "@endo/base64": "^1.0.5", - "@endo/far": "^1.1.2", - "@endo/pass-style": "^1.4.0", - "@endo/patterns": "^1.4.0", - "@endo/promise-kit": "^1.1.2" + "@endo/base64": "^1.0.7", + "@endo/far": "^1.1.5", + "@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/swingset-vat": "^0.32.2", "@agoric/vow": "^0.1.0", "@agoric/zone": "^0.2.2", - "@endo/bundle-source": "^3.2.3", + "@endo/bundle-source": "^3.4.0", "ava": "^5.3.0", "c8": "^9.1.0" }, @@ -66,6 +66,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 90.69 + "atLeast": 91.15 } } diff --git a/packages/network/src/network.js b/packages/network/src/network.js index d6e1a3bbc86..4f31ef83b95 100644 --- a/packages/network/src/network.js +++ b/packages/network/src/network.js @@ -10,15 +10,24 @@ import { Shape } from './shapes.js'; /// /** - * @import {AttemptDescription, Bytes, Closable, CloseReason, Connection, ConnectionHandler, Endpoint, ListenHandler, Port, Protocol, ProtocolHandler, ProtocolImpl} from './types.js'; + * @import {AttemptDescription, Bytes, CloseReason, Closable, Connection, ConnectionHandler, Endpoint, ListenHandler, Port, Protocol, ProtocolHandler, ProtocolImpl} from './types.js'; + * @import {PromiseVow, Remote, VowTools} from '@agoric/vow'; */ +/** @typedef {VowTools & { finalizer: Finalizer }} Powers */ + +const sink = () => {}; +harden(sink); + /** * Compatibility note: this must match what our peers use, so don't change it * casually. */ export const ENDPOINT_SEPARATOR = '/'; +// Mark the finalizer close reason. +export const CLOSE_REASON_FINALIZER = 'closed-by-finalizer'; + /** @param {unknown} err */ export const rethrowUnlessMissing = err => { // Ugly hack rather than being able to determine if the function @@ -60,14 +69,14 @@ function throwIfInvalidPortName(specifiedName) { // Valid symbols: ., ,, _, +, -, #, [, ], <, > const portNameRegex = new RegExp('^[a-zA-Z0-9.,_+\\-#<>\\[\\]]{2,128}$'); if (!portNameRegex.test(specifiedName)) { - throw new Error(`Invalid IBC port name: ${specifiedName}`); + throw Error(`Invalid IBC port name: ${specifiedName}`); } } /** * @typedef {object} ConnectionOpts * @property {Endpoint[]} addrs - * @property {import('@agoric/vow').Remote>[]} handlers + * @property {Remote>[]} handlers * @property {MapStore} conns * @property {WeakSetStore} current * @property {0|1} l @@ -76,9 +85,9 @@ function throwIfInvalidPortName(specifiedName) { /** * @param {import('@agoric/base-zone').Zone} zone - * @param {ReturnType} powers + * @param {Powers} powers */ -const prepareHalfConnection = (zone, { watch }) => { +const prepareHalfConnection = (zone, { watch, allVows, finalizer }) => { const makeHalfConnectionKit = zone.exoClassKit( 'Connection', Shape.ConnectionI, @@ -123,18 +132,20 @@ const prepareHalfConnection = (zone, { watch }) => { return watch(innerVow, this.facets.rethrowUnlessMissingWatcher); }, async close() { - const { closed, current, conns, l, handlers } = this.state; + const { closed, current, conns, l, r } = this.state; if (closed) { throw Error(closed); } this.state.closed = 'Connection closed'; - current.delete(conns.get(l)); + + // Tear down both sides. + const lconn = conns.get(l); + const rconn = conns.get(r); + current.delete(lconn); + current.delete(rconn); + const innerVow = watch( - E(this.state.handlers[l]).onClose( - conns.get(l), - undefined, - handlers[l], - ), + allVows([finalizer.finalize(lconn), finalizer.finalize(rconn)]), this.facets.sinkWatcher, ); @@ -176,11 +187,12 @@ const prepareHalfConnection = (zone, { watch }) => { /** * @param {import('@agoric/zone').Zone} zone - * @param {import('@agoric/vow').Remote>} handler0 + * @param {Remote>} handler0 * @param {Endpoint} addr0 - * @param {import('@agoric/vow').Remote>} handler1 + * @param {Remote>} handler1 * @param {Endpoint} addr1 * @param {(opts: ConnectionOpts) => Connection} makeConnection + * @param {Finalizer} finalizer * @param {WeakSetStore} [current] */ export const crossoverConnection = ( @@ -190,6 +202,7 @@ export const crossoverConnection = ( handler1, addr1, makeConnection, + finalizer, current = zone.detached().weakSetStore('crossoverCurrentConnections'), ) => { const detached = zone.detached(); @@ -197,7 +210,7 @@ export const crossoverConnection = ( /** @type {MapStore} */ const conns = detached.mapStore('addrToConnections'); - /** @type {import('@agoric/vow').Remote>[]} */ + /** @type {Remote>[]} */ const handlers = harden([handler0, handler1]); /** @type {Endpoint[]} */ const addrs = harden([addr0, addr1]); @@ -215,9 +228,13 @@ export const crossoverConnection = ( * @param {number} r remote side of the connection */ const openHalfConnection = (l, r) => { - current.add(conns.get(l)); + const lconn = conns.get(l); + current.add(lconn); + if (!finalizer.has(lconn)) { + finalizer.initConnection(lconn, handlers[l]); + } E(handlers[l]) - .onOpen(conns.get(l), addrs[l], addrs[r], handlers[l]) + .onOpen(lconn, addrs[l], addrs[r], handlers[l]) .catch(rethrowUnlessMissing); }; @@ -233,9 +250,9 @@ export const crossoverConnection = ( /** * @param {import('@agoric/zone').Zone} zone * @param {(opts: ConnectionOpts) => Connection} makeConnection - * @param {ReturnType} powers + * @param {Powers} powers */ -const prepareInboundAttempt = (zone, makeConnection, { watch }) => { +const prepareInboundAttempt = (zone, makeConnection, { watch, finalizer }) => { const makeInboundAttemptKit = zone.exoClassKit( 'InboundAttempt', Shape.InboundAttemptI, @@ -245,7 +262,7 @@ const prepareInboundAttempt = (zone, makeConnection, { watch }) => { * @param {string} opts.remoteAddr * @param {MapStore>} opts.currentConnections * @param {string} opts.listenPrefix - * @param {MapStore>]>} opts.listening + * @param {MapStore>]>} opts.listening */ ({ localAddr, @@ -288,6 +305,7 @@ const prepareInboundAttempt = (zone, makeConnection, { watch }) => { const current = currentConnections.get(port); current.delete(this.facets.inboundAttempt); + finalizer.unpin(this.facets.inboundAttempt); const innerVow = watch( E(listener).onReject(port, localAddr, remoteAddr, listener), @@ -300,7 +318,7 @@ const prepareInboundAttempt = (zone, makeConnection, { watch }) => { * @param {object} opts * @param {string} [opts.localAddress] * @param {string} [opts.remoteAddress] - * @param {import('@agoric/vow').Remote} opts.handler + * @param {Remote} opts.handler */ async accept({ localAddress, remoteAddress, handler: rchandler }) { const { consummated, localAddr, remoteAddr } = this.state; @@ -342,15 +360,12 @@ const prepareInboundAttempt = (zone, makeConnection, { watch }) => { return crossoverConnection( zone, - /** @type {import('@agoric/vow').Remote>} */ ( - lchandler - ), + /** @type {Remote>} */ (lchandler), localAddress, - /** @type {import('@agoric/vow').Remote>} */ ( - rchandler - ), + /** @type {Remote>} */ (rchandler), remoteAddress, makeConnection, + finalizer, current, )[1]; }, @@ -398,22 +413,22 @@ const RevokeState = /** @type {const} */ ({ /** * @param {import('@agoric/zone').Zone} zone - * @param {ReturnType} powers + * @param {Powers} powers */ const preparePort = (zone, powers) => { const makeIncapable = zone.exoClass('Incapable', undefined, () => ({}), {}); - const { watch, allVows } = powers; + const { finalizer, watch, allVows } = powers; /** * @param {object} opts * @param {Endpoint} opts.localAddr - * @param {MapStore>]>} opts.listening - * @param {SetStore>} opts.openConnections + * @param {MapStore>]>} opts.listening + * @param {SetStore>} opts.openConnections * @param {MapStore>} opts.currentConnections * @param {MapStore} opts.boundPorts - * @param {import('@agoric/vow').Remote} opts.protocolHandler - * @param {import('@agoric/vow').Remote} opts.protocolImpl + * @param {Remote} opts.protocolHandler + * @param {Remote} opts.protocolImpl */ const initPort = ({ localAddr, @@ -443,7 +458,7 @@ const preparePort = (zone, powers) => { // Works even after revoke(). return this.state.localAddr; }, - /** @param {import('@agoric/vow').Remote} listenHandler */ + /** @param {Remote} listenHandler */ async addListener(listenHandler) { const { revoked, listening, localAddr, protocolHandler } = this.state; @@ -458,9 +473,7 @@ const preparePort = (zone, powers) => { } listening.set(localAddr, [ this.facets.port, - /** @type {import('@agoric/vow').Remote>} */ ( - listenHandler - ), + /** @type {Remote>} */ (listenHandler), ]); E(lhandler).onRemove(lport, lhandler).catch(rethrowUnlessMissing); } else { @@ -468,9 +481,7 @@ const preparePort = (zone, powers) => { localAddr, harden([ this.facets.port, - /** @type {import('@agoric/vow').Remote>} */ ( - listenHandler - ), + /** @type {Remote>} */ (listenHandler), ]), ); } @@ -489,7 +500,7 @@ const preparePort = (zone, powers) => { ); return watch(innerVow, this.facets.rethrowUnlessMissingWatcher); }, - /** @param {import('@agoric/vow').Remote} listenHandler */ + /** @param {Remote} listenHandler */ async removeListener(listenHandler) { const { listening, localAddr, protocolHandler } = this.state; listening.has(localAddr) || Fail`Port ${localAddr} is not listening`; @@ -511,11 +522,11 @@ const preparePort = (zone, powers) => { }, /** * @param {Endpoint} remotePort - * @param {import('@agoric/vow').Remote} [connectionHandler] + * @param {Remote} [connectionHandler] */ async connect( remotePort, - connectionHandler = /** @type {import('@agoric/vow').Remote} */ ( + connectionHandler = /** @type {Remote} */ ( makeIncapable() ), ) { @@ -527,7 +538,7 @@ const preparePort = (zone, powers) => { return watch( E(protocolImpl).outbound(this.facets.port, dst, connectionHandler), this.facets.portConnectWatcher, - { revoked }, + { chandler: connectionHandler }, ); }, async revoke() { @@ -538,7 +549,6 @@ const preparePort = (zone, powers) => { Fail`Port ${localAddr} is already revoked`; this.state.revoked = RevokeState.REVOKING; - const revokeVow = watch( E(protocolHandler).onRevoke( this.facets.port, @@ -564,15 +574,16 @@ const preparePort = (zone, powers) => { }, }, portConnectWatcher: { - onFulfilled(conn, watchContext) { - const { revoked } = watchContext; - const { openConnections } = this.state; + onFulfilled(conn, { chandler }) { + const { openConnections, revoked } = this.state; + if (!finalizer.has(conn)) { + finalizer.initConnection(conn, chandler); + } if (revoked) { - void E(conn).close(); - } else { - openConnections.add(conn); + return finalizer.finalize(conn); } + openConnections.add(conn); return conn; }, }, @@ -586,8 +597,8 @@ const preparePort = (zone, powers) => { const ps = []; ps.push( - ...values.map(conn => - watch(E(conn).close(), this.facets.sinkWatcher), + ...values.map(obj => + watch(finalizer.finalize(obj), this.facets.sinkWatcher), ), ); @@ -650,12 +661,12 @@ const preparePort = (zone, powers) => { /** * @param {import('@agoric/base-zone').Zone} zone - * @param {ReturnType} powers + * @param {Powers} powers */ const prepareBinder = (zone, powers) => { const makeConnection = prepareHalfConnection(zone, powers); - const { watch } = powers; + const { watch, finalizer } = powers; const makeInboundAttempt = prepareInboundAttempt( zone, @@ -730,8 +741,8 @@ const prepareBinder = (zone, powers) => { * @param {object} opts * @param {MapStore>} opts.currentConnections * @param {MapStore} opts.boundPorts - * @param {MapStore>]>} opts.listening - * @param {import('@agoric/vow').Remote} opts.protocolHandler + * @param {MapStore>]>} opts.listening + * @param {Remote} opts.protocolHandler */ ({ currentConnections, boundPorts, listening, protocolHandler }) => { /** @type {SetStore} */ @@ -777,7 +788,7 @@ const prepareBinder = (zone, powers) => { const innerVow = watch( E( - /** @type {import('@agoric/vow').Remote>} */ ( + /** @type {Remote>} */ ( protocolHandler ), ).onInstantiate( @@ -819,7 +830,7 @@ const prepareBinder = (zone, powers) => { // Allocate a local address. const instantiateInnerVow = watch( E( - /** @type {import('@agoric/vow').Remote>} */ ( + /** @type {Remote>} */ ( protocolHandler ), ).onInstantiate(port, localAddr, remoteAddr, protocolHandler), @@ -904,6 +915,7 @@ const prepareBinder = (zone, powers) => { }); current.add(inboundAttempt); + finalizer.initCloser(inboundAttempt); return inboundAttempt; }, }, @@ -945,7 +957,7 @@ const prepareBinder = (zone, powers) => { const innerVow = watch( E( - /** @type {import('@agoric/vow').Remote>} */ ( + /** @type {Remote>} */ ( protocolHandler ), ).onInstantiate( @@ -1008,15 +1020,12 @@ const prepareBinder = (zone, powers) => { return crossoverConnection( zone, - /** @type {import('@agoric/vow').Remote>} */ ( - lchandler - ), + /** @type {Remote>} */ (lchandler), negotiatedLocalAddress || requestedLocalAddress, - /** @type {import('@agoric/vow').Remote>} */ ( - rchandler - ), + /** @type {Remote>} */ (rchandler), negotiatedRemoteAddress || requestedRemoteAddress, makeConnection, + finalizer, current, )[0]; }, @@ -1169,13 +1178,13 @@ const prepareBinder = (zone, powers) => { /** * @param {import('@agoric/base-zone').Zone} zone - * @param {ReturnType} powers + * @param {Powers} powers */ export const prepareNetworkProtocol = (zone, powers) => { const makeBinderKit = prepareBinder(zone, powers); /** - * @param {import('@agoric/vow').Remote} protocolHandler + * @param {Remote} protocolHandler * @returns {Protocol} */ const makeNetworkProtocol = protocolHandler => { @@ -1187,7 +1196,7 @@ export const prepareNetworkProtocol = (zone, powers) => { /** @type {MapStore} */ const boundPorts = detached.mapStore('addrToPort'); - /** @type {MapStore>]>} */ + /** @type {MapStore>]>} */ const listening = detached.mapStore('listening'); const { binder, protocolImpl } = makeBinderKit({ @@ -1261,17 +1270,17 @@ export const prepareEchoConnectionKit = zone => { }, /** * @param {Connection} _connection - * @param {CloseReason} [_reason] + * @param {CloseReason} [reason] * @param {ConnectionHandler} [_connectionHandler] */ - async onClose(_connection, _reason, _connectionHandler) { + async onClose(_connection, reason, _connectionHandler) { const { closed } = this.state; if (closed) { throw Error(closed); } - this.state.closed = 'Connection closed'; + this.state.closed = reason || 'Connection closed'; }, }, listener: { @@ -1293,14 +1302,14 @@ export const prepareEchoConnectionKit = zone => { * Create a protocol handler that just connects to itself. * * @param {import('@agoric/base-zone').Zone} zone - * @param {ReturnType} powers + * @param {VowTools} powers */ export function prepareLoopbackProtocolHandler(zone, { watch, allVows }) { const detached = zone.detached(); /** @param {string} [instancePrefix] */ const initHandler = (instancePrefix = 'nonce/') => { - /** @type {MapStore, import('@agoric/vow').Remote>]>} */ + /** @type {MapStore, Remote>]>} */ const listeners = detached.mapStore('localAddr'); return { @@ -1379,7 +1388,7 @@ export function prepareLoopbackProtocolHandler(zone, { watch, allVows }) { localAddr, harden([ port, - /** @type {import('@agoric/vow').Remote>} */ ( + /** @type {Remote>} */ ( listenHandler ), ]), @@ -1390,17 +1399,15 @@ export function prepareLoopbackProtocolHandler(zone, { watch, allVows }) { localAddr, harden([ port, - /** @type {import('@agoric/vow').Remote>} */ ( - listenHandler - ), + /** @type {Remote>} */ (listenHandler), ]), ); } }, /** - * @param {import('@agoric/vow').Remote} port + * @param {Remote} port * @param {Endpoint} localAddr - * @param {import('@agoric/vow').Remote} listenHandler + * @param {Remote} listenHandler * @param {*} _protocolHandler */ async onListenRemove(port, localAddr, listenHandler, _protocolHandler) { @@ -1453,7 +1460,7 @@ export function prepareLoopbackProtocolHandler(zone, { watch, allVows }) { /** * * @param {import('@agoric/base-zone').Zone} zone - * @param {ReturnType} powers + * @param {Powers} powers */ export const preparePortAllocator = (zone, { watch }) => zone.exoClass( @@ -1523,3 +1530,79 @@ export const preparePortAllocator = (zone, { watch }) => }, ); /** @typedef {ReturnType>} PortAllocator */ + +/** + * Return a package-specific singleton that pins objects until they are + * explicitly unpinned or finalized. It needs to pin objects only because they + * are resources that need to be released. + * + * The reason this functionality wasn't just baked into the other network exos + * is to maintain upgrade-compatible with minimal additional changes. + * + * @param {import('@agoric/base-zone').Zone} zone + * @param {VowTools} vowTools + */ +const prepareFinalizer = (zone, { watch }) => { + /** + * @type {MapStore<{}, + * { conn: Remote, handler: Remote>} | + * { closer: Remote<{ close(): PromiseVow }> } + * >} + */ + const objToFinalizerInfo = zone.mapStore('objToFinalizerInfo'); + return zone.exo('NetworkFinalizer', undefined, { + has(obj) { + return objToFinalizerInfo.has(obj); + }, + /** + * Add a connection and handler for an `onClose` method to be called upon + * finalization. + * @param {Remote} conn + * @param {Remote>} handler + */ + initConnection(conn, handler) { + objToFinalizerInfo.init(conn, harden({ conn, handler })); + }, + /** + * Add an object with a `close` method to be called (such as an + * `inboundAttempt`) upon finalization. + * @param {Remote<{ close(): PromiseVow }>} closer + */ + initCloser(closer) { + objToFinalizerInfo.init(closer, harden({ closer })); + }, + finalize(obj) { + if (!objToFinalizerInfo.has(obj)) { + return; + } + const disposeInfo = objToFinalizerInfo.get(obj); + if ('conn' in disposeInfo) { + // A connection+handler. + const { conn, handler } = disposeInfo; + objToFinalizerInfo.delete(obj); + return watch(E(handler).onClose(conn, CLOSE_REASON_FINALIZER, handler)); + } else if ('closer' in disposeInfo) { + // Just something with a `close` method. + const { closer } = disposeInfo; + objToFinalizerInfo.delete(obj); + return watch(E(closer).close()); + } + }, + unpin(obj) { + objToFinalizerInfo.delete(obj); + }, + }); +}; +harden(prepareFinalizer); + +/** + * @param {import('@agoric/base-zone').Zone} zone + * @param {VowTools} vowTools + * @returns {Powers} + */ +export const prepareNetworkPowers = (zone, vowTools) => { + const finalizer = prepareFinalizer(zone, vowTools); + return harden({ ...vowTools, finalizer }); +}; + +/** @typedef {ReturnType} Finalizer */ diff --git a/packages/network/src/router.js b/packages/network/src/router.js index cea73335bd2..b0b6f003511 100644 --- a/packages/network/src/router.js +++ b/packages/network/src/router.js @@ -10,8 +10,8 @@ import { ENDPOINT_SEPARATOR, prepareNetworkProtocol } from './network.js'; import { Shape } from './shapes.js'; /** - * @import {AttemptDescription, Bytes, Closable, CloseReason, Connection, ConnectionHandler, Endpoint, ListenHandler, Port, Protocol, ProtocolHandler, ProtocolImpl} from './types.js'; - * @import {PromiseVow, Remote, VowKit, VowResolver, VowTools} from '@agoric/vow'; + * @import {Endpoint, Port, Protocol, ProtocolHandler} from './types.js'; + * @import {PromiseVow, Remote, VowTools} from '@agoric/vow'; */ /** @@ -108,7 +108,7 @@ export const prepareRouter = zone => { * Create a router that behaves like a Protocol. * * @param {import('@agoric/base-zone').Zone} zone - * @param {ReturnType} powers + * @param {import('./network.js').Powers} powers * @param {typeof defaultE} [E] Eventual sender */ export const prepareRouterProtocol = (zone, powers, E = defaultE) => { diff --git a/packages/network/src/shapes.js b/packages/network/src/shapes.js index fab74462b3e..726b2261112 100644 --- a/packages/network/src/shapes.js +++ b/packages/network/src/shapes.js @@ -158,18 +158,18 @@ export const Shape = /** @type {const} */ harden({ ).returns(Shape2.Vow$(M.undefined())), }), protocolHandlerAcceptWatcher: M.interface('ProtocolHandlerAcceptWatcher', { - onFulfilled: M.call(M.any()).rest(M.any()).returns(), + onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()), }), protocolHandlerInstantiateWatcher: M.interface( 'ProtocolHandlerInstantiateWatcher', { - onFulfilled: M.call(M.any()).rest(M.any()).returns(), + onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()), }, ), protocolHandlerConnectWatcher: M.interface( 'ProtocolHandlerConnectWatcher', { - onFulfilled: M.call(M.any()).rest(M.any()).returns(), + onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()), }, ), rethrowUnlessMissingWatcher: M.interface('RethrowUnlessMissingWatcher', { diff --git a/packages/network/test/fakes.js b/packages/network/test/fakes.js index 70f3d65c44f..9ad80dca982 100644 --- a/packages/network/test/fakes.js +++ b/packages/network/test/fakes.js @@ -3,6 +3,7 @@ import { prepareVowTools } from '@agoric/vow'; import assert from 'node:assert/strict'; import { prepareEchoConnectionKit, + prepareNetworkPowers, prepareNetworkProtocol, preparePortAllocator, } from '../src/index.js'; @@ -104,9 +105,10 @@ export const prepareProtocolHandler = ( * @param {Zone} zone */ export const fakeNetworkEchoStuff = zone => { - const powers = prepareVowTools(zone); - const { makeVowKit, when } = powers; + const vowTools = prepareVowTools(zone); + const powers = prepareNetworkPowers(zone, vowTools); + const { makeVowKit, when } = powers; const makeNetworkProtocol = prepareNetworkProtocol(zone, powers); const makeEchoConnectionHandler = prepareEchoConnectionKit(zone); const makeProtocolHandler = prepareProtocolHandler( diff --git a/packages/network/test/network-misc.test.js b/packages/network/test/network-misc.test.js index 968cdf41339..eb56e40335a 100644 --- a/packages/network/test/network-misc.test.js +++ b/packages/network/test/network-misc.test.js @@ -12,7 +12,9 @@ import { prepareLoopbackProtocolHandler, prepareNetworkProtocol, prepareRouter, + prepareNetworkPowers, unparse, + CLOSE_REASON_FINALIZER, } from '../src/index.js'; import { fakeNetworkEchoStuff } from './fakes.js'; @@ -39,13 +41,11 @@ test('handled protocol', async t => { const port = await when(protocol.bindPort('/ibc/*/ordered')); - const { vow, resolver } = makeVowKit(); - const prepareTestProtocolHandler = () => { const makeTestProtocolHandler = zone.exoClass( 'TestProtocolHandler', undefined, - () => ({ resolver }), + resolver => ({ resolver }), { async onOpen(connection, localAddr, remoteAddr) { t.is(localAddr, '/ibc/*/ordered'); @@ -53,11 +53,11 @@ test('handled protocol', async t => { const ack = await when(E(connection).send('ping')); // log(ack); t.is(`${ack}`, 'ping', 'received pong'); - void connection.close(); + await connection.close(); }, async onClose(_connection, reason) { - t.is(reason, undefined, 'no close reason'); - this.state.resolver.resolve(null); + t.is(reason, CLOSE_REASON_FINALIZER, 'finalizer close reason'); + this.state.resolver.resolve(reason); }, async onReceive(_connection, bytes) { t.is(`${bytes}`, 'ping'); @@ -71,8 +71,9 @@ test('handled protocol', async t => { const makeTestProtocolHandler = prepareTestProtocolHandler(); - await port.connect('/ibc/*/ordered/echo', makeTestProtocolHandler()); - await when(vow); + const { vow, resolver } = makeVowKit(); + await port.connect('/ibc/*/ordered/echo', makeTestProtocolHandler(resolver)); + t.is(await when(vow), CLOSE_REASON_FINALIZER); await when(port.revoke()); }); @@ -159,16 +160,14 @@ test('protocol connection listen', async t => { const { vow, resolver } = makeVowKit(); const prepareConnectionHandler = () => { - let handler; - const makeConnectionHandler = zone.exoClass( 'connectionHandler', undefined, - () => ({ resolver }), + () => ({ handler: undefined, resolver }), { async onOpen(connection, _localAddr, _remoteAddr, connectionHandler) { t.assert(connectionHandler, `connectionHandler is tracked in onOpen`); - handler = connectionHandler; + this.state.handler = connectionHandler; const ack = await when(connection.send('ping')); t.is(`${ack}`, 'ping', 'received pong'); await when(connection.close()); @@ -176,18 +175,17 @@ test('protocol connection listen', async t => { async onClose(c, reason, connectionHandler) { t.is( connectionHandler, - handler, + this.state.handler, `connectionHandler is tracked in onClose`, ); - handler = undefined; + this.state.handler = undefined; t.assert(c, 'connection is passed to onClose'); - t.is(reason, undefined, 'no close reason'); - this.state.resolver.resolve(null); + this.state.resolver.resolve(reason); }, async onReceive(c, packet, connectionHandler) { t.is( connectionHandler, - handler, + this.state.handler, `connectionHandler is tracked in onReceive`, ); t.assert(c, 'connection is passed to onReceive'); @@ -285,7 +283,8 @@ test('protocol connection listen', async t => { test('loopback protocol', async t => { const zone = provideDurableZone('network-loopback-protocol'); - const powers = prepareVowTools(zone); + const vowTools = prepareVowTools(zone); + const powers = prepareNetworkPowers(zone, vowTools); const { makeVowKit, when } = powers; const makeLoopbackProtocolHandler = prepareLoopbackProtocolHandler( zone, @@ -365,7 +364,7 @@ test('loopback protocol', async t => { }); test('routing', async t => { - const zone = provideDurableZone('network-loopback-protocol'); + const zone = provideDurableZone('routing-protocol'); const makeRouter = prepareRouter(zone); const router = makeRouter(); t.deepEqual(router.getRoutes('/if/local'), [], 'get routes matches none'); diff --git a/packages/notifier/package.json b/packages/notifier/package.json index b20c2ec2614..425c3dd17af 100644 --- a/packages/notifier/package.json +++ b/packages/notifier/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 --config=ava-nesm.config.js", "test:xs": "exit 0", @@ -33,21 +33,21 @@ }, "homepage": "https://github.com/Agoric/agoric-sdk#readme", "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/internal": "^0.3.2", "@agoric/vat-data": "^0.5.2", - "@endo/far": "^1.1.2", - "@endo/marshal": "^1.5.0", - "@endo/patterns": "^1.4.0", - "@endo/promise-kit": "^1.1.2" + "@endo/far": "^1.1.5", + "@endo/marshal": "^1.5.3", + "@endo/patterns": "^1.4.3", + "@endo/promise-kit": "^1.1.5" }, "devDependencies": { "@agoric/kmarshal": "^0.1.0", "@agoric/swingset-liveslots": "^0.10.2", "@agoric/swing-store": "^0.9.1", "@agoric/swingset-vat": "^0.32.2", - "@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", "c8": "^9.1.0" }, diff --git a/packages/notifier/src/notifier.js b/packages/notifier/src/notifier.js index 9439bbf528f..3c6ce35f19f 100644 --- a/packages/notifier/src/notifier.js +++ b/packages/notifier/src/notifier.js @@ -7,6 +7,7 @@ import { makePublishKit } from './publish-kit.js'; import { subscribeLatest } from './subscribe.js'; /** + * @import {Remote} from '@agoric/internal'; * @import {LatestTopic, Notifier, NotifierRecord, PublishKit, Subscriber, UpdateRecord} from './types.js'; */ @@ -41,7 +42,7 @@ export const makeNotifier = sharableInternalsP => { /** * @template T - * @param {ERef>} subscriber + * @param {ERef> | Remote>} subscriber * @returns {Notifier} */ export const makeNotifierFromSubscriber = subscriber => { diff --git a/packages/notifier/src/publish-kit.js b/packages/notifier/src/publish-kit.js index 86a3d1f295f..e2403db1455 100644 --- a/packages/notifier/src/publish-kit.js +++ b/packages/notifier/src/publish-kit.js @@ -18,7 +18,7 @@ const makeQuietRejection = reason => { return rejection; }; const tooFarRejection = makeQuietRejection( - harden(new Error('Cannot read past end of iteration.')), + harden(Error('Cannot read past end of iteration.')), ); export const PublisherI = M.interface('Publisher', { diff --git a/packages/orchestration/USAGE.md b/packages/orchestration/USAGE.md new file mode 100644 index 00000000000..6236876ad04 --- /dev/null +++ b/packages/orchestration/USAGE.md @@ -0,0 +1,46 @@ +# Usage + +Last verified 2024-09-06 + +This document describes some example contracts and test suites showing how to use Orchestration. + +## Example contracts + +See [`src/examples`](src/examples) + + +| Contract Name | Status | Description | Features Used | +|---------------|-------------|---------------|--------| +| [auto-stake-it](/packages/orchestration/src/examples/auto-stake-it.contract.js) | Ready 🟢 | Sets up an IBC hook to automatically stake tokens on a remote chain received at a deposit address. | - `LocalOrchestrationAccount`
- `CosmosOrchestrationAccount`
- `Vtransfer` (IBC Hooks) | +| [basic-flows](/packages/orchestration/src/examples/basic-flows.contract.js) | Ready 🟢 | Creates an account on a remote chain and returns a continuing offer with all platform-provided invitationMakers. | - `CosmosOrchestrationAccount`
- `LocalOrchestrationAccount`| +| [query-flows](/packages/orchestration/src/fixtures/query-flows.contract.js) | Ready 🟢 | Test fixture that enables querying account balances on local and remote chains. | - `Chain`
- `LocalOrchestrationAccount`
- `CosmosOrchestrationAccount`
- Interchain Queries | +| [send-anywhere](/packages/orchestration/src/examples/send-anywhere.contract.js) | Ready 🟢 | Allows sending payments (tokens) over IBC to another chain. | - `LocalOrchestrationAccoun`t
- `Vtransfer` (IBC Hooks) | +| [stake-bld](/packages/orchestration/src/examples/stake-bld.contract.js) | Ready 🟢 | Returns a `LocalOrchestrationAccount` that can perform staking actions. | - `LocalOrchestrationAccount` | Ready 🟢 | +| [stake-ica](/packages/orchestration/src/examples/stake-ica.contract.js) | Ready 🟢 | Returns a `CosmosOrchestrationAccount` that can perform staking actions. | - `CosmosOrchestrationAccount` | Ready 🟢 | +| [staking-combinations](/packages/orchestration/src/examples/staking-combinations.contract.js) | Ready 🟢 | Combines actions into a single offer flow and demonstrates writing continuing offers. | - `CosmosOrchestrationAccount`
- `CombineInvitationMakers`
- Continuing Offers | +| [swap](/packages/orchestration/src/examples/swap.contract.js) | Under Construction 🚧 | Demonstrates asset swapping on an external chain. | - `CosmosOrchestrationAccount`
- `ChainHub` | +| [unbond](/packages/orchestration/src/examples/unbond.contract.js) | Under Construction 🚧 | Undelegates tokens for an ICA and liquid stakes them. | - `CosmosOrchestrationAccount` | + +## E2E Test Suites + +| Test Name | Description | Contract Used | Methods Used | +|-----------|-------------|---------------|--------------| +| [account-balance-queries](/multichain-testing/test/account-balance-queries.test.ts) | Tests balance querying on local and remote chains, verifying empty balance return for newly created accounts. | query-flows | - `orch.getChain()`
- `orch.makeAccount()`
- `orchAccount.getBalance()`
- `orchAccount.getBalances()` | +| [auto-stake-it](/multichain-testing/test/auto-stake-it.test.ts) | Tests the creation of Local and Cosmos orchestration accounts and the auto-delegation process via IBC transfer. | auto-stake-it | - `orch.getChain()`
- `chain.makeAccount()`
- `localOrchAccount.monitorTransfers()`
- `cosmosOrchAccount.delegate()` | +| [basic-flows](/multichain-testing/test/basic-flows.test.ts) | Verifies the creation of a remote chain account and the generation of a continuing offer with various invitationMakers. | basic-flows | - `orch.getChain()`
- `orch.makeAccount()` | +| [chain-queries](/multichain-testing/test/chain-queries.test.ts) | Tests balance queries via ICQ and local chain queries, including error handling for chains with ICQ disabled. | query-flows | - `orch.getChain()`
- `chain.query()` | +| [ica-channel-close](/multichain-testing/test/ica-channel-close.test.ts) | Tests ICA account deactivation and reactivation, and verifies channel closure processes for ICA and Transfer channels. | basic-flows | - `orch.getChain()`
- `orch.makeAccount()`
- `orchAccount.deactivate()`
- `orchAccount.reactivate()` | +| [send-anywhere](/multichain-testing/test/send-anywhere.test.ts) | Tests the process of sending payments over IBC, including account creation, deposit, and transfer operations. | send-anywhere | - `orch.getChain()`
- `chain.getVBankAssetInfo()`
- `chain.makeAccount()`
- `localOrchAccount.makeAccount()`
- `localOrchAccount.deposit()`
- `localOrchAccount.transfer()`
- `zoeTools.localTransfer()` | +| [stake-ica](/multichain-testing/test/stake-ica.test.ts) | Verifies staking operations including delegation, reward withdrawal, and undelegation. | stakeIca | - `orch.getChain()`
- `orch.makeAccount()`
- `orchAccount.delegate()`
- `orchAccount.withdrawReward()`
- `orchAccount.undelegate()` | + +## Not Yet Tested + +| Contract Name | Not Yet Tested Features | +|---------------|--------------------------| +| [basic-flows](/packages/orchestration/src/examples/basic-flows.contract.js) | - `.send()`, `sendAll()` methods and `Send`, `SendAll` invitations ([#9193](https://github.com/Agoric/agoric-sdk/issues/9193))
- `CosmosOrchAccount.transfer()`, `Transfer` invitation ([#9193](https://github.com/Agoric/agoric-sdk/issues/9193)) | +| [send-anywhere](/packages/orchestration/src/examples/send-anywhere.contract.js) | - Multi-hop (PFM) transfers (not implemented in contract) ([#10006](https://github.com/Agoric/agoric-sdk/issues/10006)) | +| [stakeIca](/packages/orchestration/src/examples/stake-ica.contract.js) | - Redelegate
- WithdrawRewards (plural) (not implemented)
- StakingQueries (not implemented) ([#10016](https://github.com/Agoric/agoric-sdk/issues/10016))
- Staking Flows for LocalOrchAccount
- Written as async-flow ([#9838](https://github.com/Agoric/agoric-sdk/issues/9838)) | +| [stakeBld](/packages/orchestration/src/examples/stake-bld.contract.js) | - Everything*, created before e2e test suite
- Consider folding under generic "stake" contract, once [interfaces are the same](https://github.com/Agoric/agoric-sdk/blob/1976c502bcaac2e7d21f42b30447671a61053236/packages/orchestration/src/exos/local-orchestration-account.js#L487)| +| [swap](/packages/orchestration/src/examples/swap.contract.js) | - Everything - contract incomplete ([#8863](https://github.com/Agoric/agoric-sdk/issues/8863)) | +| [unbond](/packages/orchestration/src/examples/unbond.contract.js) | - Everything - contract incomplete ([#9782](https://github.com/Agoric/agoric-sdk/issues/9782)) | +| [staking-combinations](/packages/orchestration/src/examples/staking-combinations.contract.js) | Only tested via [unit tests](/packages/orchestration/src/examples/staking-combinations.contract.js) | diff --git a/packages/orchestration/index.js b/packages/orchestration/index.js index 09afecb813d..af958a142b6 100644 --- a/packages/orchestration/index.js +++ b/packages/orchestration/index.js @@ -4,4 +4,7 @@ export * from './src/types.js'; export * from './src/exos/cosmos-interchain-service.js'; +export * from './src/exos/chain-hub-admin.js'; export * from './src/typeGuards.js'; + +export { withOrchestration } from './src/utils/start-helper.js'; diff --git a/packages/orchestration/package.json b/packages/orchestration/package.json index d2c37ec1d18..96fdcad0e17 100644 --- a/packages/orchestration/package.json +++ b/packages/orchestration/package.json @@ -12,7 +12,7 @@ "build": "exit 0", "codegen": "scripts/fetch-chain-info.ts", "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", @@ -46,21 +46,21 @@ "@agoric/vow": "^0.1.0", "@agoric/zoe": "^0.26.2", "@agoric/zone": "^0.2.2", - "@endo/base64": "^1.0.5", - "@endo/errors": "^1.2.2", - "@endo/far": "^1.1.2", - "@endo/marshal": "^1.5.0", - "@endo/patterns": "^1.4.0", - "@noble/hashes": "github:paulmillr/noble-hashes#ae060da" + "@endo/base64": "^1.0.7", + "@endo/errors": "^1.2.5", + "@endo/far": "^1.1.5", + "@endo/marshal": "^1.5.3", + "@endo/patterns": "^1.4.3", + "@noble/hashes": "^1.5.0" }, "devDependencies": { "@agoric/swingset-liveslots": "^0.10.2", "@chain-registry/client": "^1.47.4", "@cosmjs/amino": "^0.32.3", "@cosmjs/proto-signing": "^0.32.3", - "@endo/bundle-source": "^3.2.3", - "@endo/import-bundle": "^1.1.2", - "@endo/ses-ava": "^1.2.2", + "@endo/bundle-source": "^3.4.0", + "@endo/import-bundle": "^1.2.2", + "@endo/ses-ava": "^1.2.5", "ava": "^5.3.1", "c8": "^9.1.0", "prettier": "^3.3.2" @@ -92,6 +92,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 98.05 + "atLeast": 97.6 } } diff --git a/packages/orchestration/src/chain-info.js b/packages/orchestration/src/chain-info.js index b5c90a1da6d..b290bfeaa29 100644 --- a/packages/orchestration/src/chain-info.js +++ b/packages/orchestration/src/chain-info.js @@ -1,72 +1,53 @@ import { E } from '@endo/far'; -import { mustMatch } from '@endo/patterns'; -import { normalizeConnectionInfo } from './exos/chain-hub.js'; +import { M, mustMatch } from '@endo/patterns'; +import { + ASSETS_KEY, + CHAIN_KEY, + CONNECTIONS_KEY, + normalizeConnectionInfo, +} from './exos/chain-hub.js'; import fetchedChainInfo from './fetched-chain-info.js'; // Refresh with scripts/refresh-chain-info.ts -import { CosmosChainInfoShape } from './typeGuards.js'; +import { CosmosAssetInfoShape, CosmosChainInfoShape } from './typeGuards.js'; -/** @import {CosmosChainInfo, EthChainInfo, IBCConnectionInfo} from './types.js'; */ +/** @import {Chain, CosmosAssetInfo, CosmosChainInfo, EthChainInfo, IBCConnectionInfo} from './types.js'; */ +/** @import {NameAdmin} from '@agoric/vats'; */ -/** @typedef {CosmosChainInfo | EthChainInfo} ChainInfo */ +/** + * Info used to build a {@link Chain} object - channel, connection, and denom + * info. + * + * @typedef {CosmosChainInfo | EthChainInfo} ChainInfo + */ const knownChains = /** @satisfies {Record} */ ( - harden({ - ...fetchedChainInfo, - // FIXME does not have useful connections - // UNTIL https://github.com/Agoric/agoric-sdk/issues/9492 - agoriclocal: { - chainId: 'agoriclocal', - connections: { - 'cosmoshub-4': { - id: 'connection-1', - client_id: '07-tendermint-3', - counterparty: { - client_id: '07-tendermint-2', - connection_id: 'connection-1', - prefix: { - key_prefix: '', - }, - }, - state: 3 /* IBCConnectionState.STATE_OPEN */, - transferChannel: { - portId: 'transfer', - channelId: 'channel-1', - counterPartyChannelId: 'channel-1', - counterPartyPortId: 'transfer', - ordering: 1 /* Order.ORDER_UNORDERED */, - state: 3 /* IBCConnectionState.STATE_OPEN */, - version: 'ics20-1', - }, - }, - osmosislocal: { - id: 'connection-0', - client_id: '07-tendermint-2', - counterparty: { - client_id: '07-tendermint-2', - connection_id: 'connection-1', - prefix: { - key_prefix: '', - }, - }, - state: 3 /* IBCConnectionState.STATE_OPEN */, - transferChannel: { - portId: 'transfer', - channelId: 'channel-0', - counterPartyChannelId: 'channel-1', - counterPartyPortId: 'transfer', - ordering: 1 /* Order.ORDER_UNORDERED */, - state: 3 /* IBCConnectionState.STATE_OPEN */, - version: 'ics20-1', - }, - }, - }, - }, - }) + harden(fetchedChainInfo) ); -/** @typedef {typeof knownChains} KnownChains */ +/** + * @typedef {typeof knownChains} KnownChains + * @internal + */ +// TODO(#9966, #9967): include this in registerChain /** - * @param {ERef} agoricNamesAdmin + * Register chain assets into agoricNames + * + * @param {ERef} agoricNamesAdmin + * @param {string} name + * @param {CosmosAssetInfo[]} assets + * @alpha + */ +export const registerChainAssets = async (agoricNamesAdmin, name, assets) => { + mustMatch(assets, M.arrayOf(CosmosAssetInfoShape)); + const { nameAdmin: assetAdmin } = + await E(agoricNamesAdmin).provideChild(ASSETS_KEY); + return E(assetAdmin).update(name, assets); +}; + +/** + * Register a chain into agoricNames + * + * @param {ERef} agoricNamesAdmin * @param {string} name * @param {CosmosChainInfo} chainInfo * @param {(...messages: string[]) => void} [log] @@ -80,9 +61,9 @@ export const registerChain = async ( log = () => {}, handledConnections = new Set(), ) => { - const { nameAdmin } = await E(agoricNamesAdmin).provideChild('chain'); + const { nameAdmin } = await E(agoricNamesAdmin).provideChild(CHAIN_KEY); const { nameAdmin: connAdmin } = - await E(agoricNamesAdmin).provideChild('chainConnection'); + await E(agoricNamesAdmin).provideChild(CONNECTIONS_KEY); mustMatch(chainInfo, CosmosChainInfoShape); const { connections = {}, ...vertex } = chainInfo; diff --git a/packages/orchestration/src/cosmos-api.ts b/packages/orchestration/src/cosmos-api.ts index 6880bb5939f..40f3e255281 100644 --- a/packages/orchestration/src/cosmos-api.ts +++ b/packages/orchestration/src/cosmos-api.ts @@ -1,7 +1,9 @@ -import type { AnyJson, TypedJson } from '@agoric/cosmic-proto'; +import type { AnyJson, TypedJson, JsonSafe } from '@agoric/cosmic-proto'; import type { Delegation, + DelegationResponse, Redelegation, + RedelegationResponse, UnbondingDelegation, } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/staking.js'; import type { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js'; @@ -11,6 +13,10 @@ import type { Order, } from '@agoric/cosmic-proto/ibc/core/channel/v1/channel.js'; import type { State as IBCConnectionState } from '@agoric/cosmic-proto/ibc/core/connection/v1/connection.js'; +import type { + RequestQuery, + ResponseQuery, +} from '@agoric/cosmic-proto/tendermint/abci/types.js'; import type { Brand, Purse, Payment, Amount } from '@agoric/ertp/src/types.js'; import type { Port } from '@agoric/network'; import type { IBCChannelID, IBCConnectionID } from '@agoric/vats'; @@ -22,7 +28,8 @@ import type { LocalIbcAddress, RemoteIbcAddress, } from '@agoric/vats/tools/ibc-utils.js'; -import type { AmountArg, ChainAddress, DenomAmount } from './types.js'; +import type { QueryDelegationTotalRewardsResponse } from '@agoric/cosmic-proto/cosmos/distribution/v1beta1/query.js'; +import type { AmountArg, ChainAddress, Denom, DenomAmount } from './types.js'; /** An address for a validator on some blockchain, e.g., cosmos, eth, etc. */ export type CosmosValidatorAddress = ChainAddress & { @@ -32,16 +39,13 @@ export type CosmosValidatorAddress = ChainAddress & { }; /** Represents an IBC Connection between two chains, which can contain multiple Channels. */ -export type IBCConnectionInfo = { +export interface IBCConnectionInfo { id: IBCConnectionID; // e.g. connection-0 client_id: string; // '07-tendermint-0' state: IBCConnectionState; counterparty: { client_id: string; connection_id: IBCConnectionID; - prefix: { - key_prefix: string; - }; }; transferChannel: { portId: string; @@ -52,7 +56,30 @@ export type IBCConnectionInfo = { state: IBCChannelState; version: string; // e.eg. 'ics20-1' }; -}; +} + +/** + * https://github.com/cosmos/chain-registry/blob/master/assetlist.schema.json + */ +export interface CosmosAssetInfo extends Record { + base: Denom; + name: string; + display: string; + symbol: string; + denom_units: Array<{ denom: Denom; exponent: number }>; + traces?: Array<{ + type: 'ibc'; + counterparty: { + chain_name: string; + base_denom: Denom; + channel_id: IBCChannelID; + }; + chain: { + channel_id: IBCChannelID; + path: string; + }; + }>; +} /** * Info for a Cosmos-based chain. @@ -70,17 +97,43 @@ export type CosmosChainInfo = Readonly<{ stakingTokens?: Readonly>; }>; +// #region Orchestration views on Cosmos response types +// Naming scheme: Cosmos for the chain system, Rewards b/c getRewards function, +// and Response because it's the return value. + +/** @see {QueryDelegationTotalRewardsResponse} */ +export interface CosmosRewardsResponse { + rewards: { validator: CosmosValidatorAddress; reward: DenomAmount[] }[]; + total: DenomAmount[]; +} + +/** @see {DelegationResponse} */ +export interface CosmosDelegationResponse { + delegator: ChainAddress; + validator: CosmosValidatorAddress; + amount: DenomAmount; +} +// #endregion + +/** + * Queries for the staking properties of an account. + * + * @see {@link https://docs.cosmos.network/main/build/modules/staking#messages x/staking messages} + * {@link https://cosmos.github.io/cosmjs/latest/stargate/interfaces/StakingExtension.html StakingExtension} in cosmjs + */ export interface StakingAccountQueries { /** * @returns all active delegations from the account to any validator (or [] if none) */ - getDelegations: () => Promise; + getDelegations: () => Promise; /** * @returns the active delegation from the account to a specific validator. Return an * empty Delegation if there is no delegation. */ - getDelegation: (validator: CosmosValidatorAddress) => Promise; + getDelegation: ( + validator: CosmosValidatorAddress, + ) => Promise; /** * @returns the unbonding delegations from the account to any validator (or [] if none) @@ -94,18 +147,13 @@ export interface StakingAccountQueries { validator: CosmosValidatorAddress, ) => Promise; - getRedelegations: () => Promise; - - getRedelegation: ( - srcValidator: CosmosValidatorAddress, - dstValidator?: CosmosValidatorAddress, - ) => Promise; + getRedelegations: () => Promise; /** * Get the pending rewards for the account. * @returns the amounts of the account's rewards pending from all validators */ - getRewards: () => Promise; + getRewards: () => Promise; /** * Get the rewards pending with a specific validator. @@ -114,6 +162,13 @@ export interface StakingAccountQueries { */ getReward: (validator: CosmosValidatorAddress) => Promise; } + +/** + * Transactions for doing staking operations on an individual account. + * + * @see {@link https://docs.cosmos.network/main/build/modules/staking#messages x/staking messages} and + * {@link https://cosmos.github.io/cosmjs/latest/stargate/interfaces/StakingExtension.html StakingExtension} in cosmjs + */ export interface StakingAccountActions { /** * Delegate an amount to a validator. The promise settles when the delegation is complete. @@ -147,7 +202,11 @@ export interface StakingAccountActions { * @param delegations - the delegation to undelegate */ undelegate: ( - delegations: Omit[], + delegations: { + amount: AmountArg; + delegator?: ChainAddress; + validator: CosmosValidatorAddress; + }[], ) => Promise; /** @@ -189,12 +248,23 @@ export interface IcaAccount { msgs: AnyJson[], opts?: Partial>, ) => Promise; - /** get Purse for a brand to .withdraw() a Payment from the account */ - getPurse: (brand: Brand) => Promise; /** - * Close the remote account + * Deactivates the ICA account by closing the ICA channel. The `Port` is + * persisted so holders can always call `.reactivate()` to re-establish a new + * channel with the same chain address. + * CAVEAT: Does not retrieve assets so they may be lost if left. + * @throws {Error} if connection is not available or already deactivated */ - close: () => Promise; + deactivate: () => Promise; + /** + * Reactivates the ICA account by re-establishing a new channel with the + * original Port and requested address. + * If a channel is closed for an unexpected reason, such as a packet timeout, + * an automatic attempt to re will be made and the holder should not need + * to call `.reactivate()`. + * @throws {Error} if connection is currently active + */ + reactivate: () => Promise; /** @returns the address of the remote channel */ getRemoteAddress: () => RemoteIbcAddress; /** @returns the address of the local channel */ @@ -203,11 +273,13 @@ export interface IcaAccount { getPort: () => Port; } -export type LiquidStakingMethods = { +/** Methods on chains that support Liquid Staking */ +export interface LiquidStakingMethods { liquidStake: (amount: AmountArg) => Promise; -}; +} -export type LocalAccountMethods = { +/** Methods supported only on Agoric chain accounts */ +export interface LocalAccountMethods { /** deposit payment (from zoe, for example) to the account */ deposit: (payment: Payment<'nat'>) => Promise; /** withdraw a Payment from the account */ @@ -223,14 +295,28 @@ export type LocalAccountMethods = { * @param tap */ monitorTransfers: (tap: TargetApp) => Promise; -}; +} -export type IBCMsgTransferOptions = { +/** + * Options for {@link OrchestrationAccountI} `transfer` method. + * + * @see {@link https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures ICS 20 Data Structures} + */ +export interface IBCMsgTransferOptions { timeoutHeight?: MsgTransfer['timeoutHeight']; timeoutTimestamp?: MsgTransfer['timeoutTimestamp']; memo?: string; -}; +} +/** + * Cosmos-specific methods to extend `OrchestrationAccountI`, parameterized + * by `CosmosChainInfo`. + * + * In particular, if the chain info includes a staking token, {@link StakingAccountActions} + * are available. + * + * @see {OrchestrationAccountI} + */ export type CosmosChainAccountMethods = (CCI extends { icaEnabled: true; @@ -240,5 +326,9 @@ export type CosmosChainAccountMethods = CCI extends { stakingTokens: {}; } - ? StakingAccountActions + ? StakingAccountActions & StakingAccountQueries : {}; + +export type ICQQueryFunction = ( + msgs: JsonSafe[], +) => Promise[]>; diff --git a/packages/orchestration/src/examples/README.md b/packages/orchestration/src/examples/README.md new file mode 100644 index 00000000000..d847fdba45a --- /dev/null +++ b/packages/orchestration/src/examples/README.md @@ -0,0 +1,16 @@ +# Examples + +This directory contains sample contracts showcasing the Orchestration API. Each example demonstrates specific functionalities: + +- **basic-flows.contract.js**: Account creation and query sending +- **send-anywhere.contract.js**: Token sending across supported blockchains +- **auto-stake-it.contract.js**: Automatic remote staking of received tokens +- **unbond.contract.js**: Cross-chain unbonding and transfer + +## In Progress + +The following contracts are a work in progress as they contain bindings that need to be promptly updated. + +- **stake-bld.contract.js**: BLD token staking on Agoric +- **stake-ica.contract.js**: Interchain account creation for remote staking +- **swap.contract.js**: Token swapping and remote staking diff --git a/packages/orchestration/src/examples/auto-stake-it.contract.js b/packages/orchestration/src/examples/auto-stake-it.contract.js index cc97565d0ba..d08781e47ff 100644 --- a/packages/orchestration/src/examples/auto-stake-it.contract.js +++ b/packages/orchestration/src/examples/auto-stake-it.contract.js @@ -2,132 +2,18 @@ import { EmptyProposalShape, InvitationShape, } from '@agoric/zoe/src/typeGuards.js'; -import { Fail } from '@endo/errors'; import { M } from '@endo/patterns'; -import { withOrchestration } from '../utils/start-helper.js'; import { prepareChainHubAdmin } from '../exos/chain-hub-admin.js'; -import { prepareStakingTap } from './auto-stake-it-tap-kit.js'; import { preparePortfolioHolder } from '../exos/portfolio-holder-kit.js'; +import { withOrchestration } from '../utils/start-helper.js'; +import { prepareStakingTap } from './auto-stake-it-tap-kit.js'; +import * as flows from './auto-stake-it.flows.js'; /** - * @import {TimerService} from '@agoric/time'; - * @import {ResolvedPublicTopic} from '@agoric/zoe/src/contractSupport/topics.js'; - * @import {LocalChain} from '@agoric/vats/src/localchain.js'; - * @import {NameHub} from '@agoric/vats'; - * @import {Remote} from '@agoric/vow'; * @import {Zone} from '@agoric/zone'; - * @import {GuestInterface} from '@agoric/async-flow'; - * @import {CosmosValidatorAddress, Orchestrator, CosmosInterchainService, Denom, OrchestrationAccount, StakingAccountActions, OrchestrationFlow} from '@agoric/orchestration'; - * @import {MakeStakingTap} from './auto-stake-it-tap-kit.js'; - * @import {MakePortfolioHolder} from '../exos/portfolio-holder-kit.js'; - * @import {ChainHub} from '../exos/chain-hub.js'; - * @import {OrchestrationTools} from '../utils/start-helper.js'; + * @import {OrchestrationPowers, OrchestrationTools} from '../utils/start-helper.js'; */ -/** - * @typedef {{ - * localchain: Remote; - * orchestrationService: Remote; - * storageNode: Remote; - * timerService: Remote; - * agoricNames: Remote; - * }} OrchestrationPowers - */ - -/** - * @satisfies {OrchestrationFlow} - * @param {Orchestrator} orch - * @param {{ - * makeStakingTap: MakeStakingTap; - * makePortfolioHolder: MakePortfolioHolder; - * chainHub: GuestInterface; - * }} ctx - * @param {ZCFSeat} seat - * @param {{ - * chainName: string; - * validator: CosmosValidatorAddress; - * localDenom: Denom; - * }} offerArgs - */ -const makeAccountsHandler = async ( - orch, - { makeStakingTap, makePortfolioHolder, chainHub }, - seat, - { - chainName, - validator, - // TODO localDenom is user supplied, until #9211 - localDenom, - }, -) => { - seat.exit(); // no funds exchanged - const [agoric, remoteChain] = await Promise.all([ - orch.getChain('agoric'), - orch.getChain(chainName), - ]); - const { chainId, stakingTokens } = await remoteChain.getChainInfo(); - const remoteDenom = stakingTokens[0].denom; - remoteDenom || - Fail`${chainId || chainName} does not have stakingTokens in config`; - if (chainId !== validator.chainId) { - Fail`validator chainId ${validator.chainId} does not match remote chainId ${chainId}`; - } - const [localAccount, stakingAccount] = await Promise.all([ - agoric.makeAccount(), - /** @type {Promise & StakingAccountActions>} */ ( - remoteChain.makeAccount() - ), - ]); - - const [localChainAddress, remoteChainAddress] = await Promise.all([ - localAccount.getAddress(), - stakingAccount.getAddress(), - ]); - const agoricChainId = (await agoric.getChainInfo()).chainId; - const { transferChannel } = await chainHub.getConnectionInfo( - agoricChainId, - chainId, - ); - assert(transferChannel.counterPartyChannelId, 'unable to find sourceChannel'); - - // Every time the `localAccount` receives `remoteDenom` over IBC, delegate it. - const tap = makeStakingTap({ - localAccount, - stakingAccount, - validator, - localChainAddress, - remoteChainAddress, - sourceChannel: transferChannel.counterPartyChannelId, - remoteDenom, - localDenom, - }); - // XXX consider storing appRegistration, so we can .revoke() or .updateTargetApp() - // @ts-expect-error tap.receiveUpcall: 'Vow | undefined' not assignable to 'Promise' - await localAccount.monitorTransfers(tap); - - const accountEntries = harden( - /** @type {[string, OrchestrationAccount][]} */ ([ - ['agoric', localAccount], - [chainName, stakingAccount], - ]), - ); - const publicTopicEntries = harden( - /** @type {[string, ResolvedPublicTopic][]} */ ( - await Promise.all( - accountEntries.map(async ([name, account]) => { - const { account: topicRecord } = await account.getPublicTopics(); - return [name, topicRecord]; - }), - ) - ), - ); - const portfolioHolder = makePortfolioHolder( - accountEntries, - publicTopicEntries, - ); - return portfolioHolder.asContinuingOffer(); -}; - /** * AutoStakeIt allows users to to create an auto-forwarding address that * transfers and stakes tokens on a remote chain when received. @@ -145,7 +31,7 @@ const contract = async ( zcf, _privateArgs, zone, - { chainHub, orchestrate, vowTools }, + { chainHub, orchestrateAll, vowTools }, ) => { const makeStakingTap = prepareStakingTap( zone.subZone('stakingTap'), @@ -156,11 +42,11 @@ const contract = async ( vowTools, ); - const makeAccounts = orchestrate( - 'makeAccounts', - { makeStakingTap, makePortfolioHolder, chainHub }, - makeAccountsHandler, - ); + const { makeAccounts } = orchestrateAll(flows, { + makeStakingTap, + makePortfolioHolder, + chainHub, + }); const publicFacet = zone.exo( 'AutoStakeIt Public Facet', @@ -185,5 +71,6 @@ const contract = async ( }; export const start = withOrchestration(contract); +harden(start); /** @typedef {typeof start} AutoStakeItSF */ diff --git a/packages/orchestration/src/examples/auto-stake-it.flows.js b/packages/orchestration/src/examples/auto-stake-it.flows.js new file mode 100644 index 00000000000..74d1fc839a7 --- /dev/null +++ b/packages/orchestration/src/examples/auto-stake-it.flows.js @@ -0,0 +1,102 @@ +import { Fail } from '@endo/errors'; +import { denomHash } from '../utils/denomHash.js'; + +/** + * @import {ResolvedPublicTopic} from '@agoric/zoe/src/contractSupport/topics.js'; + * @import {GuestInterface} from '@agoric/async-flow'; + * @import {CosmosValidatorAddress, Orchestrator, CosmosInterchainService, Denom, OrchestrationAccount, StakingAccountActions, OrchestrationFlow} from '@agoric/orchestration'; + * @import {MakeStakingTap} from './auto-stake-it-tap-kit.js'; + * @import {MakePortfolioHolder} from '../exos/portfolio-holder-kit.js'; + * @import {ChainHub} from '../exos/chain-hub.js'; + */ + +/** + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {{ + * makeStakingTap: MakeStakingTap; + * makePortfolioHolder: MakePortfolioHolder; + * chainHub: GuestInterface; + * }} ctx + * @param {ZCFSeat} seat + * @param {{ + * chainName: string; + * validator: CosmosValidatorAddress; + * }} offerArgs + */ +export const makeAccounts = async ( + orch, + { makeStakingTap, makePortfolioHolder, chainHub }, + seat, + { chainName, validator }, +) => { + seat.exit(); // no funds exchanged + const [agoric, remoteChain] = await Promise.all([ + orch.getChain('agoric'), + orch.getChain(chainName), + ]); + const { chainId, stakingTokens } = await remoteChain.getChainInfo(); + const remoteDenom = stakingTokens[0].denom; + remoteDenom || + Fail`${chainId || chainName} does not have stakingTokens in config`; + if (chainId !== validator.chainId) { + Fail`validator chainId ${validator.chainId} does not match remote chainId ${chainId}`; + } + const [localAccount, stakingAccount] = await Promise.all([ + agoric.makeAccount(), + /** @type {Promise & StakingAccountActions>} */ ( + remoteChain.makeAccount() + ), + ]); + + const [localChainAddress, remoteChainAddress] = await Promise.all([ + localAccount.getAddress(), + stakingAccount.getAddress(), + ]); + const agoricChainId = (await agoric.getChainInfo()).chainId; + const { transferChannel } = await chainHub.getConnectionInfo( + agoricChainId, + chainId, + ); + assert(transferChannel.counterPartyChannelId, 'unable to find sourceChannel'); + + const localDenom = `ibc/${denomHash({ denom: remoteDenom, channelId: transferChannel.channelId })}`; + + // Every time the `localAccount` receives `remoteDenom` over IBC, delegate it. + const tap = makeStakingTap({ + localAccount, + stakingAccount, + validator, + localChainAddress, + remoteChainAddress, + sourceChannel: transferChannel.counterPartyChannelId, + remoteDenom, + localDenom, + }); + // XXX consider storing appRegistration, so we can .revoke() or .updateTargetApp() + // @ts-expect-error tap.receiveUpcall: 'Vow | undefined' not assignable to 'Promise' + await localAccount.monitorTransfers(tap); + + const accountEntries = harden( + /** @type {[string, OrchestrationAccount][]} */ ([ + ['agoric', localAccount], + [chainName, stakingAccount], + ]), + ); + const publicTopicEntries = harden( + /** @type {[string, ResolvedPublicTopic][]} */ ( + await Promise.all( + accountEntries.map(async ([name, account]) => { + const { account: topicRecord } = await account.getPublicTopics(); + return [name, topicRecord]; + }), + ) + ), + ); + const portfolioHolder = makePortfolioHolder( + accountEntries, + publicTopicEntries, + ); + return portfolioHolder.asContinuingOffer(); +}; +harden(makeAccounts); diff --git a/packages/orchestration/src/examples/basic-flows.contract.js b/packages/orchestration/src/examples/basic-flows.contract.js index bbc428b6058..60f58cadd1f 100644 --- a/packages/orchestration/src/examples/basic-flows.contract.js +++ b/packages/orchestration/src/examples/basic-flows.contract.js @@ -3,82 +3,15 @@ * leverage basic functionality of the Orchestration API with async-flow. */ import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; -import { M, mustMatch } from '@endo/patterns'; -import { withOrchestration } from '../utils/start-helper.js'; +import { M } from '@endo/patterns'; import { preparePortfolioHolder } from '../exos/portfolio-holder-kit.js'; +import { withOrchestration } from '../utils/start-helper.js'; +import * as flows from './basic-flows.flows.js'; /** * @import {Zone} from '@agoric/zone'; - * @import {OrchestrationAccount, OrchestrationFlow, Orchestrator} from '@agoric/orchestration'; - * @import {ResolvedPublicTopic} from '@agoric/zoe/src/contractSupport/topics.js'; - * @import {OrchestrationPowers} from '../utils/start-helper.js'; - * @import {MakePortfolioHolder} from '../exos/portfolio-holder-kit.js'; - * @import {OrchestrationTools} from '../utils/start-helper.js'; - */ - -/** - * Create an account on a Cosmos chain and return a continuing offer with - * invitations makers for Delegate, WithdrawRewards, Transfer, etc. - * - * @satisfies {OrchestrationFlow} - * @param {Orchestrator} orch - * @param {undefined} _ctx - * @param {ZCFSeat} seat - * @param {{ chainName: string }} offerArgs + * @import {OrchestrationPowers, OrchestrationTools} from '../utils/start-helper.js'; */ -const makeOrchAccountHandler = async (orch, _ctx, seat, { chainName }) => { - seat.exit(); // no funds exchanged - mustMatch(chainName, M.string()); - const remoteChain = await orch.getChain(chainName); - const cosmosAccount = await remoteChain.makeAccount(); - return cosmosAccount.asContinuingOffer(); -}; - -/** - * Create accounts on multiple chains and return them in a single continuing - * offer with invitations makers for Delegate, WithdrawRewards, Transfer, etc. - * Calls to the underlying invitationMakers are proxied through the - * `MakeInvitation` invitation maker. - * - * @satisfies {OrchestrationFlow} - * @param {Orchestrator} orch - * @param {MakePortfolioHolder} makePortfolioHolder - * @param {ZCFSeat} seat - * @param {{ chainNames: string[] }} offerArgs - */ -const makePortfolioAcctHandler = async ( - orch, - makePortfolioHolder, - seat, - { chainNames }, -) => { - seat.exit(); // no funds exchanged - mustMatch(chainNames, M.arrayOf(M.string())); - const allChains = await Promise.all(chainNames.map(n => orch.getChain(n))); - const allAccounts = await Promise.all(allChains.map(c => c.makeAccount())); - - const accountEntries = harden( - /** @type {[string, OrchestrationAccount][]} */ ( - chainNames.map((chainName, index) => [chainName, allAccounts[index]]) - ), - ); - const publicTopicEntries = harden( - /** @type {[string, ResolvedPublicTopic][]} */ ( - await Promise.all( - accountEntries.map(async ([name, account]) => { - const { account: topicRecord } = await account.getPublicTopics(); - return [name, topicRecord]; - }), - ) - ), - ); - const portfolioHolder = makePortfolioHolder( - accountEntries, - publicTopicEntries, - ); - - return portfolioHolder.asContinuingOffer(); -}; /** * @param {ZCF} zcf @@ -88,23 +21,18 @@ const makePortfolioAcctHandler = async ( * @param {Zone} zone * @param {OrchestrationTools} tools */ -const contract = async (zcf, _privateArgs, zone, { orchestrate, vowTools }) => { +const contract = async ( + zcf, + _privateArgs, + zone, + { orchestrateAll, vowTools }, +) => { const makePortfolioHolder = preparePortfolioHolder( zone.subZone('portfolio'), vowTools, ); - const makeOrchAccount = orchestrate( - 'makeOrchAccount', - undefined, - makeOrchAccountHandler, - ); - - const makePortfolioAccount = orchestrate( - 'makePortfolioAccount', - makePortfolioHolder, - makePortfolioAcctHandler, - ); + const orchFns = orchestrateAll(flows, { makePortfolioHolder }); const publicFacet = zone.exo( 'Basic Flows Public Facet', @@ -115,13 +43,13 @@ const contract = async (zcf, _privateArgs, zone, { orchestrate, vowTools }) => { { makeOrchAccountInvitation() { return zcf.makeInvitation( - makeOrchAccount, + orchFns.makeOrchAccount, 'Make an Orchestration Account', ); }, makePortfolioAccountInvitation() { return zcf.makeInvitation( - makePortfolioAccount, + orchFns.makePortfolioAccount, 'Make an Orchestration Account', ); }, @@ -132,5 +60,6 @@ const contract = async (zcf, _privateArgs, zone, { orchestrate, vowTools }) => { }; export const start = withOrchestration(contract); +harden(start); /** @typedef {typeof start} BasicFlowsSF */ diff --git a/packages/orchestration/src/examples/basic-flows.flows.js b/packages/orchestration/src/examples/basic-flows.flows.js new file mode 100644 index 00000000000..0d01c4a7696 --- /dev/null +++ b/packages/orchestration/src/examples/basic-flows.flows.js @@ -0,0 +1,84 @@ +/** + * @file An example of how to leverage basic functionality of the Orchestration + * API with async-flow. Each offer returning a ContinuingOfferResult, with + * invitationMakers for Delegate, WithdrawRewards, Transfer, etc. + */ +import { makeTracer } from '@agoric/internal'; +import { M, mustMatch } from '@endo/patterns'; + +const trace = makeTracer('BasicFlows'); + +/** + * @import {OrchestrationAccount, OrchestrationFlow, Orchestrator} from '@agoric/orchestration'; + * @import {ResolvedPublicTopic} from '@agoric/zoe/src/contractSupport/topics.js'; + * @import {MakePortfolioHolder} from '../exos/portfolio-holder-kit.js'; + */ + +/** + * Create an OrchestrationAccount for a specific chain and return a continuing + * offer with invitations makers for Delegate, WithdrawRewards, Transfer, etc. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {any} _ctx + * @param {ZCFSeat} seat + * @param {{ chainName: string }} offerArgs + */ +export const makeOrchAccount = async (orch, _ctx, seat, { chainName }) => { + trace('makeOrchAccount', chainName); + seat.exit(); // no funds exchanged + mustMatch(chainName, M.string()); + const remoteChain = await orch.getChain(chainName); + const orchAccount = await remoteChain.makeAccount(); + return orchAccount.asContinuingOffer(); +}; +harden(makeOrchAccount); + +/** + * Create accounts on multiple chains and return them in a single continuing + * offer with invitations makers for Delegate, WithdrawRewards, Transfer, etc. + * Calls to the underlying invitationMakers are proxied through the `Proxying` + * invitation maker. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {MakePortfolioHolder} ctx.makePortfolioHolder + * @param {ZCFSeat} seat + * @param {{ chainNames: string[] }} offerArgs + */ +export const makePortfolioAccount = async ( + orch, + { makePortfolioHolder }, + seat, + { chainNames }, +) => { + trace('makePortfolioAccount', chainNames); + seat.exit(); // no funds exchanged + mustMatch(chainNames, M.arrayOf(M.string())); + const allChains = await Promise.all(chainNames.map(n => orch.getChain(n))); + const allAccounts = await Promise.all(allChains.map(c => c.makeAccount())); + + const accountEntries = harden( + /** @type {[string, OrchestrationAccount][]} */ ( + chainNames.map((chainName, index) => [chainName, allAccounts[index]]) + ), + ); + const publicTopicEntries = harden( + /** @type {[string, ResolvedPublicTopic][]} */ ( + await Promise.all( + accountEntries.map(async ([name, account]) => { + const { account: topicRecord } = await account.getPublicTopics(); + return [name, topicRecord]; + }), + ) + ), + ); + const portfolioHolder = makePortfolioHolder( + accountEntries, + publicTopicEntries, + ); + + return portfolioHolder.asContinuingOffer(); +}; +harden(makePortfolioAccount); diff --git a/packages/orchestration/src/examples/send-anywhere.contract.js b/packages/orchestration/src/examples/send-anywhere.contract.js new file mode 100644 index 00000000000..54aace33d0e --- /dev/null +++ b/packages/orchestration/src/examples/send-anywhere.contract.js @@ -0,0 +1,74 @@ +import { makeSharedStateRecord } from '@agoric/async-flow'; +import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; +import { M } from '@endo/patterns'; +import { withOrchestration } from '../utils/start-helper.js'; +import * as flows from './send-anywhere.flows.js'; +import { prepareChainHubAdmin } from '../exos/chain-hub-admin.js'; +import { AnyNatAmountShape } from '../typeGuards.js'; + +/** + * @import {Zone} from '@agoric/zone'; + * @import {OrchestrationPowers, OrchestrationTools} from '../utils/start-helper.js'; + */ + +export const SingleNatAmountRecord = M.and( + M.recordOf(M.string(), AnyNatAmountShape, { + numPropertiesLimit: 1, + }), + M.not(harden({})), +); +harden(SingleNatAmountRecord); + +/** + * Orchestration contract to be wrapped by withOrchestration for Zoe + * + * @param {ZCF} zcf + * @param {OrchestrationPowers & { + * marshaller: Marshaller; + * }} privateArgs + * @param {Zone} zone + * @param {OrchestrationTools} tools + */ +const contract = async ( + zcf, + privateArgs, + zone, + { chainHub, orchestrateAll, zoeTools }, +) => { + const contractState = makeSharedStateRecord( + /** @type {{ account: OrchestrationAccount | undefined }} */ { + localAccount: undefined, + }, + ); + + const creatorFacet = prepareChainHubAdmin(zone, chainHub); + + // orchestrate uses the names on orchestrationFns to do a "prepare" of the associated behavior + const orchFns = orchestrateAll(flows, { + zcf, + contractState, + zoeTools, + }); + + const publicFacet = zone.exo( + 'Send PF', + M.interface('Send PF', { + makeSendInvitation: M.callWhen().returns(InvitationShape), + }), + { + makeSendInvitation() { + return zcf.makeInvitation( + orchFns.sendIt, + 'send', + undefined, + M.splitRecord({ give: SingleNatAmountRecord }), + ); + }, + }, + ); + + return { publicFacet, creatorFacet }; +}; + +export const start = withOrchestration(contract); +harden(start); diff --git a/packages/orchestration/src/examples/send-anywhere.flows.js b/packages/orchestration/src/examples/send-anywhere.flows.js new file mode 100644 index 00000000000..c8231d915b0 --- /dev/null +++ b/packages/orchestration/src/examples/send-anywhere.flows.js @@ -0,0 +1,73 @@ +import { NonNullish } from '@agoric/internal'; +import { makeError, q } from '@endo/errors'; +import { M, mustMatch } from '@endo/patterns'; + +/** + * @import {GuestInterface} from '@agoric/async-flow'; + * @import {ZoeTools} from '../utils/zoe-tools.js'; + * @import {Orchestrator, LocalAccountMethods, OrchestrationAccountI, OrchestrationFlow} from '../types.js'; + */ + +const { entries } = Object; + +// in guest file (the orchestration functions) +// the second argument is all the endowments provided + +/** + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {{ localAccount?: OrchestrationAccountI & LocalAccountMethods }} ctx.contractState + * @param {GuestInterface} ctx.zoeTools + * @param {ZCFSeat} seat + * @param {{ chainName: string; destAddr: string }} offerArgs + */ +export const sendIt = async ( + orch, + { contractState, zoeTools: { localTransfer, withdrawToSeat } }, + seat, + offerArgs, +) => { + mustMatch(offerArgs, harden({ chainName: M.scalar(), destAddr: M.string() })); + const { chainName, destAddr } = offerArgs; + // NOTE the proposal shape ensures that the `give` is a single asset + const { give } = seat.getProposal(); + const [[_kw, amt]] = entries(give); + const agoric = await orch.getChain('agoric'); + const assets = await agoric.getVBankAssetInfo(); + const { denom } = NonNullish( + assets.find(a => a.brand === amt.brand), + `${amt.brand} not registered in vbank`, + ); + const chain = await orch.getChain(chainName); + + if (!contractState.localAccount) { + const agoricChain = await orch.getChain('agoric'); + contractState.localAccount = await agoricChain.makeAccount(); + } + + const info = await chain.getChainInfo(); + const { chainId } = info; + assert(typeof chainId === 'string', 'bad chainId'); + + await localTransfer(seat, contractState.localAccount, give); + + try { + await contractState.localAccount.transfer( + { denom, value: amt.value }, + { + value: destAddr, + encoding: 'bech32', + chainId, + }, + ); + } catch (e) { + await withdrawToSeat(contractState.localAccount, seat, give); + const errorMsg = `IBC Transfer failed ${q(e)}`; + seat.exit(errorMsg); + throw makeError(errorMsg); + } + + seat.exit(); +}; +harden(sendIt); diff --git a/packages/orchestration/src/examples/sendAnywhere.contract.js b/packages/orchestration/src/examples/sendAnywhere.contract.js deleted file mode 100644 index ba635f22dc9..00000000000 --- a/packages/orchestration/src/examples/sendAnywhere.contract.js +++ /dev/null @@ -1,106 +0,0 @@ -import { makeStateRecord } from '@agoric/async-flow'; -import { AmountShape } from '@agoric/ertp'; -import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; -import { Fail } from '@endo/errors'; -import { E } from '@endo/far'; -import { M } from '@endo/patterns'; -import { withOrchestration } from '../utils/start-helper.js'; -import * as flows from './sendAnywhere.flows.js'; -import { prepareChainHubAdmin } from '../exos/chain-hub-admin.js'; - -/** - * @import {TimerService} from '@agoric/time'; - * @import {LocalChain} from '@agoric/vats/src/localchain.js'; - * @import {NameHub} from '@agoric/vats'; - * @import {Remote, Vow} from '@agoric/vow'; - * @import {Zone} from '@agoric/zone'; - * @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; - * @import {CosmosInterchainService} from '../exos/cosmos-interchain-service.js'; - * @import {OrchestrationTools} from '../utils/start-helper.js'; - */ - -/** - * @typedef {{ - * localchain: Remote; - * orchestrationService: Remote; - * storageNode: Remote; - * timerService: Remote; - * agoricNames: Remote; - * }} OrchestrationPowers - */ - -export const SingleAmountRecord = M.and( - M.recordOf(M.string(), AmountShape, { - numPropertiesLimit: 1, - }), - M.not(harden({})), -); - -/** - * Orchestration contract to be wrapped by withOrchestration for Zoe - * - * @param {ZCF} zcf - * @param {OrchestrationPowers & { - * marshaller: Marshaller; - * }} privateArgs - * @param {Zone} zone - * @param {OrchestrationTools} tools - */ -const contract = async ( - zcf, - privateArgs, - zone, - { chainHub, orchestrateAll, vowTools, zoeTools }, -) => { - const contractState = makeStateRecord( - /** @type {{ account: OrchestrationAccount | undefined }} */ { - account: undefined, - }, - ); - - const creatorFacet = prepareChainHubAdmin(zone, chainHub); - - // TODO should be a provided helper - /** @type {(brand: Brand) => Vow} */ - const findBrandInVBank = vowTools.retriable( - zone, - 'findBrandInVBank', - /** @param {Brand} brand */ - async brand => { - const { agoricNames } = privateArgs; - const assets = await E(E(agoricNames).lookup('vbankAsset')).values(); - const it = assets.find(a => a.brand === brand); - it || Fail`brand ${brand} not in agoricNames.vbankAsset`; - return it; - }, - ); - - // orchestrate uses the names on orchestrationFns to do a "prepare" of the associated behavior - const orchFns = orchestrateAll(flows, { - zcf, - contractState, - localTransfer: zoeTools.localTransfer, - findBrandInVBank, - }); - - const publicFacet = zone.exo( - 'Send PF', - M.interface('Send PF', { - makeSendInvitation: M.callWhen().returns(InvitationShape), - }), - { - makeSendInvitation() { - return zcf.makeInvitation( - orchFns.sendIt, - 'send', - undefined, - M.splitRecord({ give: SingleAmountRecord }), - ); - }, - }, - ); - - return { publicFacet, creatorFacet }; -}; - -export const start = withOrchestration(contract); diff --git a/packages/orchestration/src/examples/sendAnywhere.flows.js b/packages/orchestration/src/examples/sendAnywhere.flows.js deleted file mode 100644 index cdd44865a51..00000000000 --- a/packages/orchestration/src/examples/sendAnywhere.flows.js +++ /dev/null @@ -1,59 +0,0 @@ -import { M, mustMatch } from '@endo/patterns'; - -/** - * @import {GuestOf} from '@agoric/async-flow'; - * @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; - * @import {ZoeTools} from '../utils/zoe-tools.js'; - * @import {Orchestrator, LocalAccountMethods, OrchestrationAccountI, OrchestrationFlow} from '../types.js'; - */ - -const { entries } = Object; - -// in guest file (the orchestration functions) -// the second argument is all the endowments provided - -/** - * @satisfies {OrchestrationFlow} - * @param {Orchestrator} orch - * @param {object} ctx - * @param {{ account?: OrchestrationAccountI & LocalAccountMethods }} ctx.contractState - * @param {GuestOf} ctx.localTransfer - * @param {(brand: Brand) => Promise} ctx.findBrandInVBank - * @param {ZCFSeat} seat - * @param {{ chainName: string; destAddr: string }} offerArgs - */ -export async function sendIt( - orch, - { contractState, localTransfer, findBrandInVBank }, - seat, - offerArgs, -) { - mustMatch(offerArgs, harden({ chainName: M.scalar(), destAddr: M.string() })); - const { chainName, destAddr } = offerArgs; - // NOTE the proposal shape ensures that the `give` is a single asset - const { give } = seat.getProposal(); - const [[_kw, amt]] = entries(give); - const { denom } = await findBrandInVBank(amt.brand); - const chain = await orch.getChain(chainName); - - if (!contractState.account) { - const agoricChain = await orch.getChain('agoric'); - contractState.account = await agoricChain.makeAccount(); - } - - const info = await chain.getChainInfo(); - const { chainId } = info; - assert(typeof chainId === 'string', 'bad chainId'); - - await localTransfer(seat, contractState.account, give); - - await contractState.account.transfer( - { denom, value: amt.value }, - { - value: destAddr, - encoding: 'bech32', - chainId, - }, - ); -} -harden(sendIt); diff --git a/packages/orchestration/src/examples/stakeBld.contract.js b/packages/orchestration/src/examples/stake-bld.contract.js similarity index 82% rename from packages/orchestration/src/examples/stakeBld.contract.js rename to packages/orchestration/src/examples/stake-bld.contract.js index 935c72b9226..82454422525 100644 --- a/packages/orchestration/src/examples/stakeBld.contract.js +++ b/packages/orchestration/src/examples/stake-bld.contract.js @@ -2,15 +2,17 @@ * @file Stake BLD contract */ import { makeTracer } from '@agoric/internal'; +import { heapVowE as E, prepareVowTools } from '@agoric/vow/vat.js'; import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/recorder.js'; import { withdrawFromSeat } from '@agoric/zoe/src/contractSupport/zoeHelpers.js'; import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; import { makeDurableZone } from '@agoric/zone/durable.js'; -import { prepareVowTools, heapVowE as E } from '@agoric/vow/vat.js'; import { deeplyFulfilled } from '@endo/marshal'; import { M } from '@endo/patterns'; -import { prepareLocalOrchestrationAccountKit } from '../exos/local-orchestration-account.js'; import { makeChainHub } from '../exos/chain-hub.js'; +import { prepareLocalOrchestrationAccountKit } from '../exos/local-orchestration-account.js'; +import fetchedChainInfo from '../fetched-chain-info.js'; +import { makeZoeTools } from '../utils/zoe-tools.js'; /** * @import {NameHub} from '@agoric/vats'; @@ -41,13 +43,21 @@ export const start = async (zcf, privateArgs, baggage) => { ); const vowTools = prepareVowTools(zone.subZone('vows')); + const chainHub = makeChainHub(privateArgs.agoricNames, vowTools); + const zoeTools = makeZoeTools(zcf, vowTools); + + const { localchain, timerService } = privateArgs; const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit( zone, - makeRecorderKit, - zcf, - privateArgs.timerService, - vowTools, - makeChainHub(privateArgs.agoricNames, vowTools), + { + makeRecorderKit, + zcf, + timerService, + vowTools, + chainHub, + localchain, + zoeTools, + }, ); // ---------------- @@ -56,6 +66,15 @@ export const start = async (zcf, privateArgs, baggage) => { const BLD = zcf.getTerms().brands.In; const bldAmountShape = await E(BLD).getAmountShape(); + // XXX big dependency (59KB) but in production will probably already be registered in agoricNames + chainHub.registerChain('agoric', fetchedChainInfo.agoric); + chainHub.registerAsset('ubld', { + baseName: 'agoric', + baseDenom: 'ubld', + brand: BLD, + chainName: 'agoric', + }); + async function makeLocalAccountKit() { const account = await E(privateArgs.localchain).makeAccount(); const address = await E(account).getAddress(); @@ -65,7 +84,7 @@ export const start = async (zcf, privateArgs, baggage) => { address: harden({ value: address, encoding: 'bech32', - chainId: 'local', + chainId: 'agoriclocal', }), storageNode: privateArgs.storageNode, }); @@ -123,3 +142,4 @@ export const start = async (zcf, privateArgs, baggage) => { return { publicFacet }; }; +harden(start); diff --git a/packages/orchestration/src/examples/stakeIca.contract.js b/packages/orchestration/src/examples/stake-ica.contract.js similarity index 68% rename from packages/orchestration/src/examples/stakeIca.contract.js rename to packages/orchestration/src/examples/stake-ica.contract.js index e40485d93ae..d6b89145368 100644 --- a/packages/orchestration/src/examples/stakeIca.contract.js +++ b/packages/orchestration/src/examples/stake-ica.contract.js @@ -11,13 +11,16 @@ import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; import { makeDurableZone } from '@agoric/zone/durable.js'; import { M } from '@endo/patterns'; import { prepareCosmosOrchestrationAccount } from '../exos/cosmos-orchestration-account.js'; +import { makeChainHub } from '../exos/chain-hub.js'; const trace = makeTracer('StakeIca'); /** * @import {Baggage} from '@agoric/vat-data'; - * @import {IBCConnectionID} from '@agoric/vats'; + * @import {Remote} from '@agoric/internal'; + * @import {IBCConnectionID, NameHub} from '@agoric/vats'; * @import {TimerService} from '@agoric/time'; - * @import {ICQConnection, CosmosInterchainService} from '../types.js'; + * @import {ResolvedContinuingOfferResult} from '../utils/zoe-tools.js'; + * @import {ICQConnection, CosmosInterchainService, ChainHub} from '../types.js'; */ /** @type {ContractMeta} */ @@ -26,24 +29,25 @@ export const meta = harden({ chainId: M.string(), hostConnectionId: M.string(), controllerConnectionId: M.string(), - bondDenom: M.string(), icqEnabled: M.boolean(), }, privateArgsShape: { + agoricNames: M.remotable('agoricNames NameHub'), cosmosInterchainService: M.remotable('cosmosInterchainService'), storageNode: StorageNodeShape, marshaller: M.remotable('marshaller'), timer: TimerServiceShape, }, }); +harden(meta); export const privateArgsShape = meta.privateArgsShape; +harden(privateArgsShape); /** * @typedef {{ * chainId: string; * hostConnectionId: IBCConnectionID; * controllerConnectionId: IBCConnectionID; - * bondDenom: string; * icqEnabled: boolean; * }} StakeIcaTerms */ @@ -51,6 +55,7 @@ export const privateArgsShape = meta.privateArgsShape; /** * @param {ZCF} zcf * @param {{ + * agoricNames: Remote; * cosmosInterchainService: CosmosInterchainService; * storageNode: StorageNode; * marshaller: Marshaller; @@ -59,14 +64,10 @@ export const privateArgsShape = meta.privateArgsShape; * @param {Baggage} baggage */ export const start = async (zcf, privateArgs, baggage) => { + const { chainId, hostConnectionId, controllerConnectionId, icqEnabled } = + zcf.getTerms(); const { - chainId, - hostConnectionId, - controllerConnectionId, - bondDenom, - icqEnabled, - } = zcf.getTerms(); - const { + agoricNames, cosmosInterchainService: orchestration, marshaller, storageNode, @@ -83,11 +84,17 @@ export const start = async (zcf, privateArgs, baggage) => { const vowTools = prepareVowTools(zone.subZone('vows')); + const chainHub = makeChainHub(agoricNames, vowTools); + const makeCosmosOrchestrationAccount = prepareCosmosOrchestrationAccount( zone, - makeRecorderKit, - vowTools, - zcf, + { + chainHub, + makeRecorderKit, + timerService: timer, + vowTools, + zcf, + }, ); async function makeAccountKit() { @@ -101,24 +108,31 @@ export const start = async (zcf, privateArgs, baggage) => { ? await E(orchestration).provideICQConnection(controllerConnectionId) : undefined; - const accountAddress = await E(account).getAddress(); - trace('account address', accountAddress); + const [chainAddress, localAddress, remoteAddress] = await Promise.all([ + E(account).getAddress(), + E(account).getLocalAddress(), + E(account).getRemoteAddress(), + ]); + trace('account address', chainAddress); const accountNode = await E(accountsStorageNode).makeChildNode( - accountAddress.value, + chainAddress.value, + ); + const holder = makeCosmosOrchestrationAccount( + { chainAddress, localAddress, remoteAddress }, + { + account, + storageNode: accountNode, + icqConnection, + timer, + }, ); - const holder = makeCosmosOrchestrationAccount(accountAddress, bondDenom, { - account, - storageNode: accountNode, - icqConnection, - timer, - }); return holder; } const publicFacet = zone.exo( 'StakeAtom', M.interface('StakeAtomI', { - makeAccount: M.callWhen().returns(M.remotable('ChainAccount')), + makeAccount: M.callWhen().returns(M.remotable('OrchestrationAccountKit')), makeAccountInvitationMaker: M.callWhen().returns(InvitationShape), }), { @@ -129,10 +143,15 @@ export const start = async (zcf, privateArgs, baggage) => { makeAccountInvitationMaker() { trace('makeCreateAccountInvitation'); return zcf.makeInvitation( + // XXX use `orchestrate` membrane for vow? + /** + * @param {ZCFSeat} seat + * @returns {Promise} + */ async seat => { seat.exit(); const holder = await makeAccountKit(); - return holder.asContinuingOffer(); + return vowTools.when(holder.asContinuingOffer()); }, 'wantStakingAccount', undefined, @@ -144,5 +163,6 @@ export const start = async (zcf, privateArgs, baggage) => { return { publicFacet }; }; +harden(start); /** @typedef {typeof start} StakeIcaSF */ diff --git a/packages/orchestration/src/examples/staking-combinations.contract.js b/packages/orchestration/src/examples/staking-combinations.contract.js new file mode 100644 index 00000000000..209b328f674 --- /dev/null +++ b/packages/orchestration/src/examples/staking-combinations.contract.js @@ -0,0 +1,161 @@ +/** + * @file This contract demonstrates the continuing invitation pattern with async + * flows. + * + * The primary offer result is a power for invitation makers that can perform + * actions with an ICA account. + */ +import { makeSharedStateRecord } from '@agoric/async-flow'; +import { AmountShape } from '@agoric/ertp'; +import { M } from '@endo/patterns'; +import { prepareCombineInvitationMakers } from '../exos/combine-invitation-makers.js'; +import { CosmosOrchestrationInvitationMakersI } from '../exos/cosmos-orchestration-account.js'; +import { ChainAddressShape, DelegationShape } from '../typeGuards.js'; +import { withOrchestration } from '../utils/start-helper.js'; +import * as flows from './staking-combinations.flows.js'; +import { prepareChainHubAdmin } from '../exos/chain-hub-admin.js'; + +/** + * @import {GuestInterface} from '@agoric/async-flow'; + * @import {Zone} from '@agoric/zone'; + * @import {OrchestrationTools, OrchestrationPowers} from '../utils/start-helper.js'; + * @import {CosmosOrchestrationAccount} from '../exos/cosmos-orchestration-account.js'; + * @import {AmountArg, ChainAddress, CosmosValidatorAddress} from '../types.js'; + */ + +const emptyOfferShape = harden({ + // Nothing to give; the funds are deposited offline + give: {}, + want: {}, // UNTIL https://github.com/Agoric/agoric-sdk/issues/2230 + exit: M.any(), +}); + +/** + * Orchestration contract to be wrapped by withOrchestration for Zoe. + * + * @param {ZCF} zcf + * @param {OrchestrationPowers & { + * marshaller: Marshaller; + * }} privateArgs + * @param {Zone} zone + * @param {OrchestrationTools} tools + */ +const contract = async ( + zcf, + privateArgs, + zone, + { orchestrateAll, zoeTools, chainHub }, +) => { + const contractState = makeSharedStateRecord( + /** + * @type {{ + * account: (OrchestrationAccount & LocalAccountMethods) | undefined; + * }} + */ { + localAccount: undefined, + }, + ); + + const StakingCombinationsInvitationMakersI = M.interface( + 'StakingCombinationsInvitationMakersI', + { + DepositAndDelegate: M.call().returns(M.promise()), + UndelegateAndTransfer: M.call( + M.arrayOf(DelegationShape), + ChainAddressShape, + ).returns(M.promise()), + }, + ); + + /** @type {any} XXX async membrane */ + const makeExtraInvitationMaker = zone.exoClass( + 'StakingCombinationsInvitationMakers', + StakingCombinationsInvitationMakersI, + /** @param {GuestInterface} account */ + account => { + return { account }; + }, + { + DepositAndDelegate() { + const { account } = this.state; + + return zcf.makeInvitation( + /** + * @param {ZCFSeat} seat + * @param {{ validator: CosmosValidatorAddress }} offerArgs + */ + (seat, { validator }) => + // eslint-disable-next-line no-use-before-define -- defined by orchestrateAll, necessarily after this + orchFns.depositAndDelegate(account, seat, validator), + 'Deposit and delegate', + undefined, + { + give: { + Stake: AmountShape, + }, + want: {}, + // user cannot exit their seat; contract must exit it. + exit: { waived: M.null() }, + }, + ); + }, + /** + * @param {{ amount: AmountArg; validator: CosmosValidatorAddress }[]} delegations + * @param {ChainAddress} destination + */ + UndelegateAndTransfer(delegations, destination) { + const { account } = this.state; + + return zcf.makeInvitation( + () => + // eslint-disable-next-line no-use-before-define -- defined by orchestrateAll, necessarily after this + orchFns.undelegateAndTransfer(account, { + delegations, + destination, + }), + 'Undelegate and transfer', + undefined, + emptyOfferShape, + ); + }, + }, + ); + + /** @type {any} XXX async membrane */ + const makeCombineInvitationMakers = prepareCombineInvitationMakers( + zone, + CosmosOrchestrationInvitationMakersI, + StakingCombinationsInvitationMakersI, + ); + + const orchFns = orchestrateAll(flows, { + contractState, + makeCombineInvitationMakers, + makeExtraInvitationMaker, + flows, + zcf, + zoeTools, + }); + + /** + * Provide invitations to contract deployer for registering assets and chains + * in the local ChainHub for this contract. + */ + const creatorFacet = prepareChainHubAdmin(zone, chainHub); + + const publicFacet = zone.exo('publicFacet', undefined, { + makeAccount() { + return zcf.makeInvitation( + orchFns.makeAccount, + 'Make an ICA account', + undefined, + emptyOfferShape, + ); + }, + }); + + return harden({ publicFacet, creatorFacet }); +}; + +export const start = withOrchestration(contract); +harden(start); diff --git a/packages/orchestration/src/examples/staking-combinations.flows.js b/packages/orchestration/src/examples/staking-combinations.flows.js new file mode 100644 index 00000000000..37712097096 --- /dev/null +++ b/packages/orchestration/src/examples/staking-combinations.flows.js @@ -0,0 +1,111 @@ +/** + * @import {GuestInterface} from '@agoric/async-flow'; + * @import {Orchestrator, OrchestrationFlow, AmountArg, CosmosValidatorAddress, ChainAddress, LocalAccountMethods, OrchestrationAccountI} from '../types.js' + * @import {ContinuingOfferResult, InvitationMakers} from '@agoric/smart-wallet/src/types.js'; + * @import {MakeCombineInvitationMakers} from '../exos/combine-invitation-makers.js'; + * @import {CosmosOrchestrationAccount} from '../exos/cosmos-orchestration-account.js'; + * @import {ZoeTools} from '../utils/zoe-tools.js'; + */ + +import { mustMatch } from '@endo/patterns'; +import { makeError, q } from '@endo/errors'; +import { makeTracer } from '@agoric/internal'; +import { ChainAddressShape } from '../typeGuards.js'; + +const trace = makeTracer('StakingCombinationsFlows'); + +/** + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {{ + * makeCombineInvitationMakers: MakeCombineInvitationMakers; + * makeExtraInvitationMaker: (account: any) => InvitationMakers; + * }} ctx + * @param {ZCFSeat} _seat + * @param {{ chainName: string }} offerArgs + * @returns {Promise} + */ +export const makeAccount = async (orch, ctx, _seat, { chainName }) => { + const chain = await orch.getChain(chainName); + const account = await chain.makeAccount(); + + const extraMakers = ctx.makeExtraInvitationMaker(account); + + /** @type {ContinuingOfferResult} */ + const result = await account.asContinuingOffer(); + + return { + ...result, + invitationMakers: ctx.makeCombineInvitationMakers( + extraMakers, + result.invitationMakers, + ), + }; +}; +harden(makeAccount); + +/** + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {{ localAccount?: OrchestrationAccountI & LocalAccountMethods }} ctx.contractState + * @param {GuestInterface} ctx.zoeTools + * @param {GuestInterface} account + * @param {ZCFSeat} seat + * @param {CosmosValidatorAddress} validator + * @returns {Promise} + */ +export const depositAndDelegate = async ( + orch, + { contractState, zoeTools }, + account, + seat, + validator, +) => { + await null; + trace('depositAndDelegate', account, seat, validator); + mustMatch(validator, ChainAddressShape); + if (!contractState.localAccount) { + const agoricChain = await orch.getChain('agoric'); + contractState.localAccount = await agoricChain.makeAccount(); + } + const { give } = seat.getProposal(); + await zoeTools.localTransfer(seat, contractState.localAccount, give); + + const address = account.getAddress(); + try { + await contractState.localAccount.transfer(give.Stake, address); + } catch (cause) { + await zoeTools.withdrawToSeat(contractState.localAccount, seat, give); + const errMsg = makeError(`ibc transfer failed ${q(cause)}`); + seat.exit(errMsg); + throw errMsg; + } + seat.exit(); + await account.delegate(validator, give.Stake); +}; +harden(depositAndDelegate); + +/** + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {GuestInterface} account + * @param {{ + * delegations: { amount: AmountArg; validator: CosmosValidatorAddress }[]; + * destination: ChainAddress; + * }} offerArgs + * @returns {Promise} + */ +export const undelegateAndTransfer = async ( + orch, + ctx, + account, + { delegations, destination }, +) => { + await account.undelegate(delegations); + for (const { amount } of delegations) { + await account.transfer(amount, destination); + } +}; +harden(undelegateAndTransfer); diff --git a/packages/orchestration/src/examples/swapExample.contract.js b/packages/orchestration/src/examples/swap.contract.js similarity index 54% rename from packages/orchestration/src/examples/swapExample.contract.js rename to packages/orchestration/src/examples/swap.contract.js index 8d75dd41087..fa2a7e0bff1 100644 --- a/packages/orchestration/src/examples/swapExample.contract.js +++ b/packages/orchestration/src/examples/swap.contract.js @@ -1,65 +1,19 @@ import { StorageNodeShape } from '@agoric/internal'; import { TimerServiceShape } from '@agoric/time'; import { M } from '@endo/patterns'; -import { orcUtils } from '../utils/orc.js'; import { withOrchestration } from '../utils/start-helper.js'; +import * as flows from './swap.flows.js'; /** - * @import {LocalTransfer} from '../utils/zoe-tools.js'; - * @import {Orchestrator, CosmosValidatorAddress, OrchestrationFlow} from '../types.js' * @import {TimerService} from '@agoric/time'; * @import {LocalChain} from '@agoric/vats/src/localchain.js'; * @import {Remote} from '@agoric/internal'; - * @import {CosmosInterchainService} from '../exos/cosmos-interchain-service.js'; + * @import {CosmosInterchainService} from '../exos/exo-interfaces.js'; * @import {NameHub} from '@agoric/vats'; * @import {Zone} from '@agoric/zone'; * @import {OrchestrationTools} from '../utils/start-helper.js'; */ -/** - * @satisfies {OrchestrationFlow} - * @param {Orchestrator} orch - * @param {object} ctx - * @param {LocalTransfer} ctx.localTransfer - * @param {ZCFSeat} seat - * @param {object} offerArgs - * @param {Amount<'nat'>} offerArgs.staked - * @param {CosmosValidatorAddress} offerArgs.validator - */ -const stakeAndSwapFn = async (orch, { localTransfer }, seat, offerArgs) => { - const { give } = seat.getProposal(); - - const omni = await orch.getChain('omniflixhub'); - const agoric = await orch.getChain('agoric'); - - const [omniAccount, localAccount] = await Promise.all([ - omni.makeAccount(), - agoric.makeAccount(), - ]); - - const omniAddress = omniAccount.getAddress(); - - // deposit funds from user seat to LocalChainAccount - await localTransfer(seat, localAccount, give); - seat.exit(); - - // build swap instructions with orcUtils library - const transferMsg = orcUtils.makeOsmosisSwap({ - destChain: 'omniflixhub', - destAddress: omniAddress, - amountIn: give.Stable, - brandOut: /** @type {any} */ ('FIXME'), - slippage: 0.03, - }); - - try { - await localAccount.transferSteps(give.Stable, transferMsg); - await omniAccount.delegate(offerArgs.validator, offerArgs.staked); - } catch (e) { - console.error(e); - } -}; - /** @type {ContractMeta} */ export const meta = { privateArgsShape: { @@ -82,6 +36,7 @@ harden(meta); */ export const makeNatAmountShape = (brand, min) => harden({ brand, value: min ? M.gte(min) : M.nat() }); +harden(makeNatAmountShape); /** * Orchestration contract to be wrapped by withOrchestration for Zoe @@ -98,20 +53,23 @@ export const makeNatAmountShape = (brand, min) => * @param {Zone} zone * @param {OrchestrationTools} tools */ -const contract = async (zcf, privateArgs, zone, { orchestrate, zoeTools }) => { +const contract = async ( + zcf, + privateArgs, + zone, + { orchestrateAll, zoeTools }, +) => { const { brands } = zcf.getTerms(); - /** deprecated historical example */ - const swapAndStakeHandler = orchestrate( - 'LSTTia', - { zcf, localTransfer: zoeTools.localTransfer }, - stakeAndSwapFn, - ); + const { stakeAndSwap } = orchestrateAll(flows, { + zcf, + localTransfer: zoeTools.localTransfer, + }); const publicFacet = zone.exo('publicFacet', undefined, { makeSwapAndStakeInvitation() { return zcf.makeInvitation( - swapAndStakeHandler, + stakeAndSwap, 'Swap for TIA and stake', undefined, harden({ @@ -127,3 +85,4 @@ const contract = async (zcf, privateArgs, zone, { orchestrate, zoeTools }) => { }; export const start = withOrchestration(contract); +harden(start); diff --git a/packages/orchestration/src/examples/swap.flows.js b/packages/orchestration/src/examples/swap.flows.js new file mode 100644 index 00000000000..7514683440f --- /dev/null +++ b/packages/orchestration/src/examples/swap.flows.js @@ -0,0 +1,57 @@ +import { orcUtils } from '../utils/orc.js'; + +/** + * @import {LocalTransfer} from '../utils/zoe-tools.js'; + * @import {Orchestrator, CosmosValidatorAddress, OrchestrationFlow} from '../types.js' + */ + +// XXX does not actually work. An early illustration that needs to be fixed. +/** + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {LocalTransfer} ctx.localTransfer + * @param {ZCFSeat} seat + * @param {object} offerArgs + * @param {Amount<'nat'>} offerArgs.staked + * @param {CosmosValidatorAddress} offerArgs.validator + */ +export const stakeAndSwap = async ( + orch, + { localTransfer }, + seat, + offerArgs, +) => { + const { give } = seat.getProposal(); + + const omni = await orch.getChain('omniflixhub'); + const agoric = await orch.getChain('agoric'); + + const [omniAccount, localAccount] = await Promise.all([ + omni.makeAccount(), + agoric.makeAccount(), + ]); + + const omniAddress = omniAccount.getAddress(); + + // deposit funds from user seat to LocalChainAccount + await localTransfer(seat, localAccount, give); + seat.exit(); + + // build swap instructions with orcUtils library + const transferMsg = orcUtils.makeOsmosisSwap({ + destChain: 'omniflixhub', + destAddress: omniAddress, + amountIn: give.Stable, + brandOut: /** @type {any} */ ('FIXME'), + slippage: 0.03, + }); + + try { + await localAccount.transferSteps(give.Stable, transferMsg); + await omniAccount.delegate(offerArgs.validator, offerArgs.staked); + } catch (e) { + console.error(e); + } +}; +harden(stakeAndSwap); diff --git a/packages/orchestration/src/examples/unbond.contract.js b/packages/orchestration/src/examples/unbond.contract.js new file mode 100644 index 00000000000..e577f2c6fec --- /dev/null +++ b/packages/orchestration/src/examples/unbond.contract.js @@ -0,0 +1,53 @@ +import { M } from '@endo/patterns'; +import { withOrchestration } from '../utils/start-helper.js'; +import * as flows from './unbond.flows.js'; + +/** + * @import {TimerService} from '@agoric/time'; + * @import {LocalChain} from '@agoric/vats/src/localchain.js'; + * @import {NameHub} from '@agoric/vats'; + * @import {Remote} from '@agoric/internal'; + * @import {Zone} from '@agoric/zone'; + * @import {CosmosInterchainService} from '../exos/exo-interfaces.js'; + * @import {OrchestrationTools} from '../utils/start-helper.js'; + */ + +/** + * Orchestration contract to be wrapped by withOrchestration for Zoe + * + * @param {ZCF} zcf + * @param {{ + * agoricNames: Remote; + * localchain: Remote; + * orchestrationService: Remote; + * storageNode: Remote; + * marshaller: Marshaller; + * timerService: Remote; + * }} privateArgs + * @param {Zone} zone + * @param {OrchestrationTools} tools + */ +const contract = async (zcf, privateArgs, zone, { orchestrateAll }) => { + const { unbondAndTransfer } = orchestrateAll(flows, { zcf }); + + const publicFacet = zone.exo('publicFacet', undefined, { + makeUnbondAndTransferInvitation() { + return zcf.makeInvitation( + unbondAndTransfer, + 'Unbond and transfer', + undefined, + harden({ + // Nothing to give; the funds come from undelegating + give: {}, + want: {}, // XXX ChainAccount Ownable? + exit: M.any(), + }), + ); + }, + }); + + return harden({ publicFacet }); +}; + +export const start = withOrchestration(contract); +harden(start); diff --git a/packages/orchestration/src/examples/unbond.flows.js b/packages/orchestration/src/examples/unbond.flows.js new file mode 100644 index 00000000000..99f19e3655f --- /dev/null +++ b/packages/orchestration/src/examples/unbond.flows.js @@ -0,0 +1,39 @@ +import { makeTracer } from '@agoric/internal'; + +const trace = makeTracer('UnbondAndTransfer'); + +/** + * @import {Orchestrator, OrchestrationFlow, CosmosDelegationResponse} from '../types.js' + */ + +/** + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {ZCF} ctx.zcf + */ +export const unbondAndTransfer = async (orch, { zcf }) => { + trace('zcf within the membrane', zcf); + // Osmosis is one of the few chains with icqEnabled + const osmosis = await orch.getChain('osmosis'); + const osmoDenom = (await osmosis.getChainInfo()).stakingTokens[0].denom; + + // In a real world scenario, accounts would be reused across invokations of the handler. + // See the staking-combinations contract for an example of how to reuse an account. + const osmoAccount = await osmosis.makeAccount(); + + /** @type {CosmosDelegationResponse[]} Cosmos */ + const delegations = await osmoAccount.getDelegations(); + trace('delegations', delegations); + const osmoDelegations = delegations.filter(d => d.amount.denom === osmoDenom); + + // wait for the undelegations to be complete (may take weeks) + await osmoAccount.undelegate(osmoDelegations); + + const stride = await orch.getChain('stride'); + const strideAccount = await stride.makeAccount(); + + const balance = await osmoAccount.getBalance(osmoDenom); + await osmoAccount.transfer(balance, strideAccount.getAddress()); +}; +harden(unbondAndTransfer); diff --git a/packages/orchestration/src/examples/unbondExample.contract.js b/packages/orchestration/src/examples/unbondExample.contract.js deleted file mode 100644 index 8752dc1ff4e..00000000000 --- a/packages/orchestration/src/examples/unbondExample.contract.js +++ /dev/null @@ -1,87 +0,0 @@ -import { M } from '@endo/patterns'; -import { withOrchestration } from '../utils/start-helper.js'; - -/** - * @import {Orchestrator, OrchestrationFlow} from '../types.js' - * @import {TimerService} from '@agoric/time'; - * @import {LocalChain} from '@agoric/vats/src/localchain.js'; - * @import {NameHub} from '@agoric/vats'; - * @import {Remote} from '@agoric/internal'; - * @import {Zone} from '@agoric/zone'; - * @import {CosmosInterchainService} from '../exos/cosmos-interchain-service.js'; - * @import {OrchestrationTools} from '../utils/start-helper.js'; - */ - -/** - * @satisfies {OrchestrationFlow} - * @param {Orchestrator} orch - * @param {object} ctx - * @param {ZCF} ctx.zcf - * @param {ZCFSeat} _seat - * @param {undefined} _offerArgs - */ -const unbondAndLiquidStakeFn = async (orch, { zcf }, _seat, _offerArgs) => { - console.log('zcf within the membrane', zcf); - // We would actually alreaady have the account from the orchestrator - // ??? could these be passed in? It would reduce the size of this handler, - // keeping it focused on long-running operations. - const omni = await orch.getChain('omniflixhub'); - const omniAccount = await omni.makeAccount(); - - // TODO implement these - // const delegations = await celestiaAccount.getDelegations(); - // // wait for the undelegations to be complete (may take weeks) - // await celestiaAccount.undelegate(delegations); - // ??? should this be synchronous? depends on how names are resolved. - const stride = await orch.getChain('stride'); - const strideAccount = await stride.makeAccount(); - - // TODO the `TIA` string actually needs to be the Brand from AgoricNames - // const tiaAmt = await celestiaAccount.getBalance('TIA'); - // await celestiaAccount.transfer(tiaAmt, strideAccount.getAddress()); - // await strideAccount.liquidStake(tiaAmt); - console.log(omniAccount, strideAccount); -}; - -/** - * Orchestration contract to be wrapped by withOrchestration for Zoe - * - * @param {ZCF} zcf - * @param {{ - * agoricNames: Remote; - * localchain: Remote; - * orchestrationService: Remote; - * storageNode: Remote; - * marshaller: Marshaller; - * timerService: Remote; - * }} privateArgs - * @param {Zone} zone - * @param {OrchestrationTools} tools - */ -const contract = async (zcf, privateArgs, zone, { orchestrate }) => { - const unbondAndLiquidStake = orchestrate( - 'LSTTia', - { zcf }, - unbondAndLiquidStakeFn, - ); - - const publicFacet = zone.exo('publicFacet', undefined, { - makeUnbondAndLiquidStakeInvitation() { - return zcf.makeInvitation( - unbondAndLiquidStake, - 'Unbond and liquid stake', - undefined, - harden({ - // Nothing to give; the funds come from undelegating - give: {}, - want: {}, // XXX ChainAccount Ownable? - exit: M.any(), - }), - ); - }, - }); - - return harden({ publicFacet }); -}; - -export const start = withOrchestration(contract); diff --git a/packages/orchestration/src/exos/README.md b/packages/orchestration/src/exos/README.md index 6e9dbf88a44..f147c1bf071 100644 --- a/packages/orchestration/src/exos/README.md +++ b/packages/orchestration/src/exos/README.md @@ -1,56 +1,129 @@ # Exo structure -As of 2024-05-29… +Last verified 2024-09-06 ```mermaid classDiagram %% Orchestration vat business logic (Zoe) - LCAKit --* LocalchainAccount - ICQConnectionKit --* Port - ICQConnectionKit --* Connection - ChainAccountKit --* Port - ChainAccountKit --* Connection - StakingAccountKit --* IcaAccount - - class ChainAccountKit { + ICQConnection --* Port + ICQConnection --* Connection + IcaAccount --* Port + IcaAccount --* Connection + IcaAccount --* CosmosInterchainService + ICQConnection --* CosmosInterchainService + CosmosInterchainService --* PortAllocator + PortAllocator --* NetworkVat + LocalChainAccount --* LocalChainVat + + class IcaAccount { port: Port connection: Connection localAddress: LocalIbcAddress requestedRemoteAddress: string remoteAddress: RemoteIbcAddress chainAddress: ChainAddress + getAddress() + getLocalAddress() + getRemoteAddress() + getPort() + executeTx() + executeEncodedTx() + deactivate() + reactivate() } - class ICQConnectionKit { + class ICQConnection { port: Port connection: Connection localAddress: LocalIbcAddress remoteAddress: RemoteIbcAddress + getLocalAddress() + getRemoteAddress() + query() } - class StakingAccountKit { - chainAddress: ChainAddress - bondDenom: string - account: ICAAccount - timer: Timer - topicKit: TopicKit - makeTransferInvitation() + + class CosmosInterchainService { + portAllocator: PortAllocator + icqConnections: MapStore + sharedICQPort: Port + makeAccount() + provideICQConnection() } %% In other vats - class LCAKit { - account: LocalChainAccount - address: ChainAddress - topicKit: RecorderKit + class Port { + getLocalAddress() + addListener() + connect() + removeListener() + revoke() } - class LocalchainAccount { - executeTx() - deposit() - withdraw() + + class Connection { + getLocalAddress() + getRemoteAddress() + send() + close() } - class IcaAccount { - executeTx() - deposit() - getPurse() - close() + + class PortAllocator { + allocateCustomIBCPort() + allocateICAControllerPort() + allocateICQControllerPort() + } + + class LocalChainAccount { + deposit() + executeTx() + getBalance() + withdraw() + executeTx() + monitorTransfers() + } + +%% In api consumer vats + + LocalOrchestrationAccount --* LocalChainAccount + CosmosOrchestrationAccount --* IcaAccount + + class LocalOrchestrationAccount { + account: LocalChainAccount + address: ChainAddress + topicKit: RecorderKit + asContinuingOffer() + delegate() + deposit() + executeTx() + getAddress() + getBalance() + getBalances() + getPublicTopics() + monitorTransfers() + send() + sendAll() + transfer() + undelegate() + withdraw() + } + + class CosmosOrchestrationAccount { + account: LocalChainAccount + chainAddress: ChainAddress + icqConnection: ICQConnection | undefined + timer: Timer + topicKit: RecorderKit + asContinuingOffer() + delegate() + executeEncodedTx() + getAddress() + getBalance() + getBalances() + getPublicTopics() + redelegate() + send() + sendAll() + transfer() + undelegate() + withdrawReward() } ``` diff --git a/packages/orchestration/src/exos/agoric-names-tools.js b/packages/orchestration/src/exos/agoric-names-tools.js deleted file mode 100644 index b6280b77180..00000000000 --- a/packages/orchestration/src/exos/agoric-names-tools.js +++ /dev/null @@ -1,109 +0,0 @@ -import { VowShape } from '@agoric/vow'; -import { E } from '@endo/far'; -import { M, makeCopyMap } from '@endo/patterns'; -import { BrandShape } from '@agoric/ertp'; - -const { Fail } = assert; - -/** - * @import {NameHub} from '@agoric/vats'; - * @import {AssetInfo} from '@agoric/vats/src/vat-bank.js'; - * @import {Remote} from '@agoric/internal'; - * @import {Vow, VowTools} from '@agoric/vow'; - * @import {Zone} from '@agoric/zone'; - */ - -/** - * Perform remote calls to agoricNames in membrane-friendly way. This is an - * interim approach until https://github.com/Agoric/agoric-sdk/issues/9541, - * https://github.com/Agoric/agoric-sdk/pull/9322, or - * https://github.com/Agoric/agoric-sdk/pull/9519. - * - * XXX only works once per zone. - * - * XXX consider exposing `has`, `entries`, `keys`, `values` from `NameHub` - * - * @param {Zone} zone - * @param {{ agoricNames: Remote; vowTools: VowTools }} powers - */ -export const makeResumableAgoricNamesHack = ( - zone, - { agoricNames, vowTools: { watch, asVow } }, -) => { - const makeResumableAgoricNamesHackKit = zone.exoClassKit( - 'ResumableAgoricNamesHack', - { - public: M.interface('ResumableAgoricNamesHackI', { - lookup: M.call().rest(M.arrayOf(M.string())).returns(VowShape), - findBrandInVBank: M.call(BrandShape) - .optional(M.boolean()) - .returns(VowShape), - }), - vbankAssetEntriesWatcher: M.interface('vbankAssetEntriesWatcher', { - onFulfilled: M.call(M.arrayOf(M.record())) - .optional(BrandShape) - .returns(VowShape), - }), - }, - () => ({ - vbankAssetsByBrand: zone.mapStore('vbankAssetsByBrand', { - keyShape: BrandShape, - valueShape: M.any(), - }), - }), - { - vbankAssetEntriesWatcher: { - /** - * @param {AssetInfo[]} assets - * @param {Brand<'nat'>} brand - */ - onFulfilled(assets, brand) { - return asVow(() => { - const { vbankAssetsByBrand } = this.state; - vbankAssetsByBrand.addAll( - makeCopyMap(assets.map(a => [a.brand, a])), - ); - vbankAssetsByBrand.has(brand) || - Fail`brand ${brand} not in agoricNames.vbankAsset`; - return vbankAssetsByBrand.get(brand); - }); - }, - }, - public: { - /** @param {...string} args */ - lookup(...args) { - return watch(E(agoricNames).lookup(...args)); - }, - /** - * Look up asset info, like denom, in agoricNames.vbankAsset using a - * Brand. - * - * Caches the query to agoricNames in the first call. Subsequent lookups - * are via cache unless a refetch is specified or a brand is not found. - * - * @param {Brand<'nat'>} brand - * @param {boolean} [refetch] if true, will invalidate the cache - * @returns {Vow} - */ - findBrandInVBank(brand, refetch) { - return asVow(() => { - const { vbankAssetsByBrand } = this.state; - if (vbankAssetsByBrand.has(brand) && !refetch) { - return vbankAssetsByBrand.get(brand); - } - const vbankAssetNameHubP = E(agoricNames).lookup('vbankAsset'); - const vbankAssetEntriesP = E(vbankAssetNameHubP).values(); - return watch( - vbankAssetEntriesP, - this.facets.vbankAssetEntriesWatcher, - brand, - ); - }); - }, - }, - }, - ); - // XXX only works once per zone. - return makeResumableAgoricNamesHackKit().public; -}; -/** @typedef {ReturnType} AgNamesTools */ diff --git a/packages/orchestration/src/exos/chain-hub-admin.js b/packages/orchestration/src/exos/chain-hub-admin.js index 527c7a70433..e790257b3b4 100644 --- a/packages/orchestration/src/exos/chain-hub-admin.js +++ b/packages/orchestration/src/exos/chain-hub-admin.js @@ -1,13 +1,14 @@ /* we expect promises to resolved promptly, */ /* eslint-disable no-restricted-syntax */ -import { M } from '@endo/patterns'; import { heapVowE } from '@agoric/vow/vat.js'; +import { M } from '@endo/patterns'; import { CosmosChainInfoShape } from '../typeGuards.js'; +import { DenomDetailShape } from './chain-hub.js'; /** * @import {Zone} from '@agoric/zone'; - * @import {CosmosChainInfo, IBCConnectionInfo} from '@agoric/orchestration'; - * @import {ChainHub} from './chain-hub.js'; + * @import {CosmosChainInfo, Denom, IBCConnectionInfo} from '@agoric/orchestration'; + * @import {ChainHub, DenomDetail} from './chain-hub.js'; */ /** @@ -15,6 +16,17 @@ import { CosmosChainInfoShape } from '../typeGuards.js'; * developers to add new chain configurations to a local chainHub, in the event * the information is not available widely in `agoricNames`. * + * @example + * + * ```js + * const chainHubAdmin = prepareChainHubAdmin(zone, chainHub); + * chainHubAdmin.initChain( + * 'hotNewChain', + * hotNewChainInfo, + * agoricTohotNewChainConnectionInfo, + * ); + * ``` + * * @param {Zone} zone * @param {ChainHub} chainHub */ @@ -23,19 +35,22 @@ export const prepareChainHubAdmin = (zone, chainHub) => { const makeCreatorFacet = zone.exo( 'ChainHub Admin', M.interface('ChainHub Admin', { - initChain: M.callWhen( + registerChain: M.callWhen( M.string(), CosmosChainInfoShape, ConnectionInfoShape, ).returns(M.undefined()), + registerAsset: M.call(M.string(), DenomDetailShape).returns(M.promise()), }), { /** - * @param {string} chainName + * Register information for a chain + * + * @param {string} chainName - must not exist in chainHub * @param {CosmosChainInfo} chainInfo - * @param {IBCConnectionInfo} connectionInfo + * @param {IBCConnectionInfo} connectionInfo - from Agoric chain */ - async initChain(chainName, chainInfo, connectionInfo) { + async registerChain(chainName, chainInfo, connectionInfo) { // when() because chainHub methods return vows. If this were inside // orchestrate() the membrane would wrap/unwrap automatically. const agoricChainInfo = await heapVowE.when( @@ -48,6 +63,19 @@ export const prepareChainHubAdmin = (zone, chainHub) => { connectionInfo, ); }, + /** + * Register an asset that may be held on a chain other than the issuing + * chain. + * + * @param {Denom} denom - on the holding chain, whose name is given in + * `detail.chainName` + * @param {DenomDetail} detail - chainName and baseName must be registered + */ + async registerAsset(denom, detail) { + // XXX async work necessary before the synchronous call + await heapVowE.when(chainHub.getChainInfo('agoric')); + chainHub.registerAsset(denom, detail); + }, }, ); return makeCreatorFacet; diff --git a/packages/orchestration/src/exos/chain-hub.js b/packages/orchestration/src/exos/chain-hub.js index 7f235bac09c..903fb370c48 100644 --- a/packages/orchestration/src/exos/chain-hub.js +++ b/packages/orchestration/src/exos/chain-hub.js @@ -1,6 +1,7 @@ -import { Fail, makeError } from '@endo/errors'; +import { Fail, makeError, q } from '@endo/errors'; import { E } from '@endo/far'; import { M } from '@endo/patterns'; +import { BrandShape } from '@agoric/ertp/src/typeGuards.js'; import { VowShape } from '@agoric/vow'; import { makeHeapZone } from '@agoric/zone'; @@ -9,23 +10,44 @@ import { CosmosChainInfoShape, IBCConnectionInfoShape } from '../typeGuards.js'; /** * @import {NameHub} from '@agoric/vats'; * @import {Vow, VowTools} from '@agoric/vow'; - * @import {CosmosChainInfo, IBCConnectionInfo} from '../cosmos-api.js'; + * @import {CosmosAssetInfo, CosmosChainInfo, IBCConnectionInfo} from '../cosmos-api.js'; * @import {ChainInfo, KnownChains} from '../chain-info.js'; + * @import {Denom} from '../orchestration-api.js'; * @import {Remote} from '@agoric/internal'; - * @import {Zone} from '@agoric/zone'; + * @import {TypedPattern} from '@agoric/internal'; */ /** + * If K matches a known chain, narrow the type from generic ChainInfo + * * @template {string} K * @typedef {K extends keyof KnownChains - * ? Omit + * ? ChainInfo & Omit * : ChainInfo} ActualChainInfo + * @internal + */ + +/** + * @typedef {object} DenomDetail + * @property {string} baseName - name of issuing chain; e.g. cosmoshub + * @property {Denom} baseDenom - e.g. uatom + * @property {string} chainName - name of holding chain; e.g. agoric + * @property {Brand<'nat'>} [brand] - vbank brand, if registered + * @see {ChainHub} `registerAsset` method */ +/** @type {TypedPattern} */ +export const DenomDetailShape = M.splitRecord( + { chainName: M.string(), baseName: M.string(), baseDenom: M.string() }, + { brand: BrandShape }, +); +// TODO refactor into an enum-ish object /** agoricNames key for ChainInfo hub */ export const CHAIN_KEY = 'chain'; /** namehub for connection info */ export const CONNECTIONS_KEY = 'chainConnection'; +/** namehub for assets info */ +export const ASSETS_KEY = 'chainAssets'; /** * Character used in a connection tuple key to separate the two chain ids. Valid @@ -62,7 +84,7 @@ export const connectionKey = (chainId1, chainId2) => { * @param {IBCConnectionInfo} connInfo * @returns {IBCConnectionInfo} */ -export const reverseConnInfo = connInfo => { +const reverseConnInfo = connInfo => { const { transferChannel } = connInfo; return { id: connInfo.counterparty.connection_id, @@ -70,9 +92,6 @@ export const reverseConnInfo = connInfo => { counterparty: { client_id: connInfo.client_id, connection_id: connInfo.id, - prefix: { - key_prefix: 'FIXME', - }, }, state: connInfo.state, transferChannel: { @@ -146,6 +165,9 @@ const ChainHubI = M.interface('ChainHub', { ).returns(), getConnectionInfo: M.call(ChainIdArgShape, ChainIdArgShape).returns(VowShape), getChainsAndConnection: M.call(M.string(), M.string()).returns(VowShape), + registerAsset: M.call(M.string(), DenomDetailShape).returns(), + getAsset: M.call(M.string()).returns(M.or(DenomDetailShape, M.undefined())), + getDenom: M.call(BrandShape).returns(M.or(M.string(), M.undefined())), }); /** @@ -172,6 +194,17 @@ export const makeChainHub = (agoricNames, vowTools) => { valueShape: IBCConnectionInfoShape, }); + /** @type {MapStore} */ + const denomDetails = zone.mapStore('denom', { + keyShape: M.string(), + valueShape: DenomDetailShape, + }); + /** @type {MapStore} */ + const brandDenoms = zone.mapStore('brandDenom', { + keyShape: BrandShape, + valueShape: M.string(), + }); + const lookupChainInfo = vowTools.retriable( zone, 'lookupChainInfo', @@ -336,8 +369,74 @@ export const makeChainHub = (agoricNames, vowTools) => { // @ts-expect-error XXX generic parameter propagation return lookupChainsAndConnection(primaryName, counterName); }, + + /** + * Register an asset that may be held on a chain other than the issuing + * chain. + * + * @param {Denom} denom - on the holding chain, whose name is given in + * `detail.chainName` + * @param {DenomDetail} detail - chainName and baseName must be registered + */ + registerAsset(denom, detail) { + const { chainName, baseName } = detail; + chainInfos.has(chainName) || + Fail`must register chain ${q(chainName)} first`; + chainInfos.has(baseName) || + Fail`must register chain ${q(baseName)} first`; + denomDetails.init(denom, detail); + if (detail.brand) { + brandDenoms.init(detail.brand, denom); + } + }, + /** + * Retrieve holding, issuing chain names etc. for a denom. + * + * @param {Denom} denom + * @returns {DenomDetail | undefined} + */ + getAsset(denom) { + if (denomDetails.has(denom)) { + return denomDetails.get(denom); + } + return undefined; + }, + /** + * Retrieve denom (string) for a Brand. + * + * @param {Brand} brand + * @returns {Denom | undefined} + */ + getDenom(brand) { + if (brandDenoms.has(brand)) { + return brandDenoms.get(brand); + } + return undefined; + }, }); return chainHub; }; /** @typedef {ReturnType} ChainHub */ + +/** + * Register assets with the given ChainHub so they are available for lookup + * + * @param {ChainHub} chainHub + * @param {string} name + * @param {CosmosAssetInfo[]} assets + */ +export const registerAssets = (chainHub, name, assets) => { + for (const { base, traces } of assets) { + const native = !traces; + native || traces.length === 1 || Fail`unexpected ${traces.length} traces`; + const [chainName, baseName, baseDenom] = native + ? [name, name, base] + : [ + name, + traces[0].counterparty.chain_name, + traces[0].counterparty.base_denom, + ]; + chainHub.registerAsset(base, { chainName, baseName, baseDenom }); + } +}; diff --git a/packages/orchestration/src/exos/combine-invitation-makers.js b/packages/orchestration/src/exos/combine-invitation-makers.js new file mode 100644 index 00000000000..e7b647e3ba6 --- /dev/null +++ b/packages/orchestration/src/exos/combine-invitation-makers.js @@ -0,0 +1,53 @@ +import { M } from '@endo/patterns'; +import { + prepareGuardedAttenuator, + makeSyncMethodCallback, +} from '@agoric/internal/src/callback.js'; +import { getMethodNames } from '@agoric/internal'; + +/** + * @import {InvitationMakers} from '@agoric/smart-wallet/src/types.js'; + * @import {Zone} from '@agoric/zone'; + */ + +// TODO use a helper from Endo https://github.com/endojs/endo/issues/2448 +/** + * Takes two or more InvitationMaker exos and combines them into a new one. + * + * @param {Zone} zone + * @param {import('@endo/patterns').InterfaceGuard[]} interfaceGuards + */ +export const prepareCombineInvitationMakers = (zone, ...interfaceGuards) => { + const methodGuards = interfaceGuards.map(ig => ig.payload.methodGuards); + const CombinedInterfaceGuard = M.interface( + 'CombinedInvitationMakers interface', + Object.assign({}, ...methodGuards), + ); + + const mixin = prepareGuardedAttenuator(zone, CombinedInterfaceGuard, { + tag: 'CombinedInvitationMakers', + }); + + /** + * @template {InvitationMakers[]} IM + * @param {IM} invitationMakers + * @returns {IM[number]} + */ + const combineInvitationMakers = (...invitationMakers) => { + const overrides = {}; + for (const invMakers of invitationMakers) { + // remove '__getInterfaceGuard__', '__getMethodNames__' + const names = getMethodNames(invMakers).filter(n => !n.startsWith('__')); + for (const key of names) { + overrides[key] = makeSyncMethodCallback(invMakers, key); + } + } + return mixin({ + overrides, + }); + }; + + return combineInvitationMakers; +}; + +/** @typedef {ReturnType} MakeCombineInvitationMakers */ diff --git a/packages/orchestration/src/exos/cosmos-interchain-service.js b/packages/orchestration/src/exos/cosmos-interchain-service.js index 82acebd8f13..5724cc9490a 100644 --- a/packages/orchestration/src/exos/cosmos-interchain-service.js +++ b/packages/orchestration/src/exos/cosmos-interchain-service.js @@ -1,15 +1,16 @@ /** @file Orchestration service */ -import { Fail, b } from '@endo/errors'; -import { E } from '@endo/far'; -import { M } from '@endo/patterns'; import { Shape as NetworkShape } from '@agoric/network'; -import { prepareChainAccountKit } from './chain-account-kit.js'; -import { prepareICQConnectionKit } from './icq-connection-kit.js'; +import { pickFacet } from '@agoric/vat-data'; +import { E } from '@endo/far'; +import { M, mustMatch } from '@endo/patterns'; import { + DEFAULT_ICQ_VERSION, makeICAChannelAddress, makeICQChannelAddress, } from '../utils/address.js'; +import { prepareIcaAccountKit } from './ica-account-kit.js'; +import { prepareICQConnectionKit } from './icq-connection-kit.js'; /** * @import {Zone} from '@agoric/base-zone'; @@ -18,52 +19,51 @@ import { * @import {IBCConnectionID} from '@agoric/vats'; * @import {RemoteIbcAddress} from '@agoric/vats/tools/ibc-utils.js'; * @import {Vow, VowTools} from '@agoric/vow'; - * @import {ICQConnection, IcaAccount, ICQConnectionKit, ChainAccountKit} from '../types.js'; + * @import {ICQConnection, IcaAccount, ICQConnectionKit, IcaAccountKit} from '../types.js'; + * @import {ICAChannelAddressOpts} from '../utils/address.js'; */ const { Vow$ } = NetworkShape; // TODO #9611 /** * @typedef {object} OrchestrationPowers * @property {Remote} portAllocator + * @property {undefined} reserved reserve a state key for future use. can hold + * an additional power or a record of powers */ -/** - * PowerStore is used so additional powers can be added on upgrade. See - * [#7337](https://github.com/Agoric/agoric-sdk/issues/7337) for tracking on Exo - * state migrations. - * - * @typedef {MapStore< - * keyof OrchestrationPowers, - * OrchestrationPowers[keyof OrchestrationPowers] - * >} PowerStore - */ +/** @typedef {MapStore} ICQConnectionStore */ -/** @typedef {MapStore} ICQConnectionStore */ +/** @typedef {IcaAccountKit | ICQConnectionKit} ConnectionKit */ -/** @typedef {ChainAccountKit | ICQConnectionKit} ConnectionKit */ +/** + * @typedef {{ + * icqConnections: ICQConnectionStore; + * sharedICQPort: Remote | undefined; + * } & OrchestrationPowers} OrchestrationState + */ /** - * @template {keyof OrchestrationPowers} K - * @param {PowerStore} powers - * @param {K} name + * Creates a key for the icqConnections mapStore based on connectionId and + * version + * + * @param {IBCConnectionID} controllerConnectionId + * @param {string} [version] + * @returns {string} */ -const getPower = (powers, name) => { - powers.has(name) || Fail`need powers.${b(name)} for this method`; - return /** @type {OrchestrationPowers[K]} */ (powers.get(name)); +const getICQConnectionKey = (controllerConnectionId, version) => { + return `${controllerConnectionId}:${version || DEFAULT_ICQ_VERSION}`; }; -/** @typedef {{ powers: PowerStore; icqConnections: ICQConnectionStore }} OrchestrationState */ - /** * @param {Zone} zone * @param {VowTools} vowTools - * @param {ReturnType} makeChainAccountKit + * @param {ReturnType} makeIcaAccountKit * @param {ReturnType} makeICQConnectionKit */ const prepareCosmosOrchestrationServiceKit = ( zone, - { watch }, - makeChainAccountKit, + { watch, asVow }, + makeIcaAccountKit, makeICQConnectionKit, ) => zone.exoClassKit( @@ -78,7 +78,7 @@ const prepareCosmosOrchestrationServiceKit = ( onFulfilled: M.call(M.remotable('Port')) .optional({ remoteConnAddr: M.string(), - controllerConnectionId: M.string(), + icqLookupKey: M.string(), }) .returns(Vow$(NetworkShape.Connection)), }), @@ -87,31 +87,30 @@ const prepareCosmosOrchestrationServiceKit = ( .optional( M.splitRecord( { connectionKit: M.record(), returnFacet: M.string() }, - { saveICQConnection: M.string() }, + { icqLookupKey: M.string() }, ), ) .returns(M.remotable('ConnectionKit Holder facet')), }), public: M.interface('CosmosInterchainService', { - makeAccount: M.call(M.string(), M.string(), M.string()).returns( - Vow$(M.remotable('ChainAccountKit')), - ), - provideICQConnection: M.call(M.string()).returns( - Vow$(M.remotable('ICQConnection')), - ), + makeAccount: M.call(M.string(), M.string(), M.string()) + .optional(M.record()) + .returns(Vow$(M.remotable('IcaAccountKit'))), + provideICQConnection: M.call(M.string()) + .optional(M.string()) + .returns(Vow$(M.remotable('ICQConnection'))), }), }, - /** @param {Partial} [initialPowers] */ - initialPowers => { - /** @type {PowerStore} */ - const powers = zone.detached().mapStore('PowerStore'); - if (initialPowers) { - for (const [name, power] of Object.entries(initialPowers)) { - powers.init(/** @type {keyof OrchestrationPowers} */ (name), power); - } - } + /** @param {Partial} powers */ + powers => { + mustMatch(powers?.portAllocator, M.remotable('PortAllocator')); const icqConnections = zone.detached().mapStore('ICQConnections'); - return /** @type {OrchestrationState} */ ({ powers, icqConnections }); + return /** @type {OrchestrationState} */ ({ + icqConnections, + sharedICQPort: undefined, + reserved: undefined, + ...powers, + }); }, { requestICAChannelWatcher: { @@ -123,15 +122,15 @@ const prepareCosmosOrchestrationServiceKit = ( * }} watchContext */ onFulfilled(port, { chainId, remoteConnAddr }) { - const chainAccountKit = makeChainAccountKit( + const connectionKit = makeIcaAccountKit( chainId, port, remoteConnAddr, ); return watch( - E(port).connect(remoteConnAddr, chainAccountKit.connectionHandler), + E(port).connect(remoteConnAddr, connectionKit.connectionHandler), this.facets.channelOpenWatcher, - { returnFacet: 'account', connectionKit: chainAccountKit }, + { returnFacet: 'account', connectionKit }, ); }, }, @@ -140,19 +139,21 @@ const prepareCosmosOrchestrationServiceKit = ( * @param {Port} port * @param {{ * remoteConnAddr: RemoteIbcAddress; - * controllerConnectionId: IBCConnectionID; + * icqLookupKey: string; * }} watchContext */ - onFulfilled(port, { remoteConnAddr, controllerConnectionId }) { + onFulfilled(port, { remoteConnAddr, icqLookupKey }) { + if (!this.state.sharedICQPort) { + this.state.sharedICQPort = port; + } const connectionKit = makeICQConnectionKit(port); - /** @param {ICQConnectionKit} kit */ return watch( E(port).connect(remoteConnAddr, connectionKit.connectionHandler), this.facets.channelOpenWatcher, { connectionKit, returnFacet: 'connection', - saveICQConnection: controllerConnectionId, + icqLookupKey, }, ); }, @@ -168,38 +169,37 @@ const prepareCosmosOrchestrationServiceKit = ( * @param {{ * connectionKit: ConnectionKit; * returnFacet: string; - * saveICQConnection?: IBCConnectionID; + * icqLookupKey?: string; * }} watchContext */ - onFulfilled( - _connection, - { connectionKit, returnFacet, saveICQConnection }, - ) { - if (saveICQConnection) { + onFulfilled(_connection, { connectionKit, returnFacet, icqLookupKey }) { + if (icqLookupKey) { this.state.icqConnections.init( - saveICQConnection, + icqLookupKey, /** @type {ICQConnectionKit} */ (connectionKit), ); } return connectionKit[returnFacet]; }, - // TODO #9317 if we fail, should we revoke the port (if it was created in this flow)? - // onRejected() {} }, public: { /** + * @satisfies {CosmosInterchainService['makeAccount']} * @param {string} chainId * @param {IBCConnectionID} hostConnectionId the counterparty * connection_id * @param {IBCConnectionID} controllerConnectionId self connection_id + * @param {ICAChannelAddressOpts} [opts] optional to configure the + * channel address, such as version and ordering * @returns {Vow} */ - makeAccount(chainId, hostConnectionId, controllerConnectionId) { + makeAccount(chainId, hostConnectionId, controllerConnectionId, opts) { const remoteConnAddr = makeICAChannelAddress( hostConnectionId, controllerConnectionId, + opts, ); - const portAllocator = getPower(this.state.powers, 'portAllocator'); + const { portAllocator } = this.state; return watch( E(portAllocator).allocateICAControllerPort(), this.facets.requestICAChannelWatcher, @@ -210,53 +210,71 @@ const prepareCosmosOrchestrationServiceKit = ( ); }, /** + * @satisfies {CosmosInterchainService['provideICQConnection']} * @param {IBCConnectionID} controllerConnectionId + * @param {string} [version] * @returns {Vow | ICQConnection} */ - provideICQConnection(controllerConnectionId) { - if (this.state.icqConnections.has(controllerConnectionId)) { - // TODO #9281 do not return synchronously. see https://github.com/Agoric/agoric-sdk/pull/9454#discussion_r1626898694 - return this.state.icqConnections.get(controllerConnectionId) - .connection; + provideICQConnection(controllerConnectionId, version) { + const icqLookupKey = getICQConnectionKey( + controllerConnectionId, + version, + ); + if (this.state.icqConnections.has(icqLookupKey)) { + return asVow( + () => this.state.icqConnections.get(icqLookupKey).connection, + ); } - const remoteConnAddr = makeICQChannelAddress(controllerConnectionId); - const portAllocator = getPower(this.state.powers, 'portAllocator'); - return watch( - // allocate a new Port for every Connection - // TODO #9317 optimize ICQ port allocation - E(portAllocator).allocateICQControllerPort(), - this.facets.requestICQChannelWatcher, - { - remoteConnAddr, - controllerConnectionId, - }, + const remoteConnAddr = makeICQChannelAddress( + controllerConnectionId, + version, ); + const { portAllocator, sharedICQPort } = this.state; + const portOrPortVow = + sharedICQPort || E(portAllocator).allocateICQControllerPort(); + + return watch(portOrPortVow, this.facets.requestICQChannelWatcher, { + remoteConnAddr, + icqLookupKey, + }); }, }, }, + { + stateShape: { + icqConnections: M.remotable('icqConnections mapStore'), + sharedICQPort: M.or(M.remotable('Port'), M.undefined()), + portAllocator: M.remotable('PortAllocator'), + reserved: M.any(), + }, + }, ); /** + * Used only by vat-orchestration and tests mocking it + * * @param {Zone} zone * @param {VowTools} vowTools + * @internal */ export const prepareCosmosInterchainService = (zone, vowTools) => { - const makeChainAccountKit = prepareChainAccountKit(zone, vowTools); + const makeIcaAccountKit = prepareIcaAccountKit(zone, vowTools); const makeICQConnectionKit = prepareICQConnectionKit(zone, vowTools); const makeCosmosOrchestrationServiceKit = prepareCosmosOrchestrationServiceKit( zone, vowTools, - makeChainAccountKit, + makeIcaAccountKit, makeICQConnectionKit, ); - const makeCosmosInterchainService = initialPowers => - makeCosmosOrchestrationServiceKit(initialPowers).public; + const makeCosmosInterchainService = pickFacet( + makeCosmosOrchestrationServiceKit, + 'public', + ); return makeCosmosInterchainService; }; harden(prepareCosmosInterchainService); /** @typedef {ReturnType} MakeCosmosInterchainService */ -/** @typedef {ReturnType} CosmosInterchainService */ diff --git a/packages/orchestration/src/exos/cosmos-orchestration-account.js b/packages/orchestration/src/exos/cosmos-orchestration-account.js index 50293b4253a..32d0de72121 100644 --- a/packages/orchestration/src/exos/cosmos-orchestration-account.js +++ b/packages/orchestration/src/exos/cosmos-orchestration-account.js @@ -1,13 +1,34 @@ /** @file Use-object for the owner of a staking account */ import { toRequestQueryJson } from '@agoric/cosmic-proto'; import { + QueryAllBalancesRequest, + QueryAllBalancesResponse, QueryBalanceRequest, QueryBalanceResponse, } from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; +import { MsgSend } from '@agoric/cosmic-proto/cosmos/bank/v1beta1/tx.js'; +import { + QueryDelegationRewardsRequest, + QueryDelegationRewardsResponse, + QueryDelegationTotalRewardsRequest, + QueryDelegationTotalRewardsResponse, +} from '@agoric/cosmic-proto/cosmos/distribution/v1beta1/query.js'; import { MsgWithdrawDelegatorReward, MsgWithdrawDelegatorRewardResponse, } from '@agoric/cosmic-proto/cosmos/distribution/v1beta1/tx.js'; +import { + QueryDelegationRequest, + QueryDelegationResponse, + QueryDelegatorDelegationsRequest, + QueryDelegatorDelegationsResponse, + QueryDelegatorUnbondingDelegationsRequest, + QueryDelegatorUnbondingDelegationsResponse, + QueryRedelegationsRequest, + QueryRedelegationsResponse, + QueryUnbondingDelegationRequest, + QueryUnbondingDelegationResponse, +} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/query.js'; import { MsgBeginRedelegate, MsgDelegate, @@ -15,29 +36,40 @@ import { MsgUndelegateResponse, } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js'; +import { MsgTransfer } from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js'; import { makeTracer } from '@agoric/internal'; import { Shape as NetworkShape } from '@agoric/network'; import { M } from '@agoric/vat-data'; import { VowShape } from '@agoric/vow'; import { decodeBase64 } from '@endo/base64'; -import { Fail } from '@endo/errors'; +import { Fail, makeError, q } from '@endo/errors'; import { E } from '@endo/far'; import { AmountArgShape, ChainAddressShape, DelegationShape, DenomAmountShape, + IBCTransferOptionsShape, } from '../typeGuards.js'; -import { maxClockSkew, tryDecodeResponse } from '../utils/cosmos.js'; +import { coerceCoin, coerceDenom } from '../utils/amounts.js'; +import { + maxClockSkew, + toCosmosDelegationResponse, + toCosmosValidatorAddress, + toDenomAmount, + toTruncatedDenomAmount, + tryDecodeResponse, +} from '../utils/cosmos.js'; import { orchestrationAccountMethods } from '../utils/orchestrationAccount.js'; +import { makeTimestampHelper } from '../utils/time.js'; /** * @import {HostOf} from '@agoric/async-flow'; - * @import {AmountArg, IcaAccount, ChainAddress, CosmosValidatorAddress, ICQConnection, StakingAccountActions, DenomAmount, OrchestrationAccountI, DenomArg} from '../types.js'; + * @import {AmountArg, IcaAccount, ChainAddress, CosmosValidatorAddress, ICQConnection, StakingAccountActions, StakingAccountQueries, OrchestrationAccountI, CosmosRewardsResponse, IBCConnectionInfo, IBCMsgTransferOptions, ChainHub, CosmosDelegationResponse} from '../types.js'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'; * @import {Coin} from '@agoric/cosmic-proto/cosmos/base/v1beta1/coin.js'; - * @import {Delegation} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/staking.js'; * @import {Remote} from '@agoric/internal'; + * @import {DelegationResponse} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/staking.js'; * @import {InvitationMakers} from '@agoric/smart-wallet/src/types.js'; * @import {TimerService} from '@agoric/time'; * @import {Vow, VowTools} from '@agoric/vow'; @@ -45,6 +77,7 @@ import { orchestrationAccountMethods } from '../utils/orchestrationAccount.js'; * @import {ResponseQuery} from '@agoric/cosmic-proto/tendermint/abci/types.js'; * @import {JsonSafe} from '@agoric/cosmic-proto'; * @import {Matcher} from '@endo/patterns'; + * @import {LocalIbcAddress, RemoteIbcAddress} from '@agoric/vats/tools/ibc-utils.js'; */ const trace = makeTracer('ComosOrchestrationAccountHolder'); @@ -57,30 +90,59 @@ const { Vow$ } = NetworkShape; // TODO #9611 */ /** + * @private * @typedef {{ * topicKit: RecorderKit; * account: IcaAccount; * chainAddress: ChainAddress; + * localAddress: LocalIbcAddress; + * remoteAddress: RemoteIbcAddress; * icqConnection: ICQConnection | undefined; - * bondDenom: string; * timer: Remote; * }} State + * Internal to the IcaAccountHolder exo */ -/** @see {OrchestrationAccountI} */ -export const IcaAccountHolderI = M.interface('IcaAccountHolder', { - ...orchestrationAccountMethods, +/** + * @typedef {{ + * localAddress: LocalIbcAddress; + * remoteAddress: RemoteIbcAddress; + * }} CosmosOrchestrationAccountStorageState + */ + +/** @see {StakingAccountActions} */ +const stakingAccountActionsMethods = { delegate: M.call(ChainAddressShape, AmountArgShape).returns(VowShape), redelegate: M.call( ChainAddressShape, ChainAddressShape, AmountArgShape, ).returns(VowShape), + undelegate: M.call(M.arrayOf(DelegationShape)).returns(VowShape), withdrawReward: M.call(ChainAddressShape).returns( Vow$(M.arrayOf(DenomAmountShape)), ), withdrawRewards: M.call().returns(Vow$(M.arrayOf(DenomAmountShape))), - undelegate: M.call(M.arrayOf(DelegationShape)).returns(VowShape), +}; + +/** @see {StakingAccountQueries} */ +const stakingAccountQueriesMethods = { + getDelegation: M.call(ChainAddressShape).returns(VowShape), + getDelegations: M.call().returns(VowShape), + getUnbondingDelegation: M.call(ChainAddressShape).returns(VowShape), + getUnbondingDelegations: M.call().returns(VowShape), + getRedelegations: M.call().returns(VowShape), + getReward: M.call(ChainAddressShape).returns(VowShape), + getRewards: M.call().returns(VowShape), +}; + +/** @see {OrchestrationAccountI} */ +export const IcaAccountHolderI = M.interface('IcaAccountHolder', { + ...orchestrationAccountMethods, + ...stakingAccountActionsMethods, + ...stakingAccountQueriesMethods, + deactivate: M.call().returns(VowShape), + reactivate: M.call().returns(VowShape), }); /** @type {{ [name: string]: [description: string, valueShape: Matcher] }} */ @@ -88,21 +150,47 @@ const PUBLIC_TOPICS = { account: ['Staking Account holder status', M.any()], }; -/** @type {(c: { denom: string; amount: string }) => DenomAmount} */ -const toDenomAmount = c => ({ denom: c.denom, value: BigInt(c.amount) }); +export const CosmosOrchestrationInvitationMakersI = M.interface( + 'invitationMakers', + { + Delegate: M.call(ChainAddressShape, AmountArgShape).returns(M.promise()), + Redelegate: M.call( + ChainAddressShape, + ChainAddressShape, + AmountArgShape, + ).returns(M.promise()), + WithdrawReward: M.call(ChainAddressShape).returns(M.promise()), + Undelegate: M.call(M.arrayOf(DelegationShape)).returns(M.promise()), + DeactivateAccount: M.call().returns(M.promise()), + ReactivateAccount: M.call().returns(M.promise()), + TransferAccount: M.call().returns(M.promise()), + Send: M.call().returns(M.promise()), + SendAll: M.call().returns(M.promise()), + Transfer: M.call().returns(M.promise()), + }, +); +harden(CosmosOrchestrationInvitationMakersI); /** * @param {Zone} zone - * @param {MakeRecorderKit} makeRecorderKit - * @param {VowTools} vowTools - * @param {ZCF} zcf + * @param {object} powers + * @param {ChainHub} powers.chainHub + * @param {MakeRecorderKit} powers.makeRecorderKit + * @param {Remote} powers.timerService + * @param {VowTools} powers.vowTools + * @param {ZCF} powers.zcf */ export const prepareCosmosOrchestrationAccountKit = ( zone, - makeRecorderKit, - { watch, asVow, when }, - zcf, + { + chainHub, + makeRecorderKit, + timerService, + vowTools: { watch, asVow, when, allVows }, + zcf, + }, ) => { + const timestampHelper = makeTimestampHelper(timerService); const makeCosmosOrchestrationAccountKit = zone.exoClassKit( 'Cosmos Orchestration Account Holder', { @@ -121,6 +209,11 @@ export const prepareCosmosOrchestrationAccountKit = ( .optional(M.arrayOf(M.undefined())) // empty context .returns(M.or(M.record(), M.undefined())), }), + allBalancesQueryWatcher: M.interface('allBalancesQueryWatcher', { + onFulfilled: M.call(M.arrayOf(M.record())).returns( + M.arrayOf(M.record()), + ), + }), undelegateWatcher: M.interface('undelegateWatcher', { onFulfilled: M.call(M.string()) .optional(M.arrayOf(M.undefined())) // empty context @@ -131,25 +224,66 @@ export const prepareCosmosOrchestrationAccountKit = ( .optional(M.arrayOf(M.undefined())) // empty context .returns(M.arrayOf(DenomAmountShape)), }), - holder: IcaAccountHolderI, - invitationMakers: M.interface('invitationMakers', { - Delegate: M.call(ChainAddressShape, AmountArgShape).returns( - M.promise(), + transferWatcher: M.interface('transferWatcher', { + onFulfilled: M.call([M.record(), M.nat()]) + .optional({ + destination: ChainAddressShape, + opts: M.or(M.undefined(), IBCTransferOptionsShape), + token: { + denom: M.string(), + amount: M.string(), + }, + }) + .returns(Vow$(M.record())), + }), + delegationQueryWatcher: M.interface('delegationQueryWatcher', { + onFulfilled: M.call(M.arrayOf(M.record())).returns(M.record()), + }), + delegationsQueryWatcher: M.interface('delegationsQueryWatcher', { + onFulfilled: M.call(M.arrayOf(M.record())).returns( + M.arrayOf(M.record()), + ), + }), + unbondingDelegationQueryWatcher: M.interface( + 'unbondingDelegationQueryWatcher', + { + onFulfilled: M.call(M.arrayOf(M.record())).returns(M.record()), + }, + ), + unbondingDelegationsQueryWatcher: M.interface( + 'unbondingDelegationsQueryWatcher', + { + onFulfilled: M.call(M.arrayOf(M.record())).returns( + M.arrayOf(M.record()), + ), + }, + ), + redelegationQueryWatcher: M.interface('redelegationQueryWatcher', { + onFulfilled: M.call(M.arrayOf(M.record())).returns( + M.arrayOf(M.record()), + ), + }), + redelegationsQueryWatcher: M.interface('redelegationsQueryWatcher', { + onFulfilled: M.call(M.arrayOf(M.record())).returns( + M.arrayOf(M.record()), ), - Redelegate: M.call( - ChainAddressShape, - ChainAddressShape, - AmountArgShape, - ).returns(M.promise()), - WithdrawReward: M.call(ChainAddressShape).returns(M.promise()), - Undelegate: M.call(M.arrayOf(DelegationShape)).returns(M.promise()), - CloseAccount: M.call().returns(M.promise()), - TransferAccount: M.call().returns(M.promise()), }), + rewardQueryWatcher: M.interface('rewardQueryWatcher', { + onFulfilled: M.call(M.arrayOf(M.record())).returns( + M.arrayOf(M.record()), + ), + }), + rewardsQueryWatcher: M.interface('rewardsQueryWatcher', { + onFulfilled: M.call(M.arrayOf(M.record())).returns(M.record()), + }), + holder: IcaAccountHolderI, + invitationMakers: CosmosOrchestrationInvitationMakersI, }, /** - * @param {ChainAddress} chainAddress - * @param {string} bondDenom e.g. 'uatom' + * @param {object} info + * @param {ChainAddress} info.chainAddress + * @param {LocalIbcAddress} info.localAddress + * @param {RemoteIbcAddress} info.remoteAddress * @param {object} io * @param {IcaAccount} io.account * @param {Remote} io.storageNode @@ -157,14 +291,31 @@ export const prepareCosmosOrchestrationAccountKit = ( * @param {Remote} io.timer * @returns {State} */ - (chainAddress, bondDenom, io) => { - const { storageNode, ...rest } = io; + ({ chainAddress, localAddress, remoteAddress }, io) => { + const { storageNode } = io; // must be the fully synchronous maker because the kit is held in durable state const topicKit = makeRecorderKit(storageNode, PUBLIC_TOPICS.account[1]); // TODO determine what goes in vstorage https://github.com/Agoric/agoric-sdk/issues/9066 - void E(topicKit.recorder).write(''); + // XXX consider parsing local/remoteAddr to portId, channelId, counterpartyPortId, counterpartyChannelId, connectionId, counterpartyConnectionId + // FIXME these values will not update if IcaAccount gets new values after reopening. + // consider having IcaAccount responsible for the owning the writer. It might choose to share it with COA. + void E(topicKit.recorder).write( + /** @type {CosmosOrchestrationAccountStorageState} */ ({ + localAddress, + remoteAddress, + }), + ); - return { chainAddress, bondDenom, topicKit, ...rest }; + const { account, icqConnection, timer } = io; + return { + account, + chainAddress, + icqConnection, + localAddress, + remoteAddress, + timer, + topicKit, + }; }, { helper: { @@ -184,17 +335,7 @@ export const prepareCosmosOrchestrationAccountKit = ( * @returns {Coin} */ amountToCoin(amount) { - const { bondDenom } = this.state; - if ('denom' in amount) { - assert.equal(amount.denom, bondDenom); - } else { - trace('TODO: handle brand', amount); - // FIXME(#9211) brand handling - } - return harden({ - denom: bondDenom, - amount: String(amount.value), - }); + return coerceCoin(chainHub, amount); }, }, balanceQueryWatcher: { @@ -210,6 +351,157 @@ export const prepareCosmosOrchestrationAccountKit = ( return harden(toDenomAmount(balance)); }, }, + delegationQueryWatcher: { + /** + * @param {JsonSafe[]} results + * @returns {CosmosDelegationResponse} + */ + onFulfilled([result]) { + if (!result?.key) throw Fail`Error parsing result ${result}`; + const { delegationResponse } = QueryDelegationResponse.decode( + decodeBase64(result.key), + ); + if (!delegationResponse) + throw Fail`Result lacked delegationResponse key: ${result}`; + const { chainAddress } = this.state; + return harden( + toCosmosDelegationResponse(chainAddress, delegationResponse), + ); + }, + }, + delegationsQueryWatcher: { + /** + * @param {JsonSafe[]} results + * @returns {CosmosDelegationResponse[]} + */ + onFulfilled([result]) { + if (!result?.key) throw Fail`Error parsing result ${result}`; + const { delegationResponses } = + QueryDelegatorDelegationsResponse.decode(decodeBase64(result.key)); + if (!delegationResponses) + throw Fail`Result lacked delegationResponses key: ${result}`; + const { chainAddress } = this.state; + return harden( + delegationResponses.map(r => + toCosmosDelegationResponse(chainAddress, r), + ), + ); + }, + }, + unbondingDelegationQueryWatcher: { + /** + * @param {JsonSafe[]} results + */ + onFulfilled([result]) { + if (!result?.key) throw Fail`Error parsing result ${result}`; + const { unbond } = QueryUnbondingDelegationResponse.decode( + decodeBase64(result.key), + ); + if (!unbond) throw Fail`Result lacked unbond key: ${result}`; + return harden(unbond); + }, + }, + unbondingDelegationsQueryWatcher: { + /** + * @param {JsonSafe[]} results + */ + onFulfilled([result]) { + if (!result?.key) throw Fail`Error parsing result ${result}`; + const { unbondingResponses } = + QueryDelegatorUnbondingDelegationsResponse.decode( + decodeBase64(result.key), + ); + if (!unbondingResponses) + throw Fail`Result lacked unbondingResponses key: ${result}`; + return harden(unbondingResponses); + }, + }, + redelegationQueryWatcher: { + /** + * @param {JsonSafe[]} results + */ + onFulfilled([result]) { + if (!result?.key) throw Fail`Error parsing result ${result}`; + const { redelegationResponses } = QueryRedelegationsResponse.decode( + decodeBase64(result.key), + ); + if (!redelegationResponses) + throw Fail`Result lacked redelegationResponses key: ${result}`; + return harden(redelegationResponses); + }, + }, + redelegationsQueryWatcher: { + /** + * @param {JsonSafe[]} results + */ + onFulfilled([result]) { + if (!result?.key) throw Fail`Error parsing result ${result}`; + const { redelegationResponses } = QueryRedelegationsResponse.decode( + decodeBase64(result.key), + ); + if (!redelegationResponses) + throw Fail`Result lacked redelegationResponses key: ${result}`; + return harden(redelegationResponses); + }, + }, + rewardQueryWatcher: { + /** + * @param {JsonSafe[]} results + */ + onFulfilled([result]) { + if (!result?.key) throw Fail`Error parsing result ${result}`; + const { rewards } = QueryDelegationRewardsResponse.decode( + decodeBase64(result.key), + ); + if (!rewards) throw Fail`Result lacked rewards key: ${result}`; + return harden(rewards.map(toTruncatedDenomAmount)); + }, + }, + rewardsQueryWatcher: { + /** + * @param {JsonSafe[]} results + * @returns {CosmosRewardsResponse} + */ + onFulfilled([result]) { + if (!result?.key) throw Fail`Error parsing result ${result}`; + const { rewards, total } = QueryDelegationTotalRewardsResponse.decode( + decodeBase64(result.key), + ); + if (!rewards || !total) + throw Fail`Result lacked rewards or total key: ${result}`; + const { chainAddress } = this.state; + return harden({ + rewards: rewards.map(reward => ({ + validator: toCosmosValidatorAddress(reward, chainAddress.chainId), + reward: reward.reward.map(toTruncatedDenomAmount), + })), + total: total.map(toTruncatedDenomAmount), + }); + }, + }, + allBalancesQueryWatcher: { + /** + * @param {JsonSafe[]} results + */ + onFulfilled([result]) { + let response; + try { + response = QueryAllBalancesResponse.decode( + // note: an empty string for result.key is a valid result + decodeBase64(result.key), + ); + } catch (cause) { + throw makeError( + `Error parsing QueryAllBalances result ${q(result)}`, + undefined, + { cause }, + ); + } + const { balances } = response; + if (!balances) throw Fail`Result lacked balances key: ${q(result)}`; + return harden(balances.map(coin => toDenomAmount(coin))); + }, + }, undelegateWatcher: { /** * @param {string} result @@ -251,6 +543,42 @@ export const prepareCosmosOrchestrationAccountKit = ( return harden(coins.map(toDenomAmount)); }, }, + transferWatcher: { + /** + * @param {[ + * { transferChannel: IBCConnectionInfo['transferChannel'] }, + * bigint, + * ]} results + * @param {{ + * destination: ChainAddress; + * opts?: IBCMsgTransferOptions; + * token: Coin; + * }} ctx + */ + onFulfilled( + [{ transferChannel }, timeoutTimestamp], + { opts, token, destination }, + ) { + const results = E(this.facets.helper.owned()).executeEncodedTx([ + Any.toJSON( + MsgTransfer.toProtoMsg({ + sourcePort: transferChannel.portId, + sourceChannel: transferChannel.channelId, + token, + sender: this.state.chainAddress.value, + receiver: destination.value, + timeoutHeight: opts?.timeoutHeight ?? { + revisionHeight: 0n, + revisionNumber: 0n, + }, + timeoutTimestamp, + memo: opts?.memo ?? '', + }), + ), + ]); + return watch(results, this.facets.returnVoidWatcher); + }, + }, invitationMakers: { /** * @param {CosmosValidatorAddress} validator @@ -282,23 +610,61 @@ export const prepareCosmosOrchestrationAccountKit = ( /** @param {CosmosValidatorAddress} validator */ WithdrawReward(validator) { trace('WithdrawReward', validator); - return zcf.makeInvitation(seat => { seat.exit(); return watch(this.facets.holder.withdrawReward(validator)); }, 'WithdrawReward'); }, - /** @param {Omit[]} delegations */ + /** + * @param {{ + * amount: AmountArg; + * validator: CosmosValidatorAddress; + * }[]} delegations + */ Undelegate(delegations) { trace('Undelegate', delegations); - return zcf.makeInvitation(seat => { seat.exit(); return watch(this.facets.holder.undelegate(delegations)); }, 'Undelegate'); }, - CloseAccount() { - throw Error('not yet implemented'); + DeactivateAccount() { + return zcf.makeInvitation(seat => { + seat.exit(); + return watch(this.facets.holder.deactivate()); + }, 'DeactivateAccount'); + }, + ReactivateAccount() { + return zcf.makeInvitation(seat => { + seat.exit(); + return watch(this.facets.holder.reactivate()); + }, 'ReactivateAccount'); + }, + Send() { + /** + * @type {OfferHandler< + * Vow, + * { toAccount: ChainAddress; amount: AmountArg } + * >} + */ + const offerHandler = (seat, { toAccount, amount }) => { + seat.exit(); + return watch(this.facets.holder.send(toAccount, amount)); + }; + return zcf.makeInvitation(offerHandler, 'Send'); + }, + SendAll() { + /** + * @type {OfferHandler< + * Vow, + * { toAccount: ChainAddress; amounts: AmountArg[] } + * >} + */ + const offerHandler = (seat, { toAccount, amounts }) => { + seat.exit(); + return watch(this.facets.holder.sendAll(toAccount, amounts)); + }; + return zcf.makeInvitation(offerHandler, 'SendAll'); }, /** * Starting a transfer revokes the account holder. The associated @@ -308,10 +674,30 @@ export const prepareCosmosOrchestrationAccountKit = ( TransferAccount() { throw Error('not yet implemented'); }, + Transfer() { + /** + * @type {OfferHandler< + * Vow, + * { + * amount: AmountArg; + * destination: ChainAddress; + * opts: IBCMsgTransferOptions; + * } + * >} + */ + const offerHandler = (seat, { amount, destination, opts }) => { + seat.exit(); + return watch( + this.facets.holder.transfer(amount, destination, opts), + ); + }; + return zcf.makeInvitation(offerHandler, 'Transfer'); + }, }, holder: { /** @type {HostOf} */ asContinuingOffer() { + // @ts-expect-error XXX invitationMakers // getPublicTopics resolves promptly (same run), so we don't need a watcher // eslint-disable-next-line no-restricted-syntax return asVow(async () => { @@ -359,23 +745,21 @@ export const prepareCosmosOrchestrationAccountKit = ( const { helper } = this.facets; const { chainAddress } = this.state; + const amountAsCoin = helper.amountToCoin(amount); + const results = E(helper.owned()).executeEncodedTx([ Any.toJSON( MsgDelegate.toProtoMsg({ delegatorAddress: chainAddress.value, validatorAddress: validator.value, - amount: helper.amountToCoin(amount), + amount: amountAsCoin, }), ), ]); return watch(results, this.facets.returnVoidWatcher); }); }, - /** @type {HostOf} */ - getBalances() { - // TODO https://github.com/Agoric/agoric-sdk/issues/9610 - return asVow(() => Fail`not yet implemented`); - }, + /** @type {HostOf} */ redelegate(srcValidator, dstValidator, amount) { return asVow(() => { @@ -422,16 +806,13 @@ export const prepareCosmosOrchestrationAccountKit = ( return asVow(() => { const { chainAddress, icqConnection } = this.state; if (!icqConnection) { - throw Fail`Queries not available for chain ${chainAddress.chainId}`; + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; } - // TODO #9211 lookup denom from brand - assert.typeof(denom, 'string'); - const results = E(icqConnection).query([ toRequestQueryJson( QueryBalanceRequest.toProtoMsg({ address: chainAddress.value, - denom, + denom: coerceDenom(chainHub, denom), }), ), ]); @@ -439,16 +820,98 @@ export const prepareCosmosOrchestrationAccountKit = ( }); }, + /** @type {HostOf} */ + getBalances() { + return asVow(() => { + const { chainAddress, icqConnection } = this.state; + if (!icqConnection) { + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; + } + const results = E(icqConnection).query([ + toRequestQueryJson( + QueryAllBalancesRequest.toProtoMsg({ + address: chainAddress.value, + }), + ), + ]); + return watch(results, this.facets.allBalancesQueryWatcher); + }); + }, + /** @type {HostOf} */ send(toAccount, amount) { - console.log('send got', toAccount, amount); - return asVow(() => Fail`not yet implemented`); + return asVow(() => { + trace('send', toAccount, amount); + const { helper } = this.facets; + const { chainAddress } = this.state; + return watch( + E(helper.owned()).executeEncodedTx([ + Any.toJSON( + MsgSend.toProtoMsg({ + fromAddress: chainAddress.value, + toAddress: toAccount.value, + amount: [helper.amountToCoin(amount)], + }), + ), + ]), + this.facets.returnVoidWatcher, + ); + }); + }, + + /** @type {HostOf} */ + sendAll(toAccount, amounts) { + return asVow(() => { + trace('sendAll', toAccount, amounts); + const { helper } = this.facets; + const { chainAddress } = this.state; + return watch( + E(helper.owned()).executeEncodedTx([ + Any.toJSON( + MsgSend.toProtoMsg({ + fromAddress: chainAddress.value, + toAddress: toAccount.value, + amount: amounts.map(x => helper.amountToCoin(x)), + }), + ), + ]), + this.facets.returnVoidWatcher, + ); + }); }, /** @type {HostOf} */ - transfer(amount, msg) { - console.log('transferSteps got', amount, msg); - return asVow(() => Fail`not yet implemented`); + transfer(amount, destination, opts) { + trace('transfer', amount, destination, opts); + return asVow(() => { + const { helper } = this.facets; + const token = helper.amountToCoin(amount); + + const connectionInfoV = watch( + chainHub.getConnectionInfo( + this.state.chainAddress.chainId, + destination.chainId, + ), + ); + + // set a `timeoutTimestamp` if caller does not supply either `timeoutHeight` or `timeoutTimestamp` + // TODO #9324 what's a reasonable default? currently 5 minutes + const timeoutTimestampVowOrValue = + opts?.timeoutTimestamp ?? + (opts?.timeoutHeight + ? 0n + : E(timestampHelper).getTimeoutTimestampNS()); + + // Resolves when host chain successfully submits, but not when + // the receiving chain acknowledges. + // See https://github.com/Agoric/agoric-sdk/issues/9784 for a + // solution that tracks the acknowledgement on the receiving chain. + return watch( + allVows([connectionInfoV, timeoutTimestampVowOrValue]), + this.facets.transferWatcher, + { opts, token, destination }, + ); + }); }, /** @type {HostOf} */ @@ -467,16 +930,20 @@ export const prepareCosmosOrchestrationAccountKit = ( return asVow(() => { trace('undelegate', delegations); const { helper } = this.facets; - const { chainAddress, bondDenom } = this.state; + const { chainAddress } = this.state; + + delegations.every(d => + d.delegator ? d.delegator.value === chainAddress.value : true, + ) || Fail`Some delegation record is for another delegator`; const undelegateV = watch( E(helper.owned()).executeEncodedTx( - delegations.map(d => + delegations.map(({ validator, amount }) => Any.toJSON( MsgUndelegate.toProtoMsg({ delegatorAddress: chainAddress.value, - validatorAddress: d.validatorAddress, - amount: { denom: bondDenom, amount: d.shares }, + validatorAddress: validator.value, + amount: coerceCoin(chainHub, amount), }), ), ), @@ -486,6 +953,146 @@ export const prepareCosmosOrchestrationAccountKit = ( return watch(undelegateV, this.facets.returnVoidWatcher); }); }, + /** @type {HostOf} */ + deactivate() { + return watch(E(this.facets.helper.owned()).deactivate()); + }, + /** @type {HostOf} */ + reactivate() { + return watch(E(this.facets.helper.owned()).reactivate()); + }, + /** @type {HostOf} */ + getDelegation(validator) { + return asVow(() => { + trace('getDelegation', validator); + const { chainAddress, icqConnection } = this.state; + if (!icqConnection) { + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; + } + const results = E(icqConnection).query([ + toRequestQueryJson( + QueryDelegationRequest.toProtoMsg({ + delegatorAddr: chainAddress.value, + validatorAddr: validator.value, + }), + ), + ]); + return watch(results, this.facets.delegationQueryWatcher); + }); + }, + /** @type {HostOf} */ + getDelegations() { + return asVow(() => { + trace('getDelegations'); + const { chainAddress, icqConnection } = this.state; + if (!icqConnection) { + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; + } + const results = E(icqConnection).query([ + toRequestQueryJson( + QueryDelegatorDelegationsRequest.toProtoMsg({ + delegatorAddr: chainAddress.value, + }), + ), + ]); + return watch(results, this.facets.delegationsQueryWatcher); + }); + }, + /** @type {HostOf} */ + getUnbondingDelegation(validator) { + return asVow(() => { + trace('getUnbondingDelegation', validator); + const { chainAddress, icqConnection } = this.state; + if (!icqConnection) { + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; + } + const results = E(icqConnection).query([ + toRequestQueryJson( + QueryUnbondingDelegationRequest.toProtoMsg({ + delegatorAddr: chainAddress.value, + validatorAddr: validator.value, + }), + ), + ]); + return watch(results, this.facets.unbondingDelegationQueryWatcher); + }); + }, + /** @type {HostOf} */ + getUnbondingDelegations() { + return asVow(() => { + trace('getUnbondingDelegations'); + const { chainAddress, icqConnection } = this.state; + if (!icqConnection) { + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; + } + const results = E(icqConnection).query([ + toRequestQueryJson( + QueryDelegatorUnbondingDelegationsRequest.toProtoMsg({ + delegatorAddr: chainAddress.value, + }), + ), + ]); + return watch(results, this.facets.unbondingDelegationsQueryWatcher); + }); + }, + /** @type {HostOf} */ + getRedelegations() { + return asVow(() => { + trace('getRedelegations'); + const { chainAddress, icqConnection } = this.state; + if (!icqConnection) { + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; + } + const results = E(icqConnection).query([ + toRequestQueryJson( + QueryRedelegationsRequest.toProtoMsg({ + delegatorAddr: chainAddress.value, + // These are optional but the protobufs require values to be set + dstValidatorAddr: '', + srcValidatorAddr: '', + }), + ), + ]); + return watch(results, this.facets.redelegationsQueryWatcher); + }); + }, + /** @type {HostOf} */ + getReward(validator) { + return asVow(() => { + trace('getReward', validator); + const { chainAddress, icqConnection } = this.state; + if (!icqConnection) { + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; + } + const results = E(icqConnection).query([ + toRequestQueryJson( + QueryDelegationRewardsRequest.toProtoMsg({ + delegatorAddress: chainAddress.value, + validatorAddress: validator.value, + }), + ), + ]); + return watch(results, this.facets.rewardQueryWatcher); + }); + }, + /** @type {HostOf} */ + getRewards() { + return asVow(() => { + trace('getRewards'); + const { chainAddress, icqConnection } = this.state; + if (!icqConnection) { + throw Fail`Queries not available for chain ${q(chainAddress.chainId)}`; + } + const results = E(icqConnection).query([ + toRequestQueryJson( + QueryDelegationTotalRewardsRequest.toProtoMsg({ + delegatorAddress: chainAddress.value, + }), + ), + ]); + return watch(results, this.facets.rewardsQueryWatcher); + }); + }, }, }, ); @@ -501,9 +1108,12 @@ export const prepareCosmosOrchestrationAccountKit = ( /** * @param {Zone} zone - * @param {MakeRecorderKit} makeRecorderKit - * @param {VowTools} vowTools - * @param {ZCF} zcf + * @param {object} powers + * @param {ChainHub} powers.chainHub + * @param {MakeRecorderKit} powers.makeRecorderKit + * @param {Remote} powers.timerService + * @param {VowTools} powers.vowTools + * @param {ZCF} powers.zcf * @returns {( * ...args: Parameters< * ReturnType @@ -512,16 +1122,15 @@ export const prepareCosmosOrchestrationAccountKit = ( */ export const prepareCosmosOrchestrationAccount = ( zone, - makeRecorderKit, - vowTools, - zcf, + { chainHub, makeRecorderKit, timerService, vowTools, zcf }, ) => { - const makeKit = prepareCosmosOrchestrationAccountKit( - zone, + const makeKit = prepareCosmosOrchestrationAccountKit(zone, { + chainHub, makeRecorderKit, + timerService, vowTools, zcf, - ); + }); return (...args) => makeKit(...args).holder; }; /** @typedef {CosmosOrchestrationAccountKit['holder']} CosmosOrchestrationAccount */ diff --git a/packages/orchestration/src/exos/exo-interfaces.ts b/packages/orchestration/src/exos/exo-interfaces.ts new file mode 100644 index 00000000000..9916556b9af --- /dev/null +++ b/packages/orchestration/src/exos/exo-interfaces.ts @@ -0,0 +1,35 @@ +import type { IBCConnectionID } from '@agoric/vats'; +import type { Vow } from '@agoric/vow'; +import type { IcaAccount } from '../cosmos-api.ts'; +import type { ICAChannelAddressOpts } from '../utils/address'; +import type { ICQConnection } from './icq-connection-kit'; + +/** + * Authority to make a Cosmos interchain account or an interchain query connection. + */ +export interface CosmosInterchainService { + /** + * @param {string} chainId + * @param {IBCConnectionID} hostConnectionId the counterparty + * connection_id + * @param {IBCConnectionID} controllerConnectionId self connection_id + * @param {ICAChannelAddressOpts} [opts] optional to configure the + * channel address, such as version and ordering + * @returns {Vow} + */ + makeAccount( + chainId: string, + hostConnectionId: IBCConnectionID, + controllerConnectionId: IBCConnectionID, + opts?: ICAChannelAddressOpts | undefined, + ): Vow; + /** + * @param {IBCConnectionID} controllerConnectionId + * @param {string} [version] + * @returns {Vow | ICQConnection} + */ + provideICQConnection( + controllerConnectionId: IBCConnectionID, + version?: string | undefined, + ): Vow | ICQConnection; +} diff --git a/packages/orchestration/src/exos/ibc-packet.js b/packages/orchestration/src/exos/ibc-packet.js new file mode 100644 index 00000000000..dd25ac55fa9 --- /dev/null +++ b/packages/orchestration/src/exos/ibc-packet.js @@ -0,0 +1,219 @@ +import { assertAllDefined } from '@agoric/internal'; +import { base64ToBytes, Shape as NetworkShape } from '@agoric/network'; +import { M } from '@endo/patterns'; +import { E } from '@endo/far'; + +// As specified in ICS20, the success result is a base64-encoded '\0x1' byte. +export const ICS20_TRANSFER_SUCCESS_RESULT = 'AQ=='; + +/** + * @import {JsonSafe, TypedJson, ResponseTo} from '@agoric/cosmic-proto'; + * @import {Vow, VowTools} from '@agoric/vow'; + * @import {LocalChainAccount} from '@agoric/vats/src/localchain.js'; + * @import {PacketOptions} from './packet-tools.js'; + */ + +const { Fail, bare } = assert; +const { Vow$ } = NetworkShape; // TODO #9611 + +/** + * Create a pattern for alterative representations of a sequence number. + * + * @param {any} sequence + * @returns {Pattern} + */ +export const createSequencePattern = sequence => { + const sequencePatterns = []; + + try { + const bintSequence = BigInt(sequence); + bintSequence > 0n && sequencePatterns.push(bintSequence); + } catch (e) { + // ignore + } + + const numSequence = Number(sequence); + numSequence > 0 && + Number.isSafeInteger(numSequence) && + sequencePatterns.push(numSequence); + + const strSequence = String(sequence); + strSequence && sequencePatterns.push(strSequence); + + if (!sequencePatterns.find(seq => seq === sequence)) { + sequencePatterns.push(sequence); + } + + switch (sequencePatterns.length) { + case 0: + throw Fail`sequence ${sequence} is not valid`; + case 1: + return sequencePatterns[0]; + default: + return M.or(...sequencePatterns); + } +}; +harden(createSequencePattern); + +/** + * @param {import('@agoric/base-zone').Zone} zone + * @param {VowTools & { makeIBCReplyKit: MakeIBCReplyKit }} powers + */ +export const prepareIBCTransferSender = (zone, { watch, makeIBCReplyKit }) => { + const makeIBCTransferSenderKit = zone.exoClassKit( + 'IBCTransferSenderKit', + { + public: M.interface('IBCTransferSender', { + sendPacket: M.call(Vow$(M.any()), M.any()).returns(Vow$(M.record())), + }), + responseWatcher: M.interface('responseWatcher', { + onFulfilled: M.call([M.record()], M.record()).returns(M.any()), + }), + verifyTransferSuccess: M.interface('verifyTransferSuccess', { + onFulfilled: M.call(M.any()).returns(), + }), + }, + /** + * @param {{ + * executeTx: LocalChainAccount['executeTx']; + * }} txExecutor + * @param {TypedJson<'/ibc.applications.transfer.v1.MsgTransfer'>} transferMsg + */ + (txExecutor, transferMsg) => ({ + txExecutor, + transferMsg: harden(transferMsg), + }), + { + public: { + sendPacket(match, opts) { + const { txExecutor, transferMsg } = this.state; + return watch( + E(txExecutor).executeTx([transferMsg]), + this.facets.responseWatcher, + { opts, match }, + ); + }, + }, + responseWatcher: { + /** + * Wait for successfully sending the transfer packet. + * + * @param {[ + * JsonSafe< + * ResponseTo< + * TypedJson<'/ibc.applications.transfer.v1.MsgTransfer'> + * > + * >, + * ]} response + * @param {Record} ctx + */ + onFulfilled([{ sequence }], ctx) { + const { match } = ctx; + const { transferMsg } = this.state; + + // Match the port/channel and sequence number. + const replyPacketPattern = M.splitRecord({ + source_port: transferMsg.sourcePort, + source_channel: transferMsg.sourceChannel, + sequence: createSequencePattern(sequence), + }); + + const { resultV: ackDataV, ...rest } = makeIBCReplyKit( + replyPacketPattern, + match, + ctx, + ); + const resultV = watch(ackDataV, this.facets.verifyTransferSuccess); + return harden({ resultV, ...rest }); + }, + }, + verifyTransferSuccess: { + onFulfilled(ackData) { + let obj; + try { + obj = JSON.parse(ackData); + } catch { + Fail`ICS20-1 transfer ack data is not JSON: ${ackData}`; + } + const { result, error } = obj; + error === undefined || Fail`ICS20-1 transfer error ${error}`; + result ?? Fail`Missing result in ICS20-1 transfer ack ${obj}`; + result === ICS20_TRANSFER_SUCCESS_RESULT || + Fail`ICS20-1 transfer unsuccessful with ack result ${result}`; + }, + }, + }, + ); + + /** + * @param {Parameters} args + */ + return (...args) => makeIBCTransferSenderKit(...args).public; +}; +harden(prepareIBCTransferSender); + +/** + * @param {import('@agoric/base-zone').Zone} zone + * @param {VowTools} vowTools + */ +export const prepareIBCReplyKit = (zone, vowTools) => { + const { watch } = vowTools; + const ibcWatcher = zone.exo( + 'ibcResultWatcher', + M.interface('processIBCWatcher', { + onFulfilled: M.call(M.record(), M.record()).returns(Vow$(M.string())), + }), + { + onFulfilled({ event, acknowledgement }, { opName = 'unknown' }) { + assertAllDefined({ event, acknowledgement }); + switch (event) { + case 'acknowledgementPacket': + return base64ToBytes(acknowledgement); + case 'timeoutPacket': + throw Fail`${bare(opName)} operation received timeout packet`; + default: + throw Fail`Unexpected event: ${event}`; + } + }, + }, + ); + + /** + * @param {Pattern} replyPacketPattern + * @param {Vow} matchV + * @param {PacketOptions} opts + */ + const makeIBCReplyKit = (replyPacketPattern, matchV, opts) => { + const eventPattern = M.or( + M.splitRecord({ + event: 'acknowledgementPacket', + packet: replyPacketPattern, + acknowledgement: M.string(), + }), + M.splitRecord({ + event: 'timeoutPacket', + packet: replyPacketPattern, + }), + ); + const resultV = watch(matchV, ibcWatcher, opts); + return harden({ eventPattern, resultV }); + }; + + return makeIBCReplyKit; +}; +harden(prepareIBCReplyKit); +/** @typedef {ReturnType} MakeIBCReplyKit */ + +/** + * @param {import('@agoric/base-zone').Zone} zone + * @param {VowTools} vowTools + */ +export const prepareIBCTools = (zone, vowTools) => { + const makeIBCReplyKit = prepareIBCReplyKit(zone, vowTools); + const makeIBCTransferSender = prepareIBCTransferSender(zone, { + makeIBCReplyKit, + ...vowTools, + }); + return harden({ makeIBCTransferSender, makeIBCReplyKit }); +}; +harden(prepareIBCTools); diff --git a/packages/orchestration/src/exos/chain-account-kit.js b/packages/orchestration/src/exos/ica-account-kit.js similarity index 60% rename from packages/orchestration/src/exos/chain-account-kit.js rename to packages/orchestration/src/exos/ica-account-kit.js index 1fce0a19ab8..1802666bb9f 100644 --- a/packages/orchestration/src/exos/chain-account-kit.js +++ b/packages/orchestration/src/exos/ica-account-kit.js @@ -1,4 +1,4 @@ -/** @file ChainAccount exo */ +/** @file IcaAccount exo */ import { Fail } from '@endo/errors'; import { E } from '@endo/far'; import { M } from '@endo/patterns'; @@ -8,41 +8,42 @@ import { ChainAddressShape, OutboundConnectionHandlerI, Proto3Shape, + TxBodyOptsShape, } from '../typeGuards.js'; import { findAddressField } from '../utils/address.js'; import { makeTxPacket, parseTxPacket } from '../utils/packet.js'; /** + * @import {HostOf} from '@agoric/async-flow'; * @import {Zone} from '@agoric/base-zone'; * @import {Connection, Port} from '@agoric/network'; * @import {Remote, Vow, VowTools} from '@agoric/vow'; * @import {AnyJson} from '@agoric/cosmic-proto'; * @import {TxBody} from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js'; * @import {LocalIbcAddress, RemoteIbcAddress} from '@agoric/vats/tools/ibc-utils.js'; - * @import {ChainAddress} from '../types.js'; + * @import {ChainAddress, IcaAccount} from '../types.js'; */ -const trace = makeTracer('ChainAccountKit'); +const trace = makeTracer('IcaAccountKit'); -/** @typedef {'UNPARSABLE_CHAIN_ADDRESS'} UnparsableChainAddress */ const UNPARSABLE_CHAIN_ADDRESS = 'UNPARSABLE_CHAIN_ADDRESS'; -export const ChainAccountI = M.interface('ChainAccount', { +export const IcaAccountI = M.interface('IcaAccount', { getAddress: M.call().returns(ChainAddressShape), - getBalance: M.call(M.string()).returns(VowShape), - getBalances: M.call().returns(VowShape), getLocalAddress: M.call().returns(M.string()), getRemoteAddress: M.call().returns(M.string()), getPort: M.call().returns(M.remotable('Port')), executeTx: M.call(M.arrayOf(M.record())).returns(VowShape), executeEncodedTx: M.call(M.arrayOf(Proto3Shape)) - .optional(M.record()) + .optional(TxBodyOptsShape) .returns(VowShape), - close: M.call().returns(VowShape), - getPurse: M.call().returns(VowShape), + deactivate: M.call().returns(VowShape), + reactivate: M.call().returns(VowShape), }); +// XXX none of these modifiers are working to exclude this type from api-docs /** + * @private * @typedef {{ * chainId: string; * port: Port; @@ -51,18 +52,24 @@ export const ChainAccountI = M.interface('ChainAccount', { * requestedRemoteAddress: string; * remoteAddress: RemoteIbcAddress | undefined; * chainAddress: ChainAddress | undefined; + * isInitiatingClose: boolean; * }} State + * Internal to the IcaAccountKit exo + * @internal */ /** + * Used only by CosmosInterchainService + * * @param {Zone} zone * @param {VowTools} vowTools + * @internal */ -export const prepareChainAccountKit = (zone, { watch, asVow }) => +export const prepareIcaAccountKit = (zone, { watch, asVow }) => zone.exoClassKit( - 'ChainAccountKit', + 'IcaAccountKit', { - account: ChainAccountI, + account: IcaAccountI, connectionHandler: OutboundConnectionHandlerI, parseTxPacketWatcher: M.interface('ParseTxPacketWatcher', { onFulfilled: M.call(M.string()) @@ -84,6 +91,7 @@ export const prepareChainAccountKit = (zone, { watch, asVow }) => remoteAddress: undefined, chainAddress: undefined, localAddress: undefined, + isInitiatingClose: false, }), { parseTxPacketWatcher: { @@ -100,16 +108,6 @@ export const prepareChainAccountKit = (zone, { watch, asVow }) => 'ICA channel creation acknowledgement not yet received.', ); }, - getBalance(_denom) { - // TODO https://github.com/Agoric/agoric-sdk/issues/9610 - // UNTIL https://github.com/Agoric/agoric-sdk/issues/9326 - return asVow(() => Fail`not yet implemented`); - }, - getBalances() { - // TODO https://github.com/Agoric/agoric-sdk/issues/9610 - // UNTIL https://github.com/Agoric/agoric-sdk/issues/9326 - return asVow(() => Fail`not yet implemented`); - }, getLocalAddress() { return NonNullish( this.state.localAddress, @@ -141,37 +139,38 @@ export const prepareChainAccountKit = (zone, { watch, asVow }) => executeEncodedTx(msgs, opts) { return asVow(() => { const { connection } = this.state; - if (!connection) throw Fail`connection not available`; + if (!connection) { + throw Fail`Account not available or deactivated.`; + } return watch( E(connection).send(makeTxPacket(msgs, opts)), this.facets.parseTxPacketWatcher, ); }); }, - /** - * Close the remote account - * - * @returns {Vow} - * @throws {Error} if connection is not available or already closed - */ - close() { + /** @type {HostOf} */ + deactivate() { return asVow(() => { - /// TODO #9192 what should the behavior be here? and `onClose`? - // - retrieve assets? - // - revoke the port? const { connection } = this.state; - if (!connection) throw Fail`connection not available`; + if (!connection) throw Fail`Account not available or deactivated.`; + this.state.isInitiatingClose = true; return E(connection).close(); }); }, - /** - * get Purse for a brand to .withdraw() a Payment from the account - * - * @param {Brand} brand - */ - getPurse(brand) { - console.log('getPurse got', brand); - return asVow(() => Fail`not yet implemented`); + /** @type {HostOf} */ + reactivate() { + return asVow(() => { + const { connection, port, requestedRemoteAddress } = this.state; + if (connection) { + throw Fail`Account is already active.`; + } + return watch( + E(port).connect( + requestedRemoteAddress, + this.facets.connectionHandler, + ), + ); + }); }, }, connectionHandler: { @@ -185,25 +184,48 @@ export const prepareChainAccountKit = (zone, { watch, asVow }) => this.state.connection = connection; this.state.remoteAddress = remoteAddr; this.state.localAddress = localAddr; + const address = findAddressField(remoteAddr); + if (!address) { + console.error('⚠️ failed to parse chain address', remoteAddr); + } this.state.chainAddress = harden({ - // FIXME need a fallback value like icacontroller-1-connection-1 if this fails - // https://github.com/Agoric/agoric-sdk/issues/9066 - value: findAddressField(remoteAddr) || UNPARSABLE_CHAIN_ADDRESS, + value: address || UNPARSABLE_CHAIN_ADDRESS, chainId: this.state.chainId, encoding: 'bech32', }); }, /** + * This handler fires any time the connection (channel) closes. This + * could be due to external factors (e.g. a packet timeout), or a holder + * initiated action (`.deactivate()`). + * + * Here, if a connection is opened again, we clear the connection and + * addresses from state as they will change - a new channel will be + * established if the connection is reopened. + * + * If the holder did not initiate the closure, a new connection is + * established using the original requested remote address. This will + * result in a new channelID but the ChainAddress will be preserved. + * * @param {Remote} _connection * @param {unknown} reason + * @see {@link https://docs.cosmos.network/v0.45/ibc/overview.html#:~:text=In%20ORDERED%20channels%2C%20a%20timeout%20of%20a%20single%20packet%20in%20the%20channel%20closes%20the%20channel.} */ async onClose(_connection, reason) { trace(`ICA Channel closed. Reason: ${reason}`); - // FIXME handle connection closing https://github.com/Agoric/agoric-sdk/issues/9192 - // XXX is there a scenario where a connection will unexpectedly close? _I think yes_ + this.state.connection = undefined; + this.state.localAddress = undefined; + this.state.remoteAddress = undefined; + if (this.state.isInitiatingClose === true) { + trace('Account deactivated by holder. Skipping reactivation.'); + this.state.isInitiatingClose = false; + } else { + trace('Account closed unexpectedly. Automatically reactivating.'); + void watch(this.facets.account.reactivate()); + } }, }, }, ); -/** @typedef {ReturnType>} ChainAccountKit */ +/** @typedef {ReturnType>} IcaAccountKit */ diff --git a/packages/orchestration/src/exos/icq-connection-kit.js b/packages/orchestration/src/exos/icq-connection-kit.js index cfe78cc8ae5..e01e4499908 100644 --- a/packages/orchestration/src/exos/icq-connection-kit.js +++ b/packages/orchestration/src/exos/icq-connection-kit.js @@ -2,14 +2,15 @@ import { Fail } from '@endo/errors'; import { E } from '@endo/far'; import { M } from '@endo/patterns'; +import { VowShape } from '@agoric/vow'; import { NonNullish, makeTracer } from '@agoric/internal'; import { makeQueryPacket, parseQueryPacket } from '../utils/packet.js'; -import { OutboundConnectionHandlerI } from '../typeGuards.js'; +import { ICQMsgShape, OutboundConnectionHandlerI } from '../typeGuards.js'; /** * @import {Zone} from '@agoric/base-zone'; * @import {Connection, Port} from '@agoric/network'; - * @import {Remote, VowTools} from '@agoric/vow'; + * @import {Remote, Vow, VowTools} from '@agoric/vow'; * @import {JsonSafe} from '@agoric/cosmic-proto'; * @import {RequestQuery, ResponseQuery} from '@agoric/cosmic-proto/tendermint/abci/types.js'; * @import {LocalIbcAddress, RemoteIbcAddress} from '@agoric/vats/tools/ibc-utils.js'; @@ -17,15 +18,10 @@ import { OutboundConnectionHandlerI } from '../typeGuards.js'; const trace = makeTracer('Orchestration:ICQConnection'); -export const ICQMsgShape = M.splitRecord( - { path: M.string(), data: M.string() }, - { height: M.string(), prove: M.boolean() }, -); - export const ICQConnectionI = M.interface('ICQConnection', { getLocalAddress: M.call().returns(M.string()), getRemoteAddress: M.call().returns(M.string()), - query: M.call(M.arrayOf(ICQMsgShape)).returns(M.promise()), + query: M.call(M.arrayOf(ICQMsgShape)).returns(VowShape), }); /** @@ -38,6 +34,8 @@ export const ICQConnectionI = M.interface('ICQConnection', { */ /** + * Used only by CosmosInterchainService + * * Prepares an ICQ Connection Kit based on the * {@link https://github.com/cosmos/ibc-apps/blob/e9b46e4bf0ad0a66cf6bc53b5e5496f6e2b4b02b/modules/async-icq/README.md | `icq/v1` IBC application protocol}. * @@ -52,8 +50,9 @@ export const ICQConnectionI = M.interface('ICQConnection', { * * @param {Zone} zone * @param {VowTools} vowTools + * @internal */ -export const prepareICQConnectionKit = (zone, { watch, when }) => +export const prepareICQConnectionKit = (zone, { watch, asVow }) => zone.exoClassKit( 'ICQConnectionKit', { @@ -88,21 +87,20 @@ export const prepareICQConnectionKit = (zone, { watch, when }) => ); }, /** + * Vow rejects if packet fails to send or an error is returned + * * @param {JsonSafe[]} msgs - * @returns {Promise[]>} - * @throws {Error} if packet fails to send or an error is returned + * @returns {Vow[]>} */ query(msgs) { - const { connection } = this.state; - // TODO #9281 do not throw synchronously when returning a promise; return a rejected Vow - /// see https://github.com/Agoric/agoric-sdk/pull/9454#discussion_r1626898694 - if (!connection) throw Fail`connection not available`; - return when( - watch( + return asVow(() => { + const { connection } = this.state; + if (!connection) throw Fail`connection not available`; + return watch( E(connection).send(makeQueryPacket(msgs)), this.facets.parseQueryPacketWatcher, - ), - ); + ); + }); }, }, parseQueryPacketWatcher: { diff --git a/packages/orchestration/src/exos/local-chain-facade.js b/packages/orchestration/src/exos/local-chain-facade.js index f00eb5e418e..7f4ace2d8b4 100644 --- a/packages/orchestration/src/exos/local-chain-facade.js +++ b/packages/orchestration/src/exos/local-chain-facade.js @@ -1,4 +1,4 @@ -/** @file ChainAccount exo */ +/** @file Localchain Facade exo */ import { E } from '@endo/far'; // eslint-disable-next-line no-restricted-syntax -- just the import import { heapVowE } from '@agoric/vow/vat.js'; @@ -6,17 +6,30 @@ import { M } from '@endo/patterns'; import { pickFacet } from '@agoric/vat-data'; import { VowShape } from '@agoric/vow'; -import { ChainFacadeI } from '../typeGuards.js'; +import { chainFacadeMethods, TypedJsonShape } from '../typeGuards.js'; /** + * @import {HostOf} from '@agoric/async-flow'; * @import {Zone} from '@agoric/base-zone'; * @import {TimerService} from '@agoric/time'; * @import {Remote} from '@agoric/internal'; - * @import {LocalChain, LocalChainAccount} from '@agoric/vats/src/localchain.js'; + * @import {LocalChain, LocalChainAccount, QueryManyFn} from '@agoric/vats/src/localchain.js'; + * @import {AssetInfo} from '@agoric/vats/src/vat-bank.js'; + * @import {NameHub} from '@agoric/vats'; * @import {Vow, VowTools} from '@agoric/vow'; - * @import {CosmosInterchainService} from './cosmos-interchain-service.js'; + * @import {CosmosInterchainService} from './exo-interfaces.js'; * @import {LocalOrchestrationAccountKit, MakeLocalOrchestrationAccountKit} from './local-orchestration-account.js'; - * @import {ChainAddress, ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount} from '../types.js'; + * @import {Chain, ChainAddress, ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount} from '../types.js'; + */ + +/** + * Chain facade methods unique to the Agoric (local) chain. + * + * @typedef {object} AgoricChainMethods + * @property {() => Promise} getVBankAssetInfo Get asset info from + * agoricNames.vbankAsset. + * + * Caches the query to agoricNames in the first call. */ /** @@ -24,6 +37,7 @@ import { ChainFacadeI } from '../typeGuards.js'; * makeLocalOrchestrationAccountKit: MakeLocalOrchestrationAccountKit; * orchestration: Remote; * storageNode: Remote; + * agoricNames: Remote; * timer: Remote; * localchain: Remote; * vowTools: VowTools; @@ -38,17 +52,27 @@ const prepareLocalChainFacadeKit = ( zone, { makeLocalOrchestrationAccountKit, + agoricNames, localchain, // TODO vstorage design https://github.com/Agoric/agoric-sdk/issues/9066 // consider making an `accounts` childNode storageNode, - vowTools: { allVows, watch }, + vowTools: { allVows, watch, asVow }, }, ) => zone.exoClassKit( 'LocalChainFacade', { - public: ChainFacadeI, + public: M.interface('LocalChainFacade', { + ...chainFacadeMethods, + query: M.call(M.arrayOf(TypedJsonShape)).returns(VowShape), + getVBankAssetInfo: M.call().optional(M.boolean()).returns(VowShape), + }), + vbankAssetValuesWatcher: M.interface('vbankAssetValuesWatcher', { + onFulfilled: M.call(M.arrayOf(M.record())) + .optional(M.arrayOf(M.undefined())) // empty context + .returns(VowShape), + }), makeAccountWatcher: M.interface('makeAccountWatcher', { onFulfilled: M.call([M.remotable('LCA Account'), M.string()]) .optional(M.arrayOf(M.undefined())) // empty context @@ -64,7 +88,10 @@ const prepareLocalChainFacadeKit = ( * @param {CosmosChainInfo} localChainInfo */ localChainInfo => { - return { localChainInfo }; + return { + localChainInfo, + vbankAssets: /** @type {AssetInfo[] | undefined} */ (undefined), + }; }, { public: { @@ -83,6 +110,35 @@ const prepareLocalChainFacadeKit = ( this.facets.makeAccountWatcher, ); }, + /** @type {HostOf['query']>} */ + query(requests) { + return watch(E(localchain).queryMany(requests)); + }, + /** @type {HostOf} */ + getVBankAssetInfo() { + return asVow(() => { + const { vbankAssets } = this.state; + if (vbankAssets) { + return vbankAssets; + } + const vbankAssetNameHubP = E(agoricNames).lookup('vbankAsset'); + const vbankAssetValuesP = E(vbankAssetNameHubP).values(); + const { vbankAssetValuesWatcher } = this.facets; + return watch(vbankAssetValuesP, vbankAssetValuesWatcher); + }); + }, + }, + vbankAssetValuesWatcher: { + /** + * @param {AssetInfo[]} assets + */ + onFulfilled(assets) { + const { state } = this; + return asVow(() => { + state.vbankAssets = assets; + return assets; + }); + }, }, makeAccountWatcher: { /** @@ -124,8 +180,11 @@ const prepareLocalChainFacadeKit = ( harden(prepareLocalChainFacadeKit); /** + * Used only by `withOrchestration` helper + * * @param {Zone} zone * @param {LocalChainFacadePowers} powers + * @internal */ export const prepareLocalChainFacade = (zone, powers) => { const makeLocalChainFacadeKit = prepareLocalChainFacadeKit(zone, powers); diff --git a/packages/orchestration/src/exos/local-orchestration-account.js b/packages/orchestration/src/exos/local-orchestration-account.js index c6f729bcbbb..aab60847cd1 100644 --- a/packages/orchestration/src/exos/local-orchestration-account.js +++ b/packages/orchestration/src/exos/local-orchestration-account.js @@ -1,53 +1,68 @@ /** @file Use-object for the owner of a localchain account */ -import { typedJson } from '@agoric/cosmic-proto/vatsafe'; +import { typedJson } from '@agoric/cosmic-proto'; import { AmountShape, PaymentShape } from '@agoric/ertp'; import { makeTracer } from '@agoric/internal'; import { Shape as NetworkShape } from '@agoric/network'; import { M } from '@agoric/vat-data'; import { VowShape } from '@agoric/vow'; import { E } from '@endo/far'; +import { Fail, q } from '@endo/errors'; + import { + AmountArgShape, + AnyNatAmountsRecord, ChainAddressShape, DenomAmountShape, DenomShape, IBCTransferOptionsShape, TimestampProtoShape, + TypedJsonShape, } from '../typeGuards.js'; -import { maxClockSkew } from '../utils/cosmos.js'; +import { maxClockSkew, toDenomAmount } from '../utils/cosmos.js'; import { orchestrationAccountMethods } from '../utils/orchestrationAccount.js'; import { makeTimestampHelper } from '../utils/time.js'; +import { preparePacketTools } from './packet-tools.js'; +import { prepareIBCTools } from './ibc-packet.js'; +import { coerceCoin, coerceDenomAmount } from '../utils/amounts.js'; /** * @import {HostOf} from '@agoric/async-flow'; - * @import {LocalChainAccount} from '@agoric/vats/src/localchain.js'; - * @import {AmountArg, ChainAddress, DenomAmount, IBCMsgTransferOptions, ChainInfo, IBCConnectionInfo, OrchestrationAccountI} from '@agoric/orchestration'; + * @import {LocalChain, LocalChainAccount} from '@agoric/vats/src/localchain.js'; + * @import {AmountArg, ChainAddress, DenomAmount, IBCMsgTransferOptions, IBCConnectionInfo, OrchestrationAccountI} from '@agoric/orchestration'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. * @import {Zone} from '@agoric/zone'; * @import {Remote} from '@agoric/internal'; * @import {InvitationMakers} from '@agoric/smart-wallet/src/types.js'; * @import {TimerService, TimestampRecord} from '@agoric/time'; * @import {Vow, VowTools} from '@agoric/vow'; - * @import {TypedJson, JsonSafe} from '@agoric/cosmic-proto'; + * @import {TypedJson, JsonSafe, ResponseTo} from '@agoric/cosmic-proto'; + * @import {Coin} from '@agoric/cosmic-proto/cosmos/base/v1beta1/coin.js'; * @import {Matcher} from '@endo/patterns'; * @import {ChainHub} from './chain-hub.js'; + * @import {PacketTools} from './packet-tools.js'; + * @import {ZoeTools} from '../utils/zoe-tools.js'; */ const trace = makeTracer('LOA'); -const { Fail } = assert; const { Vow$ } = NetworkShape; // TODO #9611 +const EVow$ = shape => M.or(Vow$(shape), M.promise(/* shape */)); + /** * @typedef {object} LocalChainAccountNotification * @property {string} address */ /** + * @private * @typedef {{ * topicKit: RecorderKit; + * packetTools: PacketTools; * account: LocalChainAccount; * address: ChainAddress; * }} State + * Internal to the LocalOrchestrationAccount exo */ const HolderI = M.interface('holder', { @@ -57,9 +72,11 @@ const HolderI = M.interface('holder', { deposit: M.call(PaymentShape).returns(VowShape), withdraw: M.call(AmountShape).returns(Vow$(PaymentShape)), executeTx: M.call(M.arrayOf(M.record())).returns(Vow$(M.record())), - monitorTransfers: M.call(M.remotable('TransferTap')).returns( - Vow$(M.remotable('TargetRegistration')), - ), + sendThenWaitForAck: M.call(EVow$(M.remotable('PacketSender'))) + .optional(M.any()) + .returns(EVow$(M.string())), + matchFirstPacket: M.call(M.any()).returns(EVow$(M.any())), + monitorTransfers: M.call(M.remotable('TargetApp')).returns(EVow$(M.any())), }); /** @type {{ [name: string]: [description: string, valueShape: Matcher] }} */ @@ -69,26 +86,45 @@ const PUBLIC_TOPICS = { /** * @param {Zone} zone - * @param {MakeRecorderKit} makeRecorderKit - * @param {ZCF} zcf - * @param {Remote} timerService - * @param {VowTools} vowTools - * @param {ChainHub} chainHub + * @param {object} powers + * @param {MakeRecorderKit} powers.makeRecorderKit + * @param {ZCF} powers.zcf + * @param {Remote} powers.timerService + * @param {VowTools} powers.vowTools + * @param {ChainHub} powers.chainHub + * @param {Remote} powers.localchain + * @param {ZoeTools} powers.zoeTools */ export const prepareLocalOrchestrationAccountKit = ( zone, - makeRecorderKit, - zcf, - timerService, - { watch, allVows, asVow, when }, - chainHub, + { + makeRecorderKit, + zcf, + timerService, + vowTools, + chainHub, + localchain, + zoeTools, + }, ) => { + const { watch, allVows, asVow, when } = vowTools; + const { makeIBCTransferSender } = prepareIBCTools( + zone.subZone('ibcTools'), + vowTools, + ); + const makePacketTools = preparePacketTools( + zone.subZone('packetTools'), + vowTools, + ); const timestampHelper = makeTimestampHelper(timerService); /** Make an object wrapping an LCA with Zoe interfaces. */ const makeLocalOrchestrationAccountKit = zone.exoClassKit( 'Local Orchestration Account Kit', { + helper: M.interface('helper', { + amountToCoin: M.call(AmountArgShape).returns(M.record()), + }), holder: HolderI, undelegateWatcher: M.interface('undelegateWatcher', { onFulfilled: M.call([ @@ -97,11 +133,6 @@ export const prepareLocalOrchestrationAccountKit = ( .optional(M.arrayOf(M.undefined())) // empty context .returns(VowShape), }), - getChainInfoWatcher: M.interface('getChainInfoWatcher', { - onFulfilled: M.call(M.record()) // agoric chain info - .optional(ChainAddressShape) - .returns(Vow$(M.record())), // connection info - }), transferWatcher: M.interface('transferWatcher', { onFulfilled: M.call([M.record(), M.nat()]) .optional({ @@ -117,19 +148,34 @@ export const prepareLocalOrchestrationAccountKit = ( .returns(M.any()), }), returnVoidWatcher: M.interface('returnVoidWatcher', { - onFulfilled: M.call(M.any()) - .optional(M.arrayOf(M.undefined())) - .returns(M.undefined()), + onFulfilled: M.call(M.any()).optional(M.any()).returns(M.undefined()), + }), + seatExiterHandler: M.interface('seatExiterHandler', { + onFulfilled: M.call(M.undefined(), M.remotable()).returns( + M.undefined(), + ), + onRejected: M.call(M.error(), M.remotable()).returns(M.undefined()), }), getBalanceWatcher: M.interface('getBalanceWatcher', { - onFulfilled: M.call(AmountShape) - .optional(DenomShape) - .returns(DenomAmountShape), + onFulfilled: M.call(AmountShape, DenomShape).returns(DenomAmountShape), + }), + queryBalanceWatcher: M.interface('queryBalanceWatcher', { + onFulfilled: M.call(TypedJsonShape).returns(DenomAmountShape), + }), + queryBalancesWatcher: M.interface('queryBalancesWatcher', { + onFulfilled: M.call(TypedJsonShape).returns( + M.arrayOf(DenomAmountShape), + ), }), invitationMakers: M.interface('invitationMakers', { + CloseAccount: M.call().returns(M.promise()), Delegate: M.call(M.string(), AmountShape).returns(M.promise()), + Deposit: M.call().returns(M.promise()), + Send: M.call().returns(M.promise()), + SendAll: M.call().returns(M.promise()), + Transfer: M.call().returns(M.promise()), Undelegate: M.call(M.string(), AmountShape).returns(M.promise()), - CloseAccount: M.call().returns(M.promise()), + Withdraw: M.call().returns(M.promise()), }), }, /** @@ -144,10 +190,20 @@ export const prepareLocalOrchestrationAccountKit = ( const topicKit = makeRecorderKit(storageNode, PUBLIC_TOPICS.account[1]); // TODO determine what goes in vstorage https://github.com/Agoric/agoric-sdk/issues/9066 void E(topicKit.recorder).write(''); + const packetTools = makePacketTools(account); - return { account, address, topicKit }; + return { account, address, topicKit, packetTools }; }, { + helper: { + /** + * @param {AmountArg} amount + * @returns {Coin} + */ + amountToCoin(amount) { + return coerceCoin(chainHub, amount); + }, + }, invitationMakers: { /** * @param {string} validatorAddress @@ -163,6 +219,27 @@ export const prepareLocalOrchestrationAccountKit = ( ); }, 'Delegate'); }, + Deposit() { + trace('Deposit'); + return zcf.makeInvitation( + seat => { + const { give } = seat.getProposal(); + return watch( + zoeTools.localTransfer( + seat, + // @ts-expect-error LocalAccount vs LocalAccountMethods + this.state.account, + give, + ), + this.facets.seatExiterHandler, + seat, + ); + }, + 'Deposit', + undefined, + M.splitRecord({ give: AnyNatAmountsRecord, want: {} }), + ); + }, /** * @param {string} validatorAddress * @param {Amount<'nat'>} ertpAmount @@ -180,6 +257,72 @@ export const prepareLocalOrchestrationAccountKit = ( CloseAccount() { throw Error('not yet implemented'); }, + Send() { + /** + * @type {OfferHandler< + * Vow, + * { toAccount: ChainAddress; amount: AmountArg } + * >} + */ + const offerHandler = (seat, { toAccount, amount }) => { + seat.exit(); + return watch(this.facets.holder.send(toAccount, amount)); + }; + return zcf.makeInvitation(offerHandler, 'Send'); + }, + SendAll() { + /** + * @type {OfferHandler< + * Vow, + * { toAccount: ChainAddress; amounts: AmountArg[] } + * >} + */ + const offerHandler = (seat, { toAccount, amounts }) => { + seat.exit(); + return watch(this.facets.holder.sendAll(toAccount, amounts)); + }; + return zcf.makeInvitation(offerHandler, 'SendAll'); + }, + Transfer() { + /** + * @type {OfferHandler< + * Vow, + * { + * amount: AmountArg; + * destination: ChainAddress; + * opts: IBCMsgTransferOptions; + * } + * >} + */ + const offerHandler = (seat, { amount, destination, opts }) => { + seat.exit(); + return watch( + this.facets.holder.transfer(amount, destination, opts), + ); + }; + return zcf.makeInvitation(offerHandler, 'Transfer'); + }, + Withdraw() { + trace('Withdraw'); + return zcf.makeInvitation( + seat => { + const { want } = seat.getProposal(); + return watch( + zoeTools.withdrawToSeat( + // @ts-expect-error LocalAccount vs LocalAccountMethods + this.state.account, + seat, + want, + ), + this.facets.seatExiterHandler, + seat, + ); + }, + 'Withdraw', + undefined, + M.splitRecord({ give: {}, want: AnyNatAmountsRecord }), + ); + }, }, undelegateWatcher: { /** @@ -200,18 +343,6 @@ export const prepareLocalOrchestrationAccountKit = ( ); }, }, - getChainInfoWatcher: { - /** - * @param {ChainInfo} agoricChainInfo - * @param {ChainAddress} destination - */ - onFulfilled(agoricChainInfo, destination) { - return chainHub.getConnectionInfo( - agoricChainInfo.chainId, - destination.chainId, - ); - }, - }, transferWatcher: { /** * @param {[ @@ -220,7 +351,7 @@ export const prepareLocalOrchestrationAccountKit = ( * ]} results * @param {{ * destination: ChainAddress; - * opts: IBCMsgTransferOptions; + * opts?: IBCMsgTransferOptions; * amount: DenomAmount; * }} ctx */ @@ -228,26 +359,35 @@ export const prepareLocalOrchestrationAccountKit = ( [{ transferChannel }, timeoutTimestamp], { opts, amount, destination }, ) { - return watch( - E(this.state.account).executeTx([ - typedJson('/ibc.applications.transfer.v1.MsgTransfer', { - sourcePort: transferChannel.portId, - sourceChannel: transferChannel.channelId, - token: { - amount: String(amount.value), - denom: amount.denom, - }, - sender: this.state.address.value, - receiver: destination.value, - timeoutHeight: opts?.timeoutHeight ?? { - revisionHeight: 0n, - revisionNumber: 0n, - }, - timeoutTimestamp, - memo: opts?.memo ?? '', - }), - ]), + const transferMsg = typedJson( + '/ibc.applications.transfer.v1.MsgTransfer', + { + sourcePort: transferChannel.portId, + sourceChannel: transferChannel.channelId, + token: { + amount: String(amount.value), + denom: amount.denom, + }, + sender: this.state.address.value, + receiver: destination.value, + timeoutHeight: opts?.timeoutHeight ?? { + revisionHeight: 0n, + revisionNumber: 0n, + }, + timeoutTimestamp, + memo: opts?.memo ?? '', + }, ); + + const { holder } = this.facets; + const sender = makeIBCTransferSender( + /** @type {any} */ (holder), + transferMsg, + ); + // Begin capturing packets, send the transfer packet, then return a + // vow that rejects unless the packet acknowledgment comes back and is + // verified. + return holder.sendThenWaitForAck(sender); }, }, /** @@ -264,15 +404,8 @@ export const prepareLocalOrchestrationAccountKit = ( return results[0]; }, }, - /** - * takes an array of results (from `executeEncodedTx`) and returns void - * since we are not interested in the result - */ returnVoidWatcher: { - /** - * @param {unknown} _result - */ - onFulfilled(_result) { + onFulfilled() { return undefined; }, }, @@ -290,9 +423,68 @@ export const prepareLocalOrchestrationAccountKit = ( return harden({ denom, value: natAmount.value }); }, }, + /** exits or fails a seat depending the outcome */ + seatExiterHandler: { + /** + * @param {undefined} _ + * @param {ZCFSeat} seat + */ + onFulfilled(_, seat) { + seat.exit(); + }, + /** + * @param {Error} reason + * @param {ZCFSeat} seat + */ + onRejected(reason, seat) { + seat.exit(reason); + throw reason; + }, + }, + /** + * handles a QueryBalanceRequest from localchain.query and returns the + * balance as a DenomAmount + */ + queryBalanceWatcher: { + /** + * @param {ResponseTo< + * TypedJson<'/cosmos.bank.v1beta1.QueryBalanceRequest'> + * >} result + * @returns {DenomAmount} + */ + onFulfilled(result) { + const { balance } = result; + if (!balance || !balance?.denom) { + throw Fail`Expected balance ${q(result)};`; + } + return harden(toDenomAmount(balance)); + }, + }, + /** + * handles a QueryAllBalancesRequest from localchain.query and returns the + * balances as a DenomAmounts + */ + queryBalancesWatcher: { + /** + * @param {JsonSafe< + * ResponseTo< + * TypedJson<'/cosmos.bank.v1beta1.QueryAllBalancesRequest'> + * > + * >} result + * @returns {DenomAmount[]} + */ + onFulfilled(result) { + const { balances } = result; + if (!balances || !Array.isArray(balances)) { + throw Fail`Expected balances ${q(result)};`; + } + return harden(balances.map(toDenomAmount)); + }, + }, holder: { /** @type {HostOf} */ asContinuingOffer() { + // @ts-expect-error XXX invitationMakers // getPublicTopics resolves promptly (same run), so we don't need a watcher // eslint-disable-next-line no-restricted-syntax return asVow(async () => { @@ -313,28 +505,48 @@ export const prepareLocalOrchestrationAccountKit = ( }); }, /** - * TODO: balance lookups for non-vbank assets - * * @type {HostOf} */ getBalance(denomArg) { - // FIXME look up real values - // UNTIL https://github.com/Agoric/agoric-sdk/issues/9211 - const [brand, denom] = - typeof denomArg === 'string' - ? [/** @type {any} */ (null), denomArg] - : [denomArg, 'FIXME']; + return asVow(() => { + const [brand, denom] = + typeof denomArg === 'string' + ? [chainHub.getAsset(denomArg)?.brand, denomArg] + : [denomArg, chainHub.getDenom(denomArg)]; - return watch( - E(this.state.account).getBalance(brand), - this.facets.getBalanceWatcher, - denom, - ); + if (!denom) { + throw Fail`No denom for brand: ${denomArg}`; + } + + if (brand) { + return watch( + E(this.state.account).getBalance(brand), + this.facets.getBalanceWatcher, + denom, + ); + } + + return watch( + E(localchain).query( + typedJson('/cosmos.bank.v1beta1.QueryBalanceRequest', { + address: this.state.address.value, + denom, + }), + ), + this.facets.queryBalanceWatcher, + ); + }); }, /** @type {HostOf} */ getBalances() { - // TODO https://github.com/Agoric/agoric-sdk/issues/9610 - return asVow(() => Fail`not yet implemented`); + return watch( + E(localchain).query( + typedJson('/cosmos.bank.v1beta1.QueryAllBalancesRequest', { + address: this.state.address.value, + }), + ), + this.facets.queryBalancesWatcher, + ); }, /** @@ -361,13 +573,10 @@ export const prepareLocalOrchestrationAccountKit = ( * @param {Amount<'nat'>} ertpAmount */ delegate(validatorAddress, ertpAmount) { - // TODO #9211 lookup denom from brand - const amount = { - amount: String(ertpAmount.value), - denom: 'ubld', - }; const { account: lca } = this.state; + const amount = coerceCoin(chainHub, ertpAmount); + return watch( E(lca).executeTx([ typedJson('/cosmos.staking.v1beta1.MsgDelegate', { @@ -386,11 +595,7 @@ export const prepareLocalOrchestrationAccountKit = ( * @returns {Vow} */ undelegate(validatorAddress, ertpAmount) { - // TODO #9211 lookup denom from brand - const amount = { - amount: String(ertpAmount.value), - denom: 'ubld', - }; + const amount = coerceCoin(chainHub, ertpAmount); const { account: lca } = this.state; return watch( E(lca).executeTx([ @@ -427,11 +632,46 @@ export const prepareLocalOrchestrationAccountKit = ( getAddress() { return this.state.address; }, + /** + * XXX consider using ERTP to send if it's vbank asset + * + * @type {HostOf} + */ send(toAccount, amount) { return asVow(() => { - // FIXME implement - console.log('send got', toAccount, amount); - throw Fail`send not yet implemented`; + trace('send', toAccount, amount); + const { helper } = this.facets; + return watch( + E(this.state.account).executeTx([ + typedJson('/cosmos.bank.v1beta1.MsgSend', { + amount: [helper.amountToCoin(amount)], + toAddress: toAccount.value, + fromAddress: this.state.address.value, + }), + ]), + this.facets.returnVoidWatcher, + ); + }); + }, + /** + * XXX consider using ERTP to send if it's vbank asset + * + * @type {HostOf} + */ + sendAll(toAccount, amounts) { + return asVow(() => { + trace('sendAll', toAccount, amounts); + const { helper } = this.facets; + return watch( + E(this.state.account).executeTx([ + typedJson('/cosmos.bank.v1beta1.MsgSend', { + amount: amounts.map(a => helper.amountToCoin(a)), + toAddress: toAccount.value, + fromAddress: this.state.address.value, + }), + ]), + this.facets.returnVoidWatcher, + ); }); }, /** @@ -441,18 +681,17 @@ export const prepareLocalOrchestrationAccountKit = ( * @param {IBCMsgTransferOptions} [opts] if either timeoutHeight or * timeoutTimestamp are not supplied, a default timeoutTimestamp will * be set for 5 minutes in the future - * @returns {Vow} + * @returns {Vow} */ transfer(amount, destination, opts) { return asVow(() => { trace('Transferring funds from LCA over IBC'); - // TODO #9211 lookup denom from brand - if ('brand' in amount) throw Fail`ERTP Amounts not yet supported`; const connectionInfoV = watch( - chainHub.getChainInfo('agoric'), - this.facets.getChainInfoWatcher, - destination, + chainHub.getConnectionInfo( + this.state.address.chainId, + destination.chainId, + ), ); // set a `timeoutTimestamp` if caller does not supply either `timeoutHeight` or `timeoutTimestamp` @@ -463,12 +702,18 @@ export const prepareLocalOrchestrationAccountKit = ( ? 0n : E(timestampHelper).getTimeoutTimestampNS()); - const transferV = watch( + // don't resolve the vow until the transfer is confirmed on remote + // and reject vow if the transfer fails for any reason + const resultV = watch( allVows([connectionInfoV, timeoutTimestampVowOrValue]), this.facets.transferWatcher, - { opts, amount, destination }, + { + opts, + amount: coerceDenomAmount(chainHub, amount), + destination, + }, ); - return watch(transferV, this.facets.returnVoidWatcher); + return resultV; }); }, /** @type {HostOf} */ @@ -478,14 +723,25 @@ export const prepareLocalOrchestrationAccountKit = ( throw Fail`not yet implemented`; }); }, + /** @type {HostOf} */ + sendThenWaitForAck(sender, opts) { + return watch( + E(this.state.packetTools).sendThenWaitForAck(sender, opts), + ); + }, + /** @type {HostOf} */ + matchFirstPacket(patternV) { + return watch(E(this.state.packetTools).matchFirstPacket(patternV)); + }, /** @type {HostOf} */ monitorTransfers(tap) { - return watch(E(this.state.account).monitorTransfers(tap)); + return watch(E(this.state.packetTools).monitorTransfers(tap)); }, }, }, ); return makeLocalOrchestrationAccountKit; }; + /** @typedef {ReturnType} MakeLocalOrchestrationAccountKit */ /** @typedef {ReturnType} LocalOrchestrationAccountKit */ diff --git a/packages/orchestration/src/exos/orchestrator.js b/packages/orchestration/src/exos/orchestrator.js index 224656d878f..9a3a2ed31ad 100644 --- a/packages/orchestration/src/exos/orchestrator.js +++ b/packages/orchestration/src/exos/orchestrator.js @@ -1,11 +1,13 @@ -/** @file ChainAccount exo */ +/** @file Orchestrator exo */ import { AmountShape } from '@agoric/ertp'; +import { pickFacet } from '@agoric/vat-data'; import { makeTracer } from '@agoric/internal'; import { Shape as NetworkShape } from '@agoric/network'; +import { Fail, q } from '@endo/errors'; import { E } from '@endo/far'; import { M } from '@endo/patterns'; import { - BrandInfoShape, + DenomInfoShape, ChainInfoShape, DenomAmountShape, DenomShape, @@ -14,22 +16,20 @@ import { /** * @import {Zone} from '@agoric/base-zone'; - * @import {ChainHub} from './chain-hub.js'; - * @import {AsyncFlowTools, HostOf} from '@agoric/async-flow'; + * @import {ActualChainInfo, ChainHub} from './chain-hub.js'; + * @import {AsyncFlowTools, HostInterface, HostOf} from '@agoric/async-flow'; * @import {Vow, VowTools} from '@agoric/vow'; * @import {TimerService} from '@agoric/time'; * @import {LocalChain} from '@agoric/vats/src/localchain.js'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. * @import {Remote} from '@agoric/internal'; * @import {PickFacet} from '@agoric/swingset-liveslots'; - * @import {CosmosInterchainService} from './cosmos-interchain-service.js'; - * @import {MakeLocalOrchestrationAccountKit} from './local-orchestration-account.js'; + * @import {CosmosInterchainService} from './exo-interfaces.js'; * @import {MakeLocalChainFacade} from './local-chain-facade.js'; * @import {MakeRemoteChainFacade} from './remote-chain-facade.js'; * @import {Chain, ChainInfo, IBCConnectionInfo, Orchestrator} from '../types.js'; */ -const { Fail } = assert; const { Vow$ } = NetworkShape; // TODO #9611 const trace = makeTracer('Orchestrator'); @@ -37,7 +37,7 @@ const trace = makeTracer('Orchestrator'); export const OrchestratorI = M.interface('Orchestrator', { getChain: M.call(M.string()).returns(Vow$(ChainInfoShape)), makeLocalAccount: M.call().returns(Vow$(LocalChainAccountShape)), - getBrandInfo: M.call(DenomShape).returns(BrandInfoShape), + getDenomInfo: M.call(DenomShape).returns(DenomInfoShape), asAmount: M.call(DenomAmountShape).returns(AmountShape), }); @@ -47,6 +47,7 @@ export const OrchestratorI = M.interface('Orchestrator', { * asyncFlowTools: AsyncFlowTools; * chainHub: ChainHub; * localchain: Remote; + * chainByName: MapStore>; * makeRecorderKit: MakeRecorderKit; * makeLocalChainFacade: MakeLocalChainFacade; * makeRemoteChainFacade: MakeRemoteChainFacade; @@ -57,14 +58,15 @@ export const OrchestratorI = M.interface('Orchestrator', { * zcf: ZCF; * }} powers */ -export const prepareOrchestratorKit = ( +const prepareOrchestratorKit = ( zone, { chainHub, localchain, + chainByName, makeLocalChainFacade, makeRemoteChainFacade, - vowTools: { watch }, + vowTools: { watch, asVow }, }, ) => zone.exoClassKit( @@ -72,16 +74,14 @@ export const prepareOrchestratorKit = ( { orchestrator: OrchestratorI, makeLocalChainFacadeWatcher: M.interface('makeLocalChainFacadeWatcher', { - onFulfilled: M.call(M.record()) - .optional(M.arrayOf(M.undefined())) - .returns(M.any()), // FIXME narrow + onFulfilled: M.call(M.record()).returns(M.remotable()), }), makeRemoteChainFacadeWatcher: M.interface( 'makeRemoteChainFacadeWatcher', { - onFulfilled: M.call(M.any()) - .optional(M.arrayOf(M.undefined())) - .returns(M.any()), // FIXME narrow + onFulfilled: M.call(M.any(), M.string()) + .optional(M.arrayOf(M.undefined())) // XXX needed? + .returns(M.remotable()), }, ), }, @@ -92,9 +92,13 @@ export const prepareOrchestratorKit = ( { /** Waits for `chainInfo` and returns a LocalChainFacade */ makeLocalChainFacadeWatcher: { - /** @param {ChainInfo} agoricChainInfo */ + /** + * @param {ActualChainInfo<'agoric'>} agoricChainInfo + */ onFulfilled(agoricChainInfo) { - return makeLocalChainFacade(agoricChainInfo); + const it = makeLocalChainFacade(agoricChainInfo); + chainByName.init('agoric', it); + return it; }, }, /** @@ -107,14 +111,20 @@ export const prepareOrchestratorKit = ( * RemoteChainFacade * * @param {[ChainInfo, ChainInfo, IBCConnectionInfo]} chainsAndConnection + * @param {string} name */ - onFulfilled([_agoricChainInfo, remoteChainInfo, connectionInfo]) { - return makeRemoteChainFacade(remoteChainInfo, connectionInfo); + onFulfilled([_agoricChainInfo, remoteChainInfo, connectionInfo], name) { + const it = makeRemoteChainFacade(remoteChainInfo, connectionInfo); + chainByName.init(name, it); + return it; }, }, orchestrator: { /** @type {HostOf} */ getChain(name) { + if (chainByName.has(name)) { + return asVow(() => chainByName.get(name)); + } if (name === 'agoric') { return watch( chainHub.getChainInfo('agoric'), @@ -124,17 +134,54 @@ export const prepareOrchestratorKit = ( return watch( chainHub.getChainsAndConnection('agoric', name), this.facets.makeRemoteChainFacadeWatcher, + name, ); }, makeLocalAccount() { return watch(E(localchain).makeAccount()); }, - getBrandInfo: () => Fail`not yet implemented`, + /** @type {HostOf} */ + getDenomInfo(denom) { + const denomDetail = chainHub.getAsset(denom); + if (!denomDetail) throw Fail`No denom detail for ${q(denom)}`; + const { chainName, baseName, baseDenom, brand } = denomDetail; + chainByName.has(chainName) || + Fail`use getChain(${q(chainName)}) before getDenomInfo(${q(denom)})`; + const chain = chainByName.get(chainName); + chainByName.has(baseName) || + Fail`use getChain(${q(baseName)}) before getDenomInfo(${q(denom)})`; + const base = chainByName.get(baseName); + return harden({ chain, base, brand, baseDenom }); + }, + /** @type {HostOf} */ asAmount: () => Fail`not yet implemented`, }, }, ); harden(prepareOrchestratorKit); + +/** + * @param {Zone} zone + * @param {{ + * asyncFlowTools: AsyncFlowTools; + * chainHub: ChainHub; + * localchain: Remote; + * chainByName: MapStore>; + * makeRecorderKit: MakeRecorderKit; + * makeLocalChainFacade: MakeLocalChainFacade; + * makeRemoteChainFacade: MakeRemoteChainFacade; + * orchestrationService: Remote; + * storageNode: Remote; + * timerService: Remote; + * vowTools: VowTools; + * zcf: ZCF; + * }} powers + */ +export const prepareOrchestrator = (zone, powers) => { + const makeOrchestratorKit = prepareOrchestratorKit(zone, powers); + return pickFacet(makeOrchestratorKit, 'orchestrator'); +}; + /** * Host side of the Orchestrator interface. (Methods return vows instead of * promises as the interface within the guest function.) diff --git a/packages/orchestration/src/exos/packet-tools.js b/packages/orchestration/src/exos/packet-tools.js new file mode 100644 index 00000000000..a4ba79c2455 --- /dev/null +++ b/packages/orchestration/src/exos/packet-tools.js @@ -0,0 +1,372 @@ +import { makeMarshal, decodeToJustin } from '@endo/marshal'; +import { Shape as NetworkShape } from '@agoric/network'; +import { M, matches } from '@endo/patterns'; +import { E } from '@endo/far'; +import { pickFacet } from '@agoric/vat-data'; + +const { toCapData } = makeMarshal(undefined, undefined, { + marshalName: 'JustEncoder', + serializeBodyFormat: 'capdata', +}); +const just = obj => { + const { body } = toCapData(obj); + return decodeToJustin(JSON.parse(body), true); +}; + +/** + * @import {Pattern} from '@endo/patterns'; + * @import {EVow, Remote, Vow, VowResolver, VowTools} from '@agoric/vow'; + * @import {LocalChainAccount} from '@agoric/vats/src/localchain.js'; + * @import {TargetApp, TargetRegistration} from '@agoric/vats/src/bridge-target.js'; + */ + +/** + * @callback MatchEvent + * @param {EVow} pattern + * @returns {Vow<{ resolver: VowResolver; match: Vow }>} + */ + +/** + * @typedef {object} PacketSender + * @property {( + * opts: PacketOptions, + * ) => Vow<{ eventPattern: Pattern; resultV: Vow }>} sendPacket + */ + +/** + * @typedef {object} PacketOptions + * @property {string} [opName] + * @property {PacketTimeout} [timeout] + */ + +/** + * @typedef {Pick< + * import('../cosmos-api').IBCMsgTransferOptions, + * 'timeoutHeight' | 'timeoutTimestamp' + * >} PacketTimeout + */ + +const { Vow$ } = NetworkShape; // TODO #9611 + +const EVow$ = shape => M.or(Vow$(shape), M.promise(/* shape */)); + +const sink = () => {}; +harden(sink); + +/** + * @param {import('@agoric/base-zone').Zone} zone + * @param {VowTools} vowTools + */ +export const preparePacketTools = (zone, vowTools) => { + const { allVows, makeVowKit, watch, when } = vowTools; + + const makePacketToolsKit = zone.exoClassKit( + 'PacketToolsKit', + { + public: M.interface('PacketTools', { + sendThenWaitForAck: M.call(EVow$(M.remotable('PacketSender'))) + .optional(M.any()) + .returns(EVow$(M.any())), + matchFirstPacket: M.call(M.any()).returns(EVow$(M.any())), + monitorTransfers: M.call(M.remotable('TargetApp')).returns( + EVow$(M.any()), + ), + }), + tap: M.interface('tap', { + // eslint-disable-next-line no-restricted-syntax + receiveUpcall: M.callWhen(M.any()).returns(M.any()), + }), + monitorRegistration: M.interface('monitorRegistration', { + // eslint-disable-next-line no-restricted-syntax + updateTargetApp: M.callWhen( + M.await(M.remotable('TargetApp')), + ).returns(), + // eslint-disable-next-line no-restricted-syntax + revoke: M.callWhen().returns(), + }), + watchPacketMatch: M.interface('watchPacketMatch', { + onFulfilled: M.call(M.any(), M.record()).returns(M.any()), + }), + watchPacketPattern: M.interface('watchPacketPattern', { + onFulfilled: M.call(M.any(), M.record()).returns(M.any()), + onRejected: M.call(M.any(), M.record()).returns(M.any()), + }), + watchDecrPendingPatterns: M.interface('watchDecrPendingPatterns', { + onFulfilled: M.call(M.any()).returns(M.any()), + onRejected: M.call(M.any()).returns(M.any()), + }), + sendPacketWatcher: M.interface('sendPacketWatcher', { + onFulfilled: M.call( + [M.record(), M.remotable('PacketSender')], + M.record(), + ).returns(M.any()), + }), + packetWasSentWatcher: M.interface('packetWasSentWatcher', { + onFulfilled: M.call( + { eventPattern: M.pattern(), resultV: Vow$(M.any()) }, + M.record(), + ).returns(M.any()), + }), + utils: M.interface('utils', { + subscribeToTransfers: M.call().returns(M.promise()), + unsubscribeFromTransfers: M.call().returns(M.undefined()), + incrPendingPatterns: M.call().returns(Vow$(M.undefined())), + decrPendingPatterns: M.call().returns(Vow$(M.undefined())), + }), + rejectResolverAndRethrowWatcher: M.interface('rejectResolverWatcher', { + onRejected: M.call(M.any(), { + resolver: M.remotable('resolver'), + }).returns(M.any()), + }), + }, + /** + * @param {LocalChainAccount} lca + */ + lca => { + const resolverToPattern = zone.detached().mapStore('resolverToPattern'); + return { + lca, + reg: /** @type {Remote | null} */ (null), + resolverToPattern, + upcallQueue: /** @type {any[] | null} */ (null), + pending: 0, + extra: null, + monitor: /** @type {Remote | null} */ (null), + }; + }, + { + public: { + /** + * @param {ERef} monitor + */ + // eslint-disable-next-line no-restricted-syntax + async monitorTransfers(monitor) { + // We set the monitor here, but we only ever subscribe our + // this.facets.tap handler to transfers. + const mreg = this.facets.monitorRegistration; + await mreg.updateTargetApp(monitor); + return mreg; + }, + /** + * @type {MatchEvent} + */ + matchFirstPacket(patternP) { + return watch( + this.facets.utils.incrPendingPatterns(), + this.facets.watchPacketMatch, + { patternP }, + ); + }, + /** + * @param {Remote} packetSender + * @param {PacketOptions} [opts] + * @returns {Vow} + */ + sendThenWaitForAck(packetSender, opts = {}) { + /** @type {import('@agoric/vow').VowKit} */ + const pattern = makeVowKit(); + + // Establish the packet matcher immediately, but don't fulfill + // the match until after pattern.vow has been resolved. + const matchV = watch( + allVows([ + this.facets.public.matchFirstPacket(pattern.vow), + packetSender, + ]), + this.facets.sendPacketWatcher, + { opts }, + ); + + // When the packet is sent, resolve the resultV for the reply. + const resultV = watch(matchV, this.facets.packetWasSentWatcher, { + opts, + patternResolver: pattern.resolver, + }); + + // If anything fails, try to reject the packet sender. + return watch(resultV, this.facets.rejectResolverAndRethrowWatcher, { + resolver: pattern.resolver, + }); + }, + }, + monitorRegistration: { + /** @type {TargetRegistration['updateTargetApp']} */ + // eslint-disable-next-line no-restricted-syntax + async updateTargetApp(tap) { + this.state.monitor = await tap; + await this.facets.utils.subscribeToTransfers(); + }, + /** @type {TargetRegistration['revoke']} */ + // eslint-disable-next-line no-restricted-syntax + async revoke() { + this.state.monitor = null; + }, + }, + tap: { + // eslint-disable-next-line no-restricted-syntax + async receiveUpcall(obj) { + const { monitor, resolverToPattern, upcallQueue, pending } = + this.state; + console.debug( + `Trying ${resolverToPattern.getSize()} current patterns and ${pending} pending patterns against`, + just(obj), + ); + + if (monitor) { + // Call the monitor (if any), but in a future turn. + void E(monitor).receiveUpcall(obj); + } + // Check all our fulfilled patterns for matches. + for (const [resolver, pattern] of resolverToPattern.entries()) { + if (matches(obj, pattern)) { + console.debug('Matched pattern:', just(pattern)); + resolver.resolve(obj); + resolverToPattern.delete(resolver); + return; + } + } + if (upcallQueue) { + // We have some pending patterns (ones that have been requested but + // haven't yet settled) that may match this object. + console.debug('Stashing object in upcallQueue'); + this.state.upcallQueue = harden(upcallQueue.concat(obj)); + } + console.debug('No match yet.'); + }, + }, + sendPacketWatcher: { + onFulfilled([{ match }, sender], ctx) { + return watch(E(sender).sendPacket(match, ctx.opts)); + }, + }, + packetWasSentWatcher: { + onFulfilled({ eventPattern, resultV }, ctx) { + const { patternResolver } = ctx; + patternResolver.resolve(eventPattern); + return resultV; + }, + }, + rejectResolverAndRethrowWatcher: { + onRejected(rej, { resolver }) { + resolver.reject(rej); + throw rej; + }, + }, + watchPacketMatch: { + onFulfilled(_, { patternP }) { + const { vow, resolver } = makeVowKit(); + const patternV = watch( + patternP, + this.facets.watchPacketPattern, + harden({ resolver }), + ); + /* void */ watch(patternV, this.facets.watchDecrPendingPatterns); + return harden({ match: vow, resolver }); + }, + }, + watchDecrPendingPatterns: { + onFulfilled() { + return this.facets.utils.decrPendingPatterns(); + }, + onRejected() { + return this.facets.utils.decrPendingPatterns(); + }, + }, + watchPacketPattern: { + onFulfilled(pattern, { resolver }) { + const { resolverToPattern, upcallQueue } = this.state; + + console.debug('watchPacketPattern onFulfilled', just(pattern)); + if (!upcallQueue) { + // Save the pattern for later. + console.debug('No upcall queue yet. Save the pattern for later.'); + resolverToPattern.init(resolver, pattern); + return; + } + + // Try matching the first in queue. + const i = upcallQueue.findIndex(obj => matches(obj, pattern)); + if (i < 0) { + // No match yet. Save the pattern for later. + console.debug('No match yet. Save the pattern for later.'); + resolverToPattern.init(resolver, pattern); + return; + } + + // Success! Remove the matched object from the queue. + console.debug( + 'Success! Remove the matched object from the queue.', + just(upcallQueue[i]), + ); + resolver.resolve(upcallQueue[i]); + this.state.upcallQueue = harden( + upcallQueue.slice(0, i).concat(upcallQueue.slice(i + 1)), + ); + }, + onRejected(reason, { resolver }) { + resolver.reject(reason); + }, + }, + + utils: { + incrPendingPatterns() { + const { pending, reg, upcallQueue } = this.state; + this.state.pending += 1; + if (!upcallQueue) { + this.state.upcallQueue = harden([]); + } + if (reg || pending > 0) { + return watch(undefined); + } + return watch(this.facets.utils.subscribeToTransfers()); + }, + decrPendingPatterns() { + this.state.pending -= 1; + if (this.state.pending > 0) { + return; + } + this.state.pending = 0; + this.state.upcallQueue = null; + // FIXME when it returns undefined this causes an error: + // In "unsubscribeFromTransfers" method of (PacketToolsKit utils): result: undefined "[undefined]" - Must be a promise + return watch(this.facets.utils.unsubscribeFromTransfers()); + }, + subscribeToTransfers() { + // Subscribe to the transfers for this account. + const { lca, reg } = this.state; + if (reg) { + return when(reg); + } + const { tap } = this.facets; + // XXX racy; fails if subscribeToTransfers is called while this promise is in flight + // e.g. 'Target "agoric1fakeLCAAddress" already registered' + return when(E(lca).monitorTransfers(tap), r => { + this.state.reg = r; + return r; + }); + }, + unsubscribeFromTransfers() { + const { reg, monitor } = this.state; + if (!reg || monitor) { + return undefined; + } + // this.state.reg = null; + // return E(reg).revoke().then(sink); + }, + }, + }, + { + finish(context) { + void context.facets.utils.subscribeToTransfers(); + }, + }, + ); + + const makePacketTools = pickFacet(makePacketToolsKit, 'public'); + return makePacketTools; +}; +harden(preparePacketTools); + +/** + * @typedef {Awaited>>} PacketTools + */ diff --git a/packages/orchestration/src/exos/portfolio-holder-kit.js b/packages/orchestration/src/exos/portfolio-holder-kit.js index 3177cdece3b..059eebe03e1 100644 --- a/packages/orchestration/src/exos/portfolio-holder-kit.js +++ b/packages/orchestration/src/exos/portfolio-holder-kit.js @@ -8,7 +8,7 @@ import { VowShape } from '@agoric/vow'; const { fromEntries } = Object; /** - * @import {HostOf} from '@agoric/async-flow'; + * @import {HostInterface, HostOf} from '@agoric/async-flow'; * @import {MapStore} from '@agoric/store'; * @import {VowTools} from '@agoric/vow'; * @import {ResolvedPublicTopic} from '@agoric/zoe/src/contractSupport/topics.js'; @@ -18,7 +18,7 @@ const { fromEntries } = Object; /** * @typedef {{ - * accounts: MapStore>; + * accounts: MapStore>>; * publicTopics: MapStore>; * }} PortfolioHolderState */ @@ -43,7 +43,7 @@ const preparePortfolioHolderKit = (zone, { asVow, when }) => { 'PortfolioHolderKit', { invitationMakers: M.interface('InvitationMakers', { - MakeInvitation: M.call( + Proxying: M.call( ChainNameShape, M.string(), M.arrayOf(M.any()), @@ -95,10 +95,11 @@ const preparePortfolioHolderKit = (zone, { asVow, when }) => { * @param {IA} invitationArgs * @returns {Promise>} */ - MakeInvitation(chainName, action, invitationArgs) { + Proxying(chainName, action, invitationArgs) { const { accounts } = this.state; accounts.has(chainName) || Fail`no account found for ${chainName}`; const account = accounts.get(chainName); + // @ts-expect-error XXX invitationMakers return when(E(account).asContinuingOffer(), ({ invitationMakers }) => E(invitationMakers)[action](...invitationArgs), ); @@ -125,7 +126,7 @@ const preparePortfolioHolderKit = (zone, { asVow, when }) => { }, /** * @param {string} chainName key where the account is stored - * @param {OrchestrationAccount} account + * @param {HostInterface>} account * @param {ResolvedPublicTopic} publicTopic */ addAccount(chainName, account, publicTopic) { diff --git a/packages/orchestration/src/exos/remote-chain-facade.js b/packages/orchestration/src/exos/remote-chain-facade.js index e33f14b6ae2..3efebfff11d 100644 --- a/packages/orchestration/src/exos/remote-chain-facade.js +++ b/packages/orchestration/src/exos/remote-chain-facade.js @@ -1,28 +1,32 @@ -/** @file ChainAccount exo */ +/** @file Remote Chain Facade exo */ import { makeTracer } from '@agoric/internal'; import { E } from '@endo/far'; +import { Fail, q } from '@endo/errors'; import { M } from '@endo/patterns'; import { pickFacet } from '@agoric/vat-data'; import { VowShape } from '@agoric/vow'; -import { ChainAddressShape, ChainFacadeI } from '../typeGuards.js'; +import { + ChainAddressShape, + chainFacadeMethods, + ICQMsgShape, +} from '../typeGuards.js'; /** - * @import {HostInterface, HostOf} from '@agoric/async-flow'; + * @import {HostOf} from '@agoric/async-flow'; * @import {Zone} from '@agoric/base-zone'; + * @import {JsonSafe} from '@agoric/cosmic-proto'; + * @import {RequestQuery, ResponseQuery} from '@agoric/cosmic-proto/tendermint/abci/types.js'; * @import {TimerService} from '@agoric/time'; * @import {Remote} from '@agoric/internal'; * @import {Vow, VowTools} from '@agoric/vow'; - * @import {CosmosInterchainService} from './cosmos-interchain-service.js'; + * @import {LocalIbcAddress, RemoteIbcAddress} from '@agoric/vats/tools/ibc-utils.js'; + * @import {CosmosInterchainService} from './exo-interfaces.js'; * @import {prepareCosmosOrchestrationAccount} from './cosmos-orchestration-account.js'; - * @import {ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount, ChainAddress, IcaAccount, Denom, Chain} from '../types.js'; + * @import {CosmosChainInfo, IBCConnectionInfo, ChainAddress, IcaAccount, Chain, ICQConnection} from '../types.js'; */ -const { Fail } = assert; const trace = makeTracer('RemoteChainFacade'); -/** @type {any} */ -const anyVal = null; - /** * @typedef {{ * makeCosmosOrchestrationAccount: ReturnType< @@ -35,6 +39,14 @@ const anyVal = null; * }} RemoteChainFacadePowers */ +/** + * @typedef {{ + * remoteChainInfo: CosmosChainInfo; + * connectionInfo: IBCConnectionInfo; + * icqConnection: ICQConnection | undefined; + * }} RemoteChainFacadeState + */ + /** * @param {Zone} zone * @param {RemoteChainFacadePowers} powers @@ -48,30 +60,46 @@ const prepareRemoteChainFacadeKit = ( // consider making an `accounts` childNode storageNode, timer, - vowTools: { asVow, watch }, + vowTools: { allVows, asVow, watch }, }, ) => zone.exoClassKit( 'RemoteChainFacade', { - public: ChainFacadeI, - makeAccountWatcher: M.interface('makeAccountWatcher', { - onFulfilled: M.call(M.remotable()) - .optional(M.arrayOf(M.undefined())) // empty context - .returns(VowShape), + public: M.interface('RemoteChainFacade', { + ...chainFacadeMethods, + query: M.call(M.arrayOf(ICQMsgShape)).returns(VowShape), }), - getAddressWatcher: M.interface('getAddressWatcher', { - onFulfilled: M.call(M.record()) - .optional(M.remotable()) - .returns(VowShape), + makeICQConnectionQueryWatcher: M.interface( + 'makeICQConnectionQueryWatcher', + { + onFulfilled: M.call(M.remotable(), M.arrayOf(ICQMsgShape)).returns( + VowShape, + ), + }, + ), + makeAccountAndProvideQueryConnWatcher: M.interface( + 'makeAccountAndProvideQueryConnWatcher', + { + onFulfilled: M.call([ + M.remotable(), + M.or(M.remotable(), M.undefined()), + ]).returns(VowShape), + }, + ), + getAddressesWatcher: M.interface('getAddressWatcher', { + onFulfilled: M.call( + [ChainAddressShape, M.string(), M.string()], + M.remotable(), + ).returns(VowShape), }), makeChildNodeWatcher: M.interface('makeChildNodeWatcher', { - onFulfilled: M.call(M.remotable()) - .optional({ - account: M.remotable(), - chainAddress: ChainAddressShape, - }) - .returns(M.remotable()), + onFulfilled: M.call(M.remotable(), { + account: M.remotable(), + chainAddress: ChainAddressShape, + localAddress: M.string(), + remoteAddress: M.string(), + }).returns(M.remotable()), }), }, /** @@ -80,7 +108,11 @@ const prepareRemoteChainFacadeKit = ( */ (remoteChainInfo, connectionInfo) => { trace('making a RemoteChainFacade'); - return { remoteChainInfo, connectionInfo }; + return /** @type {RemoteChainFacadeState} */ ({ + remoteChainInfo, + connectionInfo, + icqConnection: undefined, + }); }, { public: { @@ -94,45 +126,96 @@ const prepareRemoteChainFacadeKit = ( return asVow(() => { const { remoteChainInfo, connectionInfo } = this.state; const stakingDenom = remoteChainInfo.stakingTokens?.[0]?.denom; - if (!stakingDenom) { - throw Fail`chain info lacks staking denom`; - } + if (!stakingDenom) throw Fail`chain info lacks staking denom`; + + // icqConnection is ultimately retrieved from state, but let's + // create a connection if it doesn't exist + const icqConnOrUndefinedV = + remoteChainInfo.icqEnabled && !this.state.icqConnection + ? E(orchestration).provideICQConnection(connectionInfo.id) + : undefined; + + const makeAccountV = E(orchestration).makeAccount( + remoteChainInfo.chainId, + connectionInfo.counterparty.connection_id, + connectionInfo.id, + ); return watch( - E(orchestration).makeAccount( - remoteChainInfo.chainId, - connectionInfo.counterparty.connection_id, - connectionInfo.id, - ), - this.facets.makeAccountWatcher, + allVows([makeAccountV, icqConnOrUndefinedV]), + this.facets.makeAccountAndProvideQueryConnWatcher, ); }); }, + /** + * @type {HostOf< + * Chain['query'] + * >} + */ + query(msgs) { + return asVow(() => { + const { + remoteChainInfo: { icqEnabled, chainId }, + connectionInfo, + } = this.state; + if (!icqEnabled) { + throw Fail`Queries not available for chain ${q(chainId)}`; + } + // if none exists, make one and still send the query in the handler + if (!this.state.icqConnection) { + return watch( + E(orchestration).provideICQConnection(connectionInfo.id), + this.facets.makeICQConnectionQueryWatcher, + msgs, + ); + } + return watch(E(this.state.icqConnection).query(msgs)); + }); + }, }, - makeAccountWatcher: { + makeAccountAndProvideQueryConnWatcher: { /** - * XXX Pipeline vows allVows and E - * - * @param {IcaAccount} account + * @param {[IcaAccount, ICQConnection | undefined]} account */ - onFulfilled(account) { + onFulfilled([account, icqConnection]) { + if (icqConnection && !this.state.icqConnection) { + this.state.icqConnection = icqConnection; + // no need to pass icqConnection in ctx; we can get it from state + } return watch( - E(account).getAddress(), - this.facets.getAddressWatcher, + allVows([ + E(account).getAddress(), + E(account).getLocalAddress(), + E(account).getRemoteAddress(), + ]), + this.facets.getAddressesWatcher, account, ); }, }, - getAddressWatcher: { + makeICQConnectionQueryWatcher: { /** - * @param {ChainAddress} chainAddress + * @param {ICQConnection} icqConnection + * @param {JsonSafe[]} msgs + * @returns {Vow[]>} + */ + onFulfilled(icqConnection, msgs) { + if (!this.state.icqConnection) { + this.state.icqConnection = icqConnection; + } + return watch(E(icqConnection).query(msgs)); + }, + }, + getAddressesWatcher: { + /** + * @param {[ChainAddress, LocalIbcAddress, RemoteIbcAddress]} chainAddresses * @param {IcaAccount} account */ - onFulfilled(chainAddress, account) { + onFulfilled([chainAddress, localAddress, remoteAddress], account) { return watch( E(storageNode).makeChildNode(chainAddress.value), this.facets.makeChildNodeWatcher, - { account, chainAddress }, + { account, chainAddress, localAddress, remoteAddress }, ); }, }, @@ -142,23 +225,30 @@ const prepareRemoteChainFacadeKit = ( * @param {{ * account: IcaAccount; * chainAddress: ChainAddress; + * localAddress: LocalIbcAddress; + * remoteAddress: RemoteIbcAddress; * }} ctx */ - onFulfilled(childNode, { account, chainAddress }) { - const { remoteChainInfo } = this.state; - const stakingDenom = remoteChainInfo.stakingTokens?.[0]?.denom; - if (!stakingDenom) { - throw Fail`chain info lacks staking denom`; - } - return makeCosmosOrchestrationAccount(chainAddress, stakingDenom, { - account, - // FIXME storage path https://github.com/Agoric/agoric-sdk/issues/9066 - storageNode: childNode, - // FIXME provide real ICQ connection - // FIXME make Query Connection available via chain, not orchestrationAccount - icqConnection: anyVal, - timer, - }); + onFulfilled( + childNode, + { account, chainAddress, localAddress, remoteAddress }, + ) { + const { icqConnection } = this.state; + + return makeCosmosOrchestrationAccount( + { + chainAddress, + localAddress, + remoteAddress, + }, + { + account, + // FIXME storage path https://github.com/Agoric/agoric-sdk/issues/9066 + storageNode: childNode, + icqConnection, + timer, + }, + ); }, }, }, diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index f366b411369..64a2e48e73f 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -1,6 +1,5 @@ /** @file Orchestration facade */ - -import { assertAllDefined } from '@agoric/internal'; +import { assertAllDefined, deepMapObject } from '@agoric/internal'; /** * @import {AsyncFlowTools, GuestInterface, HostArgs, HostOf} from '@agoric/async-flow'; @@ -10,7 +9,7 @@ import { assertAllDefined } from '@agoric/internal'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. * @import {HostOrchestrator} from './exos/orchestrator.js'; * @import {Remote} from '@agoric/internal'; - * @import {CosmosInterchainService} from './exos/cosmos-interchain-service.js'; + * @import {CosmosInterchainService} from './exos/exo-interfaces.js'; * @import {Chain, ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount, OrchestrationFlow, Orchestrator} from './types.js'; */ @@ -63,7 +62,7 @@ export const makeOrchestrationFacade = ({ asyncFlowTools, }); - const { prepareEndowment, asyncFlow, adminAsyncFlow } = asyncFlowTools; + const { prepareEndowment, asyncFlow } = asyncFlowTools; /** * @template HC - host context @@ -76,30 +75,31 @@ export const makeOrchestrationFacade = ({ */ const orchestrate = (durableName, hostCtx, guestFn) => { const subZone = zone.subZone(durableName); - - const hostOrc = makeOrchestrator(); - - const [wrappedOrc, wrappedCtx] = prepareEndowment(subZone, 'endowments', [ - hostOrc, - hostCtx, - ]); - + const [wrappedCtx] = prepareEndowment(subZone, 'endowments', [hostCtx]); const hostFn = asyncFlow(subZone, 'asyncFlow', guestFn); // cast because return could be arbitrary subtype const orcFn = /** @type {HostForGuest} */ ( - (...args) => hostFn(wrappedOrc, wrappedCtx, ...args) + (...args) => { + // each invocation gets a new orchestrator + const hostOrc = makeOrchestrator(); + // TODO: why are the types showing the guest types for arguments? + // @ts-expect-error XXX fix broken types + return hostFn(hostOrc, wrappedCtx, ...args); + } ); - return harden(orcFn); }; /** * Orchestrate all the guest functions. * + * If the `guestFns` object is provided as a property of `hostCtx` the + * functions will be available within the other guests. + * * NOTE multiple calls to this with the same guestFn name will fail * - * @template HC - host context + * @template {Record} HC - host context * @template {{ * [durableName: string]: OrchestrationFlow>; * }} GFM @@ -108,18 +108,33 @@ export const makeOrchestrationFacade = ({ * @param {HC} hostCtx * @returns {{ [N in keyof GFM]: HostForGuest }} */ - const orchestrateAll = (guestFns, hostCtx) => - /** @type {{ [N in keyof GFM]: HostForGuest }} */ ( + const orchestrateAll = (guestFns, hostCtx) => { + const mappedFlows = new Map( + Object.entries(guestFns).map(([name, guestFn]) => [ + guestFn, + // eslint-disable-next-line no-use-before-define + (...args) => orcFns[name](...args), + ]), + ); + + const mappedContext = deepMapObject( + hostCtx, + val => mappedFlows.get(val) || val, + ); + + const orcFns = /** @type {{ [N in keyof GFM]: HostForGuest }} */ ( Object.fromEntries( Object.entries(guestFns).map(([name, guestFn]) => [ name, - orchestrate(name, hostCtx, guestFn), + orchestrate(name, mappedContext, guestFn), ]), ) ); + return { ...orcFns }; + }; + return harden({ - adminAsyncFlow, orchestrate, orchestrateAll, }); diff --git a/packages/orchestration/src/fetched-chain-info.js b/packages/orchestration/src/fetched-chain-info.js index 5662c11afbf..0d83cbedeb8 100644 --- a/packages/orchestration/src/fetched-chain-info.js +++ b/packages/orchestration/src/fetched-chain-info.js @@ -15,9 +15,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-927', connection_id: 'connection-649', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -36,9 +33,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-32', connection_id: 'connection-40', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -57,9 +51,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-47', connection_id: 'connection-40', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -78,9 +69,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-2109', connection_id: 'connection-1649', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -99,9 +87,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-111', connection_id: 'connection-80', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -120,9 +105,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-129', connection_id: 'connection-118', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -141,9 +123,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-152', connection_id: 'connection-101', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -173,9 +152,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-48', connection_id: 'connection-36', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -194,9 +170,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-3012', connection_id: 'connection-2503', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -215,9 +188,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-174', connection_id: 'connection-131', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -236,9 +206,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-359', connection_id: 'connection-296', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -257,9 +224,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-137', connection_id: 'connection-125', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -283,15 +247,30 @@ export default /** @type {const} } */ ({ ], icqEnabled: false, connections: { + 'stargaze-1': { + id: 'connection-918', + client_id: '07-tendermint-1188', + counterparty: { + client_id: '07-tendermint-320', + connection_id: 'connection-256', + }, + state: 3, + transferChannel: { + channelId: 'channel-730', + portId: 'transfer', + counterPartyChannelId: 'channel-239', + counterPartyPortId: 'transfer', + ordering: 0, + state: 3, + version: 'ics20-1', + }, + }, 'agoric-3': { id: 'connection-649', client_id: '07-tendermint-927', counterparty: { client_id: '07-tendermint-6', connection_id: 'connection-8', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -310,9 +289,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-3', connection_id: 'connection-2', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -331,9 +307,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-0', connection_id: 'connection-0', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -352,9 +325,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-4', connection_id: 'connection-12', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -373,9 +343,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-23', connection_id: 'connection-19', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -394,9 +361,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1', connection_id: 'connection-1', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -415,9 +379,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1', connection_id: 'connection-0', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -430,36 +391,12 @@ export default /** @type {const} } */ ({ version: 'ics20-1', }, }, - 'stargaze-1': { - id: 'connection-918', - client_id: '07-tendermint-1188', - counterparty: { - client_id: '07-tendermint-320', - connection_id: 'connection-256', - prefix: { - key_prefix: 'FIXME', - }, - }, - state: 3, - transferChannel: { - channelId: 'channel-730', - portId: 'transfer', - counterPartyChannelId: 'channel-239', - counterPartyPortId: 'transfer', - ordering: 0, - state: 3, - version: 'ics20-1', - }, - }, 'stride-1': { id: 'connection-635', client_id: '07-tendermint-913', counterparty: { client_id: '07-tendermint-0', connection_id: 'connection-0', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -489,9 +426,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-72', connection_id: 'connection-51', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -510,9 +444,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-59', connection_id: 'connection-57', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -531,9 +462,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-3009', connection_id: 'connection-2500', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -552,9 +480,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-133', connection_id: 'connection-123', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -573,9 +498,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-244', connection_id: 'connection-208', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -605,9 +527,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-439', connection_id: 'connection-372', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -626,9 +545,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-97', connection_id: 'connection-71', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -647,9 +563,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-3', connection_id: 'connection-8', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -668,9 +581,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1457', connection_id: 'connection-1142', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -689,9 +599,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-23', connection_id: 'connection-9', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -710,9 +617,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-13', connection_id: 'connection-11', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -731,9 +635,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-31', connection_id: 'connection-19', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -763,9 +664,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-29', connection_id: 'connection-7', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -784,9 +682,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1119', connection_id: 'connection-809', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -805,9 +700,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-11', connection_id: 'connection-17', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -826,9 +718,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-557', connection_id: 'connection-524', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -847,9 +736,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-25', connection_id: 'connection-34', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -868,9 +754,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-2823', connection_id: 'connection-2338', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -889,9 +772,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-199', connection_id: 'connection-192', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -910,9 +790,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-283', connection_id: 'connection-211', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -931,9 +808,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-125', connection_id: 'connection-113', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -950,11 +824,6 @@ export default /** @type {const} } */ ({ }, noble: { chainId: 'noble-1', - stakingTokens: [ - { - denom: 'ustake', - }, - ], icqEnabled: false, connections: { 'agoric-3': { @@ -963,9 +832,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-77', connection_id: 'connection-72', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -984,9 +850,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1116', connection_id: 'connection-790', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1005,9 +868,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-0', connection_id: 'connection-0', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1026,9 +886,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-334', connection_id: 'connection-322', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1047,9 +904,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-40', connection_id: 'connection-31', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1068,9 +922,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-51', connection_id: 'connection-49', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1089,9 +940,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-2704', connection_id: 'connection-2241', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1110,9 +958,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-170', connection_id: 'connection-127', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1131,9 +976,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-287', connection_id: 'connection-214', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1152,9 +994,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-248', connection_id: 'connection-210', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1184,9 +1023,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-73', connection_id: 'connection-67', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1205,9 +1041,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-656', connection_id: 'connection-501', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1226,9 +1059,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-68', connection_id: 'connection-65', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1247,9 +1077,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1829', connection_id: 'connection-1431', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1279,9 +1106,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1', connection_id: 'connection-1', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1300,9 +1124,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-10', connection_id: 'connection-2', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1321,9 +1142,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-259', connection_id: 'connection-257', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1342,9 +1160,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-3', connection_id: 'connection-7', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1363,9 +1178,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-0', connection_id: 'connection-0', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1384,9 +1196,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-19', connection_id: 'connection-18', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1405,9 +1214,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-0', connection_id: 'connection-2', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1426,9 +1232,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-8', connection_id: 'connection-8', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1447,9 +1250,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-2', connection_id: 'connection-1', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1468,9 +1268,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-0', connection_id: 'connection-0', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1489,9 +1286,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1', connection_id: 'connection-2', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1510,9 +1304,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-6', connection_id: 'connection-0', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1542,9 +1333,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-17', connection_id: 'connection-17', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1563,9 +1351,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-52', connection_id: 'connection-15', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1584,9 +1369,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-492', connection_id: 'connection-401', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1605,9 +1387,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-108', connection_id: 'connection-68', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1626,9 +1405,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-85', connection_id: 'connection-63', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1647,9 +1423,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-24', connection_id: 'connection-33', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1668,9 +1441,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1588', connection_id: 'connection-1244', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1689,9 +1459,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-177', connection_id: 'connection-110', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1710,9 +1477,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-37', connection_id: 'connection-25', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1731,9 +1495,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-249', connection_id: 'connection-213', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1763,9 +1524,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-86', connection_id: 'connection-56', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1784,9 +1542,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1188', connection_id: 'connection-918', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1805,9 +1560,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-44', connection_id: 'connection-30', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1826,9 +1578,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-31', connection_id: 'connection-23', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1847,9 +1596,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-16', connection_id: 'connection-25', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1868,9 +1614,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1562', connection_id: 'connection-1223', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1889,9 +1632,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-43', connection_id: 'connection-25', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1910,9 +1650,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-30', connection_id: 'connection-18', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1942,9 +1679,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-74', connection_id: 'connection-68', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1963,9 +1697,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-0', connection_id: 'connection-4', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -1984,9 +1715,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-913', connection_id: 'connection-635', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2005,9 +1733,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1', connection_id: 'connection-1', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2026,9 +1751,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-263', connection_id: 'connection-205', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2047,9 +1769,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-18', connection_id: 'connection-15', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2068,9 +1787,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-2119', connection_id: 'connection-1657', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2089,9 +1805,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-75', connection_id: 'connection-40', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2110,9 +1823,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-195', connection_id: 'connection-128', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2131,9 +1841,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-64', connection_id: 'connection-45', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2163,9 +1870,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-18', connection_id: 'connection-18', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2184,9 +1888,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-8', connection_id: 'connection-13', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2205,9 +1906,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-73', connection_id: 'connection-74', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2226,9 +1924,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-1805', connection_id: 'connection-1410', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2247,9 +1942,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-193', connection_id: 'connection-188', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { @@ -2268,9 +1960,6 @@ export default /** @type {const} } */ ({ counterparty: { client_id: '07-tendermint-32', connection_id: 'connection-20', - prefix: { - key_prefix: 'FIXME', - }, }, state: 3, transferChannel: { diff --git a/packages/orchestration/src/fixtures/README.md b/packages/orchestration/src/fixtures/README.md new file mode 100644 index 00000000000..cd45ba85cd9 --- /dev/null +++ b/packages/orchestration/src/fixtures/README.md @@ -0,0 +1,3 @@ +# Fixtures + +This directory contains contracts used for testing. They are NOT representative of patterns we'd like to use in production, and only exist to facilitate testing. diff --git a/packages/orchestration/src/fixtures/query-flows.contract.js b/packages/orchestration/src/fixtures/query-flows.contract.js new file mode 100644 index 00000000000..d8e1c8eb271 --- /dev/null +++ b/packages/orchestration/src/fixtures/query-flows.contract.js @@ -0,0 +1,70 @@ +/** + * @file Testing fixture for Local and Interchain Queries + */ +import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; +import { M } from '@endo/patterns'; +import { withOrchestration } from '../utils/start-helper.js'; +import * as flows from './query-flows.flows.js'; + +/** + * @import {Zone} from '@agoric/zone'; + * @import {OrchestrationPowers} from '..//utils/start-helper.js'; + * @import {OrchestrationTools} from '../utils/start-helper.js'; + */ + +/** + * @param {ZCF} zcf + * @param {OrchestrationPowers & { + * marshaller: Marshaller; + * }} _privateArgs + * @param {Zone} zone + * @param {OrchestrationTools} tools + */ +const contract = async (zcf, _privateArgs, zone, { orchestrateAll }) => { + const orchFns = orchestrateAll(flows, {}); + + const publicFacet = zone.exo( + 'Query Flows Public Facet', + M.interface('Query Flows PF', { + makeSendICQQueryInvitation: M.callWhen().returns(InvitationShape), + makeAccountAndGetBalanceQueryInvitation: + M.callWhen().returns(InvitationShape), + makeAccountAndGetBalancesQueryInvitation: + M.callWhen().returns(InvitationShape), + makeSendLocalQueryInvitation: M.callWhen().returns(InvitationShape), + }), + { + makeSendICQQueryInvitation() { + return zcf.makeInvitation( + orchFns.sendICQQuery, + 'Submit a query to a remote chain', + ); + }, + makeAccountAndGetBalanceQueryInvitation() { + return zcf.makeInvitation( + orchFns.makeAccountAndGetBalanceQuery, + 'Make an account and submit a balance query', + ); + }, + makeAccountAndGetBalancesQueryInvitation() { + return zcf.makeInvitation( + orchFns.makeAccountAndGetBalancesQuery, + 'Make an account and submit a balance query', + ); + }, + makeSendLocalQueryInvitation() { + return zcf.makeInvitation( + orchFns.sendLocalQuery, + 'Submit a query to the local chain', + ); + }, + }, + ); + + return { publicFacet }; +}; + +export const start = withOrchestration(contract); +harden(start); + +/** @typedef {typeof start} QueryFlowsSF */ diff --git a/packages/orchestration/src/fixtures/query-flows.flows.js b/packages/orchestration/src/fixtures/query-flows.flows.js new file mode 100644 index 00000000000..11b47828a93 --- /dev/null +++ b/packages/orchestration/src/fixtures/query-flows.flows.js @@ -0,0 +1,122 @@ +/** + * @file Testing fixture for Local and Interchain Queries + */ +import { makeTracer } from '@agoric/internal'; +import { Fail, q } from '@endo/errors'; +import { M, mustMatch } from '@endo/patterns'; + +const trace = makeTracer('BasicFlows'); + +/** + * @import {Chain, DenomArg, OrchestrationFlow, Orchestrator, ICQQueryFunction, CosmosChainInfo} from '@agoric/orchestration'; + * @import {QueryManyFn} from '@agoric/vats/src/localchain.js'; + */ + +/** + * Send a query to a remote chain and get the response back in an offer result. + * This invitation is for testing only. In a real scenario it's better to use an + * RPC or API client and vstorage to retrieve data for a frontend. Queries + * should only be leveraged if contract logic requires it. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {any} _ctx + * @param {ZCFSeat} seat + * @param {{ chainName: string; msgs: Parameters[0] }} offerArgs + */ +export const sendICQQuery = async (orch, _ctx, seat, { chainName, msgs }) => { + seat.exit(); // no funds exchanged + mustMatch(chainName, M.string()); + if (chainName === 'agoric') throw Fail`ICQ not supported on local chain`; + const remoteChain = + /** @type {Chain} */ ( + await orch.getChain(chainName) + ); + const queryResponse = await remoteChain.query(msgs); + trace('SendICQQuery response:', queryResponse); + // `quote` to ensure offerResult (array) is visible in smart-wallet + return q(queryResponse).toString(); +}; +harden(sendICQQuery); + +/** + * Create an account, send a balance query, and get the response back in an + * offer result. Like `sendQuery`, this invitation is for testing only. In a + * real scenario it doesn't make much sense to send a query immediately after + * the account is created - it won't have any funds. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {any} _ctx + * @param {ZCFSeat} seat + * @param {{ chainName: string; denom: DenomArg }} offerArgs + */ +export const makeAccountAndGetBalanceQuery = async ( + orch, + _ctx, + seat, + { chainName, denom }, +) => { + seat.exit(); // no funds exchanged + mustMatch(chainName, M.string()); + const chain = await orch.getChain(chainName); + const orchAccount = await chain.makeAccount(); + const queryResponse = await orchAccount.getBalance(denom); + trace('Balance Query response:', queryResponse); + // `quote` to ensure offerResult (record) is visible in smart-wallet + return q(queryResponse).toString(); +}; +harden(makeAccountAndGetBalanceQuery); + +/** + * Create an account, send an all balances query, and get the response back in + * an offer result. Like `sendQuery`, this invitation is for testing only. In a + * real scenario it doesn't make much sense to send a query immediately after + * the account is created - it won't have any funds. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {any} _ctx + * @param {ZCFSeat} seat + * @param {{ chainName: string }} offerArgs + */ +export const makeAccountAndGetBalancesQuery = async ( + orch, + _ctx, + seat, + { chainName }, +) => { + seat.exit(); // no funds exchanged + mustMatch(chainName, M.string()); + const chain = await orch.getChain(chainName); + const orchAccount = await chain.makeAccount(); + const queryResponse = await orchAccount.getBalances(); + trace('All Balances Query response:', queryResponse); + // `quote` to ensure offerResult (record) is visible in smart-wallet + return q(queryResponse).toString(); +}; +harden(makeAccountAndGetBalancesQuery); + +/** + * Send a query to the local chain and get the response back in an offer result. + * This invitation is for testing only. In a real scenario it's better to use an + * RPC or API client and vstorage to retrieve data for a frontend. Queries + * should only be leveraged if contract logic requires it. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {any} _ctx + * @param {ZCFSeat} seat + * @param {{ + * msgs: Parameters[0]; + * }} offerArgs + */ +export const sendLocalQuery = async (orch, _ctx, seat, { msgs }) => { + seat.exit(); // no funds exchanged + const remoteChain = await orch.getChain('agoric'); + const queryResponse = await remoteChain.query(msgs); + trace('Local Query response:', queryResponse); + // `quote` to ensure offerResult (array) is visible in smart-wallet + return q(queryResponse).toString(); +}; +harden(sendLocalQuery); diff --git a/packages/orchestration/src/orchestration-api.ts b/packages/orchestration/src/orchestration-api.ts index ee2201f63af..b8ab3c03e6d 100644 --- a/packages/orchestration/src/orchestration-api.ts +++ b/packages/orchestration/src/orchestration-api.ts @@ -7,16 +7,21 @@ import type { Amount, Brand, NatAmount } from '@agoric/ertp/src/types.js'; import type { CurrentWalletRecord } from '@agoric/smart-wallet/src/smartWallet.js'; import type { Timestamp } from '@agoric/time'; -import type { LocalChainAccount } from '@agoric/vats/src/localchain.js'; +import type { + LocalChainAccount, + QueryManyFn, +} from '@agoric/vats/src/localchain.js'; import type { ResolvedPublicTopic } from '@agoric/zoe/src/contractSupport/topics.js'; import type { Passable } from '@endo/marshal'; import type { + AgoricChainMethods, ChainInfo, CosmosChainAccountMethods, CosmosChainInfo, IBCMsgTransferOptions, KnownChains, LocalAccountMethods, + ICQQueryFunction, } from './types.js'; import type { ResolvedContinuingOfferResult } from './utils/zoe-tools.js'; @@ -39,7 +44,7 @@ export type Denom = string; // ibc/... or uist * In many cases, either a denom string or a local Brand can be used to * designate a remote token type. */ -export type DenomArg = Denom | Brand; +export type DenomArg = Denom | Brand<'nat'>; /** * Count of some fungible token on some blockchain. @@ -52,7 +57,7 @@ export type DenomAmount = { }; /** Amounts can be provided as pure data using denoms or as ERTP Amounts */ -export type AmountArg = DenomAmount | Amount; +export type AmountArg = DenomAmount | Amount<'nat'>; /** An address on some blockchain, e.g., cosmos, eth, etc. */ export type ChainAddress = { @@ -63,6 +68,11 @@ export type ChainAddress = { encoding: 'bech32' | 'ethereum'; }; +/** + * Object that controls an account on a particular chain. + * + * The methods available depend on the chain and its capabilities. + */ export type OrchestrationAccount = OrchestrationAccountI & (CI extends CosmosChainInfo ? CI['chainId'] extends `agoric${string}` @@ -87,40 +97,63 @@ export interface Chain { makeAccount: () => Promise>; // FUTURE supply optional port object; also fetch port object + query: CI extends { icqEnabled: true } + ? ICQQueryFunction + : CI['chainId'] extends `agoric${string}` + ? QueryManyFn + : never; + // TODO provide a way to get the local denom/brand/whatever for this chain } +export interface DenomInfo< + HoldingChain extends keyof KnownChains, + IssuingChain extends keyof KnownChains, +> { + /** The well-known Brand on Agoric for the direct asset */ + brand?: Brand; + /** The Chain at which the argument `denom` exists (where the asset is currently held) */ + chain: Chain; + /** The Chain that is the issuer of the underlying asset */ + base: Chain; + /** the Denom for the underlying asset on its issuer chain */ + baseDenom: Denom; +} + /** * Provided in the callback to `orchestrate()`. */ export interface Orchestrator { + /** + * Get a Chain object for working with the given chain. + * + * @param {C} chainName name of the chain in KnownChains or the ChainHub backing the Orchestrator + */ getChain: ( chainName: C, - ) => Promise>; + ) => Promise< + Chain & + (C extends 'agoric' ? AgoricChainMethods : {}) + >; + /** + * Make a new local (Agoric) ChainAccount + */ makeLocalAccount: () => Promise; + /** * For a denom, return information about a denom including the equivalent * local Brand, the Chain on which the denom is held, and the Chain that * issues the corresponding asset. * @param denom */ - getBrandInfo: < + getDenomInfo: < HoldingChain extends keyof KnownChains, IssuingChain extends keyof KnownChains, >( denom: Denom, - ) => { - /** The well-known Brand on Agoric for the direct asset */ - brand?: Brand; - /** The Chain at which the argument `denom` exists (where the asset is currently held) */ - chain: Chain; - /** The Chain that is the issuer of the underlying asset */ - base: Chain; - /** the Denom for the underlying asset on its issuer chain */ - baseDenom: Denom; - }; - // TODO preload the mapping so this can be synchronous + ) => DenomInfo; + /** * Convert an amount described in native data to a local, structured Amount. * @param amount - the described amount @@ -150,7 +183,15 @@ export interface OrchestrationAccountI { * @param amount - the amount to send * @returns void */ - send: (toAccount: ChainAddress, amount: AmountArg) => Promise; + send: (toAccount: ChainAddress, amounts: AmountArg) => Promise; + + /** + * Transfer multiple amounts to another account on the same chain. The promise settles when the transfer is complete. + * @param toAccount - the account to send the amount to. MUST be on the same chain + * @param amounts - the amounts to send + * @returns void + */ + sendAll: (toAccount: ChainAddress, amounts: AmountArg[]) => Promise; /** * Transfer an amount to another account, typically on another chain. @@ -193,6 +234,26 @@ export interface OrchestrationAccountI { getPublicTopics: () => Promise>>; } +/** + * Flows to orchestrate are regular Javascript functions but have some + * constraints to fulfill the requirements of resumability after termination of + * the enclosing vat. Some requirements for each orchestration flow: + * - must not close over any values that could change between invocations + * - must satisfy the `OrchestrationFlow` interface + * - must be hardened + * - must not use `E()` (eventual send) + * + * The call to `orchestrate` using a flow function in reincarnations of the vat + * must have the same `durableName` as before. To help enforce these + * constraints, we recommend: + * + * - keeping flows in a `.flows.js` module + * - importing them all with `import * as flows` to get a single object keyed by + * the export name + * - using `orchestrateAll` to treat each export name as the `durableName` of + * the flow + * - adopting `@agoric/eslint-config` that has rules to help detect problems + */ export interface OrchestrationFlow { (orc: Orchestrator, ctx: CT, ...args: Passable[]): Promise; } @@ -202,18 +263,28 @@ export interface OrchestrationFlow { * The type must be able to express transfers across different chains and transports. * * NOTE Expected to change, so consider an opaque structure. + * @internal */ -export type TransferMsg = { +export interface TransferMsg { toAccount: ChainAddress; timeout?: Timestamp; next?: TransferMsg; data?: object; -}; +} -export type AfterAction = { destChain: string; destAddress: ChainAddress }; -export type SwapExact = { amountIn: Amount; amountOut: Amount }; -export type SwapMaxSlippage = { +/** @alpha */ +export interface AfterAction { + destChain: string; + destAddress: ChainAddress; +} +/** @alpha */ +export interface SwapExact { + amountIn: Amount; + amountOut: Amount; +} +/** @alpha */ +export interface SwapMaxSlippage { amountIn: Amount; brandOut: Brand; slippage: number; -}; +} diff --git a/packages/orchestration/src/proposals/init-chain-info.js b/packages/orchestration/src/proposals/init-chain-info.js new file mode 100644 index 00000000000..d47c074bb3f --- /dev/null +++ b/packages/orchestration/src/proposals/init-chain-info.js @@ -0,0 +1,98 @@ +import { Fail } from '@endo/errors'; +import { E, Far } from '@endo/far'; +import { makeMarshal } from '@endo/marshal'; +import { makeTracer } from '@agoric/internal'; +import { registerKnownChains } from '../chain-info.js'; +import { CHAIN_KEY, CONNECTIONS_KEY } from '../exos/chain-hub.js'; + +const trace = makeTracer('InitChainInfo', true); + +/** + * Similar to publishAgoricNamesToChainStorage but publishes a node per chain + * instead of one list of entries + */ + +/** + * @param {ERef} agoricNamesAdmin + * @param {ERef} chainStorageP + */ +const publishChainInfoToChainStorage = async ( + agoricNamesAdmin, + chainStorageP, +) => { + const chainStorage = await chainStorageP; + if (!chainStorage) { + console.warn('no chain storage, not registering chain info'); + return; + } + + const agoricNamesNode = await E(chainStorage).makeChildNode('agoricNames'); + + /** + * @param {string} subpath + */ + const echoNameUpdates = async subpath => { + const chainNamesNode = E(agoricNamesNode).makeChildNode(subpath); + const { nameAdmin } = await E(agoricNamesAdmin).provideChild(subpath); + + /** + * Previous entries, to prevent redundant updates + * + * @type {Record} chainName => stringified chainInfo + */ + const prev = {}; + + // XXX cannot be changed until we upgrade vat-agoricNames to allow it + await E(nameAdmin).onUpdate( + // XXX will live on the heap in the bootstrap vat. When we upgrade or kill + // that this handler will sever and vat-agoricNames will need to be upgraded + // to allow changing the handler, or to use pubsub mechanics instead. + Far('chain info writer', { + write(entries) { + // chainInfo has no cap data but we need to marshal bigints + const marshalData = makeMarshal(_val => Fail`data only`); + for (const [chainName, info] of entries) { + const value = JSON.stringify(marshalData.toCapData(info)); + if (prev[chainName] === value) { + continue; + } + const chainNode = E(chainNamesNode).makeChildNode(chainName); + prev[chainName] = value; + void E(chainNode) + .setValue(value) + .catch(() => delete prev[chainName]); + } + }, + }), + ); + }; + await echoNameUpdates(CHAIN_KEY); + await echoNameUpdates(CONNECTIONS_KEY); +}; + +/** + * @param {BootstrapPowers} powers + */ +export const initChainInfo = async ({ + consume: { agoricNamesAdmin, chainStorage: chainStorageP }, +}) => { + trace('init-chainInfo'); + + // First set up callback to write updates to vstorage + await publishChainInfoToChainStorage(agoricNamesAdmin, chainStorageP); + + // Now register the names + await registerKnownChains(agoricNamesAdmin, trace); +}; +harden(initChainInfo); + +export const getManifestForChainInfo = () => ({ + manifest: { + [initChainInfo.name]: { + consume: { + agoricNamesAdmin: true, + chainStorage: true, + }, + }, + }, +}); diff --git a/packages/orchestration/src/proposals/orchestration-proposal.js b/packages/orchestration/src/proposals/orchestration-proposal.js index a8a3de2f976..160f284d425 100644 --- a/packages/orchestration/src/proposals/orchestration-proposal.js +++ b/packages/orchestration/src/proposals/orchestration-proposal.js @@ -1,15 +1,10 @@ -import { Fail } from '@endo/errors'; -import { E, Far } from '@endo/far'; -import { makeMarshal } from '@endo/marshal'; import { makeTracer } from '@agoric/internal'; -import { registerKnownChains } from '../chain-info.js'; -import { CHAIN_KEY, CONNECTIONS_KEY } from '../exos/chain-hub.js'; +import { E } from '@endo/far'; const trace = makeTracer('CoreEvalOrchestration', true); /** * @import {PortAllocator} from '@agoric/network'; - * @import {CosmosInterchainService} from '../exos/cosmos-interchain-service.js' */ /** @@ -28,14 +23,16 @@ export const setupOrchestrationVat = async ( consume: { loadCriticalVat, portAllocator: portAllocatorP }, produce: { orchestrationVat, ...produce }, }, - options, + { options }, ) => { - const { orchestrationRef } = options.options; + trace('setupOrchestrationVat', options); + const { orchestrationRef } = options; const vats = { orchestration: E(loadCriticalVat)('orchestration', orchestrationRef), }; // don't proceed if loadCriticalVat fails await Promise.all(Object.values(vats)); + trace('setupOrchestrationVat got vats'); orchestrationVat.reset(); orchestrationVat.resolve(vats.orchestration); @@ -50,87 +47,9 @@ export const setupOrchestrationVat = async ( produce.cosmosInterchainService.reset(); produce.cosmosInterchainService.resolve(cosmosInterchainService); + trace('setupOrchestrationVat complete'); }; -/** - * Similar to publishAgoricNamesToChainStorage but publishes a node per chain - * instead of one list of entries - */ - -/** - * @param {ERef} agoricNamesAdmin - * @param {ERef} chainStorageP - */ -const publishChainInfoToChainStorage = async ( - agoricNamesAdmin, - chainStorageP, -) => { - const chainStorage = await chainStorageP; - if (!chainStorage) { - console.warn('no chain storage, not registering chain info'); - return; - } - - const agoricNamesNode = await E(chainStorage).makeChildNode('agoricNames'); - - /** - * @param {string} subpath - */ - const echoNameUpdates = async subpath => { - const chainNamesNode = E(agoricNamesNode).makeChildNode(subpath); - const { nameAdmin } = await E(agoricNamesAdmin).provideChild(subpath); - - /** - * Previous entries, to prevent redundant updates - * - * @type {Record} chainName => stringified chainInfo - */ - const prev = {}; - - // XXX cannot be changed until we upgrade vat-agoricNames to allow it - await E(nameAdmin).onUpdate( - // XXX will live on the heap in the bootstrap vat. When we upgrade or kill - // that this handler will sever and vat-agoricNames will need to be upgraded - // to allow changing the handler, or to use pubsub mechanics instead. - Far('chain info writer', { - write(entries) { - // chainInfo has no cap data but we need to marshal bigints - const marshalData = makeMarshal(_val => Fail`data only`); - for (const [chainName, info] of entries) { - const value = JSON.stringify(marshalData.toCapData(info)); - if (prev[chainName] === value) { - continue; - } - const chainNode = E(chainNamesNode).makeChildNode(chainName); - prev[chainName] = value; - void E(chainNode) - .setValue(value) - .catch(() => delete prev[chainName]); - } - }, - }), - ); - }; - await echoNameUpdates(CHAIN_KEY); - await echoNameUpdates(CONNECTIONS_KEY); -}; - -/** - * @param {BootstrapPowers} powers - */ -export const initChainInfo = async ({ - consume: { agoricNamesAdmin, chainStorage: chainStorageP }, -}) => { - trace('init-chainInfo'); - - // First set up callback to write updates to vstorage - await publishChainInfoToChainStorage(agoricNamesAdmin, chainStorageP); - - // Now register the names - await registerKnownChains(agoricNamesAdmin, trace); -}; -harden(initChainInfo); - export const getManifestForOrchestration = (_powers, { orchestrationRef }) => ({ manifest: { [setupOrchestrationVat.name]: { @@ -143,12 +62,6 @@ export const getManifestForOrchestration = (_powers, { orchestrationRef }) => ({ orchestrationVat: 'orchestrationVat', }, }, - [initChainInfo.name]: { - consume: { - agoricNamesAdmin: true, - chainStorage: true, - }, - }, }, options: { orchestrationRef, diff --git a/packages/orchestration/src/proposals/start-stakeAtom.js b/packages/orchestration/src/proposals/start-stakeAtom.js index 8035f4fda1c..c759790a8d4 100644 --- a/packages/orchestration/src/proposals/start-stakeAtom.js +++ b/packages/orchestration/src/proposals/start-stakeAtom.js @@ -1,4 +1,4 @@ -import { makeTracer } from '@agoric/internal'; +import { deeplyFulfilledObject, makeTracer } from '@agoric/internal'; import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js'; import { prepareVowTools } from '@agoric/vow'; import { makeHeapZone } from '@agoric/zone'; @@ -7,7 +7,7 @@ import { makeChainHub } from '../exos/chain-hub.js'; /** * @import {IBCConnectionID} from '@agoric/vats'; - * @import {StakeIcaSF, StakeIcaTerms} from '../examples/stakeIca.contract'; + * @import {StakeIcaSF, StakeIcaTerms} from '../examples/stake-ica.contract'; */ const trace = makeTracer('StartStakeAtom', true); @@ -17,7 +17,7 @@ const trace = makeTracer('StartStakeAtom', true); * installation: { * consume: { * stakeIca: Installation< - * import('../examples/stakeIca.contract.js').start + * import('../examples/stake-ica.contract.js').start * >; * }; * }; @@ -28,7 +28,7 @@ export const startStakeAtom = async ({ agoricNames, board, chainStorage, - chainTimerService, + chainTimerService: timer, cosmosInterchainService, startUpgradable, }, @@ -61,15 +61,17 @@ export const startStakeAtom = async ({ chainId: cosmoshub.chainId, hostConnectionId: connectionInfo.counterparty.connection_id, controllerConnectionId: connectionInfo.id, - bondDenom: cosmoshub.stakingTokens[0].denom, icqEnabled: cosmoshub.icqEnabled, }, - privateArgs: { - cosmosInterchainService: await cosmosInterchainService, - storageNode, - marshaller, - timer: await chainTimerService, - }, + privateArgs: await deeplyFulfilledObject( + harden({ + agoricNames, + cosmosInterchainService, + storageNode, + marshaller, + timer, + }), + ), }; const { instance } = await E(startUpgradable)(startOpts); diff --git a/packages/orchestration/src/proposals/start-stakeBld.js b/packages/orchestration/src/proposals/start-stakeBld.js index cb809bc7b7b..b2de1c3f1c4 100644 --- a/packages/orchestration/src/proposals/start-stakeBld.js +++ b/packages/orchestration/src/proposals/start-stakeBld.js @@ -10,7 +10,7 @@ const trace = makeTracer('StartStakeBld', true); * installation: { * consume: { * stakeBld: Installation< - * import('../../src/examples/stakeBld.contract.js').start + * import('../../src/examples/stake-bld.contract.js').start * >; * }; * }; @@ -50,7 +50,7 @@ export const startStakeBld = async ({ /** * @type {StartUpgradableOpts< - * import('../../src/examples/stakeBld.contract.js').start + * import('../../src/examples/stake-bld.contract.js').start * >} */ const startOpts = { diff --git a/packages/orchestration/src/proposals/start-stakeOsmo.js b/packages/orchestration/src/proposals/start-stakeOsmo.js index 6fda8e812de..0f020a62a89 100644 --- a/packages/orchestration/src/proposals/start-stakeOsmo.js +++ b/packages/orchestration/src/proposals/start-stakeOsmo.js @@ -1,4 +1,4 @@ -import { makeTracer } from '@agoric/internal'; +import { deeplyFulfilledObject, makeTracer } from '@agoric/internal'; import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js'; import { prepareVowTools } from '@agoric/vow'; import { makeHeapZone } from '@agoric/zone'; @@ -7,7 +7,7 @@ import { makeChainHub } from '../exos/chain-hub.js'; /** * @import {IBCConnectionID} from '@agoric/vats'; - * @import {StakeIcaSF} from '../examples/stakeIca.contract'; + * @import {StakeIcaSF} from '../examples/stake-ica.contract'; */ const trace = makeTracer('StartStakeOsmo', true); @@ -17,7 +17,7 @@ const trace = makeTracer('StartStakeOsmo', true); * installation: { * consume: { * stakeIca: Installation< - * import('../examples/stakeIca.contract.js').start + * import('../examples/stake-ica.contract.js').start * >; * }; * }; @@ -33,7 +33,7 @@ export const startStakeOsmo = async ({ agoricNames, board, chainStorage, - chainTimerService, + chainTimerService: timer, cosmosInterchainService, startUpgradable, }, @@ -66,15 +66,17 @@ export const startStakeOsmo = async ({ chainId: osmosis.chainId, hostConnectionId: connectionInfo.counterparty.connection_id, controllerConnectionId: connectionInfo.id, - bondDenom: osmosis.stakingTokens[0].denom, icqEnabled: osmosis.icqEnabled, }, - privateArgs: { - cosmosInterchainService: await cosmosInterchainService, - storageNode, - marshaller, - timer: await chainTimerService, - }, + privateArgs: await deeplyFulfilledObject( + harden({ + agoricNames, + cosmosInterchainService, + storageNode, + marshaller, + timer, + }), + ), }; const { instance } = await E(startUpgradable)(startOpts); diff --git a/packages/orchestration/src/typeGuards.js b/packages/orchestration/src/typeGuards.js index 800b2ced1ca..1d9bcbe44dc 100644 --- a/packages/orchestration/src/typeGuards.js +++ b/packages/orchestration/src/typeGuards.js @@ -1,11 +1,13 @@ -import { AmountShape } from '@agoric/ertp'; import { VowShape } from '@agoric/vow'; import { M } from '@endo/patterns'; /** * @import {TypedPattern} from '@agoric/internal'; - * @import {ChainAddress, ChainInfo, CosmosChainInfo, DenomAmount} from './types.js'; + * @import {ChainAddress, CosmosAssetInfo, Chain, ChainInfo, CosmosChainInfo, DenomAmount, DenomDetail, DenomInfo, AmountArg, CosmosValidatorAddress} from './types.js'; + * @import {Any as Proto3Msg} from '@agoric/cosmic-proto/google/protobuf/any.js'; * @import {Delegation} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/staking.js'; + * @import {TxBody} from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js'; + * @import {TypedJson} from '@agoric/cosmic-proto'; */ /** @@ -30,18 +32,13 @@ export const ChainAddressShape = { value: M.string(), }; +/** @type {TypedPattern} */ export const Proto3Shape = { typeUrl: M.string(), value: M.string(), }; -// FIXME missing `delegatorAddress` from the type -/** @type {TypedPattern} */ -export const DelegationShape = harden({ - validatorAddress: M.string(), - shares: M.string(), // TODO: bigint? -}); - +/** @internal */ export const IBCTransferOptionsShape = M.splitRecord( {}, { @@ -54,7 +51,9 @@ export const IBCTransferOptionsShape = M.splitRecord( }, ); +/** @internal */ export const IBCChannelIDShape = M.string(); +/** @internal */ export const IBCChannelInfoShape = M.splitRecord({ portId: M.string(), channelId: IBCChannelIDShape, @@ -64,7 +63,9 @@ export const IBCChannelInfoShape = M.splitRecord({ state: M.scalar(), // XXX version: M.string(), }); +/** @internal */ export const IBCConnectionIDShape = M.string(); +/** @internal */ export const IBCConnectionInfoShape = M.splitRecord({ id: IBCConnectionIDShape, client_id: M.string(), @@ -72,13 +73,21 @@ export const IBCConnectionInfoShape = M.splitRecord({ counterparty: { client_id: M.string(), connection_id: IBCConnectionIDShape, - prefix: { - key_prefix: M.string(), - }, }, transferChannel: IBCChannelInfoShape, }); +/** @type {TypedPattern} */ +export const CosmosAssetInfoShape = M.splitRecord({ + base: M.string(), + name: M.string(), + display: M.string(), + symbol: M.string(), + denom_units: M.arrayOf( + M.splitRecord({ denom: M.string(), exponent: M.number() }), + ), +}); + /** @type {TypedPattern} */ export const CosmosChainInfoShape = M.splitRecord( { @@ -98,16 +107,52 @@ export const ChainInfoShape = M.splitRecord({ }); export const LocalChainAccountShape = M.remotable('LocalChainAccount'); export const DenomShape = M.string(); -// TODO define for #9211 -export const BrandInfoShape = M.any(); + +/** @type {TypedPattern>} */ +export const DenomInfoShape = { + chain: M.remotable('Chain'), + base: M.remotable('Chain'), + brand: M.or(M.remotable('Brand'), M.undefined()), + baseDenom: M.string(), +}; /** @type {TypedPattern} */ export const DenomAmountShape = { denom: DenomShape, value: M.bigint() }; -export const AmountArgShape = M.or(AmountShape, DenomAmountShape); +/** @type {TypedPattern>} */ +export const AnyNatAmountShape = harden({ + brand: M.remotable('Brand'), + value: M.nat(), +}); + +/** @type {TypedPattern} */ +export const AmountArgShape = M.or(AnyNatAmountShape, DenomAmountShape); + +/** + * @type {TypedPattern<{ + * validator: CosmosValidatorAddress; + * amount: AmountArg; + * }>} + */ +export const DelegationShape = M.splitRecord( + { + validator: ChainAddressShape, + amount: AmountArgShape, + }, + { delegator: ChainAddressShape }, +); + +/** Approximately @see RequestQuery */ +export const ICQMsgShape = M.splitRecord( + { path: M.string(), data: M.string() }, + { height: M.string(), prove: M.boolean() }, +); + +/** @type {TypedPattern} */ +export const TypedJsonShape = M.splitRecord({ '@type': M.string() }); /** @see {Chain} */ -export const ChainFacadeI = M.interface('ChainFacade', { +export const chainFacadeMethods = harden({ getChainInfo: M.call().returns(VowShape), makeAccount: M.call().returns(VowShape), }); @@ -115,5 +160,33 @@ export const ChainFacadeI = M.interface('ChainFacade', { /** * for google/protobuf/timestamp.proto, not to be confused with TimestampShape * from `@agoric/time` + * + * `seconds` is a big integer but since it goes through JSON it is encoded as + * string + */ +export const TimestampProtoShape = { seconds: M.string(), nanos: M.number() }; + +/** + * see {@link TxBody} for more details + * + * @internal */ -export const TimestampProtoShape = { seconds: M.nat(), nanos: M.number() }; +export const TxBodyOptsShape = M.splitRecord( + {}, + { + memo: M.string(), + timeoutHeight: M.bigint(), + extensionOptions: M.arrayOf(M.any()), + nonCriticalExtensionOptions: M.arrayOf(M.any()), + }, +); + +/** + * Ensures at least one {@link AmountKeywordRecord} entry is present and only + * permits Nat (fungible) amounts. + */ +export const AnyNatAmountsRecord = M.and( + M.recordOf(M.string(), AnyNatAmountShape), + M.not(harden({})), +); +harden(AnyNatAmountsRecord); diff --git a/packages/orchestration/src/types.ts b/packages/orchestration/src/types.ts index 482820c7a66..a8a0bf4d2b4 100644 --- a/packages/orchestration/src/types.ts +++ b/packages/orchestration/src/types.ts @@ -3,8 +3,11 @@ export type * from './chain-info.js'; export type * from './cosmos-api.js'; export type * from './ethereum-api.js'; -export type * from './exos/chain-account-kit.js'; +export type * from './exos/ica-account-kit.js'; +export type * from './exos/local-chain-facade.js'; export type * from './exos/icq-connection-kit.js'; +export type * from './exos/exo-interfaces.js'; export type * from './orchestration-api.js'; export type * from './exos/cosmos-interchain-service.js'; +export type * from './exos/chain-hub.js'; export type * from './vat-orchestration.js'; diff --git a/packages/orchestration/src/utils/address.js b/packages/orchestration/src/utils/address.js index e8455f3512a..1735040c401 100644 --- a/packages/orchestration/src/utils/address.js +++ b/packages/orchestration/src/utils/address.js @@ -6,16 +6,20 @@ import { Fail } from '@endo/errors'; * @import {RemoteIbcAddress} from '@agoric/vats/tools/ibc-utils.js'; */ +/** + * @typedef {object} ICAChannelAddressOpts + * @property {string} [encoding='proto3'] message encoding format for the + * channel + * @property {'ordered' | 'unordered'} [ordering='ordered'] channel ordering. + * currently only `ordered` is supported for ics27-1 + * @property {string} [txType='sdk_multi_msg'] default is `sdk_multi_msg` + * @property {string} [version='ics27-1'] default is `ics27-1` + */ + /** * @param {IBCConnectionID} hostConnectionId Counterparty Connection ID * @param {IBCConnectionID} controllerConnectionId Self Connection ID - * @param {object} [opts] - * @param {string} [opts.encoding] - message encoding format for the channel. - * default is `proto3` - * @param {'ordered' | 'unordered'} [opts.ordering] - channel ordering. - * currently only `ordered` is supported for ics27-1 - * @param {string} [opts.txType] - default is `sdk_multi_msg` - * @param {string} [opts.version] - default is `ics27-1` + * @param {ICAChannelAddressOpts} [opts] * @returns {RemoteIbcAddress} */ export const makeICAChannelAddress = ( @@ -42,14 +46,16 @@ export const makeICAChannelAddress = ( }; harden(makeICAChannelAddress); +export const DEFAULT_ICQ_VERSION = 'icq-1'; + /** * @param {IBCConnectionID} controllerConnectionId - * @param {{ version?: string }} [opts] + * @param {string} version defaults to icq-1 * @returns {RemoteIbcAddress} */ export const makeICQChannelAddress = ( controllerConnectionId, - { version = 'icq-1' } = {}, + version = DEFAULT_ICQ_VERSION, ) => { controllerConnectionId || Fail`controllerConnectionId is required`; return `/ibc-hop/${controllerConnectionId}/ibc-port/icqhost/unordered/${version}`; @@ -71,7 +77,8 @@ export const findAddressField = remoteAddressString => { // Extract JSON version string assuming it's always surrounded by {} const jsonStr = remoteAddressString?.match(/{.*?}/)?.[0]; const jsonObj = jsonStr ? JSON.parse(jsonStr) : undefined; - return jsonObj?.address ?? undefined; + if (!jsonObj?.address?.length) return undefined; + return jsonObj.address; } catch (error) { return undefined; } diff --git a/packages/orchestration/src/utils/amounts.js b/packages/orchestration/src/utils/amounts.js new file mode 100644 index 00000000000..3974f922e0e --- /dev/null +++ b/packages/orchestration/src/utils/amounts.js @@ -0,0 +1,59 @@ +import { makeError } from '@endo/errors'; + +/** + * @import {ChainHub} from "../types.js"; + * @import {AmountArg, Denom, DenomAmount, DenomArg} from "../orchestration-api.js"; + * @import {Coin} from '@agoric/cosmic-proto/cosmos/base/v1beta1/coin.js'; + */ + +/** + * @param {ChainHub} chainHub + * @param {DenomArg} denomArg + * @returns {Denom} + * @throws {Error} if Brand is provided and ChainHub doesn't contain Brand:Denom + * mapping + */ +export const coerceDenom = (chainHub, denomArg) => { + if (typeof denomArg === 'string') { + return denomArg; + } + const denom = chainHub.getDenom(denomArg); + if (!denom) { + throw makeError(`No denom for brand ${denomArg}`); + } + return denom; +}; + +/** + * @param {ChainHub} chainHub + * @param {DenomAmount | Amount<'nat'>} amount + * @returns {DenomAmount} + * @throws {Error} if ERTP Amount is provided and ChainHub doesn't contain + * Brand:Denom mapping + */ +export const coerceDenomAmount = (chainHub, amount) => { + if ('denom' in amount) { + return amount; + } + const denom = coerceDenom(chainHub, amount.brand); + return harden({ + denom, + value: amount.value, + }); +}; + +/** + * @param {ChainHub} chainHub + * @param {AmountArg} amount + * @returns {Coin} + * @throws {Error} if ERTP Amount is provided and ChainHub doesn't contain + * Brand:Denom mapping + */ +export const coerceCoin = (chainHub, amount) => { + const denom = + 'denom' in amount ? amount.denom : coerceDenom(chainHub, amount.brand); + return harden({ + denom, + amount: String(amount.value), + }); +}; diff --git a/packages/orchestration/src/utils/cosmos.js b/packages/orchestration/src/utils/cosmos.js index 325b3183f01..5082a1c5ed9 100644 --- a/packages/orchestration/src/utils/cosmos.js +++ b/packages/orchestration/src/utils/cosmos.js @@ -1,22 +1,15 @@ import { makeError } from '@endo/errors'; -import { decodeBase64, encodeBase64 } from '@endo/base64'; +import { decodeBase64 } from '@endo/base64'; import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js'; -/** maximum clock skew, in seconds, for unbonding time reported from other chain */ -export const maxClockSkew = 10n * 60n; - /** - * @param {unknown} response - * @param {(msg: any) => Any} toProtoMsg - * @returns {string} + * @import {CosmosDelegationResponse, CosmosValidatorAddress, DenomAmount} from '../types.js'; + * @import {Coin} from '@agoric/cosmic-proto/cosmos/base/v1beta1/coin.js' + * @import {DelegationResponse} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/staking.js'; */ -export const encodeTxResponse = (response, toProtoMsg) => { - const protoMsg = toProtoMsg(response); - const any1 = Any.fromPartial(protoMsg); - const any2 = Any.fromPartial({ value: Any.encode(any1).finish() }); - const ackStr = encodeBase64(Any.encode(any2).finish()); - return ackStr; -}; + +/** maximum clock skew, in seconds, for unbonding time reported from other chain */ +export const maxClockSkew = 10n * 60n; /** * @template T @@ -34,3 +27,56 @@ export const tryDecodeResponse = (ackStr, fromProtoMsg) => { throw makeError(`bad response: ${ackStr}`, undefined, { cause }); } }; + +/** + * Transform a cosmos-sdk {@link Coin} object into a {@link DenomAmount} + * + * @type {(c: { denom: string; amount: string }) => DenomAmount} + * @see {@link toTruncatedDenomAmount} for DecCoin + */ +export const toDenomAmount = c => ({ denom: c.denom, value: BigInt(c.amount) }); + +/** + * Transform a cosmos-sdk {@link DecCoin} object into a {@link DenomAmount}, by + * truncating the fractional portion. + * + * @type {(c: { denom: string; amount: string }) => DenomAmount} + */ +export const toTruncatedDenomAmount = c => ({ + denom: c.denom, + value: BigInt(c.amount.split('.')[0]), +}); + +/** + * Transform a cosmos-sdk `{validatorAddress}` object into an Orchestration + * {@link CosmosValidatorAddress} + * + * @type {( + * r: { validatorAddress: string }, + * chainId: string, + * ) => CosmosValidatorAddress} + */ +export const toCosmosValidatorAddress = (r, chainId) => ({ + encoding: 'bech32', + value: /** @type {CosmosValidatorAddress['value']} */ (r.validatorAddress), + chainId, +}); + +/** + * Transform a cosmos-sdk {@link DelegationResponse} object into an Orchestration + * {@link CosmosDelegationResponse} + * + * @type {( + * chainInfo: { chainId: string }, + * r: DelegationResponse, + * ) => CosmosDelegationResponse} + */ +export const toCosmosDelegationResponse = ({ chainId }, r) => ({ + delegator: { + chainId, + encoding: 'bech32', + value: r.delegation.delegatorAddress, + }, + validator: toCosmosValidatorAddress(r.delegation, chainId), + amount: toDenomAmount(r.balance), +}); diff --git a/packages/orchestration/src/utils/orchestrationAccount.js b/packages/orchestration/src/utils/orchestrationAccount.js index 34fa69de696..242482bce60 100644 --- a/packages/orchestration/src/utils/orchestrationAccount.js +++ b/packages/orchestration/src/utils/orchestrationAccount.js @@ -1,11 +1,13 @@ -import { M } from '@endo/patterns'; +import { BrandShape } from '@agoric/ertp'; import { Shape as NetworkShape } from '@agoric/network'; import { VowShape } from '@agoric/vow'; import { TopicsRecordShape } from '@agoric/zoe/src/contractSupport/topics.js'; +import { M } from '@endo/patterns'; import { AmountArgShape, ChainAddressShape, DenomAmountShape, + IBCTransferOptionsShape, } from '../typeGuards.js'; /** @import {OrchestrationAccountI} from '../orchestration-api.js'; */ @@ -15,11 +17,16 @@ const { Vow$ } = NetworkShape; // TODO #9611 /** @see {OrchestrationAccountI} */ export const orchestrationAccountMethods = { getAddress: M.call().returns(ChainAddressShape), - getBalance: M.call(M.any()).returns(Vow$(DenomAmountShape)), + getBalance: M.call(M.or(BrandShape, M.string())).returns( + Vow$(DenomAmountShape), + ), getBalances: M.call().returns(Vow$(M.arrayOf(DenomAmountShape))), send: M.call(ChainAddressShape, AmountArgShape).returns(VowShape), + sendAll: M.call(ChainAddressShape, M.arrayOf(AmountArgShape)).returns( + VowShape, + ), transfer: M.call(AmountArgShape, ChainAddressShape) - .optional(M.record()) + .optional(IBCTransferOptionsShape) .returns(VowShape), transferSteps: M.call(AmountArgShape, M.any()).returns(VowShape), asContinuingOffer: M.call().returns( diff --git a/packages/orchestration/src/utils/registry.js b/packages/orchestration/src/utils/registry.js index d7c9555e8ce..9156937910c 100644 --- a/packages/orchestration/src/utils/registry.js +++ b/packages/orchestration/src/utils/registry.js @@ -61,9 +61,6 @@ function toConnectionEntry(ibcInfo, name, chainInfo) { counterparty: { client_id: to.client_id, connection_id: /** @type {IBCConnectionID} */ (to.connection_id), - prefix: { - key_prefix: 'FIXME', - }, }, state: IBCConnectionState.STATE_OPEN, // XXX presumably transferChannel: { diff --git a/packages/orchestration/src/utils/start-helper.js b/packages/orchestration/src/utils/start-helper.js index 9f9b9ac417f..e3b2cd7aa9d 100644 --- a/packages/orchestration/src/utils/start-helper.js +++ b/packages/orchestration/src/utils/start-helper.js @@ -1,5 +1,4 @@ import { prepareAsyncFlowTools } from '@agoric/async-flow'; -import { pickFacet } from '@agoric/vat-data'; import { prepareVowTools } from '@agoric/vow'; import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/recorder.js'; import { makeDurableZone } from '@agoric/zone/durable.js'; @@ -7,20 +6,19 @@ import { makeChainHub } from '../exos/chain-hub.js'; import { prepareCosmosOrchestrationAccount } from '../exos/cosmos-orchestration-account.js'; import { prepareLocalChainFacade } from '../exos/local-chain-facade.js'; import { prepareLocalOrchestrationAccountKit } from '../exos/local-orchestration-account.js'; -import { prepareOrchestratorKit } from '../exos/orchestrator.js'; +import { prepareOrchestrator } from '../exos/orchestrator.js'; import { prepareRemoteChainFacade } from '../exos/remote-chain-facade.js'; import { makeOrchestrationFacade } from '../facade.js'; import { makeZoeTools } from './zoe-tools.js'; /** - * @import {PromiseKit} from '@endo/promise-kit' * @import {LocalChain} from '@agoric/vats/src/localchain.js'; * @import {TimerService, TimerBrand} from '@agoric/time'; * @import {Baggage} from '@agoric/vat-data'; * @import {NameHub} from '@agoric/vats'; * @import {Remote} from '@agoric/vow'; * @import {Zone} from '@agoric/zone'; - * @import {CosmosInterchainService} from '../exos/cosmos-interchain-service.js'; + * @import {CosmosInterchainService} from '../exos/exo-interfaces.js'; */ /** @@ -43,6 +41,7 @@ import { makeZoeTools } from './zoe-tools.js'; * @param {Baggage} baggage * @param {OrchestrationPowers} remotePowers * @param {Marshaller} marshaller + * @internal */ export const provideOrchestration = ( zcf, @@ -58,31 +57,37 @@ export const provideOrchestration = ( const zones = (() => { const zone = makeDurableZone(baggage); return { + /** system names for async flow */ asyncFlow: zone.subZone('asyncFlow'), - /** for contract-provided names */ - contract: zone.subZone('contract'), + /** system names for orchestration implementation */ orchestration: zone.subZone('orchestration'), + /** system names for vows */ vows: zone.subZone('vows'), - zoe: zone.subZone('zoe'), + /** contract-provided names, and subzones */ + contract: zone.subZone('contract'), }; })(); - const { agoricNames, timerService } = remotePowers; + const { agoricNames, timerService, localchain } = remotePowers; const vowTools = prepareVowTools(zones.vows); const chainHub = makeChainHub(agoricNames, vowTools); - const zoeTools = makeZoeTools(zones.zoe, { zcf, vowTools }); + const zoeTools = makeZoeTools(zcf, vowTools); const { makeRecorderKit } = prepareRecorderKitMakers(baggage, marshaller); const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit( zones.orchestration, - makeRecorderKit, - zcf, - timerService, - vowTools, - chainHub, + { + makeRecorderKit, + zcf, + timerService, + vowTools, + chainHub, + localchain, + zoeTools, + }, ); const asyncFlowTools = prepareAsyncFlowTools(zones.asyncFlow, { @@ -91,9 +96,13 @@ export const provideOrchestration = ( const makeCosmosOrchestrationAccount = prepareCosmosOrchestrationAccount( zones.orchestration, - makeRecorderKit, - vowTools, - zcf, + { + chainHub, + makeRecorderKit, + timerService, + vowTools, + zcf, + }, ); const makeRemoteChainFacade = prepareRemoteChainFacade(zones.orchestration, { @@ -109,15 +118,19 @@ export const provideOrchestration = ( localchain: remotePowers.localchain, // FIXME what path? storageNode: remotePowers.storageNode, + agoricNames, orchestration: remotePowers.orchestrationService, timer: remotePowers.timerService, vowTools, }); - const makeOrchestratorKit = prepareOrchestratorKit(zones.orchestration, { + const chainByName = zones.orchestration.mapStore('chainName'); + + const makeOrchestrator = prepareOrchestrator(zones.orchestration, { asyncFlowTools, chainHub, localchain: remotePowers.localchain, + chainByName, makeRecorderKit, makeLocalChainFacade, makeRemoteChainFacade, @@ -128,21 +141,35 @@ export const provideOrchestration = ( zcf, }); - const makeOrchestrator = pickFacet(makeOrchestratorKit, 'orchestrator'); - - const facade = makeOrchestrationFacade({ - zcf, - zone: zones.orchestration, - makeRecorderKit, - makeOrchestrator, - asyncFlowTools, - vowTools, - ...remotePowers, - }); + /** + * Create orchestrate functions in a specific zone, instead of the default + * `contract.orchestration` zone. This is used for modules that add their own + * orchestration functions (e.g., a Portfolio with orchestration flows for + * continuing offers) + * + * @param {Zone} zone + */ + const makeOrchestrateKit = zone => + makeOrchestrationFacade({ + zone, + zcf, + makeRecorderKit, + makeOrchestrator, + asyncFlowTools, + vowTools, + ...remotePowers, + }); + + // Create orchestrate functions for the default `contract.orchestration` zone + const defaultOrchestrateKit = makeOrchestrateKit( + zones.contract.subZone('orchestration'), + ); return { - ...facade, + ...defaultOrchestrateKit, + makeOrchestrateKit, chainHub, vowTools, + asyncFlowTools, zoeTools, zone: zones.contract, }; @@ -155,6 +182,13 @@ harden(provideOrchestration); * Simplifies contract functions for Orchestration by wrapping a simpler * function with all the tools it needs in order to use Orchestration. * + * @example + * + * ```js + * const contract = (zcf, privateArgs, zone, tools) => { ... }; + * export const start = withOrchestration(contract); + * ``` + * * @template {Record} CT * @template {OrchestrationPowers & { * marshaller: Marshaller; diff --git a/packages/orchestration/src/utils/time.js b/packages/orchestration/src/utils/time.js index a45848ad1ec..06f995ab06d 100644 --- a/packages/orchestration/src/utils/time.js +++ b/packages/orchestration/src/utils/time.js @@ -17,14 +17,6 @@ export const NANOSECONDS_PER_SECOND = 1_000_000_000n; * @param {Remote} timer */ export function makeTimestampHelper(timer) { - /** @type {TimerBrand | undefined} */ - let brandCache; - const getBrand = async () => { - if (brandCache) return brandCache; - brandCache = await E(timer).getTimerBrand(); - return brandCache; - }; - return harden({ /** * XXX do this need to be resumable / use Vows? @@ -43,7 +35,7 @@ export function makeTimestampHelper(timer) { relativeTime || TimeMath.coerceRelativeTimeRecord( SECONDS_PER_MINUTE * 5n, - await getBrand(), + currentTime.timerBrand, ); return ( TimeMath.addAbsRel(currentTime, timeout).absValue * diff --git a/packages/orchestration/src/utils/zoe-tools.js b/packages/orchestration/src/utils/zoe-tools.js index 32b7632bec0..e81a1136e3c 100644 --- a/packages/orchestration/src/utils/zoe-tools.js +++ b/packages/orchestration/src/utils/zoe-tools.js @@ -1,12 +1,31 @@ -import { Fail } from '@endo/errors'; -import { atomicTransfer } from '@agoric/zoe/src/contractSupport/index.js'; +/** + * @file Helper functions for transferring payments between a LocalChainAccount + * and a ZCFSeat. + * + * Maintainers: This exists as an endowment for orchestrated async-flows so we + * can make use of E and promises. The logic for recovering partial failures + * is also an added convenience for developers. + * + * Functions are written using `asVow` and non-resumable promises as we expect + * each invocation to resolve promptly - there are no timers or interchain + * network calls. + * + * A promise resolved promptly is currently safe from being severed by an + * upgrade because we only trigger vat upgrades as the result of network + * input. + */ + +import { makeError, q, Fail } from '@endo/errors'; +import { depositToSeat } from '@agoric/zoe/src/contractSupport/index.js'; +import { E } from '@endo/far'; + +const { assign, keys, values } = Object; /** + * @import {HostOf} from '@agoric/async-flow'; * @import {InvitationMakers} from '@agoric/smart-wallet/src/types.js'; * @import {ResolvedPublicTopic} from '@agoric/zoe/src/contractSupport/topics.js'; - * @import {Vow, VowTools} from '@agoric/vow'; - * @import {Zone} from '@agoric/zone'; - * @import {OrchestrationAccount} from '../orchestration-api.js' + * @import {VowTools} from '@agoric/vow'; * @import {LocalAccountMethods} from '../types.js'; */ @@ -23,31 +42,38 @@ import { atomicTransfer } from '@agoric/zoe/src/contractSupport/index.js'; * @typedef {( * srcSeat: ZCFSeat, * localAccount: LocalAccountMethods, - * give: AmountKeywordRecord, + * amounts: AmountKeywordRecord, * ) => Promise} LocalTransfer */ /** - * @param {Zone} zone - * @param {{ zcf: ZCF; vowTools: VowTools }} io + * @typedef {( + * localAccount: LocalAccountMethods, + * destSeat: ZCFSeat, + * amounts: AmountKeywordRecord, + * ) => Promise} WithdrawToSeat + */ + +/** + * @param {ZCF} zcf + * @param {VowTools} vowTools */ -export const makeZoeTools = (zone, { zcf, vowTools }) => { +export const makeZoeTools = (zcf, { when, allVows, allSettled, asVow }) => { /** - * Transfer the `give` a seat to a local account. + * Transfer the `amounts` from `srcSeat` to `localAccount`. If any of the + * deposits fail, everything will be rolled back to the `srcSeat`. Supports + * multiple items in the `amounts` {@link AmountKeywordRecord}. + * + * @type {HostOf} */ - const localTransfer = vowTools.retriable( - zone, - 'localTransfer', - /** - * @type {LocalTransfer} - */ - async (srcSeat, localAccount, give) => { + const localTransfer = (srcSeat, localAccount, amounts) => + asVow(async () => { !srcSeat.hasExited() || Fail`The seat cannot have exited.`; const { zcfSeat: tempSeat, userSeat: userSeatP } = zcf.makeEmptySeatKit(); const userSeat = await userSeatP; - atomicTransfer(zcf, srcSeat, tempSeat, give); + zcf.atomicRearrange(harden([[srcSeat, tempSeat, amounts]])); tempSeat.exit(); - // TODO get the userSeat into baggage so it's at least recoverable + // TODO (#9541) get the userSeat into baggage so it's at least recoverable // const userSeat = await subzone.makeOnce( // 'localTransferHelper', // async () => { @@ -55,26 +81,106 @@ export const makeZoeTools = (zone, { zcf, vowTools }) => { // zcf.makeEmptySeatKit(); // const uSeat = await userSeatP; // // TODO how do I store in the place for this retriable? - // atomicTransfer(zcf, srcSeat, tempSeat, give); + // atomicTransfer(zcf, srcSeat, tempSeat, amounts); // tempSeat.exit(); // return uSeat; // }, // ); - // Now all the `give` are accessible, so we can move them to the localAccount` + // Now all the `amounts` are accessible, so we can move them to the localAccount + const payments = await Promise.all( + keys(amounts).map(kw => E(userSeat).getPayout(kw)), + ); + const settleDeposits = await when( + allSettled(payments.map(pmt => E(localAccount).deposit(pmt))), + ); + // if any of the deposits to localAccount failed, unwind all of the allocations + if (settleDeposits.find(x => x.status === 'rejected')) { + const amts = values(amounts); + const errors = []; + // withdraw the successfully deposited payments + const paymentsOrWithdrawVs = settleDeposits.map((x, i) => { + if (x.status === 'rejected') { + errors.push(x.reason); + return payments[i]; + } + return E(localAccount).withdraw(amts[i]); + }); - const promises = Object.entries(give).map(async ([kw, _amount]) => { - const pmt = await userSeat.getPayout(kw); - // TODO arrange recovery on upgrade of pmt? - return localAccount.deposit(pmt); - }); - await Promise.all(promises); - // TODO remove userSeat from baggage - }, - ); + // return all payments to the srcSeat + const paymentsToReturn = await when(allVows(paymentsOrWithdrawVs)); + const paymentKwr = harden( + keys(amounts).reduce( + (kwr, kw, i) => assign(kwr, { [kw]: paymentsToReturn[i] }), + {}, + ), + ); + const depositResponse = await depositToSeat( + zcf, + srcSeat, + amounts, + paymentKwr, + ); + console.debug(depositResponse); + throw makeError(`One or more deposits failed ${q(errors)}`); + } + // TODO #9541 remove userSeat from baggage + }); + + /** + * Transfer the `amounts` from a `localAccount` to the `recipientSeat`. If any + * of the withdrawals fail, everything will be rolled back to the + * `srcLocalAccount`. Supports multiple items in the `amounts` + * {@link PaymentKeywordRecord} + * + * @type {HostOf} + */ + const withdrawToSeat = (localAccount, destSeat, amounts) => + asVow(async () => { + !destSeat.hasExited() || Fail`The seat cannot have exited.`; + + const settledWithdrawals = await when( + allSettled(values(amounts).map(amt => E(localAccount).withdraw(amt))), + ); + + // if any of the withdrawals were rejected, unwind the successful ones + if (settledWithdrawals.find(x => x.status === 'rejected')) { + const returnPaymentVs = []; + const errors = []; + for (const result of settledWithdrawals) { + if (result.status === 'fulfilled') { + returnPaymentVs.push(E(localAccount).deposit(result.value)); + } else { + errors.push(result.reason); + } + } + await when(allVows(returnPaymentVs)); + throw makeError(`One or more withdrawals failed ${q(errors)}`); + } + // successfully withdrew payments from srcLocalAccount, deposit to recipientSeat + const paymentKwr = harden( + keys(amounts).reduce( + (acc, kw, i) => + assign(acc, { + [kw]: /** @type {{ value: Amount }[]} */ (settledWithdrawals)[i] + .value, + }), + {}, + ), + ); + const depositResponse = await depositToSeat( + zcf, + destSeat, + amounts, + paymentKwr, + ); + console.debug(depositResponse); + }); return harden({ localTransfer, + withdrawToSeat, }); }; + /** @typedef {ReturnType} ZoeTools */ diff --git a/packages/orchestration/src/vat-orchestration.js b/packages/orchestration/src/vat-orchestration.js index 357ecb24eb4..016ccfac7b7 100644 --- a/packages/orchestration/src/vat-orchestration.js +++ b/packages/orchestration/src/vat-orchestration.js @@ -3,9 +3,21 @@ import { prepareSwingsetVowTools } from '@agoric/vow/vat.js'; import { makeDurableZone } from '@agoric/zone/durable.js'; import { prepareCosmosInterchainService } from './exos/cosmos-interchain-service.js'; -/** @import {OrchestrationPowers} from './exos/cosmos-interchain-service.js' */ +/** + * @import {Baggage} from '@agoric/vat-data'; + * @import {OrchestrationPowers} from './exos/cosmos-interchain-service.js'; + */ -export const buildRootObject = (_vatPowers, _args, baggage) => { +/** + * Build root object of the Orchestration vat. + * + * @param {VatPowers & { + * D: DProxy; + * }} vatPowers + * @param {never} vatParameters + * @param {Baggage} baggage + */ +export const buildRootObject = (vatPowers, vatParameters, baggage) => { const zone = makeDurableZone(baggage); const vowTools = prepareSwingsetVowTools(zone.subZone('VowTools')); const makeCosmosInterchainService = prepareCosmosInterchainService( diff --git a/packages/orchestration/test/assets.fixture.ts b/packages/orchestration/test/assets.fixture.ts new file mode 100644 index 00000000000..942be150c15 --- /dev/null +++ b/packages/orchestration/test/assets.fixture.ts @@ -0,0 +1,145 @@ +import type { CosmosAssetInfo } from '../src/cosmos-api.js'; + +// https://github.com/cosmos/chain-registry/blob/master/cosmoshub/assetlist.json +export const assets = { + cosmoshub: [ + { + description: + 'ATOM is the native cryptocurrency of the Cosmos network, designed to facilitate interoperability between multiple blockchains through its innovative hub-and-spoke model.', + extended_description: + "ATOM, the native cryptocurrency of the Cosmos network, is essential for achieving the project's goal of creating an 'Internet of Blockchains.' Launched in 2019, Cosmos aims to solve the scalability, usability, and interoperability issues prevalent in existing blockchain ecosystems. The Cosmos Hub, the central blockchain of the network, uses ATOM for transaction fees, staking, and governance. By staking ATOM, users can earn rewards and participate in governance, influencing decisions on network upgrades and changes.\n\nCosmos leverages the Tendermint consensus algorithm to achieve high transaction throughput and fast finality. Its Inter-Blockchain Communication (IBC) protocol enables seamless data and value transfer between different blockchains, fostering a highly interconnected and collaborative ecosystem. The flexibility and scalability offered by Cosmos have attracted numerous projects, enhancing its utility and adoption. ATOM's role in securing the network and facilitating governance underscores its importance in the broader blockchain landscape.", + denom_units: [ + { + denom: 'uatom', + exponent: 0, + }, + { + denom: 'atom', + exponent: 6, + }, + ], + base: 'uatom', + name: 'Cosmos Hub Atom', + display: 'atom', + symbol: 'ATOM', + logo_URIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/cosmoshub/images/atom.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/cosmoshub/images/atom.svg', + }, + coingecko_id: 'cosmos', + images: [ + { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/cosmoshub/images/atom.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/cosmoshub/images/atom.svg', + theme: { + primary_color_hex: '#272d45', + }, + }, + ], + socials: { + website: 'https://cosmos.network', + twitter: 'https://twitter.com/cosmoshub', + }, + }, + { + description: 'Tether USDt on the Cosmos Hub', + denom_units: [ + { + denom: + 'ibc/F04D72CF9B5D9C849BB278B691CDFA2241813327430EC9CDC83F8F4CA4CDC2B0', + exponent: 0, + }, + { + denom: 'usdt', + exponent: 6, + }, + ], + type_asset: 'ics20', + base: 'ibc/F04D72CF9B5D9C849BB278B691CDFA2241813327430EC9CDC83F8F4CA4CDC2B0', + name: 'Tether USDt', + display: 'usdt', + symbol: 'USDt', + traces: [ + { + type: 'ibc', + counterparty: { + chain_name: 'kava', + base_denom: 'erc20/tether/usdt', + channel_id: 'channel-0', + }, + chain: { + channel_id: 'channel-277', + path: 'transfer/channel-277/erc20/tether/usdt', + }, + }, + ], + images: [ + { + image_sync: { + chain_name: 'kava', + base_denom: 'erc20/tether/usdt', + }, + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/_non-cosmos/ethereum/images/usdt.svg', + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/_non-cosmos/ethereum/images/usdt.png', + theme: { + circle: true, + primary_color_hex: '#009393', + background_color_hex: '#009393', + }, + }, + ], + logo_URIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/_non-cosmos/ethereum/images/usdt.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/_non-cosmos/ethereum/images/usdt.svg', + }, + }, + { + description: 'FX on Cosmos Hub', + denom_units: [ + { + denom: + 'ibc/4925E6ABA571A44D2BE0286D2D29AF42A294D0FF2BB16490149A1B26EAD33729', + exponent: 0, + aliases: ['FX'], + }, + ], + type_asset: 'ics20', + base: 'ibc/4925E6ABA571A44D2BE0286D2D29AF42A294D0FF2BB16490149A1B26EAD33729', + name: 'Function X', + display: 'FX', + symbol: 'FX', + traces: [ + { + type: 'ibc', + counterparty: { + chain_name: 'fxcore', + base_denom: 'FX', + channel_id: 'channel-10', + }, + chain: { + channel_id: 'channel-585', + path: 'transfer/channel-585/FX', + }, + }, + ], + images: [ + { + image_sync: { + chain_name: 'fxcore', + base_denom: 'FX', + }, + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/fxcore/images/fx.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/fxcore/images/fx.svg', + theme: { + primary_color_hex: '#1c1c1c', + }, + }, + ], + logo_URIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/fxcore/images/fx.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/fxcore/images/fx.svg', + }, + }, + ] as CosmosAssetInfo[], +}; +harden(assets); diff --git a/packages/orchestration/test/chain-info.test.js b/packages/orchestration/test/chain-info.test.js index 1c1a80c1fe0..e6700ba9982 100644 --- a/packages/orchestration/test/chain-info.test.js +++ b/packages/orchestration/test/chain-info.test.js @@ -15,7 +15,6 @@ test('chain-info', async t => { }); t.deepEqual(chainNames.keys(), [ 'agoric', - 'agoriclocal', 'celestia', 'cosmoshub', 'dydx', diff --git a/packages/orchestration/test/cosmos-interchain-service.test.ts b/packages/orchestration/test/cosmos-interchain-service.test.ts new file mode 100644 index 00000000000..7e71a39aa17 --- /dev/null +++ b/packages/orchestration/test/cosmos-interchain-service.test.ts @@ -0,0 +1,404 @@ +import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; +import { toRequestQueryJson } from '@agoric/cosmic-proto'; +import { + QueryBalanceRequest, + QueryBalanceResponse, +} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; +import { + MsgDelegate, + MsgDelegateResponse, +} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; +import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js'; +import { matches } from '@endo/patterns'; +import { heapVowE as E } from '@agoric/vow/vat.js'; +import { decodeBase64 } from '@endo/base64'; +import type { LocalIbcAddress } from '@agoric/vats/tools/ibc-utils.js'; +import { getMethodNames } from '@agoric/internal'; +import type { Port } from '@agoric/network'; +import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; +import type { IBCMethod } from '@agoric/vats'; +import { commonSetup } from './supports.js'; +import { ChainAddressShape } from '../src/typeGuards.js'; +import { tryDecodeResponse } from '../src/utils/cosmos.js'; +import { buildChannelCloseConfirmEvent } from '../tools/ibc-mocks.js'; + +const CHAIN_ID = 'cosmoshub-99'; +const HOST_CONNECTION_ID = 'connection-0'; +const CONTROLLER_CONNECTION_ID = 'connection-1'; + +test.serial('makeICQConnection returns an ICQConnection', async t => { + const { + bootstrap: { cosmosInterchainService }, + } = await commonSetup(t); + + const icqConnection = await E(cosmosInterchainService).provideICQConnection( + CONTROLLER_CONNECTION_ID, + ); + const [localAddr, remoteAddr] = await Promise.all([ + E(icqConnection).getLocalAddress(), + E(icqConnection).getRemoteAddress(), + ]); + t.log(icqConnection, { + localAddr, + remoteAddr, + }); + t.regex(localAddr, /ibc-port\/icqcontroller-\d+/); + t.regex( + remoteAddr, + new RegExp(`/ibc-hop/${CONTROLLER_CONNECTION_ID}`), + 'remote address contains provided connectionId', + ); + t.regex( + remoteAddr, + /icqhost\/unordered\/icq-1/, + 'remote address contains icqhost port, unordered ordering, and icq-1 version string', + ); + + const icqConnection2 = await E(cosmosInterchainService).provideICQConnection( + CONTROLLER_CONNECTION_ID, + ); + const localAddr2 = await E(icqConnection2).getLocalAddress(); + t.is(localAddr, localAddr2, 'provideICQConnection is idempotent'); + + const [result] = await E(icqConnection).query([ + toRequestQueryJson( + QueryBalanceRequest.toProtoMsg({ + address: 'cosmos1test', + denom: 'uatom', + }), + ), + ]); + + t.like(QueryBalanceResponse.decode(decodeBase64(result.key)), { + balance: { amount: '0', denom: 'uatom' }, + }); + + const icqConnection3 = await E(cosmosInterchainService).provideICQConnection( + CONTROLLER_CONNECTION_ID, + 'icq-2', + ); + const localAddr3 = await E(icqConnection3).getLocalAddress(); + t.not( + localAddr3, + localAddr2, + 'non default version results in a new connection', + ); + + const icqConnection4 = await E(cosmosInterchainService).provideICQConnection( + CONTROLLER_CONNECTION_ID, + 'icq-2', + ); + const localAddr4 = await E(icqConnection4).getLocalAddress(); + t.is(localAddr3, localAddr4, 'custom version is idempotent'); + + const icqConnection5 = await E(cosmosInterchainService).provideICQConnection( + 'connection-99', + ); + const localAddr5 = await E(icqConnection5).getLocalAddress(); + + const getPortId = (lAddr: LocalIbcAddress) => lAddr.split('/')[2]; + const uniquePortIds = new Set( + [localAddr, localAddr2, localAddr3, localAddr4, localAddr5].map(getPortId), + ); + t.regex([...uniquePortIds][0], /icqcontroller-\d+/); + t.is(uniquePortIds.size, 1, 'all connections share same port'); + + await t.throwsAsync( + // @ts-expect-error icqConnectionKit doesn't have a port method + () => E(icqConnection).getPort(), + undefined, + 'ICQConnection Kit does not expose its port', + ); +}); + +test.serial('makeAccount returns an IcaAccountKit', async t => { + const { + bootstrap: { cosmosInterchainService }, + } = await commonSetup(t); + + const account = await E(cosmosInterchainService).makeAccount( + CHAIN_ID, + HOST_CONNECTION_ID, + CONTROLLER_CONNECTION_ID, + ); + const [localAddr, remoteAddr, chainAddr, port] = await Promise.all([ + E(account).getLocalAddress(), + E(account).getRemoteAddress(), + E(account).getAddress(), + E(account).getPort(), + ]); + t.log(account, { + localAddr, + remoteAddr, + chainAddr, + }); + t.regex(localAddr, /ibc-port\/icacontroller-\d+/); + t.regex( + remoteAddr, + new RegExp(`/ibc-hop/${CONTROLLER_CONNECTION_ID}`), + 'remote address contains provided connectionId', + ); + t.regex( + remoteAddr, + /icahost\/ordered/, + 'remote address contains icahost port, ordered ordering', + ); + t.regex( + remoteAddr, + /"version":"ics27-1"(.*)"encoding":"proto3"/, + 'remote address contains version and encoding in version string', + ); + t.deepEqual( + getMethodNames(port), + [ + '__getInterfaceGuard__', + '__getMethodNames__', + 'addListener', + 'connect', + 'getLocalAddress', + 'removeListener', + 'revoke', + ], + 'IcaAccountKit returns a Port remotable', + ); + + t.true(matches(chainAddr, ChainAddressShape)); + t.regex(chainAddr.value, /cosmos1test/); + + const delegateMsg = Any.toJSON( + MsgDelegate.toProtoMsg({ + delegatorAddress: 'cosmos1test', + validatorAddress: 'cosmosvaloper1test', + amount: { denom: 'uatom', amount: '10' }, + }), + ); + + const delegateResp = await E(account).executeEncodedTx([delegateMsg]); + t.deepEqual( + tryDecodeResponse(delegateResp, MsgDelegateResponse.fromProtoMsg), + {}, + ); + + await t.throwsAsync( + E(account).reactivate(), + { + message: 'Account is already active.', + }, + 'reactivate() throws if account is active', + ); + + await E(account).deactivate(); + await t.throwsAsync( + E(account).executeEncodedTx([delegateMsg]), + { + message: 'Account not available or deactivated.', + }, + 'cannot execute transaction if account is deactivated', + ); + await t.throwsAsync( + E(account).deactivate(), + { + message: 'Account not available or deactivated.', + }, + 'deactivate() throws if account is deactivated', + ); +}); + +test.serial( + 'makeAccount accepts opts (version, ordering, encoding)', + async t => { + const { + bootstrap: { cosmosInterchainService }, + } = await commonSetup(t); + + const account = await E(cosmosInterchainService).makeAccount( + CHAIN_ID, + HOST_CONNECTION_ID, + CONTROLLER_CONNECTION_ID, + { version: 'ics27-2', ordering: 'unordered', encoding: 'json' }, + ); + const [localAddr, remoteAddr] = await Promise.all([ + E(account).getLocalAddress(), + E(account).getRemoteAddress(), + ]); + t.log({ + localAddr, + remoteAddr, + }); + for (const addr of [localAddr, remoteAddr]) { + t.regex(addr, /unordered/, 'remote address contains unordered ordering'); + t.regex( + addr, + /"version":"ics27-2"(.*)"encoding":"json"/, + 'remote address contains version and encoding in version string', + ); + } + }, +); + +test.serial( + 'account automatically reactivates when channel closure is not user-initiated', + async t => { + const { + bootstrap: { cosmosInterchainService }, + mocks: { ibcBridge }, + utils: { inspectDibcBridge }, + } = await commonSetup(t); + + await E(cosmosInterchainService).makeAccount( + CHAIN_ID, + HOST_CONNECTION_ID, + CONTROLLER_CONNECTION_ID, + { version: 'ics27-2', ordering: 'unordered', encoding: 'json' }, + ); + + const { bridgeEvents: bridgeEvents0, bridgeDowncalls: bridgeDowncalls0 } = + await inspectDibcBridge(); + + t.is( + bridgeEvents0[0].event, + 'channelOpenAck', + 'bridged received channelOpenAck event', + ); + t.is(bridgeEvents0.length, 1, 'bridge received 1 event'); + + t.is( + bridgeDowncalls0[0].method, + 'bindPort', + 'bridge received bindPort downcall', + ); + t.is( + bridgeDowncalls0[1].method, + 'startChannelOpenInit', + 'bridge received startChannelOpenInit downcall', + ); + t.is(bridgeDowncalls0.length, 2, 'bridge received 2 downcalls'); + + // get channelInfo from `channelOpenAck` event + const { event, ...channelInfo } = bridgeEvents0[0]; + // simulate channel closing from remote chain + await E(ibcBridge).fromBridge(buildChannelCloseConfirmEvent(channelInfo)); + await eventLoopIteration(); + + const { bridgeEvents: bridgeEvents1, bridgeDowncalls: bridgeDowncalls1 } = + await inspectDibcBridge(); + t.log('auto reactivate bridgeEvents', bridgeEvents1); + t.log('auto reactivate bridgeDowncalls', bridgeDowncalls1); + t.is( + bridgeEvents1.filter(x => x.event === 'channelCloseConfirm').length, + 1, + 'bridged received 1 channelCloseConfirm event', + ); + t.is( + bridgeEvents1[bridgeEvents1.length - 1].event, + 'channelOpenAck', + 'onClose handler automatically reactivates the channel', + ); + t.is( + bridgeEvents1.filter(x => x.event === 'channelOpenAck').length, + 2, + 'channelOpenAck only fires once during automatic reactivate', + ); + t.is(bridgeEvents1.length, 3, 'all bridge events accounted for'); + t.is( + bridgeDowncalls1.filter(x => x.method === 'startChannelOpenInit').length, + 2, + "startChannelOpenInit fires one add'l time during automatic reactivate", + ); + t.falsy( + bridgeDowncalls1.find(x => x.method === 'startChannelCloseInit'), + 'should not send startChannelCloseInit downcall to bridge', + ); + }, +); + +test.serial( + 'reactivate an account (closed channel) after choosing to deactivate()', + async t => { + const { + bootstrap: { cosmosInterchainService }, + utils: { inspectDibcBridge }, + } = await commonSetup(t); + + const account = await E(cosmosInterchainService).makeAccount( + CHAIN_ID, + HOST_CONNECTION_ID, + CONTROLLER_CONNECTION_ID, + ); + + const [chainAddress0, remoteAddress0, localAddress0] = await Promise.all([ + E(account).getAddress(), + E(account).getRemoteAddress(), + E(account).getLocalAddress(), + ]); + + await eventLoopIteration(); // ensure there's an account to close + // deactivate the account + await E(account).deactivate(); + + await eventLoopIteration(); + const { bridgeDowncalls: bridgeDowncalls0 } = await inspectDibcBridge(); + t.is( + bridgeDowncalls0?.[2]?.method, + 'startChannelCloseInit', + 'bridge received startChannelCloseInit downcall', + ); + + // reactivate the account + await E(account).reactivate(); + await eventLoopIteration(); + + const { bridgeDowncalls, bridgeEvents } = await inspectDibcBridge(); + t.log('user initiated deactivate bridgeDowncalls', bridgeDowncalls); + t.log('user initiated deactivate bridgeEvents', bridgeEvents); + t.is( + bridgeDowncalls?.[3]?.method, + 'startChannelOpenInit', + 'bridge received startChannelOpenInit to re-establish the channel', + ); + t.is( + bridgeDowncalls.filter(x => x.method === 'startChannelOpenInit').length, + 2, + 'only sent 2 startChannelOpenInit downcalls to bridge', + ); + + const getPortAndConnectionIDs = ( + obj: IBCMethod<'startChannelOpenInit'>, + ) => { + const { hops, packet } = obj; + const { source_port: sourcePort } = packet; + return { hops, sourcePort }; + }; + + t.deepEqual( + getPortAndConnectionIDs( + bridgeDowncalls[3] as IBCMethod<'startChannelOpenInit'>, + ), + getPortAndConnectionIDs( + bridgeDowncalls[1] as IBCMethod<'startChannelOpenInit'>, + ), + 'same port and connection id are used to re-stablish the channel', + ); + + const [chainAddress, remoteAddress, localAddress] = await Promise.all([ + E(account).getAddress(), + E(account).getRemoteAddress(), + E(account).getLocalAddress(), + ]); + + t.deepEqual(chainAddress, chainAddress0, 'chain address is unchanged'); + t.notDeepEqual( + remoteAddress, + remoteAddress0, + 'remote ibc address is changed', + ); + t.notDeepEqual(localAddress, localAddress0, 'local ibc address is changed'); + const getChannelID = (lAddr: LocalIbcAddress) => + lAddr.split('/ibc-channel/')[1]; + t.not( + getChannelID(localAddress), + getChannelID(localAddress0), + 'channel id is changed', + ); + }, +); diff --git a/packages/orchestration/test/examples/auto-stake-it.contract.test.ts b/packages/orchestration/test/examples/auto-stake-it.contract.test.ts index 261fb9605fb..53b184ccc37 100644 --- a/packages/orchestration/test/examples/auto-stake-it.contract.test.ts +++ b/packages/orchestration/test/examples/auto-stake-it.contract.test.ts @@ -19,13 +19,13 @@ const contractFile = `${dirname}/../../src/examples/${contractName}.contract.js` type StartFn = typeof import('../../src/examples/auto-stake-it.contract.js').start; -test('auto-stake-it - make accounts, register tap, return invitationMakers', async t => { +test('make accounts, register tap, return invitationMakers', async t => { t.log('bootstrap, orchestration core-eval'); const { bootstrap: { storage }, commonPrivateArgs, mocks: { transferBridge }, - utils: { inspectLocalBridge, inspectDibcBridge }, + utils: { inspectLocalBridge, inspectDibcBridge, transmitTransferAck }, } = await commonSetup(t); const { zoe, bundleAndInstall } = await setUpZoeForTest(); @@ -51,8 +51,6 @@ test('auto-stake-it - make accounts, register tap, return invitationMakers', asy value: 'cosmosvaloper1test', encoding: 'bech32', }, - // TODO user supplied until #9211 - localDenom: 'ibc/fakeuatomhash', }); const result = await heapVowE(userSeat).getOfferResult(); @@ -114,11 +112,14 @@ test('auto-stake-it - make accounts, register tap, return invitationMakers', asy receiver: 'cosmos1test', sender: execAddr, sourceChannel: 'channel-5', - token: { amount: '10', denom: 'ibc/fakeuatomhash' }, + token: { + amount: '10', + }, }, 'tokens transferred from LOA to COA', ); - const { acknowledgement } = (await inspectDibcBridge()).at( + await transmitTransferAck(); + const { acknowledgement } = (await inspectDibcBridge()).bridgeEvents.at( -1, ) as IBCEvent<'acknowledgementPacket'>; // XXX consider checking ICA (dest|source)_channel, to verify the sender of @@ -138,8 +139,6 @@ test('auto-stake-it - make accounts, register tap, return invitationMakers', asy value: 'cosmosvaloper1test', encoding: 'bech32', }, - // TODO user supplied until #9211 - localDenom: 'ibc/fakeuatomhash', }); const { publicSubscribers: pubSubs2 } = await heapVowE(userSeat2).getOfferResult(); diff --git a/packages/orchestration/test/examples/bad.flows.js b/packages/orchestration/test/examples/bad.flows.js index 5a095b57101..837c27fbe9d 100644 --- a/packages/orchestration/test/examples/bad.flows.js +++ b/packages/orchestration/test/examples/bad.flows.js @@ -5,21 +5,29 @@ */ // TODO error on exports that: -// - aren't hardened (probably a new rule in @endo/eslint-plugin ) // - don't satisfy orchestration flow type // eslint-disable-next-line no-restricted-syntax -- intentional for test import { E } from '@endo/far'; -export function notFlow() { - console.log('This function is not a flow'); +// eslint-disable-next-line @endo/harden-exports -- intentional for test +export function unhardenable() { + console.log('hardening on function keyword is not safe due to hoisting'); } +harden(unhardenable); + +export const notFlow = () => { + console.log('This function is not a flow'); +}; +harden(notFlow); +// eslint-disable-next-line @endo/harden-exports -- intentional for test export async function notHardened() { console.log('This function is the most minimal flow, but it’s not hardened'); } -export async function usesE(orch, { someEref }) { +export const usesE = async (orch, { someEref }) => { // eslint-disable-next-line no-restricted-syntax -- intentional for test await E(someEref).foo(); -} +}; +harden(usesE); diff --git a/packages/orchestration/test/examples/basic-flows.contract.test.ts b/packages/orchestration/test/examples/basic-flows.contract.test.ts index a7b975c1cd1..ef8aea70719 100644 --- a/packages/orchestration/test/examples/basic-flows.contract.test.ts +++ b/packages/orchestration/test/examples/basic-flows.contract.test.ts @@ -4,6 +4,11 @@ import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; import type { Instance } from '@agoric/zoe/src/zoeService/utils.js'; import { E, getInterfaceOf } from '@endo/far'; import path from 'path'; +import { makeIssuerKit } from '@agoric/ertp'; +import { + type AmountUtils, + withAmountUtils, +} from '@agoric/zoe/tools/test-utils.js'; import { commonSetup } from '../supports.js'; const dirname = path.dirname(new URL(import.meta.url).pathname); @@ -16,17 +21,23 @@ type StartFn = type TestContext = Awaited> & { zoe: ZoeService; instance: Instance; + brands: Awaited>['brands'] & { + moolah: AmountUtils; + }; }; const test = anyTest as TestFn; -test.before(async t => { +test.beforeEach(async t => { const setupContext = await commonSetup(t); const { + brands: { bld, ist }, bootstrap: { storage }, commonPrivateArgs, } = setupContext; + const moolah = withAmountUtils(makeIssuerKit('MOO')); + const { zoe, bundleAndInstall } = await setUpZoeForTest(); t.log('contract coreEval', contractName); @@ -35,7 +46,7 @@ test.before(async t => { const storageNode = await E(storage.rootNode).makeChildNode(contractName); const { instance } = await E(zoe).startInstance( installation, - undefined, + { Stable: ist.issuer, Stake: bld.issuer, Moo: moolah.issuer }, {}, { ...commonPrivateArgs, storageNode }, ); @@ -44,12 +55,14 @@ test.before(async t => { ...setupContext, zoe, instance, + brands: { ...setupContext.brands, moolah }, }; }); const chainConfigs = { - agoric: { addressPrefix: 'agoric1fakeLCAAddress' }, - cosmoshub: { addressPrefix: 'cosmos1test' }, + agoric: { expectedAddress: 'agoric1fakeLCAAddress' }, + cosmoshub: { expectedAddress: 'cosmos1test' }, + osmosis: { expectedAddress: 'osmo1test' }, }; const orchestrationAccountScenario = test.macro({ @@ -78,7 +91,7 @@ const orchestrationAccountScenario = test.macro({ const { description, storagePath, subscriber } = publicSubscribers.account; t.regex(description!, /Account holder/); - const expectedStoragePath = `mockChainStorageRoot.basic-flows.${config.addressPrefix}`; + const expectedStoragePath = `mockChainStorageRoot.basic-flows.${config.expectedAddress}`; t.is(storagePath, expectedStoragePath); t.regex(getInterfaceOf(subscriber)!, /Durable Publish Kit subscriber/); @@ -87,3 +100,137 @@ const orchestrationAccountScenario = test.macro({ test(orchestrationAccountScenario, 'agoric'); test(orchestrationAccountScenario, 'cosmoshub'); + +test('Deposit, Withdraw - LocalOrchAccount', async t => { + const { + brands: { bld, ist }, + bootstrap: { vowTools: vt }, + zoe, + instance, + utils: { inspectBankBridge, pourPayment }, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(instance); + const inv = E(publicFacet).makeOrchAccountInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { chainName: 'agoric' }); + const { invitationMakers } = await vt.when(E(userSeat).getOfferResult()); + + const twentyIST = ist.make(20n); + const tenBLD = bld.make(10n); + const Stable = await pourPayment(twentyIST); + const Stake = await pourPayment(tenBLD); + + const depositInv = await E(invitationMakers).Deposit(); + + const depositSeat = E(zoe).offer( + depositInv, + { + give: { Stable: twentyIST, Stake: tenBLD }, + want: {}, + }, + { Stable, Stake }, + ); + const depositRes = await vt.when(E(depositSeat).getOfferResult()); + t.is(depositRes, undefined, 'undefined on success'); + + t.deepEqual( + inspectBankBridge().slice(-2), + [ + { + type: 'VBANK_GIVE', + recipient: 'agoric1fakeLCAAddress', + denom: 'uist', + amount: '20', + }, + { + type: 'VBANK_GIVE', + recipient: 'agoric1fakeLCAAddress', + denom: 'ubld', + amount: '10', + }, + ], + 'funds deposited to LCA', + ); + + const depositPayouts = await E(depositSeat).getPayouts(); + t.is((await ist.issuer.getAmountOf(depositPayouts.Stable)).value, 0n); + t.is((await bld.issuer.getAmountOf(depositPayouts.Stake)).value, 0n); + + // withdraw the payments we just deposited + const withdrawInv = await E(invitationMakers).Withdraw(); + const withdrawSeat = E(zoe).offer(withdrawInv, { + give: {}, + want: { Stable: twentyIST, Stake: tenBLD }, + }); + const withdrawRes = await vt.when(E(withdrawSeat).getOfferResult()); + t.is(withdrawRes, undefined, 'undefined on success'); + + const withdrawPayouts = await E(withdrawSeat).getPayouts(); + t.deepEqual(await ist.issuer.getAmountOf(withdrawPayouts.Stable), twentyIST); + t.deepEqual(await bld.issuer.getAmountOf(withdrawPayouts.Stake), tenBLD); +}); + +test('Deposit, Withdraw errors - LocalOrchAccount', async t => { + const { + brands: { ist, moolah }, + bootstrap: { vowTools: vt }, + zoe, + instance, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(instance); + const inv = E(publicFacet).makeOrchAccountInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { chainName: 'agoric' }); + const { invitationMakers } = await vt.when(E(userSeat).getOfferResult()); + + // deposit non-vbank asset (not supported) + const tenMoolah = moolah.make(10n); + const Moo = await E(moolah.mint).mintPayment(tenMoolah); + const depositInv = await E(invitationMakers).Deposit(); + const depositSeat = E(zoe).offer( + depositInv, + { + give: { Moo: tenMoolah }, + want: {}, + }, + { Moo }, + ); + await t.throwsAsync(vt.when(E(depositSeat).getOfferResult()), { + message: + 'One or more deposits failed ["[Error: key \\"[Alleged: MOO brand]\\" not found in collection \\"brandToAssetRecord\\"]"]', + }); + const depositPayouts = await E(depositSeat).getPayouts(); + t.deepEqual( + await moolah.issuer.getAmountOf(depositPayouts.Moo), + tenMoolah, + 'deposit returned on failure', + ); + + { + // withdraw more than balance (insufficient funds) + const tenIST = ist.make(10n); + const withdrawInv = await E(invitationMakers).Withdraw(); + const withdrawSeat = E(zoe).offer(withdrawInv, { + give: {}, + want: { Stable: tenIST }, + }); + await t.throwsAsync(vt.when(E(withdrawSeat).getOfferResult()), { + message: + 'One or more withdrawals failed ["[RangeError: -10 is negative]"]', + }); + const payouts = await E(withdrawSeat).getPayouts(); + t.deepEqual((await ist.issuer.getAmountOf(payouts.Stable)).value, 0n); + } + { + // withdraw non-vbank asset + const withdrawInv = await E(invitationMakers).Withdraw(); + const withdrawSeat = E(zoe).offer(withdrawInv, { + give: {}, + want: { Moo: tenMoolah }, + }); + await t.throwsAsync(vt.when(E(withdrawSeat).getOfferResult()), { + message: + 'One or more withdrawals failed ["[Error: key \\"[Alleged: MOO brand]\\" not found in collection \\"brandToAssetRecord\\"]"]', + }); + const payouts = await E(withdrawSeat).getPayouts(); + t.deepEqual((await moolah.issuer.getAmountOf(payouts.Moo)).value, 0n); + } +}); diff --git a/packages/orchestration/test/examples/sendAnywhere.test.ts b/packages/orchestration/test/examples/send-anywhere.test.ts similarity index 50% rename from packages/orchestration/test/examples/sendAnywhere.test.ts rename to packages/orchestration/test/examples/send-anywhere.test.ts index 1bcf4fd2771..aa42e2a6b7e 100644 --- a/packages/orchestration/test/examples/sendAnywhere.test.ts +++ b/packages/orchestration/test/examples/send-anywhere.test.ts @@ -4,19 +4,24 @@ import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; import { E } from '@endo/far'; import path from 'path'; import { mustMatch } from '@endo/patterns'; -import { makeIssuerKit } from '@agoric/ertp'; -import { inspectMapStore } from '@agoric/internal/src/testing-utils.js'; +import { AmountMath, makeIssuerKit } from '@agoric/ertp'; +import { + eventLoopIteration, + inspectMapStore, +} from '@agoric/internal/src/testing-utils.js'; +import { SIMULATED_ERRORS } from '@agoric/vats/tools/fake-bridge.js'; +import { withAmountUtils } from '@agoric/zoe/tools/test-utils.js'; import { CosmosChainInfo, IBCConnectionInfo } from '../../src/cosmos-api.js'; import { commonSetup } from '../supports.js'; -import { SingleAmountRecord } from '../../src/examples/sendAnywhere.contract.js'; +import { SingleNatAmountRecord } from '../../src/examples/send-anywhere.contract.js'; import { registerChain } from '../../src/chain-info.js'; const dirname = path.dirname(new URL(import.meta.url).pathname); const contractName = 'sendAnywhere'; -const contractFile = `${dirname}/../../src/examples/${contractName}.contract.js`; +const contractFile = `${dirname}/../../src/examples/send-anywhere.contract.js`; type StartFn = - typeof import('../../src/examples/sendAnywhere.contract.js').start; + typeof import('../../src/examples/send-anywhere.contract.js').start; const chainInfoDefaults = { connections: {}, @@ -43,10 +48,10 @@ test('single amount proposal shape (keyword record)', async t => { ], }); for (const give of cases.good) { - t.notThrows(() => mustMatch(give, SingleAmountRecord)); + t.notThrows(() => mustMatch(give, SingleNatAmountRecord)); } for (const { give, msg } of cases.bad) { - t.throws(() => mustMatch(give, SingleAmountRecord), { + t.throws(() => mustMatch(give, SingleNatAmountRecord), { message: msg, }); } @@ -58,7 +63,7 @@ test('send using arbitrary chain info', async t => { bootstrap, commonPrivateArgs, brands: { ist }, - utils: { inspectLocalBridge, pourPayment }, + utils: { inspectLocalBridge, pourPayment, transmitTransferAck }, } = await commonSetup(t); const vt = bootstrap.vowTools; @@ -92,9 +97,6 @@ test('send using arbitrary chain info', async t => { counterparty: { client_id: '07-tendermint-2109', connection_id: 'connection-1649', - prefix: { - key_prefix: 'aWJj', - }, }, transferChannel: { counterPartyChannelId: 'channel-1', @@ -103,7 +105,7 @@ test('send using arbitrary chain info', async t => { }, } as IBCConnectionInfo; const chainName = 'hot'; - await E(sendKit.creatorFacet).initChain( + await E(sendKit.creatorFacet).registerChain( chainName, hotChainInfo, agoricToHotConnection, @@ -124,6 +126,7 @@ test('send using arbitrary chain info', async t => { { Send }, { destAddr: 'hot1destAddr', chainName }, ); + await transmitTransferAck(); await vt.when(E(userSeat).getOfferResult()); const history = inspectLocalBridge(); @@ -157,6 +160,7 @@ test('send using arbitrary chain info', async t => { { Send }, { destAddr: 'cosmos1destAddr', chainName: 'cosmoshub' }, ); + await transmitTransferAck(); await vt.when(E(userSeat).getOfferResult()); const history = inspectLocalBridge(); const { messages, address: execAddr } = history.at(-1); @@ -203,6 +207,7 @@ test('send using arbitrary chain info', async t => { { Send }, { destAddr: 'hot1destAddr', chainName: 'hot' }, ); + await transmitTransferAck(); await vt.when(E(userSeat).getOfferResult()); const history = inspectLocalBridge(); const { messages, address: execAddr } = history.at(-1); @@ -221,10 +226,8 @@ test('send using arbitrary chain info', async t => { test('baggage', async t => { const { - bootstrap, commonPrivateArgs, brands: { ist }, - utils: { inspectLocalBridge, pourPayment }, } = await commonSetup(t); let contractBaggage; @@ -245,3 +248,189 @@ test('baggage', async t => { const tree = inspectMapStore(contractBaggage); t.snapshot(tree, 'contract baggage after start'); }); + +test('failed ibc transfer returns give', async t => { + t.log('bootstrap, orchestration core-eval'); + const { + bootstrap, + commonPrivateArgs, + brands: { ist }, + utils: { inspectLocalBridge, pourPayment, inspectBankBridge }, + } = await commonSetup(t); + const vt = bootstrap.vowTools; + + const { zoe, bundleAndInstall } = await setUpZoeForTest(); + + t.log('contract coreEval', contractName); + + const installation: Installation = + await bundleAndInstall(contractFile); + + const storageNode = await E(bootstrap.storage.rootNode).makeChildNode( + contractName, + ); + const sendKit = await E(zoe).startInstance( + installation, + { Stable: ist.issuer }, + {}, + { ...commonPrivateArgs, storageNode }, + ); + + t.log('client sends an ibc transfer we expect will timeout'); + + const publicFacet = await E(zoe).getPublicFacet(sendKit.instance); + const inv = E(publicFacet).makeSendInvitation(); + const amt = await E(zoe).getInvitationDetails(inv); + t.is(amt.description, 'send'); + + const anAmt = ist.make(SIMULATED_ERRORS.TIMEOUT); + const Send = await pourPayment(anAmt); + const userSeat = await E(zoe).offer( + inv, + { give: { Send: anAmt } }, + { Send }, + { destAddr: 'cosmos1destAddr', chainName: 'cosmoshub' }, + ); + + await eventLoopIteration(); + await E(userSeat).hasExited(); + const payouts = await E(userSeat).getPayouts(); + t.log('Failed offer payouts', payouts); + const amountReturned = await ist.issuer.getAmountOf(payouts.Send); + t.log('Failed offer Send amount', amountReturned); + t.deepEqual(anAmt, amountReturned, 'give is returned'); + + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: + 'IBC Transfer failed "[Error: simulated unexpected MsgTransfer packet timeout]"', + }); + + t.log('ibc MsgTransfer was attempted from a local chain account'); + const history = inspectLocalBridge(); + t.like(history, [ + { type: 'VLOCALCHAIN_ALLOCATE_ADDRESS' }, + { type: 'VLOCALCHAIN_EXECUTE_TX' }, + ]); + const [_alloc, { messages, address: execAddr }] = history; + t.is(messages.length, 1); + const [txfr] = messages; + t.log('local bridge', txfr); + t.like(txfr, { + '@type': '/ibc.applications.transfer.v1.MsgTransfer', + sender: execAddr, + sourcePort: 'transfer', + token: { amount: '504', denom: 'uist' }, + }); + + t.log('deposit to and withdrawal from LCA is observed in bank bridge'); + const bankHistory = inspectBankBridge(); + t.log('bank bridge', bankHistory); + t.deepEqual( + bankHistory[bankHistory.length - 2], + { + type: 'VBANK_GIVE', + recipient: 'agoric1fakeLCAAddress', + denom: 'uist', + amount: '504', + }, + 'funds sent to LCA', + ); + t.deepEqual( + bankHistory[bankHistory.length - 1], + { + type: 'VBANK_GRAB', + sender: 'agoric1fakeLCAAddress', + denom: 'uist', + amount: '504', + }, + 'funds withdrawn from LCA in catch block', + ); +}); + +test('non-vbank asset presented is returned', async t => { + t.log('bootstrap, orchestration core-eval'); + const { bootstrap, commonPrivateArgs } = await commonSetup(t); + const vt = bootstrap.vowTools; + + const { zoe, bundleAndInstall } = await setUpZoeForTest(); + + const moolah = withAmountUtils(makeIssuerKit('MOO')); + + const installation: Installation = + await bundleAndInstall(contractFile); + const storageNode = await E(bootstrap.storage.rootNode).makeChildNode( + contractName, + ); + const sendKit = await E(zoe).startInstance( + installation, + { MOO: moolah.issuer }, + {}, + { ...commonPrivateArgs, storageNode }, + ); + + const publicFacet = await E(zoe).getPublicFacet(sendKit.instance); + const inv = E(publicFacet).makeSendInvitation(); + + const anAmt = moolah.make(10n); + const Moo = moolah.mint.mintPayment(anAmt); + const userSeat = await E(zoe).offer( + inv, + { give: { Moo: anAmt } }, + { Moo }, + { destAddr: 'cosmos1destAddr', chainName: 'cosmoshub' }, + ); + + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: + '[object Alleged: MOO brand guest wrapper] not registered in vbank', + }); + + await E(userSeat).tryExit(); + const payouts = await E(userSeat).getPayouts(); + const amountReturned = await moolah.issuer.getAmountOf(payouts.Moo); + t.deepEqual(anAmt, amountReturned, 'give is returned'); +}); + +test('rejects multi-asset send', async t => { + t.log('bootstrap, orchestration core-eval'); + const { + bootstrap, + commonPrivateArgs, + brands: { ist, bld }, + utils: { pourPayment }, + } = await commonSetup(t); + const vt = bootstrap.vowTools; + + const { zoe, bundleAndInstall } = await setUpZoeForTest(); + + const installation: Installation = + await bundleAndInstall(contractFile); + const storageNode = await E(bootstrap.storage.rootNode).makeChildNode( + contractName, + ); + const sendKit = await E(zoe).startInstance( + installation, + { BLD: bld.issuer, IST: ist.issuer }, + {}, + { ...commonPrivateArgs, storageNode }, + ); + + const publicFacet = await E(zoe).getPublicFacet(sendKit.instance); + const inv = E(publicFacet).makeSendInvitation(); + + const tenBLD = bld.make(10n); + const tenIST = ist.make(10n); + + await t.throwsAsync( + E(zoe).offer( + inv, + { give: { BLD: tenBLD, IST: tenIST } }, + { BLD: await pourPayment(tenBLD), IST: await pourPayment(tenIST) }, + { destAddr: 'cosmos1destAddr', chainName: 'cosmoshub' }, + ), + { + message: + '"send" proposal: give: Must not have more than 1 properties: {"BLD":{"brand":"[Alleged: BLD brand]","value":"[10n]"},"IST":{"brand":"[Alleged: IST brand]","value":"[10n]"}}', + }, + ); +}); diff --git a/packages/orchestration/test/examples/snapshots/sendAnywhere.test.ts.md b/packages/orchestration/test/examples/snapshots/send-anywhere.test.ts.md similarity index 59% rename from packages/orchestration/test/examples/snapshots/sendAnywhere.test.ts.md rename to packages/orchestration/test/examples/snapshots/send-anywhere.test.ts.md index 95beb6676c2..11710ddf60d 100644 --- a/packages/orchestration/test/examples/snapshots/sendAnywhere.test.ts.md +++ b/packages/orchestration/test/examples/snapshots/send-anywhere.test.ts.md @@ -1,6 +1,6 @@ -# Snapshot report for `test/examples/sendAnywhere.test.ts` +# Snapshot report for `test/examples/send-anywhere.test.ts` -The actual snapshot is saved in `sendAnywhere.test.ts.snap`. +The actual snapshot is saved in `send-anywhere.test.ts.snap`. Generated by [AVA](https://avajs.dev). @@ -29,6 +29,23 @@ Generated by [AVA](https://avajs.dev). 'ChainHub Admin_singleton': 'Alleged: ChainHub Admin', 'Send PF_kindHandle': 'Alleged: kind', 'Send PF_singleton': 'Alleged: Send PF', + orchestration: { + sendIt: { + asyncFlow_kindHandle: 'Alleged: kind', + endowments: { + 0: { + contractState_kindHandle: 'Alleged: kind', + contractState_singleton: 'Alleged: contractState', + zoeTools: { + localTransfer_kindHandle: 'Alleged: kind', + localTransfer_singleton: 'Alleged: localTransfer', + withdrawToSeat_kindHandle: 'Alleged: kind', + withdrawToSeat_singleton: 'Alleged: withdrawToSeat', + }, + }, + }, + }, + }, }, orchestration: { 'Cosmos Orchestration Account Holder_kindHandle': 'Alleged: kind', @@ -36,18 +53,14 @@ Generated by [AVA](https://avajs.dev). LocalChainFacade_kindHandle: 'Alleged: kind', Orchestrator_kindHandle: 'Alleged: kind', RemoteChainFacade_kindHandle: 'Alleged: kind', - sendIt: { - asyncFlow_kindHandle: 'Alleged: kind', - endowments: { - 1: { - contractState_kindHandle: 'Alleged: kind', - contractState_singleton: 'Alleged: contractState', - findBrandInVBank_kindHandle: 'Alleged: kind', - findBrandInVBank_singleton: 'Alleged: findBrandInVBank', - localTransfer_kindHandle: 'Alleged: kind', - localTransfer_singleton: 'Alleged: localTransfer', - }, - }, + chainName: {}, + ibcTools: { + IBCTransferSenderKit_kindHandle: 'Alleged: kind', + ibcResultWatcher_kindHandle: 'Alleged: kind', + ibcResultWatcher_singleton: 'Alleged: ibcResultWatcher', + }, + packetTools: { + PacketToolsKit_kindHandle: 'Alleged: kind', }, }, vows: { @@ -55,5 +68,4 @@ Generated by [AVA](https://avajs.dev). VowInternalsKit_kindHandle: 'Alleged: kind', WatchUtils_kindHandle: 'Alleged: kind', }, - zoe: {}, } diff --git a/packages/orchestration/test/examples/snapshots/send-anywhere.test.ts.snap b/packages/orchestration/test/examples/snapshots/send-anywhere.test.ts.snap new file mode 100644 index 00000000000..bbf9e53542d Binary files /dev/null and b/packages/orchestration/test/examples/snapshots/send-anywhere.test.ts.snap differ diff --git a/packages/orchestration/test/examples/snapshots/sendAnywhere.test.ts.snap b/packages/orchestration/test/examples/snapshots/sendAnywhere.test.ts.snap deleted file mode 100644 index 785dda987fc..00000000000 Binary files a/packages/orchestration/test/examples/snapshots/sendAnywhere.test.ts.snap and /dev/null differ diff --git a/packages/orchestration/test/examples/snapshots/stake-ica.contract.test.ts.md b/packages/orchestration/test/examples/snapshots/stake-ica.contract.test.ts.md index e82b5bc1faa..e878c3d19ff 100644 --- a/packages/orchestration/test/examples/snapshots/stake-ica.contract.test.ts.md +++ b/packages/orchestration/test/examples/snapshots/stake-ica.contract.test.ts.md @@ -4,21 +4,21 @@ The actual snapshot is saved in `stake-ica.contract.test.ts.snap`. Generated by [AVA](https://avajs.dev). -## makeAccount, getAddress, getBalances, getBalance +## makeAccount, getAddress > accounts in vstorage Object @Map Iterator { [ 'mockChainStorageRoot.stakeAtom.accounts.cosmos1test', - '{"body":"#\\"\\"","slots":[]}', + '{"body":"#{\\"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-0\\",\\"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-0\\"}","slots":[]}', ], [ 'mockChainStorageRoot.stakeAtom.accounts.cosmos1test1', - '{"body":"#\\"\\"","slots":[]}', + '{"body":"#{\\"localAddress\\":\\"/ibc-port/icacontroller-2/ordered/{\\\\\\"version\\\\\\":\\\\\\"ics27-1\\\\\\",\\\\\\"controllerConnectionId\\\\\\":\\\\\\"connection-8\\\\\\",\\\\\\"hostConnectionId\\\\\\":\\\\\\"connection-649\\\\\\",\\\\\\"address\\\\\\":\\\\\\"cosmos1test1\\\\\\",\\\\\\"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\\\\\\":\\\\\\"cosmos1test1\\\\\\",\\\\\\"encoding\\\\\\":\\\\\\"proto3\\\\\\",\\\\\\"txType\\\\\\":\\\\\\"sdk_multi_msg\\\\\\"}/ibc-channel/channel-1\\"}","slots":[]}', ], [ 'mockChainStorageRoot.stakeOsmo.accounts.osmo1test2', - '{"body":"#\\"\\"","slots":[]}', + '{"body":"#{\\"localAddress\\":\\"/ibc-port/icacontroller-3/ordered/{\\\\\\"version\\\\\\":\\\\\\"ics27-1\\\\\\",\\\\\\"controllerConnectionId\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"hostConnectionId\\\\\\":\\\\\\"connection-1649\\\\\\",\\\\\\"address\\\\\\":\\\\\\"osmo1test2\\\\\\",\\\\\\"encoding\\\\\\":\\\\\\"proto3\\\\\\",\\\\\\"txType\\\\\\":\\\\\\"sdk_multi_msg\\\\\\"}/ibc-channel/channel-2\\",\\"remoteAddress\\":\\"/ibc-hop/connection-1/ibc-port/icahost/ordered/{\\\\\\"version\\\\\\":\\\\\\"ics27-1\\\\\\",\\\\\\"controllerConnectionId\\\\\\":\\\\\\"connection-1\\\\\\",\\\\\\"hostConnectionId\\\\\\":\\\\\\"connection-1649\\\\\\",\\\\\\"address\\\\\\":\\\\\\"osmo1test2\\\\\\",\\\\\\"encoding\\\\\\":\\\\\\"proto3\\\\\\",\\\\\\"txType\\\\\\":\\\\\\"sdk_multi_msg\\\\\\"}/ibc-channel/channel-0\\"}","slots":[]}', ], } diff --git a/packages/orchestration/test/examples/snapshots/stake-ica.contract.test.ts.snap b/packages/orchestration/test/examples/snapshots/stake-ica.contract.test.ts.snap index 5571fd10de5..171d95509f7 100644 Binary files a/packages/orchestration/test/examples/snapshots/stake-ica.contract.test.ts.snap and b/packages/orchestration/test/examples/snapshots/stake-ica.contract.test.ts.snap differ diff --git a/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.md b/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.md new file mode 100644 index 00000000000..926a50924a3 --- /dev/null +++ b/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.md @@ -0,0 +1,142 @@ +# Snapshot report for `test/examples/staking-combinations.test.ts` + +The actual snapshot is saved in `staking-combinations.test.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## start + +> contract baggage after start + + { + 'Durable Publish Kit_kindHandle': 'Alleged: kind', + Recorder_kindHandle: 'Alleged: kind', + asyncFlow: { + AdminAsyncFlow_kindHandle: 'Alleged: kind', + AdminAsyncFlow_singleton: 'Alleged: AdminAsyncFlow', + Bijection_kindHandle: 'Alleged: kind', + FunctionUnwrapper_kindHandle: 'Alleged: kind', + FunctionUnwrapper_singleton: 'Alleged: FunctionUnwrapper', + LogStore_kindHandle: 'Alleged: kind', + StateUnwrapper_kindHandle: 'Alleged: kind', + asyncFuncEagerWakers: [], + asyncFuncFailures: {}, + flowForOutcomeVow: {}, + unwrapMap: 'Alleged: weakMapStore', + }, + contract: { + 'ChainHub Admin_kindHandle': 'Alleged: kind', + 'ChainHub Admin_singleton': 'Alleged: ChainHub Admin', + CombinedInvitationMakers_kindHandle: 'Alleged: kind', + StakingCombinationsInvitationMakers_kindHandle: 'Alleged: kind', + orchestration: { + depositAndDelegate: { + asyncFlow_kindHandle: 'Alleged: kind', + endowments: { + 0: { + contractState_kindHandle: 'Alleged: kind', + contractState_singleton: 'Alleged: contractState', + flows: { + depositAndDelegate_kindHandle: 'Alleged: kind', + depositAndDelegate_singleton: 'Alleged: depositAndDelegate', + makeAccount_kindHandle: 'Alleged: kind', + makeAccount_singleton: 'Alleged: makeAccount', + undelegateAndTransfer_kindHandle: 'Alleged: kind', + undelegateAndTransfer_singleton: 'Alleged: undelegateAndTransfer', + }, + makeCombineInvitationMakers_kindHandle: 'Alleged: kind', + makeCombineInvitationMakers_singleton: 'Alleged: makeCombineInvitationMakers', + makeExtraInvitationMaker_kindHandle: 'Alleged: kind', + makeExtraInvitationMaker_singleton: 'Alleged: makeExtraInvitationMaker', + zoeTools: { + localTransfer_kindHandle: 'Alleged: kind', + localTransfer_singleton: 'Alleged: localTransfer', + withdrawToSeat_kindHandle: 'Alleged: kind', + withdrawToSeat_singleton: 'Alleged: withdrawToSeat', + }, + }, + }, + }, + makeAccount: { + asyncFlow_kindHandle: 'Alleged: kind', + endowments: { + 0: { + contractState_kindHandle: 'Alleged: kind', + contractState_singleton: 'Alleged: contractState', + flows: { + depositAndDelegate_kindHandle: 'Alleged: kind', + depositAndDelegate_singleton: 'Alleged: depositAndDelegate', + makeAccount_kindHandle: 'Alleged: kind', + makeAccount_singleton: 'Alleged: makeAccount', + undelegateAndTransfer_kindHandle: 'Alleged: kind', + undelegateAndTransfer_singleton: 'Alleged: undelegateAndTransfer', + }, + makeCombineInvitationMakers_kindHandle: 'Alleged: kind', + makeCombineInvitationMakers_singleton: 'Alleged: makeCombineInvitationMakers', + makeExtraInvitationMaker_kindHandle: 'Alleged: kind', + makeExtraInvitationMaker_singleton: 'Alleged: makeExtraInvitationMaker', + zoeTools: { + localTransfer_kindHandle: 'Alleged: kind', + localTransfer_singleton: 'Alleged: localTransfer', + withdrawToSeat_kindHandle: 'Alleged: kind', + withdrawToSeat_singleton: 'Alleged: withdrawToSeat', + }, + }, + }, + }, + undelegateAndTransfer: { + asyncFlow_kindHandle: 'Alleged: kind', + endowments: { + 0: { + contractState_kindHandle: 'Alleged: kind', + contractState_singleton: 'Alleged: contractState', + flows: { + depositAndDelegate_kindHandle: 'Alleged: kind', + depositAndDelegate_singleton: 'Alleged: depositAndDelegate', + makeAccount_kindHandle: 'Alleged: kind', + makeAccount_singleton: 'Alleged: makeAccount', + undelegateAndTransfer_kindHandle: 'Alleged: kind', + undelegateAndTransfer_singleton: 'Alleged: undelegateAndTransfer', + }, + makeCombineInvitationMakers_kindHandle: 'Alleged: kind', + makeCombineInvitationMakers_singleton: 'Alleged: makeCombineInvitationMakers', + makeExtraInvitationMaker_kindHandle: 'Alleged: kind', + makeExtraInvitationMaker_singleton: 'Alleged: makeExtraInvitationMaker', + zoeTools: { + localTransfer_kindHandle: 'Alleged: kind', + localTransfer_singleton: 'Alleged: localTransfer', + withdrawToSeat_kindHandle: 'Alleged: kind', + withdrawToSeat_singleton: 'Alleged: withdrawToSeat', + }, + }, + }, + }, + }, + publicFacet_kindHandle: 'Alleged: kind', + publicFacet_singleton: 'Alleged: publicFacet', + }, + orchestration: { + 'Cosmos Orchestration Account Holder_kindHandle': 'Alleged: kind', + 'Local Orchestration Account Kit_kindHandle': 'Alleged: kind', + LocalChainFacade_kindHandle: 'Alleged: kind', + Orchestrator_kindHandle: 'Alleged: kind', + RemoteChainFacade_kindHandle: 'Alleged: kind', + chainName: { + agoric: 'Alleged: LocalChainFacade public', + cosmoshub: 'Alleged: RemoteChainFacade public', + }, + ibcTools: { + IBCTransferSenderKit_kindHandle: 'Alleged: kind', + ibcResultWatcher_kindHandle: 'Alleged: kind', + ibcResultWatcher_singleton: 'Alleged: ibcResultWatcher', + }, + packetTools: { + PacketToolsKit_kindHandle: 'Alleged: kind', + }, + }, + vows: { + PromiseWatcher_kindHandle: 'Alleged: kind', + VowInternalsKit_kindHandle: 'Alleged: kind', + WatchUtils_kindHandle: 'Alleged: kind', + }, + } diff --git a/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.snap b/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.snap new file mode 100644 index 00000000000..7a30cfbebf4 Binary files /dev/null and b/packages/orchestration/test/examples/snapshots/staking-combinations.test.ts.snap differ diff --git a/packages/orchestration/test/examples/snapshots/unbondExample.test.ts.md b/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.md similarity index 66% rename from packages/orchestration/test/examples/snapshots/unbondExample.test.ts.md rename to packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.md index 9c684aaa5e0..1a7163c5994 100644 --- a/packages/orchestration/test/examples/snapshots/unbondExample.test.ts.md +++ b/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.md @@ -1,6 +1,6 @@ -# Snapshot report for `test/examples/unbondExample.test.ts` +# Snapshot report for `test/examples/unbond.contract.test.ts` -The actual snapshot is saved in `unbondExample.test.ts.snap`. +The actual snapshot is saved in `unbond.contract.test.ts.snap`. Generated by [AVA](https://avajs.dev). @@ -25,23 +25,36 @@ Generated by [AVA](https://avajs.dev). unwrapMap: 'Alleged: weakMapStore', }, contract: { + orchestration: { + unbondAndTransfer: { + asyncFlow_kindHandle: 'Alleged: kind', + }, + }, publicFacet_kindHandle: 'Alleged: kind', publicFacet_singleton: 'Alleged: publicFacet', }, orchestration: { 'Cosmos Orchestration Account Holder_kindHandle': 'Alleged: kind', - LSTTia: { - asyncFlow_kindHandle: 'Alleged: kind', - }, 'Local Orchestration Account Kit_kindHandle': 'Alleged: kind', LocalChainFacade_kindHandle: 'Alleged: kind', Orchestrator_kindHandle: 'Alleged: kind', RemoteChainFacade_kindHandle: 'Alleged: kind', + chainName: { + osmosis: 'Alleged: RemoteChainFacade public', + stride: 'Alleged: RemoteChainFacade public', + }, + ibcTools: { + IBCTransferSenderKit_kindHandle: 'Alleged: kind', + ibcResultWatcher_kindHandle: 'Alleged: kind', + ibcResultWatcher_singleton: 'Alleged: ibcResultWatcher', + }, + packetTools: { + PacketToolsKit_kindHandle: 'Alleged: kind', + }, }, vows: { PromiseWatcher_kindHandle: 'Alleged: kind', VowInternalsKit_kindHandle: 'Alleged: kind', WatchUtils_kindHandle: 'Alleged: kind', }, - zoe: {}, } diff --git a/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.snap b/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.snap new file mode 100644 index 00000000000..fbf713b1764 Binary files /dev/null and b/packages/orchestration/test/examples/snapshots/unbond.contract.test.ts.snap differ diff --git a/packages/orchestration/test/examples/snapshots/unbondExample.test.ts.snap b/packages/orchestration/test/examples/snapshots/unbondExample.test.ts.snap deleted file mode 100644 index 90dff347a73..00000000000 Binary files a/packages/orchestration/test/examples/snapshots/unbondExample.test.ts.snap and /dev/null differ diff --git a/packages/orchestration/test/examples/stake-bld.contract.test.ts b/packages/orchestration/test/examples/stake-bld.contract.test.ts index 09300cb8775..556e4da7d56 100644 --- a/packages/orchestration/test/examples/stake-bld.contract.test.ts +++ b/packages/orchestration/test/examples/stake-bld.contract.test.ts @@ -2,6 +2,7 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import { AmountMath } from '@agoric/ertp'; import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; +import { SIMULATED_ERRORS } from '@agoric/vats/tools/fake-bridge.js'; import { heapVowE as E } from '@agoric/vow/vat.js'; import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; import path from 'path'; @@ -9,9 +10,9 @@ import { commonSetup } from '../supports.js'; const dirname = path.dirname(new URL(import.meta.url).pathname); -const contractFile = `${dirname}/../../src/examples/stakeBld.contract.js`; +const contractFile = `${dirname}/../../src/examples/stake-bld.contract.js`; type StartFn = - typeof import('@agoric/orchestration/src/examples/stakeBld.contract.js').start; + typeof import('@agoric/orchestration/src/examples/stake-bld.contract.js').start; const startContract = async ({ agoricNames, @@ -56,8 +57,11 @@ test('makeAccount, deposit, withdraw', async t => { const depositResp = await E(account).deposit( await utils.pourPayment(bld.units(100)), ); - // FIXME #9211 - // t.deepEqual(await E(account).getBalance('ubld'), bld.units(100)); + t.deepEqual(await E(account).getBalance('ubld'), { + denom: 'ubld', + value: bld.units(100).value, + }); + // XXX races in the bridge await eventLoopIteration(); @@ -117,7 +121,7 @@ test('makeStakeBldInvitation', async t => { 'agoric1validator1', { brand: bld.brand, - value: 504n, + value: SIMULATED_ERRORS.TIMEOUT, }, ); const delegateOffer = await E(zoe).offer(delegateInv); diff --git a/packages/orchestration/test/examples/stake-ica.contract.test.ts b/packages/orchestration/test/examples/stake-ica.contract.test.ts index b7cb9f09bbd..e6d00da45e9 100644 --- a/packages/orchestration/test/examples/stake-ica.contract.test.ts +++ b/packages/orchestration/test/examples/stake-ica.contract.test.ts @@ -10,26 +10,23 @@ import { QueryBalanceResponse, } from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; import { commonSetup } from '../supports.js'; -import { type StakeIcaTerms } from '../../src/examples/stakeIca.contract.js'; +import { type StakeIcaTerms } from '../../src/examples/stake-ica.contract.js'; import fetchedChainInfo from '../../src/fetched-chain-info.js'; import { buildQueryPacketString, buildQueryResponseString, } from '../../tools/ibc-mocks.js'; import type { CosmosChainInfo } from '../../src/cosmos-api.js'; -import { - AmountArg, - ChainAddress, - DenomAmount, -} from '../../src/orchestration-api.js'; +import { DenomAmount } from '../../src/orchestration-api.js'; import { maxClockSkew } from '../../src/utils/cosmos.js'; import { UNBOND_PERIOD_SECONDS } from '../ibc-mocks.js'; +import { makeChainHub } from '../../src/exos/chain-hub.js'; const dirname = path.dirname(new URL(import.meta.url).pathname); -const contractFile = `${dirname}/../../src/examples/stakeIca.contract.js`; +const contractFile = `${dirname}/../../src/examples/stake-ica.contract.js`; type StartFn = - typeof import('@agoric/orchestration/src/examples/stakeIca.contract.js').start; + typeof import('@agoric/orchestration/src/examples/stake-ica.contract.js').start; const getChainTerms = ( chainName: keyof typeof fetchedChainInfo, @@ -44,12 +41,12 @@ const getChainTerms = ( chainId, hostConnectionId: agoricConns[chainId].counterparty.connection_id, controllerConnectionId: agoricConns[chainId].id, - bondDenom: stakingTokens[0].denom, icqEnabled: !!icqEnabled, }; }; const startContract = async ({ + agoricNames, cosmosInterchainService, timer, marshaller, @@ -67,6 +64,7 @@ const startContract = async ({ issuerKeywordRecord, terms, { + agoricNames, marshaller, cosmosInterchainService, storageNode: storage.rootNode.makeChildNode(storagePath), @@ -76,7 +74,7 @@ const startContract = async ({ return { publicFacet, zoe }; }; -test('makeAccount, getAddress, getBalances, getBalance', async t => { +test('makeAccount, getAddress', async t => { const { bootstrap, mocks } = await commonSetup(t); { // stakeAtom @@ -89,14 +87,6 @@ test('makeAccount, getAddress, getBalances, getBalance', async t => { t.regex(chainAddress.value, /cosmos1/); t.like(chainAddress, { chainId: 'cosmoshub-4', encoding: 'bech32' }); - await t.throwsAsync(E(account).getBalances(), { - message: 'not yet implemented', - }); - - await t.throwsAsync(E(account).getBalance('uatom'), { - message: 'Queries not available for chain "cosmoshub-4"', - }); - const accountP = E(publicFacet).makeAccount(); const { value: address2 } = await E(accountP).getAddress(); t.regex(address2, /cosmos1/); @@ -117,23 +107,6 @@ test('makeAccount, getAddress, getBalances, getBalance', async t => { const chainAddress = await E(account).getAddress(); t.regex(chainAddress.value, /osmo1/); t.like(chainAddress, { chainId: 'osmosis-1' }); - - const buildMocks = () => { - const balanceReq = buildQueryPacketString([ - QueryBalanceRequest.toProtoMsg({ - address: chainAddress.value, - denom: 'uosmo', - }), - ]); - const balanceResp = buildQueryResponseString(QueryBalanceResponse, { - balance: { amount: '0', denom: 'uosmo' }, - }); - return { [balanceReq]: balanceResp }; - }; - await E(ibcBridge).setMockAck(buildMocks()); - - const balance = await E(account).getBalance('uosmo'); - t.deepEqual(balance, { denom: 'uosmo', value: 0n }); } t.snapshot(bootstrap.storage.data.entries(), 'accounts in vstorage'); @@ -152,16 +125,17 @@ test('delegate, undelegate, redelegate, withdrawReward', async t => { chainId: 'cosmoshub-4', encoding: 'bech32' as const, }; - const delegation = await E(account).delegate(validatorAddr, { + const delegation = { denom: 'uatom', value: 10n, - }); - t.is(delegation, undefined, 'delegation returns void'); + }; + const delegationResult = await E(account).delegate(validatorAddr, delegation); + t.is(delegationResult, undefined, 'delegation returns void'); const undelegatationP = E(account).undelegate([ { - shares: '10', - validatorAddress: validatorAddr.value, + amount: delegation, + validator: validatorAddr, }, ]); const completionTime = UNBOND_PERIOD_SECONDS + maxClockSkew; @@ -219,43 +193,24 @@ test('makeAccountInvitationMaker', async t => { offerResult.publicSubscribers.account.subscriber, ); const storageUpdate = await E(accountNotifier).getUpdateSince(); + const expectedStorageValue = { + 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-0', + 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-0', + }; + t.deepEqual(storageUpdate, { updateCount: 1n, - value: '', + value: expectedStorageValue, }); const vstorageEntry = bootstrap.storage.data.get( 'mockChainStorageRoot.stakeAtom.accounts.cosmos1test', ); t.truthy(vstorageEntry, 'vstorage account entry created'); - t.is(bootstrap.marshaller.fromCapData(JSON.parse(vstorageEntry!)), ''); -}); - -test('CosmosOrchestrationAccount - not yet implemented', async t => { - const { bootstrap } = await commonSetup(t); - const { publicFacet } = await startContract(bootstrap); - const account = await E(publicFacet).makeAccount(); - const mockChainAddress: ChainAddress = { - value: 'cosmos1test', - chainId: 'cosmoshub-4', - encoding: 'bech32', - }; - const mockAmountArg: AmountArg = { value: 10n, denom: 'uatom' }; - - await t.throwsAsync(E(account).getBalances(), { - message: 'not yet implemented', - }); - await t.throwsAsync(E(account).send(mockChainAddress, mockAmountArg), { - message: 'not yet implemented', - }); - // XXX consider, positioning amount + address args the same for .send and .transfer - await t.throwsAsync(E(account).transfer(mockAmountArg, mockChainAddress), { - message: 'not yet implemented', - }); - await t.throwsAsync(E(account).transferSteps(mockAmountArg, null as any), { - message: 'not yet implemented', - }); - await t.throwsAsync(E(account).withdrawRewards(), { - message: 'Not Implemented. Try using withdrawReward.', - }); + t.deepEqual( + bootstrap.marshaller.fromCapData(JSON.parse(vstorageEntry!)), + expectedStorageValue, + ); }); diff --git a/packages/orchestration/test/examples/staking-combinations.test.ts b/packages/orchestration/test/examples/staking-combinations.test.ts new file mode 100644 index 00000000000..830f11a4042 --- /dev/null +++ b/packages/orchestration/test/examples/staking-combinations.test.ts @@ -0,0 +1,243 @@ +import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; + +import { + eventLoopIteration, + inspectMapStore, +} from '@agoric/internal/src/testing-utils.js'; +import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; +import { E } from '@endo/far'; +import path from 'path'; +import { + MsgTransfer, + MsgTransferResponse, +} from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js'; +import { IBCMethod } from '@agoric/vats'; +import { SIMULATED_ERRORS } from '@agoric/vats/tools/fake-bridge.js'; +import { protoMsgMocks, UNBOND_PERIOD_SECONDS } from '../ibc-mocks.js'; +import { commonSetup } from '../supports.js'; +import { + buildMsgResponseString, + buildVTransferEvent, + parseOutgoingTxPacket, +} from '../../tools/ibc-mocks.js'; + +const dirname = path.dirname(new URL(import.meta.url).pathname); + +const contractFile = `${dirname}/../../src/examples/staking-combinations.contract.js`; +type StartFn = + typeof import('@agoric/orchestration/src/examples/staking-combinations.contract.js').start; + +test('start', async t => { + const { + bootstrap: { timer, vowTools: vt }, + brands: { bld }, + mocks: { ibcBridge, transferBridge }, + utils: { inspectDibcBridge, pourPayment }, + commonPrivateArgs, + } = await commonSetup(t); + + let contractBaggage; + const { zoe, bundleAndInstall } = await setUpZoeForTest({ + setJig: ({ baggage }) => { + contractBaggage = baggage; + }, + }); + const installation: Installation = + await bundleAndInstall(contractFile); + + const { publicFacet, creatorFacet } = await E(zoe).startInstance( + installation, + // TODO use atom https://github.com/Agoric/agoric-sdk/issues/9966 + { Stake: bld.issuer }, + {}, + commonPrivateArgs, + ); + + const inv = E(publicFacet).makeAccount(); + + t.is( + (await E(zoe).getInvitationDetails(inv)).description, + 'Make an ICA account', + ); + + const userSeat = await E(zoe).offer( + inv, + {}, + {}, + { + chainName: 'cosmoshub', + }, + ); + + const result = await vt.when(E(userSeat).getOfferResult()); + t.like(result, { + publicSubscribers: { + account: { + description: 'Staking Account holder status', + storagePath: 'mockChainStorageRoot.cosmos1test', + }, + }, + }); + + // use Deposit and Delegate to fund the ICA account and delegate + const depositAndDelegateInv = await E( + result.invitationMakers, + ).DepositAndDelegate(); + + // ensure there's a denom for Stake brand + // TODO use atom https://github.com/Agoric/agoric-sdk/issues/9966 + await E(creatorFacet).registerAsset('ubld', { + chainName: 'agoric', + baseName: 'agoric', + baseDenom: 'ubld', + brand: bld.brand, + }); + + ibcBridge.addMockAck( + // Delegate 100 ubld from cosmos1test to cosmosvaloper1test observed in console + 'eyJ0eXBlIjoxLCJkYXRhIjoiQ2xVS0l5OWpiM050YjNNdWMzUmhhMmx1Wnk1Mk1XSmxkR0V4TGsxelowUmxiR1ZuWVhSbEVpNEtDMk52YzIxdmN6RjBaWE4wRWhKamIzTnRiM04yWVd4dmNHVnlNWFJsYzNRYUN3b0VkV0pzWkJJRE1UQXciLCJtZW1vIjoiIn0=', + protoMsgMocks.delegate.ack, + ); + + // TODO use atom https://github.com/Agoric/agoric-sdk/issues/9966 + const stakeAmount = bld.make(100n); + + const depositAndDelegateUserSeat = await E(zoe).offer( + depositAndDelegateInv, + { + give: { Stake: stakeAmount }, + exit: { waived: null }, + }, + { + Stake: await pourPayment(stakeAmount), + }, + { + validator: { + chainId: 'cosmoshub', + value: 'cosmosvaloper1test', + encoding: 'bech32', + }, + }, + ); + + // wait for targetApp to exist + await eventLoopIteration(); + // similar transfer ack + await E(transferBridge).fromBridge( + buildVTransferEvent({ + receiver: 'cosmos1test', + sender: 'agoric1fakeLCAAddress', + amount: 100n, + denom: 'ubld', + sourceChannel: 'channel-5', + sequence: 1n, + }), + ); + + const depositAndDelegateResult = await vt.when( + E(depositAndDelegateUserSeat).getOfferResult(), + ); + t.is(depositAndDelegateResult, undefined); + + // Undelegate the funds using the guest flow + ibcBridge.addMockAck( + // observed in console + 'eyJ0eXBlIjoxLCJkYXRhIjoiQ2xZS0pTOWpiM050YjNNdWMzUmhhMmx1Wnk1Mk1XSmxkR0V4TGsxeloxVnVaR1ZzWldkaGRHVVNMUW9MWTI5emJXOXpNWFJsYzNRU0VHOXpiVzkyWVd4dmNHVnlNWFJsYzNRYURBb0ZkVzl6Ylc4U0F6RXdNQT09IiwibWVtbyI6IiJ9', + protoMsgMocks.undelegate.ack, + ); + ibcBridge.addMockAck( + // MsgTransfer from cosmos1test to osmo1receiver observed in console + 'eyJ0eXBlIjoxLCJkYXRhIjoiQ25nS0tTOXBZbU11WVhCd2JHbGpZWFJwYjI1ekxuUnlZVzV6Wm1WeUxuWXhMazF6WjFSeVlXNXpabVZ5RWtzS0NIUnlZVzV6Wm1WeUVndGphR0Z1Ym1Wc0xURTBNUm9NQ2dWMWIzTnRieElETVRBd0lndGpiM050YjNNeGRHVnpkQ29OYjNOdGJ6RnlaV05sYVhabGNqSUFPSUNRK0lTZ21nRT0iLCJtZW1vIjoiIn0=', + buildMsgResponseString(MsgTransferResponse, { sequence: 0n }), + ); + const destination = { + chainId: 'osmosis-1', + value: 'osmo1receiver', + encoding: 'bech32', + }; + const undelegateAndTransferInv = await E( + result.invitationMakers, + ).UndelegateAndTransfer( + [ + { + validator: { + value: 'osmovaloper1test', + encoding: 'bech32', + chainId: 'osmosis', + }, + amount: { denom: 'uosmo', value: 100n }, + }, + ], + destination, + ); + t.like(await E(zoe).getInvitationDetails(undelegateAndTransferInv), { + description: 'Undelegate and transfer', + }); + + const undelegateUserSeat = await E(zoe).offer(undelegateAndTransferInv); + + // Wait for the unbonding period + timer.advanceBy(UNBOND_PERIOD_SECONDS * 1000n); + + const undelegateResult = await vt.when( + E(undelegateUserSeat).getOfferResult(), + ); + t.is(undelegateResult, undefined); + + const { bridgeDowncalls } = await inspectDibcBridge(); + const { messages } = parseOutgoingTxPacket( + (bridgeDowncalls.at(-1) as IBCMethod<'sendPacket'>).packet.data, + ); + const transferMsg = MsgTransfer.decode(messages[0].value); + t.like( + transferMsg, + { + receiver: 'osmo1receiver', + sourcePort: 'transfer', + token: { + amount: '100', + denom: 'uosmo', + }, + memo: '', + }, + 'undelegateAndTransfer sent MsgTransfer', + ); + + // snapshot the resulting contract baggage + const tree = inspectMapStore(contractBaggage); + t.snapshot(tree, 'contract baggage after start'); + + { + t.log('payments from failed transfers are returned'); + const bldAmt = bld.make(SIMULATED_ERRORS.TIMEOUT); + + const seat = await E(zoe).offer( + await E(result.invitationMakers).DepositAndDelegate(), + { + give: { Stake: bldAmt }, + exit: { waived: null }, + }, + { + Stake: await pourPayment(bldAmt), + }, + { + validator: { + chainId: 'cosmoshub', + value: 'cosmosvaloper1test', + encoding: 'bech32', + }, + }, + ); + await t.throwsAsync(vt.when(E(seat).getOfferResult()), { + message: + 'ibc transfer failed "[Error: simulated unexpected MsgTransfer packet timeout]"', + }); + await vt.when(E(seat).hasExited()); + const payouts = await E(seat).getPayouts(); + t.deepEqual( + await bld.issuer.getAmountOf(payouts.Stake), + bldAmt, + 'Stake is returned', + ); + } +}); diff --git a/packages/orchestration/test/examples/swapExample.test.ts b/packages/orchestration/test/examples/swap.contract.test.ts similarity index 70% rename from packages/orchestration/test/examples/swapExample.test.ts rename to packages/orchestration/test/examples/swap.contract.test.ts index f87ab716969..7eb8869eb38 100644 --- a/packages/orchestration/test/examples/swapExample.test.ts +++ b/packages/orchestration/test/examples/swap.contract.test.ts @@ -8,19 +8,11 @@ import { commonSetup } from '../supports.js'; const dirname = path.dirname(new URL(import.meta.url).pathname); -const contractFile = `${dirname}/../../src/examples/swapExample.contract.js`; +const contractFile = `${dirname}/../../src/examples/swap.contract.js`; type StartFn = - typeof import('@agoric/orchestration/src/examples/swapExample.contract.js').start; + typeof import('@agoric/orchestration/src/examples/swap.contract.js').start; -/* Not sure why it is failing. Possibly relevant symptoms. -``` ------ ComosOrchestrationAccountHolder.6 3 TODO: handle brand { brand: Object [Alleged: IST brand] {}, value: 10000000n } -REJECTED at top of event loop (Error#20) -Error#20: {"type":1,"data":"CmgKIy9jb3Ntb3Muc3Rha2luZy52MWJldGExLk1zZ0RlbGVnYXRlEkEKGFVOUEFSU0FCTEVfQ0hBSU5fQUREUkVTUxISYWdvcmljMXZhbG9wZXJmdWZ1GhEKBXVmbGl4EggxMDAwMDAwMA==","memo":""} - at parseTxPacket (file:///Users/markmiller/src/ongithub/agoric/agoric-sdk/packages/orchestration/src/utils/packet.js:87:14) -``` -*/ -test.skip('start', async t => { +test('start', async t => { const { bootstrap, brands: { ist }, diff --git a/packages/orchestration/test/examples/unbond.contract.test.ts b/packages/orchestration/test/examples/unbond.contract.test.ts new file mode 100644 index 00000000000..05958266b2c --- /dev/null +++ b/packages/orchestration/test/examples/unbond.contract.test.ts @@ -0,0 +1,106 @@ +import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; + +import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; +import { E } from '@endo/far'; +import path from 'path'; +import { inspectMapStore } from '@agoric/internal/src/testing-utils.js'; +import { QueryDelegatorDelegationsResponse } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/query.js'; +import { MsgUndelegateResponse } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; +import { MsgTransferResponse } from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js'; +import { QueryBalanceResponse } from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; +import { commonSetup } from '../supports.js'; +import { + buildMsgResponseString, + buildQueryResponseString, +} from '../../tools/ibc-mocks.js'; + +const dirname = path.dirname(new URL(import.meta.url).pathname); + +const contractFile = `${dirname}/../../src/examples/unbond.contract.js`; +type StartFn = + typeof import('@agoric/orchestration/src/examples/unbond.contract.js').start; + +test('start', async t => { + const { + bootstrap: { timer, vowTools: vt }, + brands: { ist }, + commonPrivateArgs, + mocks: { ibcBridge }, + } = await commonSetup(t); + + const buildMocks = () => { + const makeDelegationsResponse = () => + buildQueryResponseString(QueryDelegatorDelegationsResponse, { + delegationResponses: [ + { + delegation: { + delegatorAddress: 'cosmos1test', + validatorAddress: 'cosmosvaloper1xyz', + shares: '1000000', + }, + balance: { denom: 'uosmo', amount: '1000000' }, + }, + ], + }); + const makeUndelegateResponse = () => + buildMsgResponseString(MsgUndelegateResponse, { + completionTime: { seconds: 3600n, nanos: 0 }, + }); + + return { + 'eyJkYXRhIjoiQ2tNS0RRb0xZMjl6Ylc5ek1YUmxjM1FTTWk5amIzTnRiM011YzNSaGEybHVaeTUyTVdKbGRHRXhMbEYxWlhKNUwwUmxiR1ZuWVhSdmNrUmxiR1ZuWVhScGIyNXoiLCJtZW1vIjoiIn0=': + makeDelegationsResponse(), + 'eyJ0eXBlIjoxLCJkYXRhIjoiQ2xzS0pTOWpiM050YjNNdWMzUmhhMmx1Wnk1Mk1XSmxkR0V4TGsxeloxVnVaR1ZzWldkaGRHVVNNZ29MWTI5emJXOXpNWFJsYzNRU0VXTnZjMjF2YzNaaGJHOXdaWEl4ZUhsNkdoQUtCWFZ2YzIxdkVnY3hNREF3TURBdyIsIm1lbW8iOiIifQ==': + makeUndelegateResponse(), + 'eyJkYXRhIjoiQ2pvS0ZBb0xZMjl6Ylc5ek1YUmxjM1FTQlhWdmMyMXZFaUl2WTI5emJXOXpMbUpoYm1zdWRqRmlaWFJoTVM1UmRXVnllUzlDWVd4aGJtTmwiLCJtZW1vIjoiIn0=': + buildQueryResponseString(QueryBalanceResponse, { + balance: { denom: 'uosmo', amount: '1234' }, + }), + 'eyJ0eXBlIjoxLCJkYXRhIjoiQ25rS0tTOXBZbU11WVhCd2JHbGpZWFJwYjI1ekxuUnlZVzV6Wm1WeUxuWXhMazF6WjFSeVlXNXpabVZ5RWt3S0NIUnlZVzV6Wm1WeUVndGphR0Z1Ym1Wc0xUTXlOaG9OQ2dWMWIzTnRieElFTVRJek5DSUxZMjl6Ylc5ek1YUmxjM1FxREdOdmMyMXZjekYwWlhOME1USUFPSUR3MXRUQ3pySUciLCJtZW1vIjoiIn0=': + buildMsgResponseString(MsgTransferResponse, {}), + }; + }; + + ibcBridge.setMockAck(buildMocks()); + + let contractBaggage; + const { zoe, bundleAndInstall } = await setUpZoeForTest({ + setJig: ({ baggage }) => { + contractBaggage = baggage; + }, + }); + const installation: Installation = + await bundleAndInstall(contractFile); + + const { publicFacet } = await E(zoe).startInstance( + installation, + { Stable: ist.issuer }, + {}, + commonPrivateArgs, + ); + + const inv = E(publicFacet).makeUnbondAndTransferInvitation(); + + t.is( + (await E(zoe).getInvitationDetails(inv)).description, + 'Unbond and transfer', + ); + + const userSeat = await E(zoe).offer( + inv, + {}, + {}, + { validator: 'agoric1valopsfufu' }, + ); + const resultP = vt.when(E(userSeat).getOfferResult()); + t.truthy(resultP); + + // Wait for the completionTime to pass + timer.advanceBy(3600n * 1000n); + + const result = await resultP; + t.is(result, undefined); + + const tree = inspectMapStore(contractBaggage); + t.snapshot(tree, 'contract baggage after start'); +}); diff --git a/packages/orchestration/test/examples/unbondExample.test.ts b/packages/orchestration/test/examples/unbondExample.test.ts deleted file mode 100644 index 830353380f4..00000000000 --- a/packages/orchestration/test/examples/unbondExample.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; - -import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; -import { E } from '@endo/far'; -import path from 'path'; -import { inspectMapStore } from '@agoric/internal/src/testing-utils.js'; -import { commonSetup } from '../supports.js'; - -const dirname = path.dirname(new URL(import.meta.url).pathname); - -const contractFile = `${dirname}/../../src/examples/unbondExample.contract.js`; -type StartFn = - typeof import('@agoric/orchestration/src/examples/unbondExample.contract.js').start; - -test('start', async t => { - const { - bootstrap: { vowTools: vt }, - brands: { ist }, - commonPrivateArgs, - } = await commonSetup(t); - - let contractBaggage; - const { zoe, bundleAndInstall } = await setUpZoeForTest({ - setJig: ({ baggage }) => { - contractBaggage = baggage; - }, - }); - const installation: Installation = - await bundleAndInstall(contractFile); - - const { publicFacet } = await E(zoe).startInstance( - installation, - { Stable: ist.issuer }, - {}, - commonPrivateArgs, - ); - - const inv = E(publicFacet).makeUnbondAndLiquidStakeInvitation(); - - t.is( - (await E(zoe).getInvitationDetails(inv)).description, - 'Unbond and liquid stake', - ); - - const userSeat = await E(zoe).offer( - inv, - {}, - {}, - { validator: 'agoric1valopsfufu' }, - ); - const result = await vt.when(E(userSeat).getOfferResult()); - t.is(result, undefined); - - const tree = inspectMapStore(contractBaggage); - t.snapshot(tree, 'contract baggage after start'); -}); diff --git a/packages/orchestration/test/exos/agoric-names-tools.test.ts b/packages/orchestration/test/exos/agoric-names-tools.test.ts deleted file mode 100644 index 924a72591a7..00000000000 --- a/packages/orchestration/test/exos/agoric-names-tools.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; - -import { heapVowE as E } from '@agoric/vow/vat.js'; -import { makeHeapZone } from '@agoric/zone'; -import { withAmountUtils } from '@agoric/zoe/tools/test-utils.js'; -import { makeIssuerKit } from '@agoric/ertp'; -import { AssetInfo } from '@agoric/vats/src/vat-bank.js'; -import { makeResumableAgoricNamesHack } from '../../src/exos/agoric-names-tools.js'; -import { commonSetup } from '../supports.js'; - -test('agoric names tools', async t => { - const { - bootstrap: { agoricNames, agoricNamesAdmin, bankManager, vowTools }, - brands: { ist }, - } = await commonSetup(t); - - const zone = makeHeapZone(); - const agNamesTools = makeResumableAgoricNamesHack(zone, { - agoricNames, - vowTools, - }); - - const chainEntry = await E.when(agNamesTools.lookup('chain', 'celestia')); - t.like(chainEntry, { chainId: 'celestia' }); - - const istDenom = await E.when(agNamesTools.findBrandInVBank(ist.brand)); - t.like(istDenom, { denom: 'uist' }); - - const moolah = withAmountUtils(makeIssuerKit('MOO')); - - await t.throwsAsync(E.when(agNamesTools.findBrandInVBank(moolah.brand)), { - message: /brand(.*?)not in agoricNames.vbankAsset/, - }); - - const mooToken: AssetInfo = { - brand: moolah.brand, - issuer: moolah.issuer, - issuerName: 'MOO', - denom: 'umoo', - proposedName: 'MOO', - displayInfo: { decimalPlaces: 6, assetKind: 'nat' }, - }; - - await E(E(agoricNamesAdmin).lookupAdmin('vbankAsset')).update( - 'umoo', - harden(mooToken), - ); - t.like( - await E.when(agNamesTools.findBrandInVBank(moolah.brand)), - { denom: 'umoo' }, - 'vbankAssets are refetched if brand is not found', - ); - - await E(E(agoricNamesAdmin).lookupAdmin('vbankAsset')).update( - 'umoo', - harden({ ...mooToken, denom: 'umoo2' }), - ); - t.like( - await E.when(agNamesTools.findBrandInVBank(moolah.brand)), - { denom: 'umoo' }, - 'old AssetInfo is cached', - ); - t.like( - await E.when(agNamesTools.findBrandInVBank(moolah.brand, true)), - { denom: 'umoo2' }, - 'new AssetInfo is fetched when refetch=true', - ); -}); diff --git a/packages/orchestration/test/exos/chain-hub.test.ts b/packages/orchestration/test/exos/chain-hub.test.ts index 446c6c02bd4..98e865c3527 100644 --- a/packages/orchestration/test/exos/chain-hub.test.ts +++ b/packages/orchestration/test/exos/chain-hub.test.ts @@ -4,12 +4,21 @@ import test from '@endo/ses-ava/prepare-endo.js'; import { makeNameHubKit } from '@agoric/vats'; import { prepareSwingsetVowTools } from '@agoric/vow/vat.js'; -import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; -import { makeChainHub } from '../../src/exos/chain-hub.js'; +import { E } from '@endo/far'; +import { makeIssuerKit } from '@agoric/ertp'; +import { withAmountUtils } from '@agoric/zoe/tools/test-utils.js'; +import { makeChainHub, registerAssets } from '../../src/exos/chain-hub.js'; import { provideDurableZone } from '../supports.js'; -import { registerKnownChains } from '../../src/chain-info.js'; +import { + registerChainAssets, + registerKnownChains, +} from '../../src/chain-info.js'; import knownChains from '../../src/fetched-chain-info.js'; -import type { IBCConnectionInfo } from '../../src/cosmos-api.js'; +import type { + CosmosChainInfo, + IBCConnectionInfo, +} from '../../src/cosmos-api.js'; +import { assets as assetFixture } from '../assets.fixture.js'; const connection = { id: 'connection-1', @@ -17,9 +26,6 @@ const connection = { counterparty: { client_id: '07-tendermint-2', connection_id: 'connection-1', - prefix: { - key_prefix: '', - }, }, state: 3 /* IBCConnectionState.STATE_OPEN */, transferChannel: { @@ -87,3 +93,87 @@ test.serial('getConnectionInfo', async t => { // Look up the opposite direction t.deepEqual(await vt.when(chainHub.getConnectionInfo(b, a)), ba); }); + +test('denom info support via getAsset and getDenom', async t => { + const { chainHub } = setup(); + + const denom = 'utok1'; + const info1: CosmosChainInfo = { + chainId: 'chain1', + stakingTokens: [{ denom }], + }; + const tok1 = withAmountUtils(makeIssuerKit('Tok1')); + + chainHub.registerChain('chain1', info1); + const info = { + chainName: 'chain1', + baseName: 'chain1', + baseDenom: denom, + brand: tok1.brand, + }; + chainHub.registerAsset('utok1', info); + + t.deepEqual( + chainHub.getAsset('utok1'), + info, + 'getAsset(denom) returns denom info', + ); + + t.is( + chainHub.getAsset('utok404'), + undefined, + 'getAsset returns undefined when denom not registered', + ); + + t.deepEqual( + chainHub.getDenom(tok1.brand), + info.baseDenom, + 'getDenom(brand) returns denom info', + ); + + const tok44 = withAmountUtils(makeIssuerKit('Tok404')); + t.is( + chainHub.getDenom(tok44.brand), + undefined, + 'getDenom returns undefined when brand is not found', + ); +}); + +test('toward asset info in agoricNames (#9572)', async t => { + const { chainHub, nameAdmin, vt } = setup(); + // use fetched chain info + await registerKnownChains(nameAdmin); + + await vt.when(chainHub.getChainInfo('cosmoshub')); + + for (const name of ['kava', 'fxcore']) { + chainHub.registerChain(name, { chainId: name }); + } + + await registerChainAssets(nameAdmin, 'cosmoshub', assetFixture.cosmoshub); + const details = await E(E(nameAdmin).readonly()).lookup( + 'chainAssets', + 'cosmoshub', + ); + registerAssets(chainHub, 'cosmoshub', details); + + { + const actual = chainHub.getAsset('uatom'); + t.deepEqual(actual, { + chainName: 'cosmoshub', + baseName: 'cosmoshub', + baseDenom: 'uatom', + }); + } + + { + const actual = chainHub.getAsset( + 'ibc/F04D72CF9B5D9C849BB278B691CDFA2241813327430EC9CDC83F8F4CA4CDC2B0', + ); + t.deepEqual(actual, { + chainName: 'cosmoshub', + baseName: 'kava', + baseDenom: 'erc20/tether/usdt', + }); + } +}); diff --git a/packages/orchestration/test/exos/cosmos-orchestration-account.test.ts b/packages/orchestration/test/exos/cosmos-orchestration-account.test.ts new file mode 100644 index 00000000000..74230d14daa --- /dev/null +++ b/packages/orchestration/test/exos/cosmos-orchestration-account.test.ts @@ -0,0 +1,815 @@ +import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; +import type { TestFn } from 'ava'; +import { heapVowE as E } from '@agoric/vow/vat.js'; +import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; +import { IBCMethod } from '@agoric/vats'; +import { + MsgTransfer, + MsgTransferResponse, +} from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js'; +import { SIMULATED_ERRORS } from '@agoric/vats/tools/fake-bridge.js'; +import { + QueryAllBalancesRequest, + QueryAllBalancesResponse, + QueryBalanceRequest, + QueryBalanceResponse, +} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; +import { Coin } from '@agoric/cosmic-proto/cosmos/base/v1beta1/coin.js'; +import { + QueryDelegationRequest, + QueryDelegatorDelegationsRequest, + QueryUnbondingDelegationRequest, + QueryDelegatorUnbondingDelegationsRequest, + QueryRedelegationsRequest, + QueryDelegationResponse, + QueryDelegatorDelegationsResponse, + QueryUnbondingDelegationResponse, + QueryDelegatorUnbondingDelegationsResponse, + QueryRedelegationsResponse, +} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/query.js'; +import { + QueryDelegationRewardsRequest, + QueryDelegationTotalRewardsRequest, + QueryDelegationRewardsResponse, + QueryDelegationTotalRewardsResponse, +} from '@agoric/cosmic-proto/cosmos/distribution/v1beta1/query.js'; +import { commonSetup } from '../supports.js'; +import type { + AmountArg, + ChainAddress, + Denom, +} from '../../src/orchestration-api.js'; +import { prepareMakeTestCOAKit } from './make-test-coa-kit.js'; +import { + buildMsgResponseString, + buildQueryPacketString, + buildQueryResponseString, + buildTxPacketString, + parseOutgoingTxPacket, +} from '../../tools/ibc-mocks.js'; +import type { CosmosValidatorAddress } from '../../src/cosmos-api.js'; + +type TestContext = Awaited>; + +const test = anyTest as TestFn; + +test.beforeEach(async t => { + t.context = await commonSetup(t); +}); + +test('send (to addr on same chain)', async t => { + const { + brands: { ist }, + utils: { inspectDibcBridge }, + } = t.context; + const makeTestCOAKit = prepareMakeTestCOAKit(t, t.context); + const account = await makeTestCOAKit(); + t.assert(account, 'account is returned'); + + const toAddress: ChainAddress = { + value: 'cosmos99test', + chainId: 'cosmoshub-4', + encoding: 'bech32', + }; + + // single send + t.is( + await E(account).send(toAddress, { + value: 10n, + denom: 'uatom', + }), + undefined, + ); + + // simulate timeout error + await t.throwsAsync( + E(account).send(toAddress, { value: 504n, denom: 'uatom' } as AmountArg), + // TODO #9629 decode error messages + { message: 'ABCI code: 5: error handling packet: see events for details' }, + ); + + // IST not registered + await t.throwsAsync(E(account).send(toAddress, ist.make(10n) as AmountArg), { + message: 'No denom for brand [object Alleged: IST brand]', + }); + + // multi-send (sendAll) + t.is( + await E(account).sendAll(toAddress, [ + { value: 10n, denom: 'uatom' } as AmountArg, + { value: 10n, denom: 'ibc/1234' } as AmountArg, + ]), + undefined, + ); + + const { bridgeDowncalls } = await inspectDibcBridge(); + + t.is( + bridgeDowncalls.filter(d => d.method === 'sendPacket').length, + 3, + 'sent 2 successful txs and 1 failed. 1 rejected before sending', + ); +}); + +test('transfer', async t => { + const { + brands: { ist }, + facadeServices: { chainHub }, + utils: { inspectDibcBridge }, + mocks: { ibcBridge }, + } = t.context; + + const mockIbcTransfer = { + sourcePort: 'transfer', + sourceChannel: 'channel-536', + token: { + denom: 'ibc/uusdchash', + amount: '10', + }, + sender: 'cosmos1test', + receiver: 'noble1test', + timeoutHeight: { + revisionHeight: 0n, + revisionNumber: 0n, + }, + timeoutTimestamp: 300000000000n, // 5 mins in ns + memo: '', + }; + const buildMocks = () => { + const toTransferTxPacket = (msg: MsgTransfer) => + buildTxPacketString([MsgTransfer.toProtoMsg(msg)]); + + const defaultTransfer = toTransferTxPacket(mockIbcTransfer); + const customTimeoutHeight = toTransferTxPacket({ + ...mockIbcTransfer, + timeoutHeight: { + revisionHeight: 1000n, + revisionNumber: 1n, + }, + timeoutTimestamp: 0n, + }); + const customTimeoutTimestamp = toTransferTxPacket({ + ...mockIbcTransfer, + timeoutTimestamp: 999n, + }); + const customTimeout = toTransferTxPacket({ + ...mockIbcTransfer, + timeoutHeight: { + revisionHeight: 5000n, + revisionNumber: 5n, + }, + timeoutTimestamp: 5000n, + }); + const customMemo = toTransferTxPacket({ + ...mockIbcTransfer, + memo: JSON.stringify({ custom: 'pfm memo' }), + }); + + const transferResp = buildMsgResponseString(MsgTransferResponse, { + sequence: 0n, + }); + + const uistTransfer = toTransferTxPacket({ + ...mockIbcTransfer, + token: { + denom: 'uist', + amount: '10', + }, + }); + + return { + [defaultTransfer]: transferResp, + [customTimeoutHeight]: transferResp, + [customTimeoutTimestamp]: transferResp, + [customTimeout]: transferResp, + [customMemo]: transferResp, + [uistTransfer]: transferResp, + }; + }; + ibcBridge.setMockAck(buildMocks()); + + const getAndDecodeLatestPacket = async () => { + await eventLoopIteration(); + const { bridgeDowncalls } = await inspectDibcBridge(); + const latest = bridgeDowncalls[ + bridgeDowncalls.length - 1 + ] as IBCMethod<'sendPacket'>; + const { messages } = parseOutgoingTxPacket(latest.packet.data); + return MsgTransfer.decode(messages[0].value); + }; + + t.log('Make account on cosmoshub'); + const makeTestCOAKit = prepareMakeTestCOAKit(t, t.context); + const account = await makeTestCOAKit(); + + t.log('Send tokens from cosmoshub to noble'); + const mockDestination: ChainAddress = { + value: 'noble1test', + chainId: 'noble-1', + encoding: 'bech32', + }; + const mockAmountArg: AmountArg = { value: 10n, denom: 'ibc/uusdchash' }; + const res = E(account).transfer(mockAmountArg, mockDestination); + await eventLoopIteration(); + + t.deepEqual( + await getAndDecodeLatestPacket(), + mockIbcTransfer, + 'outgoing transfer msg matches expected default mock', + ); + t.is(await res, undefined, 'transfer returns undefined'); + + t.log('transfer accepts custom memo'); + await E(account).transfer(mockAmountArg, mockDestination, { + memo: JSON.stringify({ custom: 'pfm memo' }), + }); + t.like( + await getAndDecodeLatestPacket(), + { + memo: '{"custom":"pfm memo"}', + }, + 'accepts custom memo', + ); + + t.log('transfer accepts custom timeoutHeight'); + await E(account).transfer(mockAmountArg, mockDestination, { + timeoutHeight: { + revisionHeight: 1000n, + revisionNumber: 1n, + }, + }); + t.like( + await getAndDecodeLatestPacket(), + { + timeoutHeight: { + revisionHeight: 1000n, + revisionNumber: 1n, + }, + timeoutTimestamp: 0n, + }, + "accepts custom timeoutHeight and doesn't set timeoutTimestamp", + ); + + t.log('transfer accepts custom timeoutTimestamp'); + await E(account).transfer(mockAmountArg, mockDestination, { + timeoutTimestamp: 999n, + }); + t.like( + await getAndDecodeLatestPacket(), + { + timeoutTimestamp: 999n, + timeoutHeight: { + revisionHeight: 0n, + revisionNumber: 0n, + }, + }, + "accepts custom timeoutTimestamp and doesn't set timeoutHeight", + ); + + t.log('transfer accepts custom timeoutHeight and timeoutTimestamp'); + await E(account).transfer(mockAmountArg, mockDestination, { + timeoutHeight: { + revisionHeight: 5000n, + revisionNumber: 5n, + }, + timeoutTimestamp: 5000n, + }); + t.like( + await getAndDecodeLatestPacket(), + { + timeoutHeight: { + revisionHeight: 5000n, + revisionNumber: 5n, + }, + timeoutTimestamp: 5000n, + }, + 'accepts custom timeoutHeight and timeoutTimestamp', + ); + + t.log('transfer throws if connection is not in its chainHub'); + await t.throwsAsync( + E(account).transfer(mockAmountArg, { + ...mockDestination, + chainId: 'unknown-1', + }), + { + message: 'connection not found: cosmoshub-4<->unknown-1', + }, + ); + + t.log('transfer throws if asset is not in its chainHub'); + await t.throwsAsync(E(account).transfer(ist.make(10n), mockDestination), { + message: 'No denom for brand [object Alleged: IST brand]', + }); + chainHub.registerAsset('uist', { + baseDenom: 'uist', + baseName: 'agoric', + brand: ist.brand, + chainName: 'agoric', + }); + // uses uistTransfer mock above + await E(account).transfer(ist.make(10n), mockDestination); + + t.log('transfer timeout error recieved and handled from the bridge'); + await t.throwsAsync( + E(account).transfer( + { ...mockAmountArg, value: SIMULATED_ERRORS.TIMEOUT }, + mockDestination, + ), + { + message: 'ABCI code: 5: error handling packet: see events for details', + }, + ); + t.like( + await getAndDecodeLatestPacket(), + { + token: { + amount: String(SIMULATED_ERRORS.TIMEOUT), + }, + }, + 'timeout error received from the bridge', + ); +}); + +test('getBalance and getBalances', async t => { + const { + mocks: { ibcBridge }, + } = t.context; + const makeTestCOAKit = prepareMakeTestCOAKit(t, t.context); + + const buildMocks = () => { + const makeBalanceReq = ( + address: ChainAddress['value'] = 'osmo1test', + denom: Denom = 'uosmo', + ) => + buildQueryPacketString([ + QueryBalanceRequest.toProtoMsg({ + address, + denom, + }), + ]); + const makeAllBalanceReq = (address: ChainAddress['value'] = 'osmo1test') => + buildQueryPacketString([ + QueryAllBalancesRequest.toProtoMsg({ + address, + }), + ]); + const makeBalanceResp = ( + balance: Coin = { denom: 'usomo', amount: '10' }, + ) => + buildQueryResponseString(QueryBalanceResponse, { + balance, + }); + const makeAllBalanceResp = (balances: Coin[] = []) => + buildQueryResponseString(QueryAllBalancesResponse, { + balances, + }); + + return { + [makeBalanceReq()]: makeBalanceResp({ + denom: 'uosmo', + amount: '10', + }), + [makeAllBalanceReq()]: makeAllBalanceResp([ + { + denom: 'uosmo', + amount: '10', + }, + ]), + [makeBalanceReq('osmo1test1')]: makeBalanceResp({ + denom: 'uosmo', + amount: '0', + }), + [makeAllBalanceReq('osmo1test1')]: makeAllBalanceResp(), + }; + }; + t.log('setting mockAckMap for osmosis balance queries'); + ibcBridge.setMockAck(buildMocks()); + t.log('set address prefix to osmo'); + ibcBridge.setAddressPrefix('osmo'); + + { + t.log('osmo1test mocked to have a 10 uosmo balance'); + const account = await makeTestCOAKit({ + chainId: 'osmosis-1', + icqEnabled: true, + }); + t.assert(account, 'account is returned'); + + t.deepEqual(await E(account).getBalance('uosmo'), { + denom: 'uosmo', + value: 10n, + }); + t.deepEqual(await E(account).getBalances(), [ + { denom: 'uosmo', value: 10n }, + ]); + } + + { + t.log('osmo1test1 mocked to have no balances'); + const account = await makeTestCOAKit({ + chainId: 'osmosis-1', + icqEnabled: true, + }); + t.assert(account, 'account is returned'); + t.deepEqual(await E(account).getBalance('uosmo'), { + denom: 'uosmo', + value: 0n, + }); + t.deepEqual(await E(account).getBalances(), []); + } + + { + t.log('cosmoshub does not support balance queries'); + t.log('set address prefix to cosmos'); + ibcBridge.setAddressPrefix('cosmos'); + const account = await makeTestCOAKit(); + await t.throwsAsync(E(account).getBalance('uatom'), { + message: 'Queries not available for chain "cosmoshub-4"', + }); + await t.throwsAsync(E(account).getBalances(), { + message: 'Queries not available for chain "cosmoshub-4"', + }); + } +}); + +test('StakingAccountQueries', async t => { + const { + mocks: { ibcBridge }, + } = t.context; + const makeTestCOAKit = prepareMakeTestCOAKit(t, t.context); + + const buildMocks = () => { + const mockValidator: CosmosValidatorAddress = { + value: 'cosmosvaloper1xyz', + chainId: 'cosmoshub-4', + encoding: 'bech32', + }; + + const makeDelegationReq = () => + buildQueryPacketString([ + QueryDelegationRequest.toProtoMsg({ + delegatorAddr: 'cosmos1test', + validatorAddr: mockValidator.value, + }), + ]); + + const makeDelegationsReq = () => + buildQueryPacketString([ + QueryDelegatorDelegationsRequest.toProtoMsg({ + delegatorAddr: 'cosmos1test', + }), + ]); + + const makeUnbondingDelegationReq = () => + buildQueryPacketString([ + QueryUnbondingDelegationRequest.toProtoMsg({ + delegatorAddr: 'cosmos1test', + validatorAddr: mockValidator.value, + }), + ]); + + const makeUnbondingDelegationsReq = () => + buildQueryPacketString([ + QueryDelegatorUnbondingDelegationsRequest.toProtoMsg({ + delegatorAddr: 'cosmos1test', + }), + ]); + + const makeRedelegationReq = () => + buildQueryPacketString([ + QueryRedelegationsRequest.toProtoMsg({ + delegatorAddr: 'cosmos1test', + srcValidatorAddr: mockValidator.value, + // XXX need to provide dstValidatorAddr + dstValidatorAddr: mockValidator.value, + }), + ]); + + const makeRedelegationsReq = () => + buildQueryPacketString([ + QueryRedelegationsRequest.toProtoMsg({ + delegatorAddr: 'cosmos1test', + // Protobufs require these to be strings but they can be empty + srcValidatorAddr: '', + dstValidatorAddr: '', + }), + ]); + + const makeRewardReq = () => + buildQueryPacketString([ + QueryDelegationRewardsRequest.toProtoMsg({ + delegatorAddress: 'cosmos1test', + validatorAddress: mockValidator.value, + }), + ]); + + const makeRewardsReq = () => + buildQueryPacketString([ + QueryDelegationTotalRewardsRequest.toProtoMsg({ + delegatorAddress: 'cosmos1test', + }), + ]); + + return { + [makeDelegationReq()]: buildQueryResponseString(QueryDelegationResponse, { + delegationResponse: { + delegation: { + delegatorAddress: 'cosmos1test', + validatorAddress: mockValidator.value, + shares: '1000000', + }, + balance: { denom: 'uatom', amount: '1000000' }, + }, + }), + [makeDelegationsReq()]: buildQueryResponseString( + QueryDelegatorDelegationsResponse, + { + delegationResponses: [ + { + delegation: { + delegatorAddress: 'cosmos1test', + validatorAddress: mockValidator.value, + shares: '1000000', + }, + balance: { denom: 'uatom', amount: '1000000' }, + }, + ], + }, + ), + [makeUnbondingDelegationReq()]: buildQueryResponseString( + QueryUnbondingDelegationResponse, + { + unbond: { + delegatorAddress: 'cosmos1test', + validatorAddress: mockValidator.value, + entries: [ + { + creationHeight: 100n, + completionTime: { seconds: 1672531200n, nanos: 0 }, + initialBalance: '2000000', + balance: '1900000', + }, + ], + }, + }, + ), + [makeUnbondingDelegationsReq()]: buildQueryResponseString( + QueryDelegatorUnbondingDelegationsResponse, + { + unbondingResponses: [ + { + delegatorAddress: 'cosmos1test', + validatorAddress: mockValidator.value, + entries: [ + { + creationHeight: 100n, + completionTime: { seconds: 1672531200n, nanos: 0 }, + initialBalance: '2000000', + balance: '1900000', + }, + ], + }, + ], + }, + ), + [makeRedelegationReq()]: buildQueryResponseString( + QueryRedelegationsResponse, + { + redelegationResponses: [ + { + redelegation: { + delegatorAddress: 'cosmos1test', + validatorSrcAddress: mockValidator.value, + validatorDstAddress: 'cosmosvaloper1abc', + entries: [ + { + creationHeight: 200n, + completionTime: { seconds: 1675209600n, nanos: 0 }, + initialBalance: '3000000', + sharesDst: '2900000', + }, + ], + }, + entries: [ + { + redelegationEntry: { + creationHeight: 200n, + completionTime: { seconds: 1675209600n, nanos: 0 }, + initialBalance: '3000000', + sharesDst: '2900000', + }, + balance: '2900000', + }, + ], + }, + ], + }, + ), + [makeRedelegationsReq()]: buildQueryResponseString( + QueryRedelegationsResponse, + { + redelegationResponses: [ + { + redelegation: { + delegatorAddress: 'cosmos1test', + validatorSrcAddress: '', + validatorDstAddress: '', + entries: [ + { + creationHeight: 200n, + completionTime: { seconds: 1675209600n, nanos: 0 }, + initialBalance: '3000000', + sharesDst: '2900000', + }, + ], + }, + entries: [ + { + redelegationEntry: { + creationHeight: 200n, + completionTime: { seconds: 1675209600n, nanos: 0 }, + initialBalance: '3000000', + sharesDst: '2900000', + }, + balance: '2900000', + }, + ], + }, + ], + }, + ), + [makeRewardReq()]: buildQueryResponseString( + QueryDelegationRewardsResponse, + { + rewards: [ + { + denom: 'uatom', + // Rewards may be fractional, from operations like inflation + amount: '500000.01', + }, + ], + }, + ), + [makeRewardsReq()]: buildQueryResponseString( + QueryDelegationTotalRewardsResponse, + { + rewards: [ + { + validatorAddress: mockValidator.value, + reward: [{ denom: 'uatom', amount: '500000' }], + }, + ], + total: [{ denom: 'uatom', amount: '500000' }], + }, + ), + }; + }; + + ibcBridge.setMockAck(buildMocks()); + ibcBridge.setAddressPrefix('cosmos'); + + const account = await makeTestCOAKit({ + chainId: 'cosmoshub-4', + icqEnabled: true, + }); + t.assert(account, 'account is returned'); + + const mockValidator: CosmosValidatorAddress = { + value: 'cosmosvaloper1xyz', + chainId: 'cosmoshub-4', + encoding: 'bech32', + }; + + // Test getDelegation + const delegationResult = await E(account).getDelegation(mockValidator); + t.deepEqual(delegationResult, { + amount: { denom: 'uatom', value: 1000000n }, + delegator: { + chainId: 'cosmoshub-4', + encoding: 'bech32', + value: 'cosmos1test', + }, + validator: { + chainId: 'cosmoshub-4', + encoding: 'bech32', + value: mockValidator.value, + }, + }); + + // Test getDelegations + const delegationsResult = await E(account).getDelegations(); + t.deepEqual(delegationsResult, [ + { + amount: { denom: 'uatom', value: 1000000n }, + + delegator: { + chainId: 'cosmoshub-4', + encoding: 'bech32', + value: 'cosmos1test', + }, + validator: { + chainId: 'cosmoshub-4', + encoding: 'bech32', + value: mockValidator.value, + }, + }, + ]); + + // Test getUnbondingDelegation + const unbondingDelegationResult = + await E(account).getUnbondingDelegation(mockValidator); + t.deepEqual(unbondingDelegationResult, { + delegatorAddress: 'cosmos1test', + validatorAddress: mockValidator.value, + entries: [ + { + creationHeight: 100n, + completionTime: { seconds: 1672531200n, nanos: 0 }, + initialBalance: '2000000', + balance: '1900000', + }, + ], + }); + + // Test getUnbondingDelegations + const unbondingDelegationsResult = await E(account).getUnbondingDelegations(); + t.deepEqual(unbondingDelegationsResult, [ + { + delegatorAddress: 'cosmos1test', + validatorAddress: mockValidator.value, + entries: [ + { + creationHeight: 100n, + completionTime: { seconds: 1672531200n, nanos: 0 }, + initialBalance: '2000000', + balance: '1900000', + }, + ], + }, + ]); + + // Test getRedelegations + const redelegationsResult = await E(account).getRedelegations(); + t.deepEqual(redelegationsResult, [ + { + redelegation: { + delegatorAddress: 'cosmos1test', + validatorSrcAddress: '', + validatorDstAddress: '', + entries: [ + { + creationHeight: 200n, + completionTime: { seconds: 1675209600n, nanos: 0 }, + initialBalance: '3000000', + sharesDst: '2900000', + }, + ], + }, + entries: [ + { + redelegationEntry: { + creationHeight: 200n, + completionTime: { seconds: 1675209600n, nanos: 0 }, + initialBalance: '3000000', + sharesDst: '2900000', + }, + balance: '2900000', + }, + ], + }, + ]); + + // Test getReward + const rewardResult = await E(account).getReward(mockValidator); + t.deepEqual(rewardResult, [{ denom: 'uatom', value: 500000n }]); + + // Test getRewards + const rewardsResult = await E(account).getRewards(); + t.deepEqual(rewardsResult, { + rewards: [ + { + validator: { + encoding: 'bech32', + value: mockValidator.value, + chainId: 'cosmoshub-4', + }, + reward: [{ denom: 'uatom', value: 500000n }], + }, + ], + total: [{ denom: 'uatom', value: 500000n }], + }); +}); + +test('not yet implemented', async t => { + const makeTestCOAKit = prepareMakeTestCOAKit(t, t.context); + const account = await makeTestCOAKit(); + const mockAmountArg: AmountArg = { value: 10n, denom: 'uatom' }; + + await t.throwsAsync(E(account).transferSteps(mockAmountArg, null as any), { + message: 'not yet implemented', + }); + await t.throwsAsync(E(account).withdrawRewards(), { + message: 'Not Implemented. Try using withdrawReward.', + }); +}); diff --git a/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts b/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts index aee995de057..1f0aec2587a 100644 --- a/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts +++ b/packages/orchestration/test/exos/local-orchestration-account-kit.test.ts @@ -1,20 +1,25 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; -import { AmountMath } from '@agoric/ertp'; +import { AmountMath, makeIssuerKit } from '@agoric/ertp'; import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; -import { heapVowE as E } from '@agoric/vow/vat.js'; import { TargetApp } from '@agoric/vats/src/bridge-target.js'; -import { ChainAddress } from '../../src/orchestration-api.js'; +import { + LOCALCHAIN_QUERY_ALL_BALANCES_RESPONSE, + SIMULATED_ERRORS, +} from '@agoric/vats/tools/fake-bridge.js'; +import { heapVowE as VE } from '@agoric/vow/vat.js'; +import { withAmountUtils } from '@agoric/zoe/tools/test-utils.js'; +import { ChainAddress, type AmountArg } from '../../src/orchestration-api.js'; +import { maxClockSkew } from '../../src/utils/cosmos.js'; import { NANOSECONDS_PER_SECOND } from '../../src/utils/time.js'; -import { commonSetup } from '../supports.js'; +import { buildVTransferEvent } from '../../tools/ibc-mocks.js'; import { UNBOND_PERIOD_SECONDS } from '../ibc-mocks.js'; -import { maxClockSkew } from '../../src/utils/cosmos.js'; +import { commonSetup } from '../supports.js'; import { prepareMakeTestLOAKit } from './make-test-loa-kit.js'; -import { buildVTransferEvent } from '../../tools/ibc-mocks.js'; test('deposit, withdraw', async t => { const common = await commonSetup(t); - const makeTestLOAKit = prepareMakeTestLOAKit(t, common.bootstrap); + const makeTestLOAKit = prepareMakeTestLOAKit(t, common); const account = await makeTestLOAKit(); const { @@ -25,13 +30,15 @@ test('deposit, withdraw', async t => { const oneHundredStakePmt = await utils.pourPayment(stake.units(100)); t.log('deposit 100 bld to account'); - await E(account).deposit(oneHundredStakePmt); - // FIXME #9211 - // t.deepEqual(await E(account).getBalance('ubld'), stake.units(100)); + await VE(account).deposit(oneHundredStakePmt); + t.deepEqual(await VE(account).getBalance('ubld'), { + denom: 'ubld', + value: stake.units(100).value, + }); // XXX races in the bridge await eventLoopIteration(); - const withdrawal1 = await E(account).withdraw(stake.units(50)); + const withdrawal1 = await VE(account).withdraw(stake.units(50)); t.true( AmountMath.isEqual( await stake.issuer.getAmountOf(withdrawal1), @@ -40,16 +47,16 @@ test('deposit, withdraw', async t => { ); await t.throwsAsync( - E(account).withdraw(stake.units(51)), + VE(account).withdraw(stake.units(51)), undefined, 'fails to overwithdraw', ); await t.notThrowsAsync( - E(account).withdraw(stake.units(50)), + VE(account).withdraw(stake.units(50)), 'succeeeds at exactly empty', ); await t.throwsAsync( - E(account).withdraw(stake.make(1n)), + VE(account).withdraw(stake.make(1n)), undefined, 'fails to overwithdraw', ); @@ -57,7 +64,7 @@ test('deposit, withdraw', async t => { test('delegate, undelegate', async t => { const common = await commonSetup(t); - const makeTestLOAKit = prepareMakeTestLOAKit(t, common.bootstrap); + const makeTestLOAKit = prepareMakeTestLOAKit(t, common); const account = await makeTestLOAKit(); const { @@ -66,7 +73,7 @@ test('delegate, undelegate', async t => { utils, } = common; - await E(account).deposit(await utils.pourPayment(bld.units(100))); + await VE(account).deposit(await utils.pourPayment(bld.units(100))); const validatorAddress = 'agoric1validator1'; @@ -74,8 +81,8 @@ test('delegate, undelegate', async t => { // 1. these succeed even if funds aren't available // 2. there are no return values // 3. there are no side-effects such as assets being locked - await E(account).delegate(validatorAddress, bld.units(999)); - const undelegateP = E(account).undelegate(validatorAddress, bld.units(999)); + await VE(account).delegate(validatorAddress, bld.units(999)); + const undelegateP = VE(account).undelegate(validatorAddress, bld.units(999)); const completionTime = UNBOND_PERIOD_SECONDS + maxClockSkew; const notTooSoon = Promise.race([ @@ -93,11 +100,14 @@ test('delegate, undelegate', async t => { test('transfer', async t => { const common = await commonSetup(t); - const makeTestLOAKit = prepareMakeTestLOAKit(t, common.bootstrap); + const makeTestLOAKit = prepareMakeTestLOAKit(t, common); const account = await makeTestLOAKit(); + const { value: sender } = await VE(account).getAddress(); + const { brands: { bld: stake }, + mocks: { transferBridge }, utils, } = common; @@ -106,31 +116,72 @@ test('transfer', async t => { const oneHundredStakePmt = await utils.pourPayment(stake.units(100)); t.log('deposit 100 bld to account'); - await E(account).deposit(oneHundredStakePmt); - // FIXME #9211 - // t.deepEqual(await E(account).getBalance('ubld'), stake.units(100)); + await VE(account).deposit(oneHundredStakePmt); + t.deepEqual(await VE(account).getBalance('ubld'), { + denom: 'ubld', + value: stake.units(100).value, + }); const destination: ChainAddress = { chainId: 'cosmoshub-4', value: 'cosmos1pleab', encoding: 'bech32', }; - - // TODO #9211, support ERTP amounts - t.log('ERTP Amounts not yet supported for AmountArg'); - await t.throwsAsync(() => E(account).transfer(stake.units(1), destination), { - message: 'ERTP Amounts not yet supported', - }); + const sourceChannel = 'channel-5'; // observed in toBridge VLOCALCHAIN_EXECUTE_TX sourceChannel, confirmed via fetched-chain-info.js + + // TODO rename to lastSequence + /** The running tally of transfer messages that were sent over the bridge */ + let sequence = 0n; + /** + * Helper to start the transfer without awaiting the result. It await the + * event loop so the promise starts and increments sequence for use in the + * acknowledgementPacket bridge message and wants + * @param amount + * @param dest + * @param opts + */ + const startTransfer = async ( + amount: AmountArg, + dest: ChainAddress, + opts = {}, + ) => { + const transferP = VE(account).transfer(amount, dest, opts); + sequence += 1n; + // Ensure the toBridge of the transferP happens before the fromBridge is awaited after this function returns + await eventLoopIteration(); + return { transferP }; + }; t.log('.transfer() 1 bld to cosmos using DenomAmount'); - const transferResp = await E(account).transfer( + const { transferP } = await startTransfer( { denom: 'ubld', value: 1_000_000n }, destination, ); - t.is(transferResp, undefined, 'Successful transfer returns Promise.'); + t.is(await Promise.race([transferP, 'not yet']), 'not yet'); + + // simulate incoming message so that the transfer promise resolves + await VE(transferBridge).fromBridge( + buildVTransferEvent({ + receiver: destination.value, + sender, + sourceChannel, + sequence, + }), + ); + + const transferRes = await transferP; + t.true( + transferRes === undefined, + 'Successful transfer returns Promise.', + ); await t.throwsAsync( - () => E(account).transfer({ denom: 'ubld', value: 504n }, destination), + ( + await startTransfer( + { denom: 'ubld', value: SIMULATED_ERRORS.TIMEOUT }, + destination, + ) + ).transferP, { message: 'simulated unexpected MsgTransfer packet timeout', }, @@ -141,42 +192,64 @@ test('transfer', async t => { value: 'fakenet1pleab', encoding: 'bech32', }; + // XXX dev has to know not to startTransfer here await t.throwsAsync( - () => E(account).transfer({ denom: 'ubld', value: 1n }, unknownDestination), + VE(account).transfer({ denom: 'ubld', value: 1n }, unknownDestination), { message: /connection not found: agoric-3<->fakenet/ }, 'cannot create transfer msg with unknown chainId', ); - await t.notThrowsAsync( - () => - E(account).transfer({ denom: 'ubld', value: 10n }, destination, { - memo: 'hello', + /** + * Helper to start the transfer AND send the ack packet so this promise can be awaited + * @param amount + * @param dest + * @param opts + */ + const doTransfer = async ( + amount: AmountArg, + dest: ChainAddress, + opts = {}, + ) => { + const { transferP: promise } = await startTransfer(amount, dest, opts); + // simulate incoming message so that promise resolves + await VE(transferBridge).fromBridge( + buildVTransferEvent({ + receiver: dest.value, + sender, + sourceChannel, + sequence, }), + ); + return promise; + }; + + await t.notThrowsAsync( + doTransfer({ denom: 'ubld', value: 10n }, destination, { + memo: 'hello', + }), 'can create transfer msg with memo', ); // TODO, intercept/spy the bridge message to see that it has a memo await t.notThrowsAsync( - () => - E(account).transfer({ denom: 'ubld', value: 10n }, destination, { - // sets to current time, which shouldn't work in a real env - timeoutTimestamp: BigInt(new Date().getTime()) * NANOSECONDS_PER_SECOND, - }), + doTransfer({ denom: 'ubld', value: 10n }, destination, { + // sets to current time, which shouldn't work in a real env + timeoutTimestamp: BigInt(new Date().getTime()) * NANOSECONDS_PER_SECOND, + }), 'accepts custom timeoutTimestamp', ); await t.notThrowsAsync( - () => - E(account).transfer({ denom: 'ubld', value: 10n }, destination, { - timeoutHeight: { revisionHeight: 100n, revisionNumber: 1n }, - }), + doTransfer({ denom: 'ubld', value: 10n }, destination, { + timeoutHeight: { revisionHeight: 100n, revisionNumber: 1n }, + }), 'accepts custom timeoutHeight', ); }); test('monitor transfers', async t => { const common = await commonSetup(t); - const makeTestLOAKit = prepareMakeTestLOAKit(t, common.bootstrap); + const makeTestLOAKit = prepareMakeTestLOAKit(t, common); const account = await makeTestLOAKit(); const { mocks: { transferBridge }, @@ -193,12 +266,16 @@ test('monitor transfers', async t => { }, }); - const { value: target } = await E(account).getAddress(); - const appRegistration = await E(account).monitorTransfers(tap); + const { value: target } = await VE(account).getAddress(); + // XXX let the PacketTools subscribeToTransfers complete before triggering it + // again with monitorTransfers + await eventLoopIteration(); + + const appRegistration = await VE(account).monitorTransfers(tap); // simulate upcall from golang to VM const simulateIncomingTransfer = async () => - E(transferBridge).fromBridge( + VE(transferBridge).fromBridge( buildVTransferEvent({ receiver: target, }), @@ -210,6 +287,142 @@ test('monitor transfers', async t => { t.is(upcallCount, 2, 'second upcall received'); await appRegistration.revoke(); - await t.throwsAsync(simulateIncomingTransfer()); + await simulateIncomingTransfer(); t.is(upcallCount, 2, 'no more events after app is revoked'); }); + +test('send', async t => { + const common = await commonSetup(t); + const makeTestLOAKit = prepareMakeTestLOAKit(t, common); + const account = await makeTestLOAKit(); + t.truthy(account, 'account is returned'); + + const { + brands: { bld: stake, ist: stable }, + utils: { pourPayment, inspectLocalBridge }, + } = common; + const oneHundredStakePmt = await pourPayment(stake.units(100)); + const oneHundredStablePmt = await pourPayment(stable.units(100)); + t.log('deposit 100 bld to account'); + await VE(account).deposit(oneHundredStakePmt); + t.log('deposit 100 ist to account'); + await VE(account).deposit(oneHundredStablePmt); + + const toAddress = { + value: 'agoric1EOAAccAddress', + chainId: 'agoric-3', + encoding: 'bech32' as const, + }; + + t.log(`send 10 bld to ${toAddress.value}`); + await VE(account).send(toAddress, stake.units(10)); + + // this would normally fail since we do not have ibc/1234 in our wallet, + // but the mocked localchain bridge doesn't currently know about balances + t.log(`send 10 ibc/1234 (not in vbank) to ${toAddress.value}`); + await VE(account).send(toAddress, { denom: 'ibc/1234', value: 10n }); + + await t.throwsAsync( + VE(account).send(toAddress, { + denom: 'ibc/400', + value: SIMULATED_ERRORS.BAD_REQUEST, + }), + { + message: 'simulated error', + }, + ); + + t.log(`send 10 bld and 10 ist to ${toAddress.value} via sendAll`); + await VE(account).sendAll(toAddress, [ + { denom: 'ubld', value: 10_000_000n }, + { denom: 'uist', value: 10_000_000n }, + ]); + + const messages = await inspectLocalBridge(); + const executedBankSends = messages.filter( + m => + m.type === 'VLOCALCHAIN_EXECUTE_TX' && + m.messages?.[0]?.['@type'] === '/cosmos.bank.v1beta1.MsgSend', + ); + t.is( + executedBankSends.length, + 4, + 'sent 2 successful txs and 1 failed. 1 rejected before sending', + ); +}); + +test('getBalance', async t => { + const common = await commonSetup(t); + const makeTestLOAKit = prepareMakeTestLOAKit(t, common); + const account = await makeTestLOAKit(); + t.truthy(account, 'account is returned'); + + const { + brands: { bld: stake }, + utils: { pourPayment, inspectLocalBridge }, + } = common; + const oneHundredStakePmt = await pourPayment(stake.make(100n)); + const expectedBalance = { denom: 'ubld', value: 100n }; + t.log('deposit 100 ubld to account'); + await VE(account).deposit(oneHundredStakePmt); + + t.deepEqual( + await VE(account).getBalance(stake.brand), + expectedBalance, + 'getBalance from brand', + ); + t.deepEqual( + await VE(account).getBalance('ubld'), + expectedBalance, + 'getBalance from denom', + ); + + const ibcBalance = await VE(account).getBalance('ibc/1234'); + t.deepEqual( + ibcBalance, + { denom: 'ibc/1234', value: 10n }, + 'getBalance returns balance of non-vbank denom', + ); + + const moolah = withAmountUtils(makeIssuerKit('MOOLAH')); + await t.throwsAsync( + VE(account).getBalance(moolah.brand), + { + message: 'No denom for brand: "[Alleged: MOOLAH brand]"', + }, + 'getBalance throws when presented non-vbank brand', + ); + + const localBridgeMessages = inspectLocalBridge(); + const queryMessages = localBridgeMessages.filter( + x => x.type === 'VLOCALCHAIN_QUERY_MANY', + ); + t.is(queryMessages.length, 1, 'only sent query for non-vbank DenomArg'); + t.is( + queryMessages[0].messages[0].denom, + 'ibc/1234', + 'only sent query for ibc/1234', + ); +}); + +test('getBalances', async t => { + const common = await commonSetup(t); + const makeTestLOAKit = prepareMakeTestLOAKit(t, common); + const account = await makeTestLOAKit(); + t.truthy(account, 'account is returned'); + + const { + utils: { inspectLocalBridge }, + } = common; + + t.deepEqual( + await VE(account).getBalances(), + LOCALCHAIN_QUERY_ALL_BALANCES_RESPONSE, + ); + + const localBridgeMessages = inspectLocalBridge(); + const queryMessages = localBridgeMessages.filter( + x => x.type === 'VLOCALCHAIN_QUERY_MANY', + ); + t.is(queryMessages.length, 1, 'getBalances sends query to cosmos golang'); +}); diff --git a/packages/orchestration/test/exos/make-test-coa-kit.ts b/packages/orchestration/test/exos/make-test-coa-kit.ts index 99da8b9880d..77cb2ca3ec2 100644 --- a/packages/orchestration/test/exos/make-test-coa-kit.ts +++ b/packages/orchestration/test/exos/make-test-coa-kit.ts @@ -1,9 +1,11 @@ -import { Far } from '@endo/far'; +/* eslint-disable jsdoc/require-param -- ts types */ import { heapVowE as E } from '@agoric/vow/vat.js'; import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/recorder.js'; +import { Far } from '@endo/far'; import type { ExecutionContext } from 'ava'; -import { commonSetup } from '../supports.js'; import { prepareCosmosOrchestrationAccount } from '../../src/exos/cosmos-orchestration-account.js'; +import { commonSetup } from '../supports.js'; +import type { ICQConnection } from '../../src/exos/icq-connection-kit.js'; /** * A testing utility that creates a (Cosmos)ChainAccount and makes a @@ -12,17 +14,13 @@ import { prepareCosmosOrchestrationAccount } from '../../src/exos/cosmos-orchest * * Helps reduce boilerplate in test files, and retains testing context through * parameterized endowments. - * - * @param t - * @param bootstrap - * @param opts - * @param opts.zcf */ export const prepareMakeTestCOAKit = ( t: ExecutionContext, - bootstrap: Awaited>['bootstrap'], + { bootstrap, facadeServices, utils }: Awaited>, { zcf = Far('MockZCF', {}) } = {}, ) => { + t.log('exo setup - prepareCosmosOrchestrationAccount'); const { cosmosInterchainService, marshaller, rootZone, timer, vowTools } = bootstrap; @@ -33,21 +31,23 @@ export const prepareMakeTestCOAKit = ( const makeCosmosOrchestrationAccount = prepareCosmosOrchestrationAccount( rootZone.subZone('CosmosOrchAccount'), - makeRecorderKit, - vowTools, - // @ts-expect-error mocked zcf - zcf, + { + chainHub: facadeServices.chainHub, + makeRecorderKit, + timerService: timer, + vowTools, + // @ts-expect-error mocked zcf + zcf, + }, ); return async ({ storageNode = bootstrap.storage.rootNode.makeChildNode('accounts'), - chainId = 'cosmoshub-99', + chainId = 'cosmoshub-4', hostConnectionId = 'connection-0' as const, controllerConnectionId = 'connection-1' as const, - bondDenom = 'uatom', + icqEnabled = false, } = {}) => { - t.log('exo setup - prepareCosmosOrchestrationAccount'); - t.log('request account from orchestration service'); const cosmosOrchAccount = await E(cosmosInterchainService).makeAccount( chainId, @@ -55,15 +55,33 @@ export const prepareMakeTestCOAKit = ( controllerConnectionId, ); - const accountAddress = await E(cosmosOrchAccount).getAddress(); + let icqConnection: ICQConnection | undefined; + if (icqEnabled) { + t.log('requesting icq connection from orchestration service'); + icqConnection = await E(cosmosInterchainService).provideICQConnection( + controllerConnectionId, + ); + } + + const [chainAddress, localAddress, remoteAddress] = await Promise.all([ + E(cosmosOrchAccount).getAddress(), + E(cosmosOrchAccount).getLocalAddress(), + E(cosmosOrchAccount).getRemoteAddress(), + ]); t.log('make a CosmosOrchestrationAccount'); - const holder = makeCosmosOrchestrationAccount(accountAddress, bondDenom, { - account: cosmosOrchAccount, - storageNode: storageNode.makeChildNode(accountAddress.value), - icqConnection: undefined, - timer, - }); + const holder = makeCosmosOrchestrationAccount( + { chainAddress, localAddress, remoteAddress }, + { + account: cosmosOrchAccount, + storageNode: storageNode.makeChildNode(chainAddress.value), + icqConnection, + timer, + }, + ); + + t.log('register Agoric chain and BLD in ChainHub'); + utils.registerAgoricBld(); return holder; }; diff --git a/packages/orchestration/test/exos/make-test-loa-kit.ts b/packages/orchestration/test/exos/make-test-loa-kit.ts index 765e7d48f58..82656a7841a 100644 --- a/packages/orchestration/test/exos/make-test-loa-kit.ts +++ b/packages/orchestration/test/exos/make-test-loa-kit.ts @@ -1,9 +1,9 @@ +/* eslint-disable jsdoc/require-param -- ts types */ import { heapVowE as E } from '@agoric/vow/vat.js'; import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/recorder.js'; import { Far } from '@endo/far'; import { ExecutionContext } from 'ava'; import { prepareLocalOrchestrationAccountKit } from '../../src/exos/local-orchestration-account.js'; -import { makeChainHub } from '../../src/exos/chain-hub.js'; import { commonSetup } from '../supports.js'; /** @@ -13,19 +13,17 @@ import { commonSetup } from '../supports.js'; * * Helps reduce boilerplate in test files, and retains testing context through * parameterized endowments. - * - * @param t - * @param bootstrap - * @param opts - * @param opts.zcf */ export const prepareMakeTestLOAKit = ( t: ExecutionContext, - bootstrap: Awaited>['bootstrap'], + { + bootstrap, + facadeServices: { chainHub }, + utils, + }: Awaited>, { zcf = Far('MockZCF', {}) } = {}, ) => { - const { timer, localchain, marshaller, rootZone, vowTools, agoricNames } = - bootstrap; + const { timer, localchain, marshaller, rootZone, vowTools } = bootstrap; const { makeRecorderKit } = prepareRecorderKitMakers( rootZone.mapStore('recorder'), @@ -34,12 +32,15 @@ export const prepareMakeTestLOAKit = ( const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit( rootZone, - makeRecorderKit, - // @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer - zcf, - timer, - vowTools, - makeChainHub(agoricNames, vowTools), + { + makeRecorderKit, + // @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer + zcf, + timerService: timer, + vowTools, + chainHub, + localchain, + }, ); return async ({ @@ -56,11 +57,14 @@ export const prepareMakeTestLOAKit = ( account: lca, address: harden({ value: address, - chainId: 'agoric-n', + chainId: 'agoric-3', encoding: 'bech32', }), storageNode: storageNode.makeChildNode(address), }); + + t.log('register Agoric chain and BLD in ChainHub'); + utils.registerAgoricBld(); return account; }; }; diff --git a/packages/orchestration/test/exos/portfolio-holder-kit.test.ts b/packages/orchestration/test/exos/portfolio-holder-kit.test.ts index 216764b64e1..62f48203f25 100644 --- a/packages/orchestration/test/exos/portfolio-holder-kit.test.ts +++ b/packages/orchestration/test/exos/portfolio-holder-kit.test.ts @@ -7,8 +7,8 @@ import { prepareMakeTestLOAKit } from './make-test-loa-kit.js'; import { prepareMakeTestCOAKit } from './make-test-coa-kit.js'; test('portfolio holder kit behaviors', async t => { - const { bootstrap } = await commonSetup(t); - const { rootZone, storage, vowTools } = bootstrap; + const common = await commonSetup(t); + const { rootZone, storage, vowTools } = common.bootstrap; const storageNode = storage.rootNode.makeChildNode('accounts'); /** @@ -23,8 +23,10 @@ test('portfolio holder kit behaviors', async t => { }, }); - const makeTestCOAKit = prepareMakeTestCOAKit(t, bootstrap, { zcf: mockZcf }); - const makeTestLOAKit = prepareMakeTestLOAKit(t, bootstrap, { zcf: mockZcf }); + const makeTestCOAKit = prepareMakeTestCOAKit(t, common, { + zcf: mockZcf, + }); + const makeTestLOAKit = prepareMakeTestLOAKit(t, common, { zcf: mockZcf }); const makeCosmosAccount = async ({ chainId, hostConnectionId, @@ -70,14 +72,13 @@ test('portfolio holder kit behaviors', async t => { const cosmosAccount = await E(holder).getAccount('cosmoshub'); t.is( cosmosAccount, - // @ts-expect-error type mismatch between kit and OrchestrationAccountI accounts.cosmoshub, 'same account holder kit provided is returned', ); const { invitationMakers } = await E(holder).asContinuingOffer(); - const delegateInv = await E(invitationMakers).MakeInvitation( + const delegateInv = await E(invitationMakers).Proxying( 'cosmoshub', 'Delegate', [ @@ -98,7 +99,7 @@ test('portfolio holder kit behaviors', async t => { // note: mocked zcf (we are not in a contract) returns inv description // @ts-expect-error Argument of type 'string' is not assignable to parameter of type 'Vow' 'Delegate', - 'any invitation maker accessible via MakeInvitation', + 'any invitation maker accessible via Proxying', ); const osmosisAccount = await makeCosmosAccount({ @@ -109,12 +110,15 @@ test('portfolio holder kit behaviors', async t => { const osmosisTopic = (await E(osmosisAccount).getPublicTopics()).account; - // @ts-expect-error type mismatch between kit and OrchestrationAccountI - await E(holder).addAccount('osmosis', osmosisAccount, osmosisTopic); + await E(holder).addAccount( + 'osmosis', + osmosisAccount, + // @ts-expect-error the promise from `subscriber.getUpdateSince` can't be used in a flow + osmosisTopic, + ); t.is( await E(holder).getAccount('osmosis'), - // @ts-expect-error type mismatch between kit and OrchestrationAccountI osmosisAccount, 'new accounts can be added', ); diff --git a/packages/orchestration/test/facade-durability.test.ts b/packages/orchestration/test/facade-durability.test.ts new file mode 100644 index 00000000000..3952ec59c7e --- /dev/null +++ b/packages/orchestration/test/facade-durability.test.ts @@ -0,0 +1,231 @@ +import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; + +import { makeIssuerKit } from '@agoric/ertp'; +import { reincarnate } from '@agoric/swingset-liveslots/tools/setup-vat-data.js'; +import { prepareSwingsetVowTools } from '@agoric/vow/vat.js'; +import { setupZCFTest } from '@agoric/zoe/test/unitTests/zcf/setupZcfTest.js'; +import type { CosmosChainInfo, IBCConnectionInfo } from '../src/cosmos-api.js'; +import fetchedChainInfo from '../src/fetched-chain-info.js'; // Refresh with scripts/refresh-chain-info.ts +import type { Chain } from '../src/orchestration-api.js'; +import { denomHash } from '../src/utils/denomHash.js'; +import { provideOrchestration } from '../src/utils/start-helper.js'; +import { commonSetup, provideDurableZone } from './supports.js'; + +const test = anyTest; + +const mockChainInfo: CosmosChainInfo = harden({ + chainId: 'mock-1', + icaEnabled: false, + icqEnabled: false, + pfmEnabled: false, + ibcHooksEnabled: false, + stakingTokens: [{ denom: 'umock' }], +}); +const mockChainConnection: IBCConnectionInfo = { + id: 'connection-0', + client_id: '07-tendermint-2', + counterparty: { + client_id: '07-tendermint-2', + connection_id: 'connection-1', + }, + state: 3 /* IBCConnectionState.STATE_OPEN */, + transferChannel: { + portId: 'transfer', + channelId: 'channel-1', + counterPartyChannelId: 'channel-1', + counterPartyPortId: 'transfer', + ordering: 1 /* Order.ORDER_UNORDERED */, + state: 3 /* IBCConnectionState.STATE_OPEN */, + version: 'ics20-1', + }, +}; + +test.serial('chain info', async t => { + const { bootstrap, facadeServices, commonPrivateArgs } = await commonSetup(t); + + const { zcf } = await setupZCFTest(); + + // After setupZCFTest because this disables relaxDurabilityRules + // which breaks Zoe test setup's fakeVatAdmin + const zone = provideDurableZone('test'); + const vt = prepareSwingsetVowTools(zone); + + const orchKit = provideOrchestration( + zcf, + zone.mapStore('test'), + { + agoricNames: facadeServices.agoricNames, + timerService: facadeServices.timerService, + storageNode: commonPrivateArgs.storageNode, + orchestrationService: facadeServices.orchestrationService, + localchain: facadeServices.localchain, + }, + commonPrivateArgs.marshaller, + ); + + const { chainHub, orchestrate } = orchKit; + + chainHub.registerChain('mock', mockChainInfo); + chainHub.registerConnection( + 'agoric-3', + mockChainInfo.chainId, + mockChainConnection, + ); + + const handle = orchestrate('mock', {}, async orc => { + return orc.getChain('mock'); + }); + + const result = (await vt.when(handle())) as Chain; + t.deepEqual(await vt.when(result.getChainInfo()), mockChainInfo); +}); + +test.serial('faulty chain info', async t => { + const { facadeServices, commonPrivateArgs } = await commonSetup(t); + + // XXX relax again so setupZCFTest can run. This is also why the tests are serial. + reincarnate({ relaxDurabilityRules: true }); + const { zcf } = await setupZCFTest(); + + // After setupZCFTest because this disables relaxDurabilityRules + // which breaks Zoe test setup's fakeVatAdmin + const zone = provideDurableZone('test'); + const vt = prepareSwingsetVowTools(zone); + + const orchKit = provideOrchestration( + zcf, + zone.mapStore('test'), + { + agoricNames: facadeServices.agoricNames, + timerService: facadeServices.timerService, + storageNode: commonPrivateArgs.storageNode, + orchestrationService: facadeServices.orchestrationService, + localchain: facadeServices.localchain, + }, + commonPrivateArgs.marshaller, + ); + + const { chainHub, orchestrate } = orchKit; + + const { stakingTokens, ...sansStakingTokens } = mockChainInfo; + + chainHub.registerChain('mock', sansStakingTokens); + chainHub.registerConnection( + 'agoric-3', + mockChainInfo.chainId, + mockChainConnection, + ); + + const handle = orchestrate('mock', {}, async orc => { + const chain = await orc.getChain('mock'); + const account = await chain.makeAccount(); + return account; + }); + + await t.throwsAsync(vt.when(handle()), { + message: 'chain info lacks staking denom', + }); +}); + +test.serial('asset / denom info', async t => { + const { facadeServices, commonPrivateArgs } = await commonSetup(t); + + // XXX relax again + reincarnate({ relaxDurabilityRules: true }); + const { zcf } = await setupZCFTest(); + const zone = provideDurableZone('test'); + const vt = prepareSwingsetVowTools(zone); + const orchKit = provideOrchestration( + zcf, + zone.mapStore('test'), + { + agoricNames: facadeServices.agoricNames, + timerService: facadeServices.timerService, + storageNode: commonPrivateArgs.storageNode, + orchestrationService: facadeServices.orchestrationService, + localchain: facadeServices.localchain, + }, + commonPrivateArgs.marshaller, + ); + const { chainHub, orchestrate } = orchKit; + + chainHub.registerChain('agoric', fetchedChainInfo.agoric); + chainHub.registerChain(mockChainInfo.chainId, mockChainInfo); + chainHub.registerConnection( + 'agoric-3', + mockChainInfo.chainId, + mockChainConnection, + ); + + chainHub.registerAsset('utoken1', { + chainName: mockChainInfo.chainId, + baseName: mockChainInfo.chainId, + baseDenom: 'utoken1', + }); + + const { channelId } = mockChainConnection.transferChannel; + const agDenom = `ibc/${denomHash({ denom: 'utoken1', channelId })}`; + const { brand } = makeIssuerKit('Token1'); + t.log(`utoken1 over ${channelId}: ${agDenom}`); + chainHub.registerAsset(agDenom, { + chainName: 'agoric', + baseName: mockChainInfo.chainId, + baseDenom: 'utoken1', + brand, + }); + + const handle = orchestrate( + 'useDenoms', + { brand }, + // eslint-disable-next-line no-shadow + async (orc, { brand }) => { + const c1 = await orc.getChain(mockChainInfo.chainId); + + { + const actual = orc.getDenomInfo('utoken1'); + console.log('actual', actual); + const info = await actual.chain.getChainInfo(); + t.deepEqual(info, mockChainInfo); + + t.deepEqual(actual, { + base: c1, + chain: c1, + baseDenom: 'utoken1', + brand: undefined, + }); + } + + const ag = await orc.getChain('agoric'); + { + const actual = orc.getDenomInfo(agDenom); + + t.deepEqual(actual, { + chain: ag, + base: c1, + baseDenom: 'utoken1', + brand, + }); + } + }, + ); + + await vt.when(handle()); + + chainHub.registerChain('anotherChain', mockChainInfo); + chainHub.registerConnection('agoric-3', 'anotherChain', mockChainConnection); + chainHub.registerAsset('utoken2', { + chainName: 'anotherChain', + baseName: 'anotherChain', + baseDenom: 'utoken2', + }); + + const missingGetChain = orchestrate('missing getChain', {}, async orc => { + const actual = orc.getDenomInfo('utoken2'); + }); + + await t.throwsAsync(vt.when(missingGetChain()), { + message: 'use getChain("anotherChain") before getDenomInfo("utoken2")', + }); +}); + +test.todo('contract upgrade'); diff --git a/packages/orchestration/test/facade.test.ts b/packages/orchestration/test/facade.test.ts index 5132770fa5a..8ee3e4aaa45 100644 --- a/packages/orchestration/test/facade.test.ts +++ b/packages/orchestration/test/facade.test.ts @@ -1,53 +1,21 @@ +/* eslint-disable @jessie.js/safe-await-separator */ import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; +import type { VowTools } from '@agoric/vow'; import { prepareSwingsetVowTools } from '@agoric/vow/vat.js'; import { setupZCFTest } from '@agoric/zoe/test/unitTests/zcf/setupZcfTest.js'; -import { reincarnate } from '@agoric/swingset-liveslots/tools/setup-vat-data.js'; -import type { CosmosChainInfo, IBCConnectionInfo } from '../src/cosmos-api.js'; -import type { Chain } from '../src/orchestration-api.js'; +import { makeHeapZone } from '@agoric/zone'; +import type { TestFn } from 'ava'; +import type { OrchestrationFlow } from '../src/orchestration-api.js'; import { provideOrchestration } from '../src/utils/start-helper.js'; -import { commonSetup, provideDurableZone } from './supports.js'; +import { commonSetup } from './supports.js'; -const test = anyTest; - -export const mockChainInfo: CosmosChainInfo = harden({ - chainId: 'mock-1', - icaEnabled: false, - icqEnabled: false, - pfmEnabled: false, - ibcHooksEnabled: false, - stakingTokens: [{ denom: 'umock' }], -}); -export const mockChainConnection: IBCConnectionInfo = { - id: 'connection-0', - client_id: '07-tendermint-2', - counterparty: { - client_id: '07-tendermint-2', - connection_id: 'connection-1', - prefix: { - key_prefix: '', - }, - }, - state: 3 /* IBCConnectionState.STATE_OPEN */, - transferChannel: { - portId: 'transfer', - channelId: 'channel-1', - counterPartyChannelId: 'channel-1', - counterPartyPortId: 'transfer', - ordering: 1 /* Order.ORDER_UNORDERED */, - state: 3 /* IBCConnectionState.STATE_OPEN */, - version: 'ics20-1', - }, -}; - -test.serial('chain info', async t => { - const { bootstrap, facadeServices, commonPrivateArgs } = await commonSetup(t); +const test = anyTest as TestFn<{ vt: VowTools; orchestrateAll: any; zcf: ZCF }>; +test.beforeEach(async t => { + const { facadeServices, commonPrivateArgs } = await commonSetup(t); const { zcf } = await setupZCFTest(); - - // After setupZCFTest because this disables relaxDurabilityRules - // which breaks Zoe test setup's fakeVatAdmin - const zone = provideDurableZone('test'); + const zone = makeHeapZone(); const vt = prepareSwingsetVowTools(zone); const orchKit = provideOrchestration( @@ -63,68 +31,47 @@ test.serial('chain info', async t => { commonPrivateArgs.marshaller, ); - const { chainHub, orchestrate } = orchKit; - - chainHub.registerChain('mock', mockChainInfo); - chainHub.registerConnection( - 'agoric-3', - mockChainInfo.chainId, - mockChainConnection, - ); - - const handle = orchestrate('mock', {}, async orc => { - return orc.getChain('mock'); - }); - - const result = (await vt.when(handle())) as Chain; - t.deepEqual(await vt.when(result.getChainInfo()), mockChainInfo); + const { orchestrateAll } = orchKit; + t.context = { vt, orchestrateAll, zcf }; }); -test.serial('faulty chain info', async t => { - const { facadeServices, commonPrivateArgs } = await commonSetup(t); - - // XXX relax again so setupZCFTest can run. This is also why the tests are serial. - reincarnate({ relaxDurabilityRules: true }); - const { zcf } = await setupZCFTest(); +test('calls between flows', async t => { + const { vt, orchestrateAll, zcf } = t.context; - // After setupZCFTest because this disables relaxDurabilityRules - // which breaks Zoe test setup's fakeVatAdmin - const zone = provideDurableZone('test'); - const vt = prepareSwingsetVowTools(zone); + const flows = { + outer(orch, ctx, ...recipients) { + return ctx.peerFlows.inner('Hello', ...recipients); + }, + inner(orch, ctx, ...strs) { + return Promise.resolve(strs.join(' ')); + }, + } as Record>; - const orchKit = provideOrchestration( + const { outer, outer2, inner } = orchestrateAll(flows, { + peerFlows: flows, zcf, - zone.mapStore('test'), - { - agoricNames: facadeServices.agoricNames, - timerService: facadeServices.timerService, - storageNode: commonPrivateArgs.storageNode, - orchestrationService: facadeServices.orchestrationService, - localchain: facadeServices.localchain, - }, - commonPrivateArgs.marshaller, - ); + }); - const { chainHub, orchestrate } = orchKit; + t.deepEqual(await vt.when(inner('a', 'b', 'c')), 'a b c'); + t.deepEqual(await vt.when(outer('a', 'b', 'c')), 'Hello a b c'); +}); - const { stakingTokens, ...sansStakingTokens } = mockChainInfo; +test('context mapping individual flows', async t => { + const { vt, orchestrateAll, zcf } = t.context; - chainHub.registerChain('mock', sansStakingTokens); - chainHub.registerConnection( - 'agoric-3', - mockChainInfo.chainId, - mockChainConnection, - ); + const flows = { + outer(orch, ctx, ...recipients) { + return ctx.peerFlows.inner('Hello', ...recipients); + }, + inner(orch, ctx, ...strs) { + return Promise.resolve(strs.join(' ')); + }, + } as Record>; - const handle = orchestrate('mock', {}, async orc => { - const chain = await orc.getChain('mock'); - const account = await chain.makeAccount(); - return account; + const { outer } = orchestrateAll(flows, { + peerFlows: { inner: flows.inner }, + zcf, }); - await t.throwsAsync(vt.when(handle()), { - message: 'chain info lacks staking denom', - }); + t.deepEqual(await vt.when(outer('a', 'b', 'c')), 'Hello a b c'); }); - -test.todo('contract upgrade'); diff --git a/packages/orchestration/test/fixtures/query-flows.contract.test.ts b/packages/orchestration/test/fixtures/query-flows.contract.test.ts new file mode 100644 index 00000000000..f3c9b88d6fe --- /dev/null +++ b/packages/orchestration/test/fixtures/query-flows.contract.test.ts @@ -0,0 +1,307 @@ +import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; +import type { TestFn } from 'ava'; +import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; +import type { Instance } from '@agoric/zoe/src/zoeService/utils.js'; +import { E } from '@endo/far'; +import path from 'path'; +import { JsonSafe, toRequestQueryJson, typedJson } from '@agoric/cosmic-proto'; +import { + QueryAllBalancesRequest, + QueryAllBalancesResponse, + QueryBalanceRequest, + QueryBalanceResponse, +} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; +import type { ResponseQuery } from '@agoric/cosmic-proto/tendermint/abci/types.js'; +import { decodeBase64 } from '@endo/base64'; +import { + LOCALCHAIN_DEFAULT_ADDRESS, + LOCALCHAIN_QUERY_ALL_BALANCES_RESPONSE, +} from '@agoric/vats/tools/fake-bridge.js'; +import { commonSetup } from '../supports.js'; +import { defaultMockAckMap } from '../ibc-mocks.js'; +import { + buildQueryPacketString, + buildQueryResponseString, +} from '../../tools/ibc-mocks.js'; + +const dirname = path.dirname(new URL(import.meta.url).pathname); + +const contractName = 'query-flows'; +const contractFile = `${dirname}/../../src/fixtures/query-flows.contract.js`; +type StartFn = + typeof import('../../src/fixtures/query-flows.contract.js').start; + +type TestContext = Awaited> & { + zoe: ZoeService; + instance: Instance; +}; + +const test = anyTest as TestFn; + +const decodeBalanceQueryResponse = (results: JsonSafe[]) => + results.map(({ key }) => QueryBalanceResponse.decode(decodeBase64(key))); + +test.beforeEach(async t => { + const setupContext = await commonSetup(t); + const { + bootstrap: { storage }, + commonPrivateArgs, + } = setupContext; + + const { zoe, bundleAndInstall } = await setUpZoeForTest(); + + t.log('contract coreEval', contractName); + const installation = await bundleAndInstall(contractFile); + + const storageNode = await E(storage.rootNode).makeChildNode(contractName); + const { instance } = await E(zoe).startInstance( + installation, + undefined, + {}, + { ...commonPrivateArgs, storageNode }, + ); + + t.context = { + ...setupContext, + zoe, + instance, + }; +}); + +test('send query from chain object', async t => { + const { + bootstrap: { vowTools: vt }, + zoe, + instance, + utils: { inspectDibcBridge }, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(instance); + const balanceQuery = toRequestQueryJson( + QueryBalanceRequest.toProtoMsg({ + address: 'cosmos1test', + denom: 'uatom', + }), + ); + { + t.log('send query on chain with icqEnabled: true'); + const inv = E(publicFacet).makeSendICQQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'osmosis', + msgs: [balanceQuery], + }); + const offerResultString = await vt.when(E(userSeat).getOfferResult()); + const offerResult = JSON.parse(offerResultString); + t.log(offerResult); + t.assert(offerResult[0].key, 'base64 encoded response returned'); + const decodedResponse = decodeBalanceQueryResponse(offerResult); + t.deepEqual(decodedResponse, [ + { + balance: { + amount: '0', + denom: 'uatom', + }, + }, + ]); + } + { + t.log('send query on chain with icqEnabled: false'); + const inv = E(publicFacet).makeSendICQQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'cosmoshub', + msgs: [balanceQuery], + }); + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: 'Queries not available for chain "cosmoshub-4"', + }); + } + { + t.log('sending subsequent queries should not result in new ICQ channels'); + const inv = E(publicFacet).makeSendICQQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'osmosis', + msgs: [balanceQuery], + }); + await vt.when(E(userSeat).getOfferResult()); + const { bridgeDowncalls } = await inspectDibcBridge(); + + const portBindings = bridgeDowncalls.filter(x => x.method === 'bindPort'); + t.is(portBindings.length, 1, 'only one port bound'); + t.regex(portBindings?.[0]?.packet.source_port, /icqcontroller-/); + const icqChannelInits = bridgeDowncalls.filter( + x => x.method === 'startChannelOpenInit' && x.version === 'icq-1', + ); + t.is(icqChannelInits.length, 1, 'only one ICQ channel opened'); + const sendPacketCalls = bridgeDowncalls.filter( + x => + x.method === 'sendPacket' && x.packet.source_port === 'icqcontroller-1', + ); + t.is(sendPacketCalls.length, 2, 'sent two queries'); + } + const proto3JsonQuery = typedJson( + '/cosmos.bank.v1beta1.QueryAllBalancesRequest', + { + address: LOCALCHAIN_DEFAULT_ADDRESS, + }, + ); + { + t.log('send a query from the localchain'); + const inv = E(publicFacet).makeSendLocalQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + msgs: [proto3JsonQuery], + }); + const offerResultString = await vt.when(E(userSeat).getOfferResult()); + const offerResult = JSON.parse(offerResultString); + t.log(offerResult); + t.deepEqual( + offerResult, + [ + { + error: '', + height: '1', + reply: { + '@type': '/cosmos.bank.v1beta1.QueryAllBalancesResponse', + balances: [ + { denom: 'ubld', amount: '10' }, + { denom: 'uist', amount: '10' }, + ], + pagination: { + nextKey: null, + total: '2', + }, + }, + }, + ], + 'balances returned', + ); + } + { + t.log('remote chain facade guards offer with M.arrayOf(ICQMsgShape)'); + const inv = E(publicFacet).makeSendICQQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'osmosis', + // @ts-expect-error intentional error + msgs: [proto3JsonQuery], + }); + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: /.*Must have missing properties \["path","data"\]/, + }); + } +}); + +test('send query from orch account in an async-flow', async t => { + const { + bootstrap: { vowTools: vt }, + zoe, + instance, + mocks: { ibcBridge }, + utils: { inspectDibcBridge }, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(instance); + + { + t.log('send query from orchAccount on chain with icqEnabled: true'); + const inv = E(publicFacet).makeAccountAndGetBalanceQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'osmosis', + denom: 'uatom', + }); + const offerResultString = await vt.when(E(userSeat).getOfferResult()); + const offerResult = JSON.parse(offerResultString); + t.deepEqual(offerResult, { + value: '[0n]', + denom: 'uatom', + }); + } + { + t.log('send query from orchAccount that times out'); + const inv = E(publicFacet).makeAccountAndGetBalanceQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'osmosis', + denom: 'notarealdenom', + }); + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: 'ABCI code: 5: error handling packet: see events for details', + }); + } + { + t.log('send query from orchAccount on chain with icqEnabled: false'); + const inv = E(publicFacet).makeAccountAndGetBalanceQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'cosmoshub', + denom: 'uatom,', + }); + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: 'Queries not available for chain "cosmoshub-4"', + }); + } + + t.log("creating add'l account should not result in new ICQ channels"); + const { bridgeDowncalls } = await inspectDibcBridge(); + const icqPortBindings = bridgeDowncalls.filter( + x => + x.method === 'bindPort' && x.packet.source_port.includes('icqcontroller'), + ); + t.is(icqPortBindings.length, 1, 'only one icq port bound'); + const icqChannelInits = bridgeDowncalls.filter( + x => x.method === 'startChannelOpenInit' && x.version === 'icq-1', + ); + t.is(icqChannelInits.length, 1, 'only one ICQ channel opened'); + + { + t.log( + 'send allBalances query from orchAccount on chain with icqEnabled: true', + ); + const [query, ack] = [ + buildQueryPacketString([ + QueryAllBalancesRequest.toProtoMsg({ + address: 'osmo1test3', + }), + ]), + buildQueryResponseString(QueryAllBalancesResponse, { + balances: [], + }), + ]; + ibcBridge.setAddressPrefix('osmo'); + ibcBridge.setMockAck({ + ...defaultMockAckMap, + [query]: ack, + }); + const inv = E(publicFacet).makeAccountAndGetBalancesQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'osmosis', + }); + const offerResultString = await vt.when(E(userSeat).getOfferResult()); + const offerResult = JSON.parse(offerResultString); + t.deepEqual(offerResult, []); + } + + { + t.log('send balance query from localOrchAccount'); + const inv = E(publicFacet).makeAccountAndGetBalanceQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'agoric', + denom: 'ibc/idk', + }); + const offerResultString = await vt.when(E(userSeat).getOfferResult()); + const offerResult = JSON.parse(offerResultString); + t.deepEqual(offerResult, { + // fake bridge mocked to return 10n for all denoms + value: '[10n]', + denom: 'ibc/idk', + }); + } + { + t.log('send allBalances query from localOrchAccount'); + const inv = E(publicFacet).makeAccountAndGetBalancesQueryInvitation(); + const userSeat = E(zoe).offer(inv, {}, undefined, { + chainName: 'agoric', + }); + const offerResultString = await vt.when(E(userSeat).getOfferResult()); + const offerResult = JSON.parse(offerResultString); + const expectedBalances = LOCALCHAIN_QUERY_ALL_BALANCES_RESPONSE.map(x => ({ + ...x, + value: `[${x.value}n]`, + })); + t.deepEqual(offerResult, expectedBalances); + } +}); diff --git a/packages/orchestration/test/fixtures/zoe-tools.contract.js b/packages/orchestration/test/fixtures/zoe-tools.contract.js new file mode 100644 index 00000000000..67e3ae5268c --- /dev/null +++ b/packages/orchestration/test/fixtures/zoe-tools.contract.js @@ -0,0 +1,112 @@ +/** + * @file Testing fixture that takes shortcuts to ensure we hit error paths + * around `zoeTools.localTransfer` and `zoeTools.withdrawToSeat` + */ + +import { makeSharedStateRecord } from '@agoric/async-flow'; +import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; +import { E } from '@endo/far'; +import { M } from '@endo/patterns'; +import { withOrchestration } from '../../src/utils/start-helper.js'; +import { prepareChainHubAdmin } from '../../src/exos/chain-hub-admin.js'; +import * as flows from './zoe-tools.flows.js'; +import fetchedChainInfo from '../../src/fetched-chain-info.js'; + +const { values } = Object; + +/** + * @import {TimerService} from '@agoric/time'; + * @import {LocalChain} from '@agoric/vats/src/localchain.js'; + * @import {NameHub} from '@agoric/vats'; + * @import {Remote} from '@agoric/vow'; + * @import {Zone} from '@agoric/zone'; + * @import {AssetInfo} from '@agoric/vats/src/vat-bank.js'; + * @import {CosmosInterchainService} from '@agoric/orchestration'; + * @import {OrchestrationTools} from '../../src/utils/start-helper.js'; + */ + +/** + * @typedef {{ + * localchain: Remote; + * orchestrationService: Remote; + * storageNode: Remote; + * timerService: Remote; + * agoricNames: Remote; + * }} OrchestrationPowers + */ + +/** + * @param {ZCF} zcf + * @param {OrchestrationPowers & { + * marshaller: Marshaller; + * }} privateArgs + * @param {Zone} zone + * @param {OrchestrationTools} tools + */ +const contract = async ( + zcf, + privateArgs, + zone, + { chainHub, orchestrateAll, zoeTools }, +) => { + const contractState = makeSharedStateRecord( + /** @type {{ account: OrchestrationAccount | undefined }} */ { + localAccount: undefined, + }, + ); + + const creatorFacet = prepareChainHubAdmin(zone, chainHub); + + const orchFns = orchestrateAll(flows, { + zcf, + contractState, + zoeTools, + }); + + // register assets in ChainHub ourselves, + // UNTIL https://github.com/Agoric/agoric-sdk/issues/9752 + const assets = /** @type {AssetInfo[]} */ ( + await E(E(privateArgs.agoricNames).lookup('vbankAsset')).values() + ); + for (const chainName of ['agoric', 'cosmoshub']) { + chainHub.registerChain(chainName, fetchedChainInfo[chainName]); + } + for (const brand of values(zcf.getTerms().brands)) { + const info = assets.find(a => a.brand === brand); + if (info) { + chainHub.registerAsset(info.denom, { + // we are only registering agoric assets, so safe to use denom and + // hardcode chainName + baseDenom: info.denom, + baseName: 'agoric', + chainName: 'agoric', + brand, + }); + } + } + + const publicFacet = zone.exo( + 'Zoe Tools Test PF', + M.interface('Zoe Tools Test PF', { + makeDepositSendInvitation: M.callWhen().returns(InvitationShape), + makeDepositInvitation: M.callWhen().returns(InvitationShape), + makeWithdrawInvitation: M.callWhen().returns(InvitationShape), + }), + { + makeDepositSendInvitation() { + return zcf.makeInvitation(orchFns.depositSend, 'depositSend'); + }, + makeDepositInvitation() { + return zcf.makeInvitation(orchFns.deposit, 'deposit'); + }, + makeWithdrawInvitation() { + return zcf.makeInvitation(orchFns.withdraw, 'withdraw'); + }, + }, + ); + + return { publicFacet, creatorFacet }; +}; + +export const start = withOrchestration(contract); +harden(start); diff --git a/packages/orchestration/test/fixtures/zoe-tools.flows.js b/packages/orchestration/test/fixtures/zoe-tools.flows.js new file mode 100644 index 00000000000..15338b63d2a --- /dev/null +++ b/packages/orchestration/test/fixtures/zoe-tools.flows.js @@ -0,0 +1,128 @@ +/** + * @file Testing fixture that takes shortcuts to ensure we hit error paths + * around `zoeTools.localTransfer` and `zoeTools.withdrawToSeat`. + */ + +import { makeError, q } from '@endo/errors'; +import { mustMatch } from '@endo/patterns'; +import { ChainAddressShape } from '../../src/typeGuards.js'; + +const { values } = Object; + +/** + * @import {GuestInterface} from '@agoric/async-flow'; + * @import {Orchestrator, LocalAccountMethods, OrchestrationAccountI, OrchestrationFlow, ChainAddress} from '@agoric/orchestration'; + * @import {ZoeTools} from '../../src/utils/zoe-tools.js'; + */ + +/** + * Accept one or more deposits and send them to an account on the local chain + * using MsgSend. Intentionally skips a check to ensure an asset is in vbank to + * facilitate failure path testing of ZoeTools. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {{ localAccount?: OrchestrationAccountI & LocalAccountMethods }} ctx.contractState + * @param {GuestInterface} ctx.zoeTools + * @param {ZCFSeat} seat + * @param {{ destAddr: ChainAddress }} offerArgs + */ +export const depositSend = async ( + orch, + { contractState, zoeTools: { localTransfer, withdrawToSeat } }, + seat, + offerArgs, +) => { + mustMatch(offerArgs, harden({ destAddr: ChainAddressShape })); + const { destAddr } = offerArgs; + assert(destAddr.value.startsWith('agoric1'), 'must send to a local address'); + + const { give } = seat.getProposal(); + + await null; + if (!contractState.localAccount) { + const agoricChain = await orch.getChain('agoric'); + contractState.localAccount = await agoricChain.makeAccount(); + } + + await localTransfer(seat, contractState.localAccount, give); + + try { + await contractState.localAccount.sendAll(destAddr, values(give)); + } catch (error) { + await withdrawToSeat(contractState.localAccount, seat, give); + const errMsg = makeError(`SendAll failed ${q(error)}`); + seat.exit(errMsg); + throw errMsg; + } + seat.exit(); +}; +harden(depositSend); + +/** + * Accept one or more deposits and transfer them to the contract's local + * account. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {{ localAccount?: OrchestrationAccountI & LocalAccountMethods }} ctx.contractState + * @param {GuestInterface} ctx.zoeTools + * @param {ZCFSeat} seat + */ +export const deposit = async ( + orch, + { contractState, zoeTools: { localTransfer } }, + seat, +) => { + const { give } = seat.getProposal(); + + await null; + if (!contractState.localAccount) { + const agoricChain = await orch.getChain('agoric'); + contractState.localAccount = await agoricChain.makeAccount(); + } + + try { + await localTransfer(seat, contractState.localAccount, give); + } catch (e) { + seat.exit(e); + throw e; + } + seat.exit(); +}; +harden(deposit); + +/** + * Withdraw funds from the contract's local account to the offer's seat. + * + * @satisfies {OrchestrationFlow} + * @param {Orchestrator} orch + * @param {object} ctx + * @param {{ localAccount?: OrchestrationAccountI & LocalAccountMethods }} ctx.contractState + * @param {GuestInterface} ctx.zoeTools + * @param {ZCFSeat} seat + */ +export const withdraw = async ( + orch, + { contractState, zoeTools: { withdrawToSeat } }, + seat, +) => { + const { want } = seat.getProposal(); + + await null; + if (!contractState.localAccount) { + const agoricChain = await orch.getChain('agoric'); + contractState.localAccount = await agoricChain.makeAccount(); + } + + try { + await withdrawToSeat(contractState.localAccount, seat, want); + } catch (e) { + seat.exit(e); + throw e; + } + seat.exit(); +}; +harden(withdraw); diff --git a/packages/orchestration/test/ibc-mocks.test.ts b/packages/orchestration/test/ibc-mocks.test.ts index 30a1d8e3c25..b970e0511d9 100644 --- a/packages/orchestration/test/ibc-mocks.test.ts +++ b/packages/orchestration/test/ibc-mocks.test.ts @@ -1,28 +1,34 @@ -import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import { QueryBalanceRequest, QueryBalanceResponse, } from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; +import { QueryDelegatorDelegationsResponse } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/query.js'; import { MsgDelegate, MsgDelegateResponse, } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; import { + CosmosQuery, + CosmosResponse, +} from '@agoric/cosmic-proto/icq/v1/packet.js'; +import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; +import { + buildMsgErrorString, buildMsgResponseString, + buildQueryPacketString, buildQueryResponseString, - buildMsgErrorString, buildTxPacketString, - buildQueryPacketString, + parseOutgoingTxPacket, } from '../tools/ibc-mocks.js'; -test('ibc-mocks - buildMsgResponseString matches observed values in e2e testing', t => { +test('buildMsgResponseString matches observed values in e2e testing', t => { t.is( buildMsgResponseString(MsgDelegateResponse, {}), 'eyJyZXN1bHQiOiJFaTBLS3k5amIzTnRiM011YzNSaGEybHVaeTUyTVdKbGRHRXhMazF6WjBSbGJHVm5ZWFJsVW1WemNHOXVjMlU9In0=', ); }); -test('ibc-mocks - buildMsgErrorString matches observed values in e2e testing', t => { +test('buildMsgErrorString matches observed values in e2e testing', t => { t.is( buildMsgErrorString(), 'eyJlcnJvciI6IkFCQ0kgY29kZTogNTogZXJyb3IgaGFuZGxpbmcgcGFja2V0OiBzZWUgZXZlbnRzIGZvciBkZXRhaWxzIn0=', @@ -37,7 +43,7 @@ test('ibc-mocks - buildMsgErrorString matches observed values in e2e testing', t ); }); -test('ibcMocks - buildQueryResponseString matches observed values in e2e testing', t => { +test('buildQueryResponseString matches observed values in e2e testing', t => { t.is( buildQueryResponseString(QueryBalanceResponse, { balance: { amount: '0', denom: 'uatom' }, @@ -47,30 +53,65 @@ test('ibcMocks - buildQueryResponseString matches observed values in e2e testing ); }); -test('ibcMocks - build Tx Packet', t => { - t.is( - buildTxPacketString([ - MsgDelegate.toProtoMsg({ - amount: { - denom: 'uatom', - amount: '10', - }, - delegatorAddress: 'cosmos1test', - validatorAddress: 'cosmosvaloper1test', - }), - ]), - 'eyJ0eXBlIjoxLCJkYXRhIjoiQ2xVS0l5OWpiM050YjNNdWMzUmhhMmx1Wnk1Mk1XSmxkR0V4TGsxelowUmxiR1ZuWVhSbEVpNEtDMk52YzIxdmN6RjBaWE4wRWhKamIzTnRiM04yWVd4dmNHVnlNWFJsYzNRYUN3b0ZkV0YwYjIwU0FqRXciLCJtZW1vIjoiIn0=', +test('build Tx Packet', t => { + const obj = { + amount: { + denom: 'uatom', + amount: '10', + }, + delegatorAddress: 'cosmos1test', + validatorAddress: 'cosmosvaloper1test', + }; + const encoded = buildTxPacketString([MsgDelegate.toProtoMsg(obj)]); + t.snapshot(encoded); + + const parsed = parseOutgoingTxPacket(encoded); + const decoded = MsgDelegate.decode(parsed.messages[0].value); + t.deepEqual(decoded, obj); +}); + +test('build Query Packet', t => { + const obj = { + address: 'cosmos1test', + denom: 'uatom', + }; + const b64 = buildQueryPacketString([QueryBalanceRequest.toProtoMsg(obj)]); + t.snapshot(b64); + + const { data } = JSON.parse(atob(b64)); + const decodedQuery = CosmosQuery.decode(Buffer.from(data, 'base64')); + const decodedRequest = QueryBalanceRequest.decode( + decodedQuery.requests[0].data, ); + t.deepEqual(decodedRequest, obj); }); -test('ibcMocks - build Query Packet', t => { - t.is( - buildQueryPacketString([ - QueryBalanceRequest.toProtoMsg({ - address: 'cosmos1test', - denom: 'uatom', - }), - ]), - 'eyJkYXRhIjoiQ2pvS0ZBb0xZMjl6Ylc5ek1YUmxjM1FTQlhWaGRHOXRFaUl2WTI5emJXOXpMbUpoYm1zdWRqRmlaWFJoTVM1UmRXVnllUzlDWVd4aGJtTmwiLCJtZW1vIjoiIn0=', +test('build Query Response', t => { + const obj = { + delegationResponses: [ + { + delegation: { + delegatorAddress: 'cosmos1test', + validatorAddress: 'cosmosvaloper1test', + shares: '1000000', + }, + balance: { denom: 'uatom', amount: '1000000' }, + }, + ], + }; + const encoded = buildQueryResponseString( + QueryDelegatorDelegationsResponse, + obj, ); + t.snapshot(encoded); + + const { result } = JSON.parse(atob(encoded)); + const { data } = JSON.parse(atob(result)); + const cosmosResponse = CosmosResponse.decode(Buffer.from(data, 'base64')); + const decodedResponseKey = cosmosResponse.responses[0].key; + + t.deepEqual(QueryDelegatorDelegationsResponse.decode(decodedResponseKey), { + ...obj, + pagination: undefined, + }); }); diff --git a/packages/orchestration/test/ibc-mocks.ts b/packages/orchestration/test/ibc-mocks.ts index 5aa40ce2e05..6992227ee34 100644 --- a/packages/orchestration/test/ibc-mocks.ts +++ b/packages/orchestration/test/ibc-mocks.ts @@ -1,3 +1,4 @@ +/** @file The mocks used in these tests */ import { QueryBalanceRequest, QueryBalanceResponse, @@ -15,12 +16,17 @@ import { MsgWithdrawDelegatorRewardResponse, } from '@agoric/cosmic-proto/cosmos/distribution/v1beta1/tx.js'; import type { Timestamp } from '@agoric/cosmic-proto/google/protobuf/timestamp.js'; +import { + MsgSend, + MsgSendResponse, +} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/tx.js'; import { buildMsgResponseString, buildQueryResponseString, buildMsgErrorString, buildTxPacketString, buildQueryPacketString, + createMockAckMap, } from '../tools/ibc-mocks.js'; /** @@ -51,6 +57,19 @@ const redelegation = { amount: '10', }, }; +const bankSend = { + fromAddress: 'cosmos1test', + toAddress: 'cosmos99test', + amount: [{ denom: 'uatom', amount: '10' }], +}; +const bankSendMulti = { + fromAddress: 'cosmos1test', + toAddress: 'cosmos99test', + amount: [ + { denom: 'uatom', amount: '10' }, + { denom: 'ibc/1234', amount: '10' }, + ], +}; export const UNBOND_PERIOD_SECONDS = 5n; @@ -95,15 +114,15 @@ export const protoMsgMocks = { balance: { amount: '0', denom: 'uatom' }, }), }, + bankSend: { + msg: buildTxPacketString([MsgSend.toProtoMsg(bankSend)]), + ack: buildMsgResponseString(MsgSendResponse, {}), + }, + bankSendMulti: { + msg: buildTxPacketString([MsgSend.toProtoMsg(bankSendMulti)]), + ack: buildMsgResponseString(MsgSendResponse, {}), + }, }; -export function createMockAckMap(mockMap: typeof protoMsgMocks) { - const res = Object.values(mockMap).reduce((acc, { msg, ack }) => { - acc[msg] = ack; - return acc; - }, {}); - return res; -} - export const defaultMockAckMap: Record = createMockAckMap(protoMsgMocks); diff --git a/packages/orchestration/test/network-fakes.test.ts b/packages/orchestration/test/network-fakes.test.ts index 9c70d14bb71..937807153b9 100644 --- a/packages/orchestration/test/network-fakes.test.ts +++ b/packages/orchestration/test/network-fakes.test.ts @@ -16,7 +16,7 @@ test.before(async t => { await t.context.setupIBCProtocol(); }); -test('network fakes - echo connection', async t => { +test('echo connection', async t => { const { portAllocator, networkVat } = t.context; // Allocate an echo port @@ -36,13 +36,13 @@ test('network fakes - echo connection', async t => { t.is(response, message, 'Echo returns the same message'); }); -test('network fakes - port allocator', async t => { +test('port allocator', async t => { const { portAllocator } = t.context; const customPort = await E(portAllocator).allocateCustomIBCPort('test-port'); t.is(await E(customPort).getLocalAddress(), '/ibc-port/custom-test-port'); }); -test('network fakes - ibc connection', async t => { +test('ibc connection', async t => { const { portAllocator } = t.context; // allocate ICA controller port and connect to remote chain diff --git a/packages/orchestration/test/network-fakes.ts b/packages/orchestration/test/network-fakes.ts index 18cbddc081a..9a948ace95d 100644 --- a/packages/orchestration/test/network-fakes.ts +++ b/packages/orchestration/test/network-fakes.ts @@ -1,7 +1,11 @@ +import { inspect } from 'node:util'; + import { VowTools } from '@agoric/vow'; import { + base64ToBytes, prepareEchoConnectionKit, prepareLoopbackProtocolHandler, + prepareNetworkPowers, preparePortAllocator, prepareRouterProtocol, } from '@agoric/network'; @@ -11,15 +15,20 @@ import type { IBCMethod, IBCEvent, ScopedBridgeManagerMethods, + IBCConnectionID, + IBCPortID, } from '@agoric/vats'; import { prepareCallbacks as prepareIBCCallbacks, prepareIBCProtocol, } from '@agoric/vats/src/ibc.js'; -import { BridgeId } from '@agoric/internal'; +import { BridgeId, makeTracer } from '@agoric/internal'; import { E, Far } from '@endo/far'; import type { Guarded } from '@endo/exo'; import { defaultMockAckMap, errorAcknowledgments } from './ibc-mocks.js'; +import { decodeProtobufBase64 } from '../tools/protobuf-decoder.js'; + +const trace = makeTracer('NetworkFakes'); /** * Mimic IBC Channel version negotation @@ -53,7 +62,11 @@ export const ibcBridgeMocks: { [T in ImplementedIBCEvents]: T extends 'channelOpenAck' ? ( obj: IBCMethod<'startChannelOpenInit'>, - opts: { bech32Prefix: string; sequence: number }, + opts: { + channelID: IBCChannelID; + counterpartyChannelID: IBCChannelID; + mockChainAddress: string; + }, ) => IBCEvent<'channelOpenAck'> : T extends 'acknowledgementPacket' ? ( @@ -64,24 +77,26 @@ export const ibcBridgeMocks: { } = { channelOpenAck: ( obj: IBCMethod<'startChannelOpenInit'>, - { bech32Prefix, sequence }: { bech32Prefix: string; sequence: number }, + { + channelID, + counterpartyChannelID, + mockChainAddress, + }: { + channelID: IBCChannelID; + counterpartyChannelID: IBCChannelID; + mockChainAddress: string; + }, ): IBCEvent<'channelOpenAck'> => { - const mocklID = Number(obj.packet.source_port.split('-').at(-1)); - const mockLocalChannelID: IBCChannelID = `channel-${mocklID}`; - const mockRemoteChannelID: IBCChannelID = `channel-${mocklID}`; - const mockChainAddress = - sequence > 0 ? `${bech32Prefix}1test${sequence}` : `${bech32Prefix}1test`; - return { type: 'IBC_EVENT', blockHeight: 99, blockTime: 1711571357, event: 'channelOpenAck', portID: obj.packet.source_port, - channelID: mockLocalChannelID, + channelID, counterparty: { port_id: obj.packet.destination_port, - channel_id: mockRemoteChannelID, + channel_id: counterpartyChannelID, }, counterpartyVersion: addParamsIfJsonVersion(obj.version, { address: mockChainAddress, @@ -119,7 +134,17 @@ export const ibcBridgeMocks: { }; type BridgeEvents = Array< - IBCEvent<'channelOpenAck'> | IBCEvent<'acknowledgementPacket'> + | IBCEvent<'channelOpenAck'> + | IBCEvent<'acknowledgementPacket'> + | IBCEvent<'channelCloseConfirm'> + | IBCEvent<'sendPacket'> +>; + +type BridgeDowncalls = Array< + | IBCMethod<'startChannelOpenInit'> + | IBCMethod<'startChannelCloseInit'> + | IBCMethod<'bindPort'> + | IBCMethod<'sendPacket'> >; /** @@ -133,9 +158,13 @@ export const makeFakeIBCBridge = ( zone: Zone, ): Guarded< ScopedBridgeManagerMethods<'dibc'> & { + addMockAck: (msgData: string, ackData: string) => void; setMockAck: (mockAckMap: Record) => void; setAddressPrefix: (addressPrefix: string) => void; - inspectDibcBridge: () => BridgeEvents; + inspectDibcBridge: () => { + bridgeEvents: BridgeEvents; + bridgeDowncalls: BridgeDowncalls; + }; } > => { let bridgeHandler: any; @@ -149,39 +178,102 @@ export const makeFakeIBCBridge = ( let ibcSequenceNonce = 0; /** * The number of channels created. Currently used as a proxy to increment - * fake account addresses. + * fake account addresses and channels. * @type {nubmer} */ let channelCount = 0; + let icaAccountCount = 0; let bech32Prefix = 'cosmos'; + /** + * Keep track channels requested by remote chain. Used as a proxy for + * counterpaty channel ids + */ + const remoteChannelMap: Record = {}; + /** * Packet byte string map of requests to responses * @type {Record} */ let mockAckMap = defaultMockAckMap; let bridgeEvents: BridgeEvents = []; + let bridgeDowncalls: BridgeDowncalls = []; + + /** + * Store remote mock addresses that have been distributed. + * If there's a `channelOpenInit` request for a PortId:ConnnectionId + * pair that's been previously established, let's reuse it to mimic + * the behavior of the ICS-27 protocol. + */ + type AddressKey = `${IBCPortID}:${IBCConnectionID}`; + const getAddressKey = ( + obj: IBCMethod<'startChannelOpenInit'>, + ): AddressKey => { + return `${obj.packet.source_port as IBCPortID}:${obj.hops[0] as IBCConnectionID}`; + }; + const addressMap = new Map(); return zone.exo('Fake IBC Bridge Manager', undefined, { getBridgeId: () => BridgeId.DIBC, toBridge: async obj => { + trace( + 'toBridge', + obj, + obj.packet?.data ? base64ToBytes(obj.packet.data) : undefined, + ); if (obj.type === 'IBC_METHOD') { + bridgeDowncalls = bridgeDowncalls.concat(obj); switch (obj.method) { case 'startChannelOpenInit': { + const connectionChannelCount = remoteChannelMap[obj.hops[0]] || 0; + const addressKey = getAddressKey(obj); + let mockChainAddress; + if (addressMap.has(addressKey)) { + mockChainAddress = addressMap.get(addressKey); + } else { + mockChainAddress = + icaAccountCount > 0 + ? `${bech32Prefix}1test${icaAccountCount}` + : `${bech32Prefix}1test`; + addressMap.set(addressKey, mockChainAddress); + } const ackEvent = ibcBridgeMocks.channelOpenAck(obj, { - bech32Prefix, - sequence: channelCount, + mockChainAddress, + channelID: `channel-${channelCount}`, + counterpartyChannelID: `channel-${connectionChannelCount}`, }); bridgeHandler?.fromBridge(ackEvent); bridgeEvents = bridgeEvents.concat(ackEvent); channelCount += 1; + if (obj.packet.source_port.includes('icacontroller')) { + icaAccountCount += 1; + } + remoteChannelMap[obj.hops[0]] = connectionChannelCount + 1; return undefined; } case 'sendPacket': { + const mockAckMapHasData = obj.packet.data in mockAckMap; + if (!mockAckMapHasData) { + trace( + `sendPacket acking err because no mock ack for b64 data key: '${obj.packet.data}'`, + ); + try { + const decoded = decodeProtobufBase64( + JSON.parse(base64ToBytes(obj.packet.data)).data, + ); + trace( + 'Fix the source of this request or define a ack mapping for it:', + inspect(decoded, { depth: null }), + ); + } catch (err) { + trace('Could not decode packet data', err); + } + } const ackEvent = ibcBridgeMocks.acknowledgementPacket(obj, { sequence: ibcSequenceNonce, - acknowledgement: - mockAckMap?.[obj.packet.data] || errorAcknowledgments.error5, + acknowledgement: mockAckMapHasData + ? mockAckMap[obj.packet.data] + : errorAcknowledgments.error5, }); bridgeEvents = bridgeEvents.concat(ackEvent); ibcSequenceNonce += 1; @@ -195,6 +287,8 @@ export const makeFakeIBCBridge = ( return undefined; }, fromBridge: async obj => { + trace('fromBridge', obj); + bridgeEvents = bridgeEvents.concat(obj); if (!bridgeHandler) throw Error('no handler!'); return bridgeHandler.fromBridge(obj); }, @@ -213,21 +307,27 @@ export const makeFakeIBCBridge = ( * @param ackMap */ setMockAck: (ackMap: typeof mockAckMap) => { + trace('setMockAck', ackMap); mockAckMap = ackMap; }, + addMockAck: (msgData: string, ackData: string) => { + trace('addMockAck', msgData, ackData); + mockAckMap[msgData] = ackData; + }, /** * Set a new bech32 prefix for the mocked ICA channel. Defaults to `cosmos`. * * @param newPrefix */ setAddressPrefix: (newPrefix: typeof bech32Prefix) => { + trace('setAddressPrefix', newPrefix); bech32Prefix = newPrefix; }, /** * for debugging and testing */ inspectDibcBridge() { - return bridgeEvents; + return { bridgeEvents, bridgeDowncalls }; }, }); }; @@ -236,8 +336,9 @@ export const setupFakeNetwork = ( zone: Zone, { vowTools }: { vowTools: VowTools }, ) => { - const makeRouterProtocol = prepareRouterProtocol(zone, vowTools); - const makePortAllocator = preparePortAllocator(zone, vowTools); + const powers = prepareNetworkPowers(zone, vowTools); + const makeRouterProtocol = prepareRouterProtocol(zone, powers); + const makePortAllocator = preparePortAllocator(zone, powers); const makeLoopbackProtocolHandler = prepareLoopbackProtocolHandler( zone, vowTools, diff --git a/packages/orchestration/test/service.test.ts b/packages/orchestration/test/service.test.ts deleted file mode 100644 index 20996a83ae8..00000000000 --- a/packages/orchestration/test/service.test.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; -import { toRequestQueryJson } from '@agoric/cosmic-proto'; -import { - QueryBalanceRequest, - QueryBalanceResponse, -} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; -import { - MsgDelegate, - MsgDelegateResponse, -} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; -import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js'; -import { matches } from '@endo/patterns'; -import { heapVowE as E } from '@agoric/vow/vat.js'; -import { decodeBase64 } from '@endo/base64'; -import { commonSetup } from './supports.js'; -import { ChainAddressShape } from '../src/typeGuards.js'; -import { tryDecodeResponse } from '../src/utils/cosmos.js'; - -test('makeICQConnection returns an ICQConnection', async t => { - const { - bootstrap: { cosmosInterchainService }, - } = await commonSetup(t); - - const CONTROLLER_CONNECTION_ID = 'connection-0'; - - const icqConnection = await E(cosmosInterchainService).provideICQConnection( - CONTROLLER_CONNECTION_ID, - ); - const [localAddr, remoteAddr] = await Promise.all([ - E(icqConnection).getLocalAddress(), - E(icqConnection).getRemoteAddress(), - ]); - t.log(icqConnection, { - localAddr, - remoteAddr, - }); - t.regex(localAddr, /ibc-port\/icqcontroller-\d+/); - t.regex( - remoteAddr, - new RegExp(`/ibc-hop/${CONTROLLER_CONNECTION_ID}`), - 'remote address contains provided connectionId', - ); - t.regex( - remoteAddr, - /icqhost\/unordered\/icq-1/, - 'remote address contains icqhost port, unordered ordering, and icq-1 version string', - ); - - const icqConnection2 = await E(cosmosInterchainService).provideICQConnection( - CONTROLLER_CONNECTION_ID, - ); - const localAddr2 = await E(icqConnection2).getLocalAddress(); - t.is(localAddr, localAddr2, 'provideICQConnection is idempotent'); - - const [result] = await E(icqConnection).query([ - toRequestQueryJson( - QueryBalanceRequest.toProtoMsg({ - address: 'cosmos1test', - denom: 'uatom', - }), - ), - ]); - - t.like(QueryBalanceResponse.decode(decodeBase64(result.key)), { - balance: { amount: '0', denom: 'uatom' }, - }); -}); - -test('makeAccount returns a ChainAccount', async t => { - const { - bootstrap: { cosmosInterchainService }, - } = await commonSetup(t); - - const CHAIN_ID = 'cosmoshub-99'; - const HOST_CONNECTION_ID = 'connection-0'; - const CONTROLLER_CONNECTION_ID = 'connection-1'; - - const account = await E(cosmosInterchainService).makeAccount( - CHAIN_ID, - HOST_CONNECTION_ID, - CONTROLLER_CONNECTION_ID, - ); - const [localAddr, remoteAddr, chainAddr] = await Promise.all([ - E(account).getLocalAddress(), - E(account).getRemoteAddress(), - E(account).getAddress(), - ]); - t.log(account, { - localAddr, - remoteAddr, - chainAddr, - }); - t.regex(localAddr, /ibc-port\/icacontroller-\d+/); - t.regex( - remoteAddr, - new RegExp(`/ibc-hop/${CONTROLLER_CONNECTION_ID}`), - 'remote address contains provided connectionId', - ); - t.regex( - remoteAddr, - /icahost\/ordered/, - 'remote address contains icahost port, ordered ordering', - ); - t.regex( - remoteAddr, - /"version":"ics27-1"(.*)"encoding":"proto3"/, - 'remote address contains version and encoding in version string', - ); - - t.true(matches(chainAddr, ChainAddressShape)); - t.regex(chainAddr.value, /cosmos1test/); - - const delegateMsg = Any.toJSON( - MsgDelegate.toProtoMsg({ - delegatorAddress: 'cosmos1test', - validatorAddress: 'cosmosvaloper1test', - amount: { denom: 'uatom', amount: '10' }, - }), - ); - - const delegateResp = await E(account).executeEncodedTx([delegateMsg]); - t.deepEqual( - tryDecodeResponse(delegateResp, MsgDelegateResponse.fromProtoMsg), - {}, - ); - - await E(account).close(); - await t.throwsAsync( - E(account).executeEncodedTx([delegateMsg]), - { - message: 'Connection closed', - }, - 'cannot execute transaction if connection is closed', - ); -}); diff --git a/packages/orchestration/test/snapshots/chain-info.test.js.md b/packages/orchestration/test/snapshots/chain-info.test.js.md index 05d523eba3b..9a7bab61b77 100644 --- a/packages/orchestration/test/snapshots/chain-info.test.js.md +++ b/packages/orchestration/test/snapshots/chain-info.test.js.md @@ -21,12 +21,6 @@ Generated by [AVA](https://avajs.dev). ], }, ], - [ - 'agoriclocal', - { - chainId: 'agoriclocal', - }, - ], [ 'celestia', { @@ -92,11 +86,6 @@ Generated by [AVA](https://avajs.dev). { chainId: 'noble-1', icqEnabled: false, - stakingTokens: [ - { - denom: 'ustake', - }, - ], }, ], [ diff --git a/packages/orchestration/test/snapshots/chain-info.test.js.snap b/packages/orchestration/test/snapshots/chain-info.test.js.snap index 4cea37213e3..f75f04ba200 100644 Binary files a/packages/orchestration/test/snapshots/chain-info.test.js.snap and b/packages/orchestration/test/snapshots/chain-info.test.js.snap differ diff --git a/packages/orchestration/test/snapshots/ibc-mocks.test.ts.md b/packages/orchestration/test/snapshots/ibc-mocks.test.ts.md new file mode 100644 index 00000000000..3c44283847e --- /dev/null +++ b/packages/orchestration/test/snapshots/ibc-mocks.test.ts.md @@ -0,0 +1,23 @@ +# Snapshot report for `test/ibc-mocks.test.ts` + +The actual snapshot is saved in `ibc-mocks.test.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## build Tx Packet + +> Snapshot 1 + + 'eyJ0eXBlIjoxLCJkYXRhIjoiQ2xVS0l5OWpiM050YjNNdWMzUmhhMmx1Wnk1Mk1XSmxkR0V4TGsxelowUmxiR1ZuWVhSbEVpNEtDMk52YzIxdmN6RjBaWE4wRWhKamIzTnRiM04yWVd4dmNHVnlNWFJsYzNRYUN3b0ZkV0YwYjIwU0FqRXciLCJtZW1vIjoiIn0=' + +## build Query Packet + +> Snapshot 1 + + 'eyJkYXRhIjoiQ2pvS0ZBb0xZMjl6Ylc5ek1YUmxjM1FTQlhWaGRHOXRFaUl2WTI5emJXOXpMbUpoYm1zdWRqRmlaWFJoTVM1UmRXVnllUzlDWVd4aGJtTmwiLCJtZW1vIjoiIn0=' + +## build Query Response + +> Snapshot 1 + + 'eyJyZXN1bHQiOiJleUprWVhSaElqb2lRMnhSZVZWbmNGRkRhbmRMUXpKT2RtTXlNWFpqZWtZd1dsaE9NRVZvU21waU0wNTBZak5PTWxsWGVIWmpSMVo1VFZoU2JHTXpVV0ZIVkVWM1RVUkJkMDFFUVhkTlJFRjNUVVJCZDAxRVFYZE5SRUYzVFVSQmQwMUVRVk5GUVc5R1pGZEdNR0l5TUZOQ2VrVjNUVVJCZDAxRVFUMGlmUT09In0=' diff --git a/packages/orchestration/test/snapshots/ibc-mocks.test.ts.snap b/packages/orchestration/test/snapshots/ibc-mocks.test.ts.snap new file mode 100644 index 00000000000..0464dbf7c87 Binary files /dev/null and b/packages/orchestration/test/snapshots/ibc-mocks.test.ts.snap differ diff --git a/packages/orchestration/test/staking-ops.test.ts b/packages/orchestration/test/staking-ops.test.ts index 0a975f4e290..4b9dc90ff53 100644 --- a/packages/orchestration/test/staking-ops.test.ts +++ b/packages/orchestration/test/staking-ops.test.ts @@ -10,6 +10,7 @@ import { MsgDelegateResponse, MsgUndelegateResponse, } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; +import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js'; import { makeFakeStorageKit } from '@agoric/internal/src/storage-test-utils.js'; import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; import { makeNotifierFromSubscriber } from '@agoric/notifier'; @@ -20,13 +21,32 @@ import { prepareVowTools, heapVowE as E } from '@agoric/vow/vat.js'; import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/recorder.js'; import { buildZoeManualTimer } from '@agoric/zoe/tools/manualTimer.js'; import { makeDurableZone } from '@agoric/zone/durable.js'; -import { decodeBase64 } from '@endo/base64'; +import { decodeBase64, encodeBase64 } from '@endo/base64'; import { Far } from '@endo/far'; import { Timestamp } from '@agoric/cosmic-proto/google/protobuf/timestamp.js'; +import { makeNameHubKit } from '@agoric/vats'; import { prepareCosmosOrchestrationAccountKit } from '../src/exos/cosmos-orchestration-account.js'; -import type { ChainAddress, IcaAccount, ICQConnection } from '../src/types.js'; -import { encodeTxResponse } from '../src/utils/cosmos.js'; +import type { + ChainAddress, + DenomAmount, + IcaAccount, + ICQConnection, +} from '../src/types.js'; import { MILLISECONDS_PER_SECOND } from '../src/utils/time.js'; +import { makeChainHub } from '../src/exos/chain-hub.js'; + +/** + * @param {unknown} response + * @param {(msg: any) => Any} toProtoMsg + * @returns {string} + */ +const encodeTxResponse = (response, toProtoMsg) => { + const protoMsg = toProtoMsg(response); + const any1 = Any.fromPartial(protoMsg); + const any2 = Any.fromPartial({ value: Any.encode(any1).finish() }); + const ackStr = encodeBase64(Any.encode(any2).finish()); + return ackStr; +}; const trivialDelegateResponse = encodeTxResponse( {}, @@ -43,11 +63,15 @@ test('MsgDelegateResponse trivial response', t => { const configStaking = { acct1: { value: 'agoric1spy36ltduehs5dmszfrp792f0k2emcntrql3nx', + 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-0', + 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-0', }, validator: { value: 'agoric1valoper234', encoding: 'bech32', - chainId: 'agoriclocal', + chainId: 'agoric-3', }, delegations: { agoric1valoper234: { denom: 'uatom', amount: '200' }, @@ -150,13 +174,11 @@ const makeScenario = () => { return doMessage(msgs[0]); }, executeTx: () => Fail`mock`, - close: () => Fail`mock`, - deposit: () => Fail`mock`, - getPurse: () => Fail`mock`, - prepareTransfer: () => Fail`mock`, - getLocalAddress: () => Fail`mock`, - getRemoteAddress: () => Fail`mock`, + deactivate: () => Fail`mock`, + getLocalAddress: () => configStaking.acct1.localAddress, + getRemoteAddress: () => configStaking.acct1.remoteAddress, getPort: () => Fail`mock`, + reactivate: () => Fail`mock`, }); return { account, calls }; }; @@ -206,6 +228,7 @@ const makeScenario = () => { timeStep: TICK, eventLoopIteration, }); + const { nameHub: agoricNames } = makeNameHubKit(); return { baggage, zone, @@ -216,57 +239,92 @@ const makeScenario = () => { icqConnection, vowTools, ...mockZCF(), + agoricNames, }; }; test('makeAccount() writes to storage', async t => { const s = makeScenario(); const { account, timer } = s; - const { makeRecorderKit, storageNode, zcf, icqConnection, vowTools, zone } = - s; - const make = prepareCosmosOrchestrationAccountKit( + const { + agoricNames, + makeRecorderKit, + storageNode, + zcf, + icqConnection, + vowTools, zone, + } = s; + const make = prepareCosmosOrchestrationAccountKit(zone, { + chainHub: makeChainHub(agoricNames, vowTools), makeRecorderKit, + timerService: timer, vowTools, zcf, - ); - - const { holder } = make(account.getAddress(), 'uatom', { - account, - storageNode, - icqConnection, - timer, }); + + const { holder } = make( + { + chainAddress: account.getAddress(), + localAddress: account.getLocalAddress(), + remoteAddress: account.getRemoteAddress(), + }, + { + account, + storageNode, + icqConnection, + timer, + }, + ); const { publicSubscribers } = await E.when(holder.asContinuingOffer()); const accountNotifier = makeNotifierFromSubscriber( + // @ts-expect-error the promise from `subscriber.getUpdateSince` can't be used in a flow publicSubscribers.account.subscriber, ); const storageUpdate = await E(accountNotifier).getUpdateSince(); t.deepEqual(storageUpdate, { updateCount: 1n, - value: '', + value: { + localAddress: configStaking.acct1.localAddress, + remoteAddress: configStaking.acct1.remoteAddress, + }, }); }); test('withdrawRewards() on StakingAccountHolder formats message correctly', async t => { const s = makeScenario(); const { account, calls, timer } = s; - const { makeRecorderKit, storageNode, zcf, icqConnection, vowTools, zone } = - s; - const make = prepareCosmosOrchestrationAccountKit( + const { + agoricNames, + makeRecorderKit, + storageNode, + zcf, + icqConnection, + vowTools, zone, + } = s; + const make = prepareCosmosOrchestrationAccountKit(zone, { + chainHub: makeChainHub(agoricNames, vowTools), makeRecorderKit, + timerService: timer, vowTools, zcf, - ); + }); // Higher fidelity tests below use invitationMakers. - const { holder } = make(account.getAddress(), 'uatom', { - account, - storageNode, - icqConnection, - timer, - }); + const { holder } = make( + { + chainAddress: account.getAddress(), + localAddress: account.getLocalAddress(), + remoteAddress: account.getRemoteAddress(), + }, + { + account, + storageNode, + icqConnection, + timer, + }, + ); const { validator } = configStaking; const actual = await E(holder).withdrawReward(validator); t.deepEqual(actual, [{ denom: 'uatom', value: 2n }]); @@ -281,6 +339,7 @@ test(`delegate; redelegate using invitationMakers`, async t => { const s = makeScenario(); const { account, calls, timer } = s; const { + agoricNames, makeRecorderKit, storageNode, zcf, @@ -289,21 +348,28 @@ test(`delegate; redelegate using invitationMakers`, async t => { vowTools, zone, } = s; - const aBrand = Far('Token') as Brand<'nat'>; - const makeAccountKit = prepareCosmosOrchestrationAccountKit( - zone, + const makeAccountKit = prepareCosmosOrchestrationAccountKit(zone, { + chainHub: makeChainHub(agoricNames, vowTools), makeRecorderKit, + timerService: timer, vowTools, zcf, - ); - - const { invitationMakers } = makeAccountKit(account.getAddress(), 'uatom', { - account, - storageNode, - icqConnection, - timer, }); + const { invitationMakers } = makeAccountKit( + { + chainAddress: account.getAddress(), + localAddress: account.getLocalAddress(), + remoteAddress: account.getRemoteAddress(), + }, + { + account, + storageNode, + icqConnection, + timer, + }, + ); + const { validator, delegations } = configStaking; { const value = BigInt(Object.values(delegations)[0].amount); @@ -340,7 +406,7 @@ test(`delegate; redelegate using invitationMakers`, async t => { { const { validator: dst } = configRedelegate; const value = BigInt(Object.values(configRedelegate.delegations)[0].amount); - const anAmount = { brand: aBrand, value }; + const anAmount = { denom: 'uatom', value }; const toRedelegate = await E(invitationMakers).Redelegate( validator, dst, @@ -363,6 +429,7 @@ test(`withdraw rewards using invitationMakers`, async t => { const s = makeScenario(); const { account, calls, timer } = s; const { + agoricNames, makeRecorderKit, storageNode, zcf, @@ -371,20 +438,28 @@ test(`withdraw rewards using invitationMakers`, async t => { vowTools, zone, } = s; - const makeAccountKit = prepareCosmosOrchestrationAccountKit( - zone, + const makeAccountKit = prepareCosmosOrchestrationAccountKit(zone, { + chainHub: makeChainHub(agoricNames, vowTools), makeRecorderKit, + timerService: timer, vowTools, zcf, - ); - - const { invitationMakers } = makeAccountKit(account.getAddress(), 'uatom', { - account, - storageNode, - icqConnection, - timer, }); + const { invitationMakers } = makeAccountKit( + { + chainAddress: account.getAddress(), + localAddress: account.getLocalAddress(), + remoteAddress: account.getRemoteAddress(), + }, + { + account, + storageNode, + icqConnection, + timer, + }, + ); + const { validator } = configStaking; const toWithdraw = await E(invitationMakers).WithdrawReward(validator); const seat = E(zoe).offer(toWithdraw); @@ -402,6 +477,7 @@ test(`undelegate waits for unbonding period`, async t => { const s = makeScenario(); const { account, calls, timer } = s; const { + agoricNames, makeRecorderKit, storageNode, zcf, @@ -410,31 +486,38 @@ test(`undelegate waits for unbonding period`, async t => { vowTools, zone, } = s; - const makeAccountKit = prepareCosmosOrchestrationAccountKit( - zone, + const makeAccountKit = prepareCosmosOrchestrationAccountKit(zone, { + chainHub: makeChainHub(agoricNames, vowTools), makeRecorderKit, + timerService: timer, vowTools, zcf, - ); - - const { invitationMakers } = makeAccountKit(account.getAddress(), 'uatom', { - account, - storageNode, - icqConnection, - timer, }); + const { invitationMakers } = makeAccountKit( + { + chainAddress: account.getAddress(), + localAddress: account.getLocalAddress(), + remoteAddress: account.getRemoteAddress(), + }, + { + account, + storageNode, + icqConnection, + timer, + }, + ); + const { validator, delegations } = configStaking; - const value = BigInt(Object.values(delegations)[0].amount); - const anAmount = { brand: Far('Token'), value } as Amount<'nat'>; + const { denom, amount } = Object.values(delegations)[0]; const delegation = { - shares: `${anAmount.value}`, - validatorAddress: validator.value, + amount: { denom, value: BigInt(amount) } as DenomAmount, + validator, }; const toUndelegate = await E(invitationMakers).Undelegate([delegation]); const current = () => E(timer).getCurrentTimestamp().then(time.format); - t.log(await current(), 'undelegate', delegation.shares); + t.log(await current(), 'undelegate', delegation.amount.value); const seat = E(zoe).offer(toUndelegate); const beforeDone = E(timer) diff --git a/packages/orchestration/test/supports.ts b/packages/orchestration/test/supports.ts index b3754320e28..21603240711 100644 --- a/packages/orchestration/test/supports.ts +++ b/packages/orchestration/test/supports.ts @@ -13,7 +13,7 @@ import { makeFakeLocalchainBridge, makeFakeTransferBridge, } from '@agoric/vats/tools/fake-bridge.js'; -import { prepareVowTools } from '@agoric/vow'; +import { prepareSwingsetVowTools } from '@agoric/vow/vat.js'; import type { Installation } from '@agoric/zoe/src/zoeService/utils.js'; import { buildZoeManualTimer } from '@agoric/zoe/tools/manualTimer.js'; import { withAmountUtils } from '@agoric/zoe/tools/test-utils.js'; @@ -21,9 +21,13 @@ import { makeHeapZone, type Zone } from '@agoric/zone'; import { makeDurableZone } from '@agoric/zone/durable.js'; import { E } from '@endo/far'; import type { ExecutionContext } from 'ava'; +import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; import { registerKnownChains } from '../src/chain-info.js'; import { prepareCosmosInterchainService } from '../src/exos/cosmos-interchain-service.js'; import { setupFakeNetwork } from './network-fakes.js'; +import { buildVTransferEvent } from '../tools/ibc-mocks.js'; +import { makeChainHub } from '../src/exos/chain-hub.js'; +import fetchedChainInfo from '../src/fetched-chain-info.js'; export { makeFakeLocalchainBridge, @@ -43,7 +47,10 @@ export const commonSetup = async (t: ExecutionContext) => { const bld = withAmountUtils(makeIssuerKit('BLD')); const ist = withAmountUtils(makeIssuerKit('IST')); - const { bankManager, pourPayment } = await makeFakeBankManagerKit(); + const bankBridgeMessages = [] as any[]; + const { bankManager, pourPayment } = await makeFakeBankManagerKit({ + onToBridge: obj => bankBridgeMessages.push(obj), + }); await E(bankManager).addAsset('ubld', 'BLD', 'Staking Token', bld.issuerKit); await E(bankManager).addAsset( 'uist', @@ -56,6 +63,7 @@ export const commonSetup = async (t: ExecutionContext) => { const { mint: _b, ...bldSansMint } = bld; const { mint: _i, ...istSansMint } = ist; // XXX real bankManager does this. fake should too? + // TODO https://github.com/Agoric/agoric-sdk/issues/9966 await makeWellKnownSpaces(agoricNamesAdmin, t.log, ['vbankAsset']); await E(E(agoricNamesAdmin).lookupAdmin('vbankAsset')).update( 'uist', @@ -68,8 +76,19 @@ export const commonSetup = async (t: ExecutionContext) => { displayInfo: { IOU: true }, }), ); + await E(E(agoricNamesAdmin).lookupAdmin('vbankAsset')).update( + 'ubld', + /** @type {AssetInfo} */ harden({ + brand: bld.brand, + issuer: bld.issuer, + issuerName: 'BLD', + denom: 'ubld', + proposedName: 'BLD', + displayInfo: { IOU: true }, + }), + ); - const vowTools = prepareVowTools(rootZone.subZone('vows')); + const vowTools = prepareSwingsetVowTools(rootZone.subZone('vows')); const transferBridge = makeFakeTransferBridge(rootZone); const { makeBridgeTargetKit } = prepareBridgeTargetModule( @@ -90,9 +109,9 @@ export const commonSetup = async (t: ExecutionContext) => { finisher.useRegistry(bridgeTargetKit.targetRegistry); await E(transferBridge).initHandler(bridgeTargetKit.bridgeHandler); - const localBrigeMessages = [] as any[]; + const localBridgeMessages = [] as any[]; const localchainBridge = makeFakeLocalchainBridge(rootZone, obj => - localBrigeMessages.push(obj), + localBridgeMessages.push(obj), ); const localchain = prepareLocalChainTools( rootZone.subZone('localchain'), @@ -124,6 +143,46 @@ export const commonSetup = async (t: ExecutionContext) => { await registerKnownChains(agoricNamesAdmin, () => {}); + let ibcSequenceNonce = 0n; + /** simulate incoming message as if the transfer completed over IBC */ + const transmitTransferAck = async () => { + // assume this is called after each outgoing IBC transfer + ibcSequenceNonce += 1n; + // let the promise for the transfer start + await eventLoopIteration(); + const lastMsgTransfer = localBridgeMessages.at(-1).messages[0]; + await E(transferBridge).fromBridge( + buildVTransferEvent({ + receiver: lastMsgTransfer.receiver, + sender: lastMsgTransfer.sender, + target: lastMsgTransfer.sender, + sourceChannel: lastMsgTransfer.sourceChannel, + sequence: ibcSequenceNonce, + }), + ); + // let the bridge handler finish + await eventLoopIteration(); + }; + + const chainHub = makeChainHub(agoricNames, vowTools); + + /** + * Register BLD if it's not already registered. + * Does not work with `withOrchestration` contracts, as these have their own + * ChainHub. Use `ChainHubAdmin` instead. + */ + const registerAgoricBld = () => { + if (!chainHub.getAsset('ubld')) { + chainHub.registerChain('agoric', fetchedChainInfo.agoric); + chainHub.registerAsset('ubld', { + chainName: 'agoric', + baseName: 'agoric', + baseDenom: 'ubld', + brand: bld.brand, + }); + } + }; + return { bootstrap: { agoricNames, @@ -131,11 +190,13 @@ export const commonSetup = async (t: ExecutionContext) => { bankManager, timer, localchain, + // TODO remove; bootstrap doesn't havemarshaller marshaller, cosmosInterchainService, // TODO remove; bootstrap doesn't have a zone rootZone: rootZone.subZone('contract'), storage, + // TODO remove; bootstrap doesn't have vowTools vowTools, }, brands: { @@ -156,14 +217,18 @@ export const commonSetup = async (t: ExecutionContext) => { }, facadeServices: { agoricNames, + chainHub, localchain, orchestrationService: cosmosInterchainService, timerService: timer, }, utils: { pourPayment, - inspectLocalBridge: () => harden([...localBrigeMessages]), + inspectLocalBridge: () => harden([...localBridgeMessages]), inspectDibcBridge: () => E(ibcBridge).inspectDibcBridge(), + inspectBankBridge: () => harden([...bankBridgeMessages]), + registerAgoricBld, + transmitTransferAck, }, }; }; diff --git a/packages/orchestration/test/types.test-d.ts b/packages/orchestration/test/types.test-d.ts index 92f9c8de758..84a6b69b5be 100644 --- a/packages/orchestration/test/types.test-d.ts +++ b/packages/orchestration/test/types.test-d.ts @@ -1,22 +1,33 @@ /** * @file pure types types, no runtime, ignored by Ava */ -import { expectNotType, expectType } from 'tsd'; -import { typedJson } from '@agoric/cosmic-proto'; + +import type { HostInterface, HostOf } from '@agoric/async-flow'; +import { JsonSafe, typedJson } from '@agoric/cosmic-proto'; +import type { + QueryAllBalancesResponse, + QueryBalanceResponse, +} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; import type { MsgDelegateResponse } from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; -import type { QueryAllBalancesResponse } from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js'; +import type { ResponseQuery } from '@agoric/cosmic-proto/tendermint/abci/types.js'; import type { Vow, VowTools } from '@agoric/vow'; -import type { GuestAsyncFunc, HostInterface, HostOf } from '@agoric/async-flow'; +import type { ResolvedPublicTopic } from '@agoric/zoe/src/contractSupport/topics.js'; +import type { Passable } from '@endo/marshal'; +import { expectAssignable, expectNotType, expectType } from 'tsd'; +import { prepareCosmosOrchestrationAccount } from '../src/exos/cosmos-orchestration-account.js'; +import type { LocalOrchestrationAccountKit } from '../src/exos/local-orchestration-account.js'; +import type { OrchestrationFacade } from '../src/facade.js'; import type { + Chain, ChainAddress, + ChainInfo, + CosmosChainInfo, CosmosValidatorAddress, - StakingAccountActions, + DenomAmount, OrchestrationAccount, Orchestrator, + StakingAccountActions, } from '../src/types.js'; -import type { LocalOrchestrationAccountKit } from '../src/exos/local-orchestration-account.js'; -import { prepareCosmosOrchestrationAccount } from '../src/exos/cosmos-orchestration-account.js'; -import type { OrchestrationFacade } from '../src/facade.js'; import type { ResolvedContinuingOfferResult } from '../src/utils/zoe-tools.js'; const anyVal = null as any; @@ -67,13 +78,10 @@ expectNotType(chainAddr); const makeCosmosOrchestrationAccount = prepareCosmosOrchestrationAccount( anyVal, anyVal, - anyVal, - anyVal, ); makeCosmosOrchestrationAccount( anyVal, anyVal, - anyVal, ) satisfies HostInterface; } @@ -94,6 +102,30 @@ expectNotType(chainAddr); // Negative test expectNotType<() => Promise>(vowFn); + + const getDenomInfo: HostOf = null as any; + const chainHostOf = getDenomInfo('uatom').chain; + expectType>(chainHostOf.getChainInfo()); +} + +{ + // HostInterface + + const chain: Chain = null as any; + expectType>(chain.getChainInfo()); + const chainHostInterface: HostInterface> = null as any; + expectType>(chainHostInterface.getChainInfo()); + + const publicTopicRecord: HostInterface< + Record> + > = { + someTopic: { + subscriber: null as any, + storagePath: 'published.somewhere', + }, + }; + // @ts-expect-error the promise from `subscriber.getUpdateSince` can't be used in a flow + expectType>>(publicTopicRecord); } // HostOf with TransferSteps @@ -158,3 +190,80 @@ expectNotType(chainAddr); expectType>(h()); } } + +// Test LocalChain.query() +{ + type ChainFacade = Chain<{ chainId: 'agoriclocal' }>; + const localChain: ChainFacade = null as any; + const results = localChain.query([ + typedJson('/cosmos.bank.v1beta1.QueryBalanceRequest', { + address: 'agoric1pleab', + denom: 'ubld', + }), + typedJson('/cosmos.bank.v1beta1.QueryAllBalancesRequest', { + address: 'agoric1pleab', + }), + ] as const); + + expectType>(results); + expectType<{ reply: JsonSafe }>(results[0]); + expectType<{ reply: JsonSafe }>(results[1]); +} + +// Test RemoteCosmosChain.query() (icqEnabled: true) +{ + type ChainFacade = Chain; + const remoteChain: ChainFacade = null as any; + const results = remoteChain.query([ + { + path: '/cosmos.staking.v1beta1.Query/Delegation', + data: 'base64bytes=', + height: '1', + prove: true, + }, + { + path: '/cosmos.bank.v1beta1.Query/Balance', + data: 'base64bytes=', + height: '1', + prove: true, + }, + ] as const); + + expectType>(results); + expectType>(results[0]); + expectType>(results[1]); +} + +// Test RemoteCosmosChain.query() (icqEnabled: false) +{ + type ChainFacade = Chain; + const remoteChain: ChainFacade = null as any; + + expectType(remoteChain.query); + + // @ts-expect-error query will throw an error + const results = remoteChain.query([ + { + path: '/cosmos.bank.v1beta1.Query/Balance', + data: 'base64bytes=', + height: '1', + prove: true, + }, + ] as const); +} + +{ + const addr = { + chainId: 'chainId', + encoding: 'bech32', + value: 'agoric1valoperfoo', + }; + expectAssignable(addr); + const denomAmount = { denom: 'bld', value: 10n }; + expectAssignable(denomAmount); + + // XXX when these types are interfaces this test fails. + // TODO https://github.com/Agoric/agoric-sdk/issues/9822 + expectAssignable(addr as CosmosValidatorAddress); + expectAssignable(denomAmount as DenomAmount); +} diff --git a/packages/orchestration/test/utils/address.test.ts b/packages/orchestration/test/utils/address.test.ts index 5e624feb000..9012edc9da3 100644 --- a/packages/orchestration/test/utils/address.test.ts +++ b/packages/orchestration/test/utils/address.test.ts @@ -54,8 +54,8 @@ test('findAddressField', t => { findAddressField( '/ibc-hop/connection-0/ibc-port/icahost/ordered/{"version":"ics27-1","controllerConnectionId":"connection-0","hostConnectionId":"connection-1","address":"","encoding":"proto3","txType":"sdk_multi_msg"}', ), - '', - 'returns empty string if address is an empty string', + undefined, + 'returns undefined if address is an empty string', ); t.is( findAddressField( @@ -71,6 +71,13 @@ test('findAddressField', t => { 'osmo1m30khedzqy9msu4502u74ugmep30v69pzee370jkas57xhmjfgjqe67ayq', 'returns address when localAddrr is appended to version string', ); + t.is( + findAddressField( + '/ibc-hop/connection-0/ibc-port/icahost/ordered/{not valid JSON}', + ), + undefined, + 'returns undefined when JSON is malformed', + ); }); test('makeICQChannelAddress', t => { @@ -84,18 +91,14 @@ test('makeICQChannelAddress', t => { 'returns connection string when controllerConnectionId is provided', ); t.is( - makeICQChannelAddress('connection-0', { - version: 'icq-2', - }), + makeICQChannelAddress('connection-0', 'icq-2'), '/ibc-hop/connection-0/ibc-port/icqhost/unordered/icq-2', 'accepts custom version', ); t.throws( () => validateRemoteIbcAddress( - makeICQChannelAddress('connection-0', { - version: 'ic/q-/2', - }), + makeICQChannelAddress('connection-0', 'ic/q-/2'), ), { message: diff --git a/packages/orchestration/test/utils/cosmos.test.ts b/packages/orchestration/test/utils/cosmos.test.ts new file mode 100644 index 00000000000..f7f1c627a89 --- /dev/null +++ b/packages/orchestration/test/utils/cosmos.test.ts @@ -0,0 +1,32 @@ +import test from '@endo/ses-ava/prepare-endo.js'; +import { + toDenomAmount, + toTruncatedDenomAmount, +} from '../../src/utils/cosmos.js'; + +const denom = 'uosmo'; + +test('convert Coin amount', t => { + const amount = '100'; + const value = 100n; + t.deepEqual(toDenomAmount({ denom, amount }), { + denom, + value, + }); + t.deepEqual(toTruncatedDenomAmount({ denom, amount }), { + denom, + value, + }); +}); + +test('convert DecCoin amount', t => { + const amount = '100.01'; + const value = 100n; + t.throws(() => toDenomAmount({ denom, amount }), { + message: 'Cannot convert 100.01 to a BigInt', + }); + t.deepEqual(toTruncatedDenomAmount({ denom, amount }), { + denom, + value, + }); +}); diff --git a/packages/orchestration/test/utils/zoe-tools.test.ts b/packages/orchestration/test/utils/zoe-tools.test.ts new file mode 100644 index 00000000000..e9535ea919f --- /dev/null +++ b/packages/orchestration/test/utils/zoe-tools.test.ts @@ -0,0 +1,410 @@ +import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; +import type { TestFn } from 'ava'; + +import path from 'path'; +import { setUpZoeForTest } from '@agoric/zoe/tools/setup-zoe.js'; +import { makeIssuerKit } from '@agoric/ertp'; +import { AmountUtils, withAmountUtils } from '@agoric/zoe/tools/test-utils.js'; +import { Issuer } from '@agoric/ertp/src/types.js'; +import { E } from '@endo/far'; +import { + LOCALCHAIN_DEFAULT_ADDRESS, + SIMULATED_ERRORS, +} from '@agoric/vats/tools/fake-bridge.js'; +import { commonSetup } from '../supports.js'; + +const dirname = path.dirname(new URL(import.meta.url).pathname); + +const contractName = 'zoeTools'; +const contractFile = `${dirname}/../../test/fixtures/zoe-tools.contract.js`; +type StartFn = typeof import('../../test/fixtures/zoe-tools.contract.js').start; + +type TestContext = Awaited> & { + brands: Awaited>['brands'] & { + moolah: AmountUtils; + }; + zoe: ZoeService; + contractKit: StartedInstanceKit; + getIssuer: (keyword: string) => Issuer<'nat'>; +}; + +const test = anyTest as TestFn; + +test.beforeEach(async t => { + t.log('bootstrap, orchestration core-eval'); + const common = await commonSetup(t); + const { + bootstrap, + commonPrivateArgs, + brands: { ist, bld }, + } = common; + + const moolah = withAmountUtils(makeIssuerKit('MOO')); + t.log('Making Moolah issuer kit', moolah); + + t.log('contract coreEval', contractName); + const { zoe, bundleAndInstall } = await setUpZoeForTest(); + const installation: Installation = + await bundleAndInstall(contractFile); + + const issuerKeywordRecord = harden({ + IST: ist.issuer, + BLD: bld.issuer, + MOO: moolah.issuer, + }); + t.log('issuerKeywordRecord', issuerKeywordRecord); + + const storageNode = await E(bootstrap.storage.rootNode).makeChildNode( + contractName, + ); + const contractKit = await E(zoe).startInstance( + installation, + issuerKeywordRecord, + {}, + { ...commonPrivateArgs, storageNode }, + ); + + const getIssuer = (key: string) => issuerKeywordRecord[key] as Issuer<'nat'>; + + t.context = { + ...common, + brands: { + ...common.brands, + moolah, + }, + contractKit, + getIssuer, + zoe, + }; +}); + +/** + * Tests to ensure `localTransfer` recovers when presented non-vbank asset(s) + * Also tests withdrawSeat, as it's used in the recovery path. + */ +test('zoeTool.localTransfer error paths', async t => { + const { + bootstrap, + brands: { ist, bld, moolah }, + utils: { pourPayment }, + contractKit, + zoe, + getIssuer, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(contractKit.instance); + const vt = bootstrap.vowTools; + + const destAddr = { + chainId: 'agoriclocal', + value: 'agoric1testrecipient', + encoding: 'bech32', + }; + + t.log('localTransfer recovers when presented non-vbank asset'); + { + const tenMoolah = moolah.make(10n); + const MOO = await E(moolah.mint).mintPayment(tenMoolah); + const userSeat = await E(zoe).offer( + E(publicFacet).makeDepositSendInvitation(), + { give: { MOO: tenMoolah } }, + { MOO }, + { + destAddr, + }, + ); + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: + 'One or more deposits failed ["[Error: key \\"[Alleged: MOO brand]\\" not found in collection \\"brandToAssetRecord\\"]"]', + }); + await E(userSeat).tryExit(); + const payouts = await E(userSeat).getPayouts(); + const payoutEntries = Object.entries(payouts); + t.is(payoutEntries.length, 1, 'expecting 1 MOO payout'); + for (const [kw, pmt] of payoutEntries) { + const payment = await getIssuer(kw).getAmountOf(pmt); + t.is(payment.value, 10n, `${kw} payment returned`); + } + } + + t.log('localTransfer recovers from: give: { IST, MOO }'); + { + const tenMoolah = moolah.make(10n); + const MOO = await E(moolah.mint).mintPayment(tenMoolah); + const tenStable = ist.make(10n); + const IST = await pourPayment(tenStable); + const userSeat = await E(zoe).offer( + E(publicFacet).makeDepositSendInvitation(), + { give: { IST: tenStable, MOO: tenMoolah } }, + { IST, MOO }, + { + destAddr, + }, + ); + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: + 'One or more deposits failed ["[Error: key \\"[Alleged: MOO brand]\\" not found in collection \\"brandToAssetRecord\\"]"]', + }); + await E(userSeat).tryExit(); + const payouts = await E(userSeat).getPayouts(); + const payoutEntries = Object.entries(payouts); + t.is(payoutEntries.length, 2, 'expecting IST, MOO payouts'); + for (const [kw, pmt] of payoutEntries) { + const payment = await getIssuer(kw).getAmountOf(pmt); + t.is(payment.value, 10n, `${kw} payment returned`); + } + } + + t.log('localTransfer recovers from: give: { BLD, MOO, IST } '); + { + const tenMoolah = moolah.make(10n); + const MOO = await E(moolah.mint).mintPayment(tenMoolah); + const tenStable = ist.make(10n); + const IST = await pourPayment(tenStable); + const tenStake = bld.make(10n); + const BLD = await pourPayment(tenStake); + const userSeat = await E(zoe).offer( + E(publicFacet).makeDepositSendInvitation(), + { give: { BLD: tenStake, MOO: tenMoolah, IST: tenStable } }, + { BLD, MOO, IST }, + { + destAddr, + }, + ); + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: + 'One or more deposits failed ["[Error: key \\"[Alleged: MOO brand]\\" not found in collection \\"brandToAssetRecord\\"]"]', + }); + await E(userSeat).tryExit(); + const payouts = await E(userSeat).getPayouts(); + const payoutEntries = Object.entries(payouts); + t.is(payoutEntries.length, 3, 'expecting BLD, IST, MOO payouts'); + for (const [kw, pmt] of payoutEntries) { + const payment = await getIssuer(kw).getAmountOf(pmt); + t.is(payment.value, 10n, `${kw} payment returned`); + } + } + t.log('withdrawToSeat recovers from: simulated sendAll failure '); + { + const tenStable = ist.make(SIMULATED_ERRORS.BAD_REQUEST); + const IST = await pourPayment(tenStable); + const tenStake = bld.make(SIMULATED_ERRORS.BAD_REQUEST); + const BLD = await pourPayment(tenStake); + const userSeat = await E(zoe).offer( + E(publicFacet).makeDepositSendInvitation(), + { give: { BLD: tenStake, IST: tenStable } }, + { BLD, IST }, + { + destAddr, + }, + ); + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: 'SendAll failed "[Error: simulated error]"', + }); + await E(userSeat).hasExited(); + const payouts = await E(userSeat).getPayouts(); + const payoutEntries = Object.entries(payouts); + t.is(payoutEntries.length, 2, 'expecting BLD, IST payouts'); + for (const [kw, pmt] of payoutEntries) { + const payment = await getIssuer(kw).getAmountOf(pmt); + t.is( + payment.value, + SIMULATED_ERRORS.BAD_REQUEST, + `${kw} payment returned`, + ); + } + } +}); + +test('localTransfer happy path', async t => { + const { + bootstrap, + brands: { ist, bld }, + utils: { pourPayment, inspectBankBridge, inspectLocalBridge }, + contractKit, + zoe, + getIssuer, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(contractKit.instance); + const vt = bootstrap.vowTools; + + const destAddr = { + chainId: 'agoriclocal', + value: 'agoric1testrecipient', + encoding: 'bech32', + }; + + const tenStable = ist.make(10n); + const tenStake = bld.make(10n); + + const expectedAmounts = [ + { + denom: 'ubld', + amount: '10', + }, + { + denom: 'uist', + amount: '10', + }, + ]; + + { + t.log('localTransfer happy path via depositAndSend'); + const IST = await pourPayment(tenStable); + const BLD = await pourPayment(tenStake); + + const userSeat = await E(zoe).offer( + E(publicFacet).makeDepositSendInvitation(), + { give: { BLD: tenStake, IST: tenStable } }, + { BLD, IST }, + { + destAddr, + }, + ); + + await vt.when(E(userSeat).getOfferResult()); + const payouts = await E(userSeat).getPayouts(); + const payoutEntries = Object.entries(payouts); + t.is(payoutEntries.length, 2, 'expecting BLD, IST payouts'); + for (const [kw, pmt] of payoutEntries) { + const payment = await getIssuer(kw).getAmountOf(pmt); + t.is(payment.value, 0n, `no payout for ${kw}`); + } + + t.like( + inspectBankBridge().filter(m => m.type === 'VBANK_GIVE'), + expectedAmounts.map(x => ({ + ...x, + recipient: LOCALCHAIN_DEFAULT_ADDRESS, + })), + 'funds deposited to contract LCA', + ); + t.like( + inspectLocalBridge().find(x => x.type === 'VLOCALCHAIN_EXECUTE_TX') + ?.messages?.[0], + { + '@type': '/cosmos.bank.v1beta1.MsgSend', + fromAddress: LOCALCHAIN_DEFAULT_ADDRESS, + toAddress: destAddr.value, + amount: expectedAmounts, + }, + 'sendAll sent', + ); + } + { + t.log('localTransfer happy path via deposit'); + const IST = await pourPayment(tenStable); + const BLD = await pourPayment(tenStake); + + const userSeat = await E(zoe).offer( + E(publicFacet).makeDepositInvitation(), + { give: { BLD: tenStake, IST: tenStable } }, + { BLD, IST }, + ); + + await vt.when(E(userSeat).getOfferResult()); + + const payouts = await E(userSeat).getPayouts(); + const payoutEntries = Object.entries(payouts); + for (const [kw, pmt] of payoutEntries) { + const payment = await getIssuer(kw).getAmountOf(pmt); + t.is(payment.value, 0n, `no payout for ${kw}`); + } + + t.like( + inspectBankBridge().filter(m => m.type === 'VBANK_GIVE'), + expectedAmounts.map(x => ({ + ...x, + recipient: LOCALCHAIN_DEFAULT_ADDRESS, + })), + 'funds deposited to contract LCA', + ); + } +}); + +test('withdraw (withdrawToSeat) from LCA with insufficient balance', async t => { + const { + bootstrap, + brands: { ist, bld }, + contractKit, + zoe, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(contractKit.instance); + const vt = bootstrap.vowTools; + + const tenStable = ist.make(10n); + const tenStake = bld.make(10n); + + const userSeat = await E(zoe).offer(E(publicFacet).makeWithdrawInvitation(), { + want: { BLD: tenStake, IST: tenStable }, + }); + + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: + 'One or more withdrawals failed ["[RangeError: -10 is negative]","[RangeError: -10 is negative]"]', + }); +}); + +test('withdraw (withdrawToSeat) happy path', async t => { + const { + bootstrap, + brands: { ist, bld }, + contractKit, + zoe, + getIssuer, + utils: { pourPayment }, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(contractKit.instance); + const vt = bootstrap.vowTools; + + const tenStable = ist.make(10n); + const tenStake = bld.make(10n); + + t.log('ensure contract LCA has funds to withdraw'); + const IST = await pourPayment(tenStable); + const BLD = await pourPayment(tenStake); + + const depositSeat = await E(zoe).offer( + E(publicFacet).makeDepositInvitation(), + { give: { BLD: tenStake, IST: tenStable } }, + { BLD, IST }, + ); + await vt.when(E(depositSeat).getOfferResult()); + + const withdrawSeat = await E(zoe).offer( + E(publicFacet).makeWithdrawInvitation(), + { + want: { BLD: tenStake, IST: tenStable }, + }, + ); + await vt.when(E(withdrawSeat).getOfferResult()); + + const payouts = await E(withdrawSeat).getPayouts(); + const payoutEntries = Object.entries(payouts); + t.is(payoutEntries.length, 2, 'expecting BLD, IST payouts'); + for (const [kw, pmt] of payoutEntries) { + const payment = await getIssuer(kw).getAmountOf(pmt); + t.is(payment.value, 10n, `${kw} payment given`); + } +}); + +test('withdrawToSeat, unknown brand', async t => { + const { + bootstrap, + brands: { moolah }, + contractKit, + zoe, + } = t.context; + const publicFacet = await E(zoe).getPublicFacet(contractKit.instance); + const vt = bootstrap.vowTools; + + const tenMoolah = moolah.make(10n); + + const userSeat = await E(zoe).offer(E(publicFacet).makeWithdrawInvitation(), { + want: { MOO: tenMoolah }, + }); + + await t.throwsAsync(vt.when(E(userSeat).getOfferResult()), { + message: + 'One or more withdrawals failed ["[Error: key \\"[Alleged: MOO brand]\\" not found in collection \\"brandToAssetRecord\\"]"]', + }); +}); diff --git a/packages/orchestration/tools/ibc-mocks.ts b/packages/orchestration/tools/ibc-mocks.ts index cc056eccd37..65266645e5d 100644 --- a/packages/orchestration/tools/ibc-mocks.ts +++ b/packages/orchestration/tools/ibc-mocks.ts @@ -1,14 +1,26 @@ +/** @file Tools to support making IBC mocks */ import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js'; import { CosmosResponse } from '@agoric/cosmic-proto/icq/v1/packet.js'; import { RequestQuery, ResponseQuery, } from '@agoric/cosmic-proto/tendermint/abci/types.js'; -import { encodeBase64, btoa } from '@endo/base64'; +import { encodeBase64, btoa, atob, decodeBase64 } from '@endo/base64'; import { toRequestQueryJson } from '@agoric/cosmic-proto'; -import { IBCChannelID, VTransferIBCEvent } from '@agoric/vats'; -import { VTRANSFER_IBC_EVENT } from '@agoric/internal/src/action-types.js'; +import { + IBCChannelID, + IBCEvent, + VTransferIBCEvent, + type IBCPacket, +} from '@agoric/vats'; +import { + IBC_EVENT, + VTRANSFER_IBC_EVENT, +} from '@agoric/internal/src/action-types.js'; import { FungibleTokenPacketData } from '@agoric/cosmic-proto/ibc/applications/transfer/v2/packet.js'; +import type { PacketSDKType } from '@agoric/cosmic-proto/ibc/core/channel/v1/channel.js'; +import { LOCALCHAIN_DEFAULT_ADDRESS } from '@agoric/vats/tools/fake-bridge.js'; +import { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js'; import { makeQueryPacket, makeTxPacket } from '../src/utils/packet.js'; import { ChainAddress } from '../src/orchestration-api.js'; @@ -117,6 +129,16 @@ export function buildTxPacketString( return btoa(makeTxPacket(msgs.map(Any.toJSON))); } +/** + * Parse an outgoing ica tx packet. Useful for testing when inspecting + * outgoing dibc bridge messages. + * + * @param b64 base64 encoded string + */ +export const parseOutgoingTxPacket = (b64: string) => { + return TxBody.decode(decodeBase64(JSON.parse(atob(b64)).data)); +}; + /** * Build a query packet string for the mocked dibc bridge handler * @param msgs @@ -136,10 +158,12 @@ type BuildVTransferEventParams = { sender?: ChainAddress['value']; /** defaults to agoric1fakeLCAAddress. set to a different value to simulate an outgoing transfer event */ receiver?: ChainAddress['value']; + target?: ChainAddress['value']; amount?: bigint; denom?: string; destinationChannel?: IBCChannelID; sourceChannel?: IBCChannelID; + sequence?: PacketSDKType['sequence']; }; /** @@ -170,11 +194,13 @@ type BuildVTransferEventParams = { export const buildVTransferEvent = ({ event = 'acknowledgementPacket' as const, sender = 'cosmos1AccAddress', - receiver = 'agoric1fakeLCAAddress', + receiver = LOCALCHAIN_DEFAULT_ADDRESS, + target = LOCALCHAIN_DEFAULT_ADDRESS, amount = 10n, denom = 'uatom', destinationChannel = 'channel-0' as IBCChannelID, sourceChannel = 'channel-405' as IBCChannelID, + sequence = 0n, }: BuildVTransferEventParams = {}): VTransferIBCEvent => ({ type: VTRANSFER_IBC_EVENT, blockHeight: 0, @@ -182,7 +208,7 @@ export const buildVTransferEvent = ({ event, acknowledgement: btoa(JSON.stringify({ result: 'AQ==' })), relayer: 'agoric123', - target: receiver, + target, packet: { data: btoa( JSON.stringify( @@ -198,5 +224,38 @@ export const buildVTransferEvent = ({ source_channel: sourceChannel, destination_port: 'transfer', source_port: 'transfer', - }, + sequence, + } as IBCPacket, +}); + +export function createMockAckMap( + mockMap: Record, +) { + const res = Object.values(mockMap).reduce((acc, { msg, ack }) => { + acc[msg] = ack; + return acc; + }, {}); + return res; +} + +/** + * Simulate an IBC channelCloseConfirm event. This can be used to simulate an + * ICA channel closing for an unexpected reason from a remote chain, _or + * anything besides the Connection holder calling `.close()`_. If `close()` is + * called, we'd instead expect to see a Downcall for channelCloseInit. + * + * @param {Pick, 'portID' | 'channelID'>} event + */ +export const buildChannelCloseConfirmEvent = ({ + channelID = 'channel-0', + portID = 'icacontroller-1', +}: Partial> = {}): Partial< + IBCEvent<'channelCloseConfirm'> +> => ({ + blockHeight: 0, + blockTime: 0, + channelID, + event: 'channelCloseConfirm', + portID, + type: IBC_EVENT, }); diff --git a/packages/orchestration/tools/protobuf-decoder.js b/packages/orchestration/tools/protobuf-decoder.js new file mode 100644 index 00000000000..a7b68896b71 --- /dev/null +++ b/packages/orchestration/tools/protobuf-decoder.js @@ -0,0 +1,153 @@ +/* eslint-env node */ +/* eslint-disable -- generated by Sonnet, easier to leave alone */ + +const WIRE_TYPES = { + VARINT: 0, + FIXED64: 1, + LENGTH_DELIMITED: 2, + START_GROUP: 3, + END_GROUP: 4, + FIXED32: 5, +}; + +function decodeVarint(buffer, offset) { + let result = 0n; + let shift = 0; + let byte; + + do { + if (offset >= buffer.length) { + throw new Error('Buffer overflow while decoding varint'); + } + byte = buffer[offset]; + result |= BigInt(byte & 0x7f) << BigInt(shift); + shift += 7; + offset++; + } while (byte & 0x80); + + return { value: result, bytesRead: shift / 7 }; +} + +function decodeFixed32(buffer, offset) { + if (offset + 4 > buffer.length) { + throw new Error('Buffer overflow while decoding fixed32'); + } + return { + value: buffer.readUInt32LE(offset), + bytesRead: 4, + }; +} + +function decodeFixed64(buffer, offset) { + if (offset + 8 > buffer.length) { + throw new Error('Buffer overflow while decoding fixed64'); + } + const low = buffer.readUInt32LE(offset); + const high = buffer.readUInt32LE(offset + 4); + return { + value: BigInt(high) * 2n ** 32n + BigInt(low), + bytesRead: 8, + }; +} + +function decodeString(buffer, offset, length) { + if (offset + length > buffer.length) { + throw new Error('Buffer overflow while decoding string'); + } + return { + value: buffer.toString('utf8', offset, offset + length), + bytesRead: length, + }; +} + +function decodeField(buffer, offset) { + const tag = decodeVarint(buffer, offset); + offset += tag.bytesRead; + + const fieldNumber = Number(tag.value >> 3n); + const wireType = Number(tag.value & 0x7n); + + let value; + let bytesRead; + + switch (wireType) { + case WIRE_TYPES.VARINT: + ({ value, bytesRead } = decodeVarint(buffer, offset)); + break; + case WIRE_TYPES.FIXED64: + ({ value, bytesRead } = decodeFixed64(buffer, offset)); + break; + case WIRE_TYPES.LENGTH_DELIMITED: + const length = decodeVarint(buffer, offset); + offset += length.bytesRead; + // Try to decode as a nested message first + try { + ({ value, bytesRead } = decodeProtobuf( + buffer.slice(offset, offset + Number(length.value)), + )); + } catch (e) { + // If it fails, decode as a string + ({ value, bytesRead } = decodeString( + buffer, + offset, + Number(length.value), + )); + } + bytesRead += length.bytesRead; + break; + case WIRE_TYPES.FIXED32: + ({ value, bytesRead } = decodeFixed32(buffer, offset)); + break; + default: + throw new Error(`Unsupported wire type: ${wireType}`); + } + + return { + fieldNumber, + wireType, + value, + bytesRead: tag.bytesRead + bytesRead, + }; +} + +function getFieldName(fieldNumber, wireType) { + const typePrefix = + wireType === WIRE_TYPES.LENGTH_DELIMITED + ? 'subMessage' + : wireType === WIRE_TYPES.VARINT + ? 'int' + : wireType === WIRE_TYPES.FIXED32 + ? 'fixed32' + : wireType === WIRE_TYPES.FIXED64 + ? 'fixed64' + : 'string'; + return `${typePrefix}_${fieldNumber}`; +} + +/** + * Decodes a protobuf message from the given buffer. + * + * @param {Buffer} buffer + */ +export function decodeProtobuf(buffer) { + let offset = 0; + const message = {}; + + while (offset < buffer.length) { + const field = decodeField(buffer, offset); + const fieldName = getFieldName(field.fieldNumber, field.wireType); + message[fieldName] = field.value; + offset += field.bytesRead; + } + + return { value: message, bytesRead: offset }; +} +/** + * Decodes a protobuf message from the given base64-encoded data. + * + * @param {string} base64String + */ +export function decodeProtobufBase64(base64String) { + const buffer = Buffer.from(base64String, 'base64'); + return decodeProtobuf(buffer); +} diff --git a/packages/pegasus/package.json b/packages/pegasus/package.json index aa15b76c817..1dc2ae6ce40 100644 --- a/packages/pegasus/package.json +++ b/packages/pegasus/package.json @@ -28,7 +28,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/network": "^0.1.0", @@ -38,13 +38,13 @@ "@agoric/vats": "^0.15.1", "@agoric/vow": "^0.1.0", "@agoric/zoe": "^0.26.2", - "@endo/bundle-source": "^3.2.3", + "@endo/bundle-source": "^3.4.0", "@agoric/zone": "^0.2.2", - "@endo/captp": "^4.2.0", - "@endo/far": "^1.1.2", - "@endo/init": "^1.1.2", - "@endo/nat": "^5.0.7", - "@endo/promise-kit": "^1.1.2" + "@endo/captp": "^4.3.0", + "@endo/far": "^1.1.5", + "@endo/init": "^1.1.4", + "@endo/nat": "^5.0.10", + "@endo/promise-kit": "^1.1.5" }, "devDependencies": { "ava": "^5.3.0", @@ -70,6 +70,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 91.18 + "atLeast": 91.21 } } diff --git a/packages/pegasus/test/peg.test.js b/packages/pegasus/test/peg.test.js index bdf17045b9d..ec4d7f4a55b 100644 --- a/packages/pegasus/test/peg.test.js +++ b/packages/pegasus/test/peg.test.js @@ -5,6 +5,7 @@ import { E, Far } from '@endo/far'; import { prepareNetworkProtocol, prepareLoopbackProtocolHandler, + prepareNetworkPowers, } from '@agoric/network'; import bundleSource from '@endo/bundle-source'; @@ -43,8 +44,9 @@ async function testRemotePeg(t) { t.plan(24); // const zone = makeHeapZone(); - const zone = makeDurableZone(provideBaggage('peagsus')); - const powers = prepareVowTools(zone); + const zone = makeDurableZone(provideBaggage('pegasus')); + const vowTools = prepareVowTools(zone); + const powers = prepareNetworkPowers(zone, vowTools); const { makeVowKit, when } = powers; /** diff --git a/packages/smart-wallet/package.json b/packages/smart-wallet/package.json index d6768b15a68..69cbaac80db 100644 --- a/packages/smart-wallet/package.json +++ b/packages/smart-wallet/package.json @@ -7,7 +7,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:xs": "exit 0", "lint": "run-s --continue-on-error lint:*", @@ -18,14 +18,14 @@ "devDependencies": { "@agoric/cosmic-proto": "^0.4.0", "@agoric/swingset-vat": "^0.32.2", - "@endo/bundle-source": "^3.2.3", - "@endo/captp": "^4.2.0", - "@endo/init": "^1.1.2", + "@endo/bundle-source": "^3.4.0", + "@endo/captp": "^4.3.0", + "@endo/init": "^1.1.4", "ava": "^5.3.0", "import-meta-resolve": "^2.2.1" }, "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/casting": "^0.4.2", "@agoric/ertp": "^0.16.2", "@agoric/internal": "^0.3.2", @@ -36,11 +36,11 @@ "@agoric/vow": "^0.1.0", "@agoric/zoe": "^0.26.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/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/promise-kit": "^1.1.5" }, "files": [ "src/" diff --git a/packages/smart-wallet/test/invitation1.test.js b/packages/smart-wallet/test/invitation1.test.js index 5e9d2287779..b530f1727ad 100644 --- a/packages/smart-wallet/test/invitation1.test.js +++ b/packages/smart-wallet/test/invitation1.test.js @@ -193,7 +193,7 @@ test.serial('handle failure to create invitation', async t => { return slowWithdrawPurse; }, getAssetSubscription: () => { - throw new Error('TODO'); + throw Error('TODO'); }, }); diff --git a/packages/smart-wallet/test/supports.js b/packages/smart-wallet/test/supports.js index c02c11b3b5b..45628382da1 100644 --- a/packages/smart-wallet/test/supports.js +++ b/packages/smart-wallet/test/supports.js @@ -63,7 +63,6 @@ export const subscriptionKey = subscription => { /** @returns {import('@agoric/vats').BridgeManager} */ const makeFakeBridgeManager = () => - // @ts-expect-error XXX generics puzzle: could be instantiated with a different subtype of constraint Far('fakeBridgeManager', { register(bridgeId, handler) { return Far('scopedBridgeManager', { diff --git a/packages/solo/package.json b/packages/solo/package.json index 2bbb646e661..9d84a6d5e6e 100644 --- a/packages/solo/package.json +++ b/packages/solo/package.json @@ -23,7 +23,7 @@ "license": "Apache-2.0", "dependencies": { "@agoric/access-token": "^0.4.21", - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/cache": "^0.3.2", "@agoric/cosmic-swingset": "^0.41.3", "@agoric/internal": "^0.3.2", @@ -36,12 +36,12 @@ "@agoric/time": "^0.3.2", "@agoric/vats": "^0.15.1", "@agoric/wallet": "^0.18.3", - "@endo/captp": "^4.2.0", - "@endo/eventual-send": "^1.2.2", - "@endo/import-bundle": "^1.1.2", - "@endo/init": "^1.1.2", - "@endo/marshal": "^1.5.0", - "@endo/promise-kit": "^1.1.2", + "@endo/captp": "^4.3.0", + "@endo/eventual-send": "^1.2.5", + "@endo/import-bundle": "^1.2.2", + "@endo/init": "^1.1.4", + "@endo/marshal": "^1.5.3", + "@endo/promise-kit": "^1.1.5", "anylogger": "^0.21.0", "deterministic-json": "^1.0.5", "esm": "agoric-labs/esm#Agoric-built", @@ -50,14 +50,13 @@ "import-meta-resolve": "^2.2.1", "minimist": "^1.2.0", "morgan": "^1.10.0", - "node-fetch": "^2.6.0", "temp": "^0.9.1", "tmp": "^0.2.1", "ws": "^7.2.0" }, "devDependencies": { "@agoric/ertp": "^0.16.2", - "@endo/bundle-source": "^3.2.3", + "@endo/bundle-source": "^3.4.0", "ava": "^5.3.0", "c8": "^9.1.0" }, @@ -78,6 +77,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 73.36 + "atLeast": 73.55 } } diff --git a/packages/solo/src/add-chain.js b/packages/solo/src/add-chain.js index 39aab2f9b3a..d72095ff007 100644 --- a/packages/solo/src/add-chain.js +++ b/packages/solo/src/add-chain.js @@ -1,5 +1,4 @@ -/* global process */ -import fetch from 'node-fetch'; +/* eslint-env node */ import crypto from 'crypto'; import djson from 'deterministic-json'; import path from 'path'; diff --git a/packages/solo/src/main.js b/packages/solo/src/main.js index 7d9fd993af1..f70fa8185c1 100644 --- a/packages/solo/src/main.js +++ b/packages/solo/src/main.js @@ -12,7 +12,6 @@ import addChain from './add-chain.js'; import initBasedir from './init-basedir.js'; import resetState from './reset-state.js'; import setGCIIngress from './set-gci-ingress.js'; -import setFakeChain from './set-fake-chain.js'; import start from './start.js'; const log = anylogger('ag-solo'); @@ -120,13 +119,6 @@ start setGCIIngress(basedir, GCI, rpcAddresses, chainID); break; } - case 'set-fake-chain': { - const basedir = insistIsBasedir(); - const { _: subArgs, delay } = parseArgs(argv.slice(1), {}); - const GCI = subArgs[0]; - setFakeChain(basedir, GCI, delay); - break; - } case 'start': { const basedir = insistIsBasedir(); await start(basedir, { diff --git a/packages/solo/src/start.js b/packages/solo/src/start.js index d138d35d742..6fa76c05bb5 100644 --- a/packages/solo/src/start.js +++ b/packages/solo/src/start.js @@ -40,7 +40,7 @@ import { } from '@agoric/cosmic-swingset/src/kernel-stats.js'; import { deliver, addDeliveryTarget } from './outbound.js'; -import { connectToPipe } from './pipe.js'; +// import { connectToPipe } from './pipe.js'; import { makeHTTPListener } from './web.js'; import { connectToChain } from './chain-cosmos-sdk.js'; @@ -518,16 +518,6 @@ const start = async (basedir, argv) => { addDeliveryTarget(c.GCI, deliverator); } break; - case 'fake-chain': { - log(`adding follower/sender for fake chain ${c.GCI}`); - const deliverator = await connectToPipe({ - method: 'connectToFakeChain', - args: [basedir, c.GCI, c.fakeDelay], - deliverInboundToMbx, - }); - addDeliveryTarget(c.GCI, deliverator); - break; - } case 'http': { log(`adding HTTP/WS listener on ${c.host}:${c.port}`); !broadcastJSON || Fail`duplicate type=http in connections.json`; diff --git a/packages/solo/test/home.test.js b/packages/solo/test/home.test.js index 9821f264c9b..96ded71f14c 100644 --- a/packages/solo/test/home.test.js +++ b/packages/solo/test/home.test.js @@ -48,7 +48,7 @@ test.before('setup', async t => { // Now come the tests that use `home`... // ========================================= -test.serial('home.board', async t => { +test.skip('home.board', async t => { const { home } = t.context; const { board } = E.get(home); await t.throwsAsync( @@ -73,7 +73,7 @@ test.serial('home.board', async t => { t.is(myId2, myId, `board gives the same id for the same value`); }); -test.serial('home.wallet - transfer funds to the feePurse', async t => { +test.skip('home.wallet - transfer funds to the feePurse', async t => { const { home } = t.context; const { wallet, faucet } = E.get(home); const feePurse = E(faucet).getFeePurse(); @@ -86,7 +86,7 @@ test.serial('home.wallet - transfer funds to the feePurse', async t => { t.deepEqual(deposited, feeAmount, `all fees deposited to feePurse`); }); -test.serial('home.wallet - receive zoe invite', async t => { +test.skip('home.wallet - receive zoe invite', async t => { const { home, loadBundle } = t.context; const { wallet, zoe, board } = E.get(home); @@ -133,7 +133,7 @@ test.serial('home.wallet - receive zoe invite', async t => { ); }); -test.serial('home.wallet - central issuer setup', async t => { +test.skip('home.wallet - central issuer setup', async t => { const { home } = t.context; const { wallet } = E.get(home); diff --git a/packages/solo/test/startsolo.sh b/packages/solo/test/startsolo.sh index 13aad5a747f..f0e9cb7c6d6 100755 --- a/packages/solo/test/startsolo.sh +++ b/packages/solo/test/startsolo.sh @@ -5,7 +5,6 @@ AG_SOLO=$(cd .. && pwd)/bin/ag-solo TDIR="${TMPDIR-/tmp}/startsolo.$$" trap 'rm -rf "$TDIR"' EXIT -"$AG_SOLO" init "$TDIR" --egresses=fake --webport=$PORT --defaultManagerType=local +"$AG_SOLO" init "$TDIR" --webport=$PORT --defaultManagerType=local cd "$TDIR" -"$AG_SOLO" set-fake-chain --delay=0 mySimGCI exec "$AG_SOLO" start diff --git a/packages/spawner/package.json b/packages/spawner/package.json index 3795a1038a4..90240bfe6ab 100644 --- a/packages/spawner/package.json +++ b/packages/spawner/package.json @@ -31,16 +31,16 @@ }, "homepage": "https://github.com/Agoric/agoric-sdk#readme", "dependencies": { - "@endo/errors": "^1.2.2", - "@endo/eventual-send": "^1.2.2", - "@endo/import-bundle": "^1.1.2", - "@endo/marshal": "^1.5.0" + "@endo/errors": "^1.2.5", + "@endo/eventual-send": "^1.2.5", + "@endo/import-bundle": "^1.2.2", + "@endo/marshal": "^1.5.3" }, "devDependencies": { "@agoric/internal": "^0.3.2", "@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/stat-logger/package.json b/packages/stat-logger/package.json index 63782d4b75c..5d8ae62b018 100644 --- a/packages/stat-logger/package.json +++ b/packages/stat-logger/package.json @@ -16,7 +16,7 @@ "lint:eslint": "eslint ." }, "dependencies": { - "@endo/errors": "^1.2.2" + "@endo/errors": "^1.2.5" }, "peerDependencies": { "canvas": "^2.6.1", diff --git a/packages/store/package.json b/packages/store/package.json index d5459a898c5..3c218f401cb 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -30,15 +30,15 @@ }, "homepage": "https://github.com/Agoric/agoric-sdk#readme", "dependencies": { - "@endo/errors": "^1.2.2", - "@endo/exo": "^1.5.0", - "@endo/marshal": "^1.5.0", - "@endo/pass-style": "^1.4.0", - "@endo/patterns": "^1.4.0" + "@endo/errors": "^1.2.5", + "@endo/exo": "^1.5.3", + "@endo/marshal": "^1.5.3", + "@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" }, "files": [ @@ -59,6 +59,6 @@ "timeout": "2m" }, "typeCoverage": { - "atLeast": 89.39 + "atLeast": 89.53 } } diff --git a/packages/swing-store/docs/bundlestore.md b/packages/swing-store/docs/bundlestore.md new file mode 100644 index 00000000000..661c196b9e3 --- /dev/null +++ b/packages/swing-store/docs/bundlestore.md @@ -0,0 +1,30 @@ +# BundleStore + +The `kernelStorage.bundleStore` sub-store manages code bundles. These can be used to hold vat-worker supervisor code (e.g. the [`@endo/lockdown`](https://github.com/endojs/endo/tree/master/packages/lockdown) bundle, or the [`@agoric/swingset-xsnap-supervisor` package](../../swingset-xsnap-supervisor), which incorporates liveslots), or the initial vat code bundles (for both kernel-defined bundles like vat-comms or vat-timer, or for application-defined bundles like vat-zoe or the ZCF code). It can also hold bundles that will be loaded later by userspace vat code, such as contract bundles. + +Each bundle held by the bundleStore is identified by a secure BundleID, which contains a format version integer and a hash, with a format like `b0-123abc456def...` or `b1-789ghi012...`. This contains enough information to securely define the behavior of the code inside the bundle, and to identify the tools needed to load/evaluate it. + +The bundleStore provides a simple add/get/remove API to the kernel. The kernel adds its own bundles during initialization, and provides the host application with an API to load additional ones in later. The kernel code that creates new vats will read bundles from the bundleStore when necessary, as vats are created. Userspace can get access to "BundleCap" objects that represent bundles, to keep the large bundle blobs out of RAM as much as possible. + +## Data Model + +Bundles are actually JavaScript objects: records of at least `{ moduleFormat }`, plus some format-specific fields like `endoZipBase64` and `endoZipBase64Sha512`. They are created by the [`@endo/bundle-source`](https://github.com/endojs/endo/tree/master/packages/bundle-source) package. Many are consumed by [`@endo/import-bundle`](https://github.com/endojs/endo/tree/master/packages/import-bundle), but the `b0-` format bundles can be loaded with some simple string manipulation and a call to `eval()` (which is how supervisor bundles are injected into new vat workers, before `@endo/import-bundle` is available). + +The bundleStore database treats each bundle as BundleID and a blob of contents. The SQLite `bundles` table is just `(bundleID TEXT, bundle BLOB)`. The bundleStore knows about each `moduleFormat` and how to extract the meaningful data and compress it into a blob, and how to produce the Bundle object during retrieval. + +The bundleStore also knows about the BundleID computation rules. The `addBundle()` API will verify that the contents match the ID, however it currently relies upon the caller to verify e.g. that the bundle does not contain any unexpected properties. The `importSwingStore()` API performs more extensive validation, to prevent corruption during the export+import process. + +The kernel is expected to keep track of which bundles are needed and when (with reference counts), and to not delete a bundle unless it is really unneeded. Currently, this means all bundles are retained forever. + +Unlike the `snapStore`, there is no notion of pruning bundles: either the bundle is present (with all its data), or there is no record of the BundleID at all. + +## Export Model + +Each bundle gets a single export-data entry, whose name is `bundle.${bundleID}`, and whose value is just `${bundleID}`. Each bundle also gets a single export artifact, whose name is `bundle.${bundleID}`, and whose contents are the compressed BLOB from the database (from which a Bundle record can be reconstructed). + +## Slow Deletion + +Since bundles are not owned by vats, there is nothing to delete when a vat is terminated. So unlike `transcriptStore` and `snapStore`, there is no concept of "slow deletion", and no APIs to support it. + +When a bundle is deleted by `bundleStore.deleteBundle()`, its export-data item is deleted immediately, and subsequent exports will omit the corresponding artifact. + diff --git a/packages/swing-store/docs/data-export.md b/packages/swing-store/docs/data-export.md index 9fd1ef21288..bf0ca524da3 100644 --- a/packages/swing-store/docs/data-export.md +++ b/packages/swing-store/docs/data-export.md @@ -188,13 +188,13 @@ Once the new SwingStore is fully populated with the previously-exported data, th Some of the data maintained by SwingStore is not strictly necessary for kernel execution, at least under normal circumstances. For example, once a vat worker performs a heap snapshot, we no longer need the transcript entries from before the snapshot was taken, since vat replay will start from the snapshot point. We split each vat's transcript into "spans", delimited by heap snapshot events, and the "current span" is the most recent one (still growing), whereas the "historical spans" are all closed and immutable. Likewise, we only really need the most recent heap snapshot for each vat: older snapshots might be interesting for experiments that replay old transcripts with different versions of the XS engine, but no normal kernel will ever need them. -Most validators would prefer to prune this data, to reduce their storage needs. But we can imagine some [extreme upgrade scenarios](https://github.com/Agoric/agoric-sdk/issues/1691) that would require access to these historical transcript spans. Our compromise is to record *validation data* for these historical spans in the export data, but omit the spans themselves from the export artifacts. Validators can delete the old spans at will, and if we ever need them in the future, we can add code that will fetch copies from an archive service, validate them against the export data hashes, and re-insert the relevant entries into the SwingStore. +Most blockchain validator nodes would prefer to prune this data, to reduce their storage needs. But we can imagine some [extreme upgrade scenarios](https://github.com/Agoric/agoric-sdk/issues/1691) that would require access to these historical transcript spans. Our compromise is to record *validation data* for these historical spans in the export data, but omit the spans themselves from the export artifacts. Validators can delete the old spans at will, and if we ever need them in the future, we can add code that will fetch copies from an archive service, validate them against the export data hashes, and re-insert the relevant entries into the SwingStore. Likewise, each time a heap snapshot is recorded, we cease to need any previous snapshot. And again, as a hedge against even more drastic recovery scenarios, we strike a compromise between minimizing retained data and the ability to validate old snapshots, by retaining only their hashes. -As a result, for each active vat, the first-stage Export Data contains a record for every old transcript span, plus one for the current span. It also contains a record for every old heap snapshot, plus one for the most recent heap snapshot, plus a `.current` record that points to the most recent snapshot. However the exported artifacts may or may not include blobs for the old transcript spans, or for the old heap snapshots. +As a result, for each active vat, the first-stage Export Data contains a record for every old heap snapshot, plus one for the most recent heap snapshot, plus a `.current` record that points to the most recent snapshot. It also contains a record for every old transcript span, plus one for the current span. However the exported artifacts may or may not include blobs for the old heap snapshots, or for the old transcript spans. -The `openSwingStore()` function has an option named `keepTranscripts` (which defaults to `true`), which causes the transcriptStore to retain the old transcript items. A second option named `keepSnapshots` (which defaults to `false`) causes the snapStore to retain the old heap snapshots. Opening the swingStore with a `false` option does not necessarily delete the old items immediately, but they'll probably get deleted the next time the kernel triggers a heap snapshot or transcript-span rollover. Validators who care about minimizing their disk usage will want to set both to `false`. In the future, we will arrange the SwingStore SQLite tables to provide easy `sqlite3` CLI commands that will delete the old data, so validators can also periodically use the CLI command to prune it. +The `openSwingStore()` function has an option named `keepSnapshots` (which defaults to `false`), which causes the snapStore to retain the old heap snapshots. A second option named `keepTranscripts` (which defaults to `true`) causes the transcriptStore to retain the old transcript items. Opening the swingStore with a `false` option does not necessarily delete the old items immediately, but they may get deleted the next time the kernel triggers a heap snapshot or transcript-span rollover. Hosts who care about minimizing their disk usage will want to set both to `false`. In the future, we will arrange the SwingStore SQLite tables to provide easy `sqlite3` CLI commands that will delete the old data, for use in periodic pruning. When exporting, the `makeSwingStoreExporter()` function takes an `artifactMode` option (in an options bag). This serves to both limit, and provide some minimal guarantees about, the set of artifacts that will be provided in the export. The defined values of `artifactMode` each build upon the previous one: @@ -218,9 +218,9 @@ While `importSwingStore()`'s options bag accepts the same options as `openSwingS So, to avoid pruning current-incarnation historical transcript spans when exporting from one swingstore to another, you must set (or avoid overriding) the following options along the way: * the original swingstore must not be opened with `{ keepTranscripts: false }`, otherwise the old spans will be pruned immediately -* the export must use `makeSwingStoreExporter(dirpath, { artifactMode: 'replay'})`, otherwise the export will omit the old spans -* the import must use `importSwingStore(exporter, dirPath, { artifactMode: 'replay'})`, otherwise the import will ignore the old spans - * subsequent `openSwingStore` calls must not use `keepTranscripts: false`, otherwise the new swingstore will prune historical spans as new ones are created (during `rolloverSpan`). +* the export must use `makeSwingStoreExporter(dirpath, { artifactMode: 'replay' })`, otherwise the export will omit the old spans +* the import must use `importSwingStore(exporter, dirPath, { artifactMode: 'replay' })`, otherwise the import will ignore the old spans + * subsequent `openSwingStore` calls must not use `keepTranscripts: false`, otherwise the new swingstore will prune historical spans they are replaced during `rolloverSpan`. ## Implementation Details diff --git a/packages/swing-store/docs/kvstore.md b/packages/swing-store/docs/kvstore.md new file mode 100644 index 00000000000..a710b4eee70 --- /dev/null +++ b/packages/swing-store/docs/kvstore.md @@ -0,0 +1,35 @@ +# KVStore + +The `kernelStorage.kvStore` sub-store manages a table of arbitrary key-value (string-to-string) pairs. It provides the usual get/set/has/delete APIs, plus a `getNextKey` call to support lexicographic iteration. + +There are three separate sections of the namespace. The normal one is the "consensus" section. Each value written here will be given an export-data row, and incorporated into the "crankhash" (described below). + +The second is "local", and includes any key which is prefixed with `local.`. These keys are *not* given export-data rows, nor are they included in the crankhash. + +The third is "host", and includes any key which is prefixed with `host.`. This is not available to `kernelStorage.kvStore` at all: it is only accessed by methods on `hostStorage.kvStore` (the `kernelStorage` methods will throw an error if given a key like `host.foo`, and the `hostStorage` methods will throw *unless* given a key like `host.foo`). These are also excluded from export-data and the crankhash. Host keys are reserved for the host application, and are generally used to keep track of things like which block has been executed, to manage consistency between a separate host database (eg IAVL) and the swingstore. The host can record "I told the kernel to execute the contents of block 56" into `hostStorage.kvStore`, and then do `hostStorage.commit()`, and then it can record "I processed the rest of block 56" into is own DB, and then commit its own DB. If, upon startup, it observes a discrepancy between the `hostStorage.kvStore` record and its own DB, it knows it got interrupted between these two commit points, which can trigger recovery code. + +Any key which doesn't start with `local.` or `host.` is part of the "consensus" section. + +## CrankHash and ActivityHash + +Swingset kernels are frequently run in a consensus mode, where multiple instances of the kernel (on different machines) are expected to execute the same deliveries in lock-step. In this mode, every kernel is expected to do exactly the same computation, and any divergence indicates a failure (or attempt at malice). We want to detect such variations quickly, so the diverging/failing member can "fall out of consensus" promptly. + +The swingstore hashes all changes to the "consensus" portion of the kvStore into the "crank hash". This hash covers every change since the beginning of the current crank, and the kernel logs the result at the end of each crank, at which point the crankhash is reset. + +Each crank also updates a value called the "activity hash", by hashing the previous activityhash and the latest crankhash together. This records a chain of changes, and is logged at the end of each crank too. + +The host application can record the activityhash into its own consensus-tracking database (eg IAVL) at the end of each kernel run, to ensure that any internal divergence of swingset behavior is escalated to a proper consensus failure. Without this, one instance of the kernel might "think differently" than the others, but still "act" the same (in terms of IO or externally-visible messages) without triggering a failure, which would be a lurking problem. + +Logging both the crankhash and the activityhash improves our ability to diagnose consensus failures. By comparing logs between a "good" machine and a "bad" (diverging) one, we can quickly determine which crank caused the problem, and usually compare slogfile delivery/syscall records to narrow the divergence down to a specific syscall. + +kvStore changes are also recorded by the export-data, but these are too voluminous to be logged, and do not capture multiple changes to the same key. And not all host applications use exports, so there might not be anything watching export data. + +## Data Model + +The kvStore holds a simple string-to-string key/value store. The SQLite schema for the `kvStore` table is simply `(key TEXT, value TEXT)`. + +## Export Model + +To ensure that every key/value pair is correctly validatable, *all* in-consensus kvStore rows get their own export-data item. The name is just `kv.${key}`, and the value is just the value. `kvStore.delete(key)` will delete the export-data item. There are no artifacts. + +These make up the vast majority of the export-data items, both by count and by "churn" (the number of export-data items changed in a single crank). In the future, we would prefer to keep the kvStore in some sort of Merkle-tree data structure, and emit only a handful of export-data rows that contain hashes (perhaps just a single root hash). In this approach, the actual data would be exported in one or more artifacts. However, our SQLite backend does not provide the same kind of automatic Merkleization as IAVL, and only holds a single version of data at a time, making this impractical. diff --git a/packages/swing-store/docs/snapstore.md b/packages/swing-store/docs/snapstore.md new file mode 100644 index 00000000000..8cd88097a56 --- /dev/null +++ b/packages/swing-store/docs/snapstore.md @@ -0,0 +1,49 @@ +# SnapStore + +The `kernelStorage.snapStore` sub-store tracks vat heap snapshots. These blobs capture the state of an XS JavaScript engine, between deliveries, to speed up replay-based persistence. The kernel can start a vat worker from a recent heap snapshot, and then it only needs to replay a handful of transcript items (deliveries), instead of replaying every delivery since the beginning of the incarnation. + +The XS / [`xsnap`](../../xsnap) engine defines the heap snapshot format. It consists of a large table of "slots", which are linked together to form JavaScript objects, strings, Maps, functions, etc. The snapshot also includes "chunks" for large data fields (like strings and BigInts), a stack, and some other supporting tables. The snapStore doesn't care about any of the internal details: it just gets a big blob of bytes. + +## Data Model + +Each snapshot is compressed and stored in the SQLite row as a BLOB. The snapStore has a single table named `snapshots`, with a schema of `(vatID TEXT, snapPos INTEGER, inUse INTEGER, hash TEXT, uncompressedSize INTEGER, compressedSize INTEGER, compressedSnapshot BLOB)`. + +The kernel has a scheduler which decides when to take a heap snapshot for each vat. There is a tradeoff between the immediate cost of creating the snapshot, versus the expected future savings of having a shorter transcript to replay. More frequent snapshots save time later, at the cost of time spent now. + +The kernel currently uses a [very simple scheduler](../../SwingSet/src/kernel/vat-warehouse.js), which takes a snapshot every `snapshotInterval` deliveries (e.g. 200), plus an extra one a few deliveries (`snapshotInitial`) into the new incarnation, to avoid replaying expensive contract startup code. The [SwingSet configuration documentation](../../SwingSet/docs/configuration.md) has the details. + +However, the swingstore is unaware of the kernel's scheduling policy. Every once in a while, the kernel tells the snapStore about a new snapshot, and the snapStore updates its data. + +Like the [transcriptStore](./transcriptstore.md), the snapStore retains a hash of older records, even after it prunes the snapshot data itself. There is at most one `inUse = 1` record for each vatID, and it will always have the highest `snapPos` value. When a particular vatID's active snapshot is replaced, the SQLite table row is updated to clear the `inUse` flag (i.e. set it to NULL). By default, the `compressedSnapshot` field is also set to NULL, removing the large data blob, but there is an option (`keepSnapshots: true`) to retain the full contents of all snapshots, even the ones that are no longer in use. + +## Export Model + +Each snapshot, both current and historic, gets an export-data entry. The name is `snapshot.${vatID}.${position}`, where `position` is the latest delivery (eg highest delivery number) that was included in the heap state captured by the snapshot. The value is a JSON-serialized record of `{ vatID, snapPos, hash, inUse }`. + +If there is a "current" snapshot, there will be one additional export-data record, whose name is `snapshot.${vatID}.current`, and whose value is `snapshot.${vatID}.${position}`. This value is the same as the name of the latest export-data record, and is meant as a convenient pointer to find that latest snapshot. + +The export *artifacts* will generally only include the current snapshot for each vat. Only the `debug` mode will include historical snapshots (and only if the swingstore was retaining them in the first place). + +## Slow Deletion + +As soon as a vat is terminated, the kernel will call `snapStore.stopUsingLastSnapshot()`. The DB is updated to clear the `inUse` flag of the latest snapshot, leaving no rows with `inUse = 1`. This immediately makes the vat non-loadable by the kernel. The snapshot data itself is deleted (unless `keepSnapshots: true`). + +This also modifies the latest `snapshot.${vatID}.${snapPos}` export-data record, to change `inUse` to 0, and removes the `snapshot.${vatID}.current` record. The modification and deletion are added to the export-data callback queue, so the host-app can learn about them after the next commit. Any subsequent `getExportData()` calls will observe the changes. + +As a result, all non-`debug` swing-store exports after this point will omit any artifacts for the snapshot blob, but they will still include export-data records (hashes) for all snapshots. (Deleting all the export-data records is too much work to do in a single step, so it is spread out over time). + +Later, as the kernel performs cleanup work for this vatID, the cleanup call will delete DB rows (one per `budget`). Each row deleted will also remove one export-data record, which feeds the callback queue, as well as affecting the full `getExportData()` results. + +Eventually, the snapStore runs out of rows to delete, and `deleteVatSnapshots(budget)` returns `{ done: true }`, so the kernel can finally rest. + +### SnapStore Vat Lifetime + +The SnapStore doesn't provide an explicit API to call when a vat is first created. The kernel just calls `saveSnapshot()` for both the first and all subsequent snapshots. Each `saveSnapshot()` marks the previous snapshot as unused, so there is at most one `inUse = 1` snapshot at any time. There will be zero in-use snapshots just after each incarnation starts, until enough deliveries have been made to trigger the first snapshot. + +When terminating a vat, the kernel should first call `snapStore.stopUsingLastSnapshot(vatID)`, the same call it would make at the end of an incarnation, to indicate that we're no longer using the last snapshot. This results in zero in-use snapshots. + +Then, the kernel must either call `snapStore.deleteVatSnapshots(vatID)` or `deleteVatSnapshots(vatID, Infinity)` to delete everything at once, or make a series of calls (spread out over time/blocks) to `snapStore.deleteVatSnapshots(vatID, budget)`. Each will return `{ done, cleanups }`, which can be used to manage the rate-limiting and know when the process is finished. + +The `stopUsingLastSnapshot()` is a performance improvement, but is not mandatory. If omitted, exports will continue to include the vat's snapshot artifacts until the first call to `deleteVatSnapshots()`, after which they will go away. Snapshots are deleted in descending `snapPos` order, so the first call will delete the only `inUse = 1` snapshot, after which exports will omit all artifacts for the vatID. `stopUsingLastSnapshot()` is idempotent, and extra calls will leave the DB unchanged. + +The kernel must keep calling `deleteVatSnapshots(vatID, budget)` until the `{ done }` return value is `true`. It is safe to call it again after that point; the function will keep returning `true`. But note, this costs one DB txn, so it may be cheaper for the kernel to somehow remember that we've reached the end. diff --git a/packages/swing-store/docs/swingstore.md b/packages/swing-store/docs/swingstore.md index 56bd174dd28..b6cde0a45c1 100644 --- a/packages/swing-store/docs/swingstore.md +++ b/packages/swing-store/docs/swingstore.md @@ -1,13 +1,57 @@ -# SwingStore Data Model +# The SwingStore The "SwingStore" provides a database to hold SwingSet kernel state, with an API crafted to help both the kernel and the host application mutate, commit, export, and import this state. -The state is broken up into several pieces, or "stores": +The entire durable state of the kernel lives in the SwingStore: it does not use any other files or databases, and the only commit point is in `hostStorage.commit()`. Careful host applications can use this to avoid "hangover inconsistency", by storing all device output messages in the same database, and only releasing them once the kernel changes have been committed. + +In theory, an alternate implementation of this API could be provided with e.g. a different backend database, such as the host application's own native database (eg IAVL, for cosmos-sdk -based apps). This could simplify the atomicity domains by using just one database instead of two. This must be balanced against performance tradeoffs: swing-store takes advantage of SQL's indexing and iteration abilities, which might not be present in the other database. + +## Creating and Opening a SwingStore + + +`initSwingStore(dirPath, options)` will create a new swingstore in the given directory, which will be created if it doesn't already exist. The entire directory is reserved for the swingstore: the host application should not put any other files there. The swingstore library will populated it with the SQLite DB's backing files: `swingstore.sqlite`, `swingstore.sqlite-wal`, and `swingstore.sqlite-shm`. If called on a directory that already contains a database, the DB will be erased first. + +`openSwingStore(dirPath, options)` does the same, but will not erase a pre-existing DB. In general, use `initSwingStore` for the initial creation of the DB, and `openSwingStore` for all subsequent access. + +Both calls return a record with `{ hostStorage, kernelStorage }`, along with some additional facets for testing and debugging. `dirPath` can be null to use a ephemeral (in-memory) DB, which is only useful for unit tests. + +## HostStorage + +The `hostStorage` facet is reserved for the host application. It is mostly used to manage commit points for the application. + +The host is responsible for calling `hostStorage.commit()` when it is done with kernel execution. This causes a SQLite `COMMIT` of the underlying database. It should perform this commit before it releases any device output messages. This facet is the only one with a `commit()` method: the kernel is explicitly unable to commit its own changes to the underlying SQLite database, because the kernel does not know anything about the host's application lifecycle or input/output activity, so it cannot know what qualifies as a safe commit point. + +If, for some reason, the host wants to abandon execution, it can call `hostStorage.close()`, which will close the swingstore without committing any changes. This is not normally useful: the kernel must be abandoned at this point too, so most of the time the host application should just exit entirely. + +`hostStorage.kvStore` is also available to let the host add items to a separate portion of the kvStore, using keys which start with a `host.` prefix. It can use this to coordinate with a separately-committed host database (e.g. to remember how much work has been given to the kernel, and how much has been successfully executed). This portion of the kvStore is unreachable by the kernel. + +`hostStorage.setExportCallback()` is used to register an export callback after swingstore creation, see [data-export.md](./data-export.md) for details. Most applications will instead provide `options.exportCallback` to `openSwingStore()`. + +`hostStorage.repairMetadata()` was used to repair a historical flaw in the database format, and is not needed by new installations. + +## KernelStorage + +The host application is supposed to deliver the `kernelStorage` facet to the kernel, by passing it into `initializeSwingset()`, `upgradeSwingset()`, and `buildVatController()`. The host application should not use `kernelStorage` itself. + +The kernel receives a facet named `kernelStorage`, from which it can access four sub-stores: + +* [`bundleStore`](./bundlestore.md): a string-keyed Bundle-value table, holding source bundles which can be evaluated by `importBundle` to create vats, or new Compartments within a vat +* [`transcriptStore`](./transcriptstore.md): records a linear sequence of deliveries and syscalls (with results), collectively known as "transcript entries", for each vat +* [`snapStore`](./snapstore.md): records one or more XS heap snapshots for each vat, to rebuild a worker more efficiently than replaying all transcript entries from the beginning +* [`kvStore`](./kvstore.md): a string-keyed string-valued table, which holds everything else. Currently, this holds each vat's c-list and vatstore data, as well as the kernel-wide object and promise tables, and run-queues. + +These pieces operate independently: data in one substore does not affect the operation of the others. + +`kernelStorage` also provides access to the "crank" tools. Kernel execution proceeds in a series of steps named "cranks", many of which involve delivering a message to a vat worker. Sometimes these messages cause a failure halfway through the delivery, where it is better to record either complete deliveries or nothing at all. To support this, the kernel can mark the beginning of the crank (by calling `kernelStorage.startCrank()`), and then either discard the changes (`rollbackCrank()`) or accept them (`endCrank()`). The `emitCrankHashes()` method rotates the crankhash and updates the activityhash (see the kvStore documentation for details). + +Note that `endCrank()` does *not* perform a SQLite `COMMIT`, as that power is reserved for the host application (through `hostStorage.commit()`). Instead, the kernel only has access to SQLite "savepoints", which are smaller-scale than full transactions. + + +# SwingStore Data Model + + +The state is broken up into several pieces, or "sub-stores": -* `bundleStore`: a string-keyed Bundle-value table, holding source bundles which can be evaluated by `importBundle` to create vats, or new Compartments within a vat -* `transcriptStore`: records a linear sequence of deliveries and syscalls (with results), collectively known as "transcript entries", for each vat -* `snapStore`: records one or more XS heap snapshots for each vat, to rebuild a worker more efficiently than replaying all transcript entries from the beginning -* `kvStore`: a string-keyed string-valued table, which holds everything else. Currently, this holds each vat's c-list and vatstore data, as well as the kernel-wide object and promise tables, and run-queues. ## Incarnations, Spans, Snapshots @@ -50,3 +94,15 @@ When a transcript span is pruned, the `transcriptSpans` row is left alone, but t During import, we create the metadata first (as the export-data is parsed), then later, we fill in the details as the artifacts are read. Bundles are never pruned, however during import, the `bundles` table will temporarily contain rows whose `bundle` BLOB is NULL. + +## Vat Lifetimes + +Two sub-stores are keyed by VatID: `transcriptStore` and `snapStore` (the `bundleStore` does not know which vats might know about each bundle, and the `kvStore` entries which relate to a specific vat will have the VatID embedded in the key, so the swing-store doesn't need to know about them). + +When the kernel terminates a vat, we want to delete the no-longer-necessary data. However, if the vat had a large number of transcript entries and/or heap snapshots, deleting all this data at the same time might cause excessing CPU or I/O usage (eg thousands of DB queries, or a multi-gigabyte `swingstore.sqlite-wal` file. It might also push a large number of changes into the export-data callbacks, which can cause memory or CPU stall problems in the host application. In the worst case, the entire application could crash. + +To limit this usage, and allow the kernel to delete vat state slowly, the swing-store is somewhat more aware of a vat's lifetime than a mere database should be. In particular, we split the shutdown process into two pieces. "Terminating a vat" happens first, and tells the sub-store to hide the vat from exports and from API calls that are meant to find out which vats are available. The kernel should call this exactly once, when the vat is terminated. + +The second part is "deletion", and it can happen either all-at-once or in multiple budget-limited calls. Both forms share the same API calls, differing only in their `budget` argument (`undefined` means all-at-once). The deletion API can be called multiple times, with a small budget, and each call will only delete a small portion of the state. They will return a value that indicates when the last bit of state has been deleted, so the kernel can know when to stop calling them. + +See [transcriptstore.md](./transcriptstore.md) and [snapstore.md](./snapstore.md) for more details. diff --git a/packages/swing-store/docs/transcriptstore.md b/packages/swing-store/docs/transcriptstore.md new file mode 100644 index 00000000000..2a10f68c807 --- /dev/null +++ b/packages/swing-store/docs/transcriptstore.md @@ -0,0 +1,70 @@ +# TranscriptStore + +The `kernelStorage.transcriptStore` sub-store tracks vat delivery transcripts, through which the kernel can provide orthogonal persistence of JavaScript runtime environments (vats). + +Each vat is a JavaScript runtime environment, initialized by evaluating some starting code bundle, and then fed a series of deliveries. Each delivery may provoke some number of syscalls back to the kernel, with each get some response data. The delivery finishes with a "delivery result". + +For each delivery, this data (delivery, syscall/response pairs, delivery-result) is serialized and stored in a single "transcript item". Each item is indexed by an incrementing "delivery number" (`deliveryNum`). + +When a vat worker is brought online, the kernel retrieves these transcript items from the transcriptStore and replays them, by performing the delivery and responding to the syscalls, even though the syscall responses are pulled from the transcript instead of causing actual execution. The kernel asserts that the new worker behaves exactly like the original one did. For xsnap workers, the kernel doesn't actually have to replay the *entire* transcript, because it can start from a heap snapshot (stored in the adjoining [`snapStore`](./snapstore.md)). So generally it only needs to replay a single span. + +## Data Model + +Vat lifetimes are broken up into "incarnations", separated by upgrade events. Within each incarnation, the transcript is broken up into "spans", separated by heap-snapshot cycles. To end a span, the kernel records the worker's heap snapshot, then "closes" the old span, and opens a new one. + +This results in a single open or "current" span for each active vat, and a series of historical spans. For operational purposes, we only care about the current span. But to support some potential deep-replay needs, the transcriptStore can retain data about earlier spans. + +The SQLite database has one table that tracks transcript spans, named `transcriptSpans`. All vatIDs and incarnations are stored in the same table, whose schema is `(vatID TEXT, startPos INTEGER, endPos INTEGER, hash TEXT, isCurrent INTEGER, incarnation INTEGER)`. `startPos` and `endPos` define a zero-based range over the sequence of all deliveries into a vat (the former inclusive and the latter exclusive, such that e.g. `startPos=0` and `endPos=3` would encompass the first three deliveries, with positions 0, 1, and 2). + +A separate table named `transcriptItems` tracks the items themselves, with a schema of `(vatID TEXT, position INTEGER, item TEXT, incarnation INTEGER)`. This table has one row per transcript item, each of which is "owned" by a single span with matching values for `vatID` and `incarnation` and having `startPos <= position` and `endPos > position`. Each span owns multiple items (typically 200, but it depends upon how frequently the kernel rolls over new spans). + +In the future, historical spans may be compressed, and their item rows replaced with a single compressed blob in the span record. This would reduce the space needed without actually pruning the data. + +## Retention / Pruning + +If the current swingstore was opened with the `keepTranscripts = false` option, then the transcriptStore will "prune" each span as soon as it becomes historical. Pruned spans will still have a span record, with a hash, to enable safely-validated restoration of the transcript items later, if necessary. However their item records will be deleted, to save space. + +When `keepTranscripts = true`, all span items are retained. + +Pruned spans are not available for export artifacts, of course, because the data is missing. However the span *hashes* are still included in the export-data, to support safe validation. You can start with a pruned swingstore, produce an export dataset, import that dataset into a new swingstore, and the new swingstore will be just as capable of validating replacement span records as the original was. + +## Export Model + +Every transcript span, both current and historic, gets an export-data record. The record name is different for the two types of spans. + +Historical spans, which are "closed" and no longer growing, use a record name of `transcript.${vatID}.${startPos}.${endPos}`, where `startPos` is the delivery number of the first delivery included in the span and `endPos` is the the delivery number of the first delivery included in the **next** span (i.e., the former is an inclusive lower bound and the latter is an exclusive upper bound). +The value is a JSON-serialized record of `{ vatID, startPos, endPos, hash, isCurrent, incarnation }` (where `isCurrent = 0`). + +The current span, if any, uses a record name of `transcript.${vatID}.current`, and has the same value as historical spans (except `isCurrent = 1`). Current spans are growing: new transcript items are added as more deliveries are made, until the span is closed off (becomes historical) and replaced with a new current span. There is at most one current span per vatID. + +The available export *artifacts* will depend upon the export mode, and upon the swingstore's `keepTranscripts` setting. Each export artifact corresponds to a single span, and the artifact names are always `transcript.${vatID}.${startPos}.${endPos}` (for both historical and current spans). + +In the most-minimal `operational` mode, the export includes one artifact for each active (non-terminated) vat: just the current span. If `keepTranscripts` is not true, these will be the only available artifacts anyways. + +The `replay` mode includes all spans for each vat's current incarnation, but omits spans from earlier incarnations. The `archival` mode includes all spans from all incarnations. + +The `debug` mode includes all available spans, even for terminated vats. For the non-`debug` modes, terminated vats will not provide export-data or artifacts. + +## Slow Deletion + +As soon as a vat is terminated, the kernel will call `transcriptStore.stopUsingTranscript()`. The DB is updated to clear the `isCurrent` flag of the latest span, leaving no rows with `isCurrent = 1`. This immediately makes the vat non-loadable by the kernel. + +This also removes the `transcript.${vatID}.current` export-data record, and replaces it with a `transcript.${vatID}.${startPos}` one, effectively making the span historical. This change (one deletion, one addition) is added to the export-data callback queue, so the host-app can learn about it after the next commit, and any subsequent `getExportData()` calls will see the replacement record, instead of a `.current` record. + +At this point, all non-`debug` swing-store exports after this point will omit any artifacts for the vat, but they will still include export-data records (hashes) for all spans, all of which look historical. (Deleting all the span records, and their corresponding export-data records, is too much work to do in a single step). + +Later, as the kernel performs cleanup work for this vatID, the `transcriptStore.deleteVatTranscripts(budget)` cleanup call will delete one span row per `budget`, along with all related item rows (typically 200). Each span deleted will also remove one export-data record (which feeds the callback queue, as well as affecting the full `getExportData()` results). + +Eventually, the transcriptStore runs out of rows to delete, and `deleteVatTranscripts(budget)` returns `{ done: true }`, so the kernel can finally rest. + +### TranscriptStore Vat Lifetime + +Unlike the [SnapStore](./snapstore.md), the TranscriptStore *does* have an explicit call to be made when a vat is first created: `transcriptStore.initTranscript(vatID)`. Also unlike SnapStore, TranscriptStore (normally) always has an `isCurrent = 1` span for each vat (it might just be empty of items, immediately after the span rolls over). + +When a vat is terminated, the kernel should first call `transcriptStore.stopUsingTranscript(vatID)`. This will mark the single current span as `isCurrent = 0`. The kernel must not attempt to read, add, or rollover spans or items while in this state. While in this state, exports (export for `mode = debug`) will not emit artifacts for this VatID: export-data records will still exist for all spans, as these must be deleted slowly, however there will be no associated artifacts or artifact names. + +Then, the kernel should either call `transcriptStore.deleteVatTranscripts(vatID)` exactly once, or it should call `transcriptStore.deleteVatTranscripts(vatID, budget)` until it returns `{ done: true }`. + +As with snapshots, the `stopUsingTranscript()` is a non-mandatory performance improvement. If omitted, exports will continue to include (many) span artifacts for this vat until the first call to `deleteVatTranscripts()` removes the one `isCurrent = 1` span (since spans are deleted most-recent-first). After that point, exports will stop including any artifacts for the vatID. `stopUsingTranscript()` is idempotent, and extra calls will leave the DB unchanged. + +The kernel must keep calling `deleteVatTranscripts(vatID, budget)` until the `{ done }` return value is `true`. As with the SnapStore, it is safe to call it again after that point; the function will keep returning `true`. diff --git a/packages/swing-store/package.json b/packages/swing-store/package.json index ac7ce9a749a..7e068e46042 100644 --- a/packages/swing-store/package.json +++ b/packages/swing-store/package.json @@ -21,16 +21,16 @@ "lint:eslint": "eslint ." }, "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/internal": "^0.3.2", - "@endo/base64": "^1.0.5", - "@endo/bundle-source": "^3.2.3", - "@endo/check-bundle": "^1.0.7", - "@endo/nat": "^5.0.7", + "@endo/base64": "^1.0.7", + "@endo/bundle-source": "^3.4.0", + "@endo/check-bundle": "^1.0.9", + "@endo/nat": "^5.0.10", "better-sqlite3": "^9.1.1" }, "devDependencies": { - "@endo/init": "^1.1.2", + "@endo/init": "^1.1.4", "@types/better-sqlite3": "^7.6.9", "ava": "^5.3.0", "c8": "^9.1.0", @@ -49,6 +49,6 @@ "timeout": "2m" }, "typeCoverage": { - "atLeast": 76.31 + "atLeast": 79.02 } } diff --git a/packages/swing-store/src/archiver.js b/packages/swing-store/src/archiver.js new file mode 100644 index 00000000000..c79ca9424fb --- /dev/null +++ b/packages/swing-store/src/archiver.js @@ -0,0 +1,80 @@ +import { finished as streamFinishedCallback, Readable } from 'node:stream'; +import { promisify } from 'node:util'; +import { createGzip } from 'node:zlib'; +import { withDeferredCleanup } from '@agoric/internal'; + +const streamFinished = promisify(streamFinishedCallback); + +/* + * @param {string} dirPath + * @param {object} powers + * @param {Pick} powers.fs + * @param {Pick} powers.path + * @param {Pick} powers.tmp + */ +export const makeArchiveSnapshot = (dirPath, powers) => { + const { fs, path, tmp } = powers; + fs.mkdirSync(dirPath, { recursive: true }); + const archiveSnapshot = (name, gzData) => { + const destPath = path.join(dirPath, `${name}.gz`); + return withDeferredCleanup(async addCleanup => { + const { + name: tmpName, + fd, + removeCallback, + } = tmp.fileSync({ + prefix: name, + postfix: '.gz', + detachDescriptor: true, + }); + addCleanup(() => removeCallback()); + const writer = fs.createWriteStream('', { fd, flush: true }); + const reader = Readable.from(gzData); + const destroyReader = promisify(reader.destroy.bind(reader)); + addCleanup(() => destroyReader(null)); + reader.pipe(writer); + await streamFinished(writer); + fs.renameSync(tmpName, destPath); + }); + }; + return archiveSnapshot; +}; +harden(makeArchiveSnapshot); + +/* + * @param {string} dirPath + * @param {object} powers + * @param {Pick} powers.fs + * @param {Pick} powers.path + * @param {Pick} powers.tmp + */ +export const makeArchiveTranscript = (dirPath, powers) => { + const { fs, path, tmp } = powers; + fs.mkdirSync(dirPath, { recursive: true }); + const archiveTranscript = (spanName, entries) => { + const destPath = path.join(dirPath, `${spanName}.gz`); + return withDeferredCleanup(async addCleanup => { + const { + name: tmpName, + fd, + removeCallback, + } = tmp.fileSync({ + prefix: spanName, + postfix: '.gz', + detachDescriptor: true, + }); + addCleanup(() => removeCallback()); + const writer = fs.createWriteStream('', { fd, flush: true }); + const gzip = createGzip(); + gzip.pipe(writer); + const reader = Readable.from(entries); + const destroyReader = promisify(reader.destroy.bind(reader)); + addCleanup(() => destroyReader(null)); + reader.pipe(gzip); + await streamFinished(gzip); + fs.renameSync(tmpName, destPath); + }); + }; + return archiveTranscript; +}; +harden(makeArchiveTranscript); diff --git a/packages/swing-store/src/index.js b/packages/swing-store/src/index.js index f2144bc43ee..3fe49b91ad5 100644 --- a/packages/swing-store/src/index.js +++ b/packages/swing-store/src/index.js @@ -2,6 +2,8 @@ export { initSwingStore, openSwingStore, isSwingStore } from './swingStore.js'; export { makeSwingStoreExporter } from './exporter.js'; export { importSwingStore } from './importer.js'; +export { makeArchiveSnapshot, makeArchiveTranscript } from './archiver.js'; + // temporary, for the benefit of SwingSet/misc-tools/replay-transcript.js export { makeSnapStore } from './snapStore.js'; // and less temporary, for SwingSet/test/vat-warehouse/test-reload-snapshot.js diff --git a/packages/swing-store/src/snapStore.js b/packages/swing-store/src/snapStore.js index c96a49c0343..e8548c77fef 100644 --- a/packages/swing-store/src/snapStore.js +++ b/packages/swing-store/src/snapStore.js @@ -4,10 +4,7 @@ import { finished as finishedCallback, PassThrough, Readable } from 'stream'; import { promisify } from 'util'; import { createGzip, createGunzip } from 'zlib'; import { Fail, q } from '@endo/errors'; -import { - aggregateTryFinally, - PromiseAllOrErrors, -} from '@agoric/internal/src/node/utils.js'; +import { withDeferredCleanup } from '@agoric/internal'; import { buffer } from './util.js'; /** @@ -17,6 +14,7 @@ import { buffer } from './util.js'; * @property {number} dbSaveSeconds time to write snapshot in DB * @property {number} compressedSize size of (compressed) snapshot * @property {number} compressSeconds time to generate and compress the snapshot + * @property {number} [archiveWriteSeconds] time to write an archive to disk (if applicable) */ /** @@ -39,7 +37,7 @@ import { buffer } from './util.js'; * loadSnapshot: (vatID: string) => AsyncIterableIterator, * saveSnapshot: (vatID: string, snapPos: number, snapshotStream: AsyncIterable) => Promise, * deleteAllUnusedSnapshots: () => void, - * deleteVatSnapshots: (vatID: string) => void, + * deleteVatSnapshots: (vatID: string, budget?: number) => { done: boolean, cleanups: number }, * stopUsingLastSnapshot: (vatID: string) => void, * getSnapshotInfo: (vatID: string) => SnapshotInfo, * }} SnapStore @@ -73,6 +71,7 @@ const finished = promisify(finishedCallback); * @param {(key: string, value: string | undefined) => void} noteExport * @param {object} [options] * @param {boolean | undefined} [options.keepSnapshots] + * @param {(name: string, compressedData: Parameters[0]) => Promise} [options.archiveSnapshot] * @returns {SnapStore & SnapStoreInternal & SnapStoreDebug} */ export function makeSnapStore( @@ -80,7 +79,7 @@ export function makeSnapStore( ensureTxn, { measureSeconds }, noteExport = () => {}, - { keepSnapshots = false } = {}, + { keepSnapshots = false, archiveSnapshot } = {}, ) { db.exec(` CREATE TABLE IF NOT EXISTS snapshots ( @@ -173,11 +172,13 @@ export function makeSnapStore( `); function stopUsingLastSnapshot(vatID) { + // idempotent ensureTxn(); const oldInfo = sqlGetPriorSnapshotInfo.get(vatID); if (oldInfo) { const rec = snapshotRec(vatID, oldInfo.snapPos, oldInfo.hash, 0); noteExport(snapshotMetadataKey(rec), JSON.stringify(rec)); + noteExport(currentSnapshotMetadataKey(rec), undefined); if (keepSnapshots) { sqlStopUsingLastSnapshot.run(vatID); } else { @@ -194,7 +195,8 @@ export function makeSnapStore( /** * Generates a new XS heap snapshot, stores a gzipped copy of it into the - * snapshots table, and reports information about the process, including + * snapshots table (and also to an archiveSnapshot callback if provided for + * e.g. disk archival), and reports information about the process, including * snapshot size and timing metrics. * * @param {string} vatID @@ -203,74 +205,62 @@ export function makeSnapStore( * @returns {Promise} */ async function saveSnapshot(vatID, snapPos, snapshotStream) { - const cleanup = []; - return aggregateTryFinally( - async () => { - const hashStream = createHash('sha256'); - const gzip = createGzip(); - let compressedSize = 0; - let uncompressedSize = 0; - - const { duration: compressSeconds, result: compressedSnapshot } = - await measureSeconds(async () => { - const snapReader = Readable.from(snapshotStream); - cleanup.push( - () => - new Promise((resolve, reject) => - snapReader.destroy( - null, - // @ts-expect-error incorrect types - err => (err ? reject(err) : resolve()), - ), - ), - ); - - snapReader.on('data', chunk => { - uncompressedSize += chunk.length; - }); - snapReader.pipe(hashStream); - const compressedSnapshotData = await buffer(snapReader.pipe(gzip)); - await finished(snapReader); - return compressedSnapshotData; + return withDeferredCleanup(async addCleanup => { + const hashStream = createHash('sha256'); + const gzip = createGzip(); + let compressedSize = 0; + let uncompressedSize = 0; + + const { duration: compressSeconds, result: compressedSnapshot } = + await measureSeconds(async () => { + const snapReader = Readable.from(snapshotStream); + const destroyReader = promisify(snapReader.destroy.bind(snapReader)); + addCleanup(() => destroyReader(null)); + snapReader.on('data', chunk => { + uncompressedSize += chunk.length; }); - const hash = hashStream.digest('hex'); - - const { duration: dbSaveSeconds } = await measureSeconds(async () => { - ensureTxn(); - stopUsingLastSnapshot(vatID); - compressedSize = compressedSnapshot.length; - sqlSaveSnapshot.run( - vatID, - snapPos, - 1, - hash, - uncompressedSize, - compressedSize, - compressedSnapshot, - ); - const rec = snapshotRec(vatID, snapPos, hash, 1); - const exportKey = snapshotMetadataKey(rec); - noteExport(exportKey, JSON.stringify(rec)); - noteExport( - currentSnapshotMetadataKey(rec), - snapshotArtifactName(rec), - ); + snapReader.pipe(hashStream); + const compressedSnapshotData = await buffer(snapReader.pipe(gzip)); + await finished(snapReader); + return compressedSnapshotData; }); + const hash = hashStream.digest('hex'); + const rec = snapshotRec(vatID, snapPos, hash, 1); + const exportKey = snapshotMetadataKey(rec); - return harden({ + const { duration: dbSaveSeconds } = await measureSeconds(async () => { + ensureTxn(); + stopUsingLastSnapshot(vatID); + compressedSize = compressedSnapshot.length; + sqlSaveSnapshot.run( + vatID, + snapPos, + 1, hash, uncompressedSize, - compressSeconds, - dbSaveSeconds, compressedSize, - }); - }, - async () => { - await PromiseAllOrErrors( - cleanup.reverse().map(fn => Promise.resolve().then(() => fn())), + compressedSnapshot, ); - }, - ); + noteExport(exportKey, JSON.stringify(rec)); + noteExport(currentSnapshotMetadataKey(rec), snapshotArtifactName(rec)); + }); + + let archiveWriteSeconds; + if (archiveSnapshot) { + ({ duration: archiveWriteSeconds } = await measureSeconds(async () => { + await archiveSnapshot(exportKey, compressedSnapshot); + })); + } + + return harden({ + hash, + uncompressedSize, + compressSeconds, + dbSaveSeconds, + archiveWriteSeconds, + compressedSize, + }); + }); } const sqlGetSnapshot = db.prepare(` @@ -354,28 +344,74 @@ export function makeSnapStore( WHERE vatID = ? `); + const sqlDeleteOneVatSnapshot = db.prepare(` + DELETE FROM snapshots + WHERE vatID = ? AND snapPos = ? + `); + const sqlGetSnapshotList = db.prepare(` SELECT snapPos FROM snapshots WHERE vatID = ? ORDER BY snapPos `); - sqlGetSnapshotList.pluck(true); + + const sqlGetSnapshotListLimited = db.prepare(` + SELECT snapPos, inUse + FROM snapshots + WHERE vatID = ? + ORDER BY snapPos DESC + LIMIT ? + `); /** - * Delete all snapshots for a given vat (for use when, e.g., a vat is terminated) + * @param {string} vatID + * @returns {boolean} + */ + function hasSnapshots(vatID) { + // the LIMIT 1 means we aren't really getting all entries + return sqlGetSnapshotListLimited.all(vatID, 1).length > 0; + } + + /** + * Delete some or all snapshots for a given vat (for use when, e.g., + * a vat is terminated) * * @param {string} vatID + * @param {number} [budget] + * @returns {{ done: boolean, cleanups: number }} */ - function deleteVatSnapshots(vatID) { + function deleteVatSnapshots(vatID, budget = Infinity) { ensureTxn(); - const deletions = sqlGetSnapshotList.all(vatID); - for (const snapPos of deletions) { + const deleteAll = budget === Infinity; + assert(deleteAll || budget >= 1, 'budget must be undefined or positive'); + // We can't use .iterate because noteExport can write to the DB, + // and overlapping queries are not supported. + const deletions = deleteAll + ? sqlGetSnapshotList.all(vatID) + : sqlGetSnapshotListLimited.all(vatID, budget); + let clearCurrent = deleteAll; + for (const deletion of deletions) { + clearCurrent ||= deletion.inUse; + const { snapPos } = deletion; const exportRec = snapshotRec(vatID, snapPos, undefined); noteExport(snapshotMetadataKey(exportRec), undefined); + // Budgeted deletion must delete rows one by one, + // but full deletion is handled all at once after this loop. + if (!deleteAll) { + sqlDeleteOneVatSnapshot.run(vatID, snapPos); + } + } + if (deleteAll) { + sqlDeleteVatSnapshots.run(vatID); + } + if (clearCurrent) { + noteExport(currentSnapshotMetadataKey({ vatID }), undefined); } - noteExport(currentSnapshotMetadataKey({ vatID }), undefined); - sqlDeleteVatSnapshots.run(vatID); + return { + done: deleteAll || deletions.length === 0 || !hasSnapshots(vatID), + cleanups: deletions.length, + }; } const sqlGetSnapshotInfo = db.prepare(` @@ -452,7 +488,7 @@ export function makeSnapStore( `); /** - * Obtain artifact metadata records for spanshots contained in this store. + * Obtain artifact metadata records for snapshots contained in this store. * * @param {boolean} includeHistorical If true, include all metadata that is * present in the store regardless of its currency; if false, only include diff --git a/packages/swing-store/src/swingStore.js b/packages/swing-store/src/swingStore.js index ccf9c200687..14181a16a8c 100644 --- a/packages/swing-store/src/swingStore.js +++ b/packages/swing-store/src/swingStore.js @@ -169,7 +169,13 @@ export function makeSwingStore(dirPath, forceReset, options = {}) { filePath = ':memory:'; } - const { traceFile, keepSnapshots, keepTranscripts } = options; + const { + traceFile, + keepSnapshots, + keepTranscripts, + archiveSnapshot, + archiveTranscript, + } = options; let traceOutput = traceFile ? fs.createWriteStream(path.resolve(traceFile), { @@ -297,6 +303,7 @@ export function makeSwingStore(dirPath, forceReset, options = {}) { noteExport, { keepTranscripts, + archiveTranscript, }, ); const { dumpSnapshots, ...snapStore } = makeSnapStore( @@ -306,6 +313,7 @@ export function makeSwingStore(dirPath, forceReset, options = {}) { noteExport, { keepSnapshots, + archiveSnapshot, }, ); const { dumpBundles, ...bundleStore } = makeBundleStore( @@ -554,6 +562,7 @@ export function makeSwingStore(dirPath, forceReset, options = {}) { getCurrentSpanBounds: transcriptStore.getCurrentSpanBounds, addItem: transcriptStore.addItem, readSpan: transcriptStore.readSpan, + stopUsingTranscript: transcriptStore.stopUsingTranscript, deleteVatTranscripts: transcriptStore.deleteVatTranscripts, }; diff --git a/packages/swing-store/src/transcriptStore.js b/packages/swing-store/src/transcriptStore.js index adbcb71e5d1..06be31aa9b0 100644 --- a/packages/swing-store/src/transcriptStore.js +++ b/packages/swing-store/src/transcriptStore.js @@ -15,10 +15,11 @@ import { createSHA256 } from './hasher.js'; * * @typedef {{ * initTranscript: (vatID: string) => void, - * rolloverSpan: (vatID: string) => number, - * rolloverIncarnation: (vatID: string) => number, + * rolloverSpan: (vatID: string) => Promise, + * rolloverIncarnation: (vatID: string) => Promise, * getCurrentSpanBounds: (vatID: string) => { startPos: number, endPos: number, hash: string, incarnation: number }, - * deleteVatTranscripts: (vatID: string) => void, + * stopUsingTranscript: (vatID: string) => Promise, + * deleteVatTranscripts: (vatID: string, budget?: number) => { done: boolean, cleanups: number }, * addItem: (vatID: string, item: string) => void, * readSpan: (vatID: string, startPos?: number) => IterableIterator, * }} TranscriptStore @@ -60,14 +61,15 @@ function insistTranscriptPosition(position) { * @param {() => void} ensureTxn * @param {(key: string, value: string | undefined ) => void} noteExport * @param {object} [options] - * @param {boolean | undefined} [options.keepTranscripts] + * @param {boolean} [options.keepTranscripts] + * @param {(spanName: string, entries: ReturnType) => Promise} [options.archiveTranscript] * @returns { TranscriptStore & TranscriptStoreInternal & TranscriptStoreDebug } */ export function makeTranscriptStore( db, ensureTxn, noteExport = () => {}, - { keepTranscripts = true } = {}, + { keepTranscripts = true, archiveTranscript } = {}, ) { db.exec(` CREATE TABLE IF NOT EXISTS transcriptItems ( @@ -79,15 +81,21 @@ export function makeTranscriptStore( ) `); - // Transcripts are broken up into "spans", delimited by heap snapshots. If we - // take heap snapshots after deliveries 100 and 200, and have not yet - // performed delivery 201, we'll have two non-current (i.e., isCurrent=null) - // spans (one with startPos=0, endPos=100, the second with startPos=100, - // endPos=200), and a single empty isCurrent==1 span with startPos=200 and - // endPos=200. After we perform delivery 201, the single isCurrent=1 span - // will will still have startPos=200 but will now have endPos=201. For every - // vatID, there will be exactly one isCurrent=1 span, and zero or more - // non-current (historical) spans. + // Transcripts are broken up into "spans", delimited by heap snapshots. + // The items of each transcript consist of deliveries and pseudo-deliveries + // such as initialize-worker and load-snapshot. + // For every vatID, there will be exactly one current span (with isCurrent=1), + // and zero or more non-current (historical) spans (with isCurrent=null). + // If we take a heap snapshot after the first hundred items and again after + // the second hundred (i.e., after zero-indexed items 99 and 199), + // and have not yet extended the transcript after the second snapshot, we'll + // have two historical spans (one with startPos=0 and endPos=100, the second + // with startPos=100 and endPos=200) and a single empty current span with + // startPos=200 and endPos=200. But this situation is transient, and will + // generally be followed by a load-snapshot pseudo-delivery before the next + // commit (at which point the single current span will still have startPos=200 + // but will have endPos=201). After we perform the next delivery, the single + // current span will still have startPos=200 but will now have endPos=202. // // The transcriptItems associated with historical spans may or may not exist, // depending on pruning. However, the items associated with the current span @@ -212,10 +220,12 @@ export function makeTranscriptStore( */ function initTranscript(vatID) { ensureTxn(); - const initialIncarnation = 0; - sqlWriteSpan.run(vatID, 0, 0, initialHash, 1, initialIncarnation); - const newRec = spanRec(vatID, 0, 0, initialHash, 1, 0); - noteExport(spanMetadataKey(newRec), JSON.stringify(newRec)); + const pos = 0; + const isCurrent = 1; + const incarnation = 0; + sqlWriteSpan.run(vatID, pos, pos, initialHash, isCurrent, incarnation); + const rec = spanRec(vatID, pos, pos, initialHash, isCurrent, incarnation); + noteExport(spanMetadataKey(rec), JSON.stringify(rec)); } const sqlGetCurrentSpanBounds = db.prepare(` @@ -237,6 +247,102 @@ export function makeTranscriptStore( return bounds; } + const sqlGetSpanEndPos = db.prepare(` + SELECT endPos + FROM transcriptSpans + WHERE vatID = ? AND startPos = ? + `); + sqlGetSpanEndPos.pluck(true); + + const sqlReadSpanItems = db.prepare(` + SELECT item + FROM transcriptItems + WHERE vatID = ? AND ? <= position AND position < ? + ORDER BY position + `); + + /** + * Read the items in a transcript span + * + * @param {string} vatID The vat whose transcript is being read + * @param {number} [startPos] A start position identifying the span to be + * read; defaults to the current span, whatever it is + * + * @returns {IterableIterator} An iterator over the items in the indicated span + */ + function readSpan(vatID, startPos) { + /** @type {number | undefined} */ + let endPos; + if (startPos === undefined) { + ({ startPos, endPos } = getCurrentSpanBounds(vatID)); + } else { + insistTranscriptPosition(startPos); + endPos = sqlGetSpanEndPos.get(vatID, startPos); + if (typeof endPos !== 'number') { + throw Fail`no transcript span for ${q(vatID)} at ${q(startPos)}`; + } + } + startPos <= endPos || Fail`${q(startPos)} <= ${q(endPos)}}`; + const expectedCount = endPos - startPos; + + function* reader() { + let count = 0; + for (const { item } of sqlReadSpanItems.iterate( + vatID, + startPos, + endPos, + )) { + yield item; + count += 1; + } + count === expectedCount || + Fail`read ${q(count)} transcript entries (expected ${q( + expectedCount, + )})`; + } + harden(reader); + + if (startPos === endPos) { + return empty(); + } + + return reader(); + } + + const sqlGetSpanIsCurrent = db.prepare(` + SELECT isCurrent + FROM transcriptSpans + WHERE vatID = ? AND startPos = ? + `); + sqlGetSpanIsCurrent.pluck(true); + + /** + * Read a transcript span and return it as a stream of data suitable for + * export to another store. Transcript items are terminated by newlines. + * + * Transcript span artifact names should be strings of the form: + * `transcript.${vatID}.${startPos}.${endPos}` + * + * @param {string} name The name of the transcript artifact to be read + * @returns {AsyncIterableIterator} + * @yields {Uint8Array} + */ + async function* exportSpan(name) { + typeof name === 'string' || Fail`artifact name must be a string`; + const parts = name.split('.'); + const [type, vatID, pos] = parts; + // prettier-ignore + (parts.length === 4 && type === 'transcript') || + Fail`expected artifact name of the form 'transcript.{vatID}.{startPos}.{endPos}', saw ${q(name)}`; + const isCurrent = sqlGetSpanIsCurrent.get(vatID, pos); + isCurrent !== undefined || Fail`transcript span ${q(name)} not available`; + const startPos = Number(pos); + for (const entry of readSpan(vatID, startPos)) { + yield Buffer.from(`${entry}\n`); + } + } + harden(exportSpan); + const sqlEndCurrentSpan = db.prepare(` UPDATE transcriptSpans SET isCurrent = null @@ -245,30 +351,71 @@ export function makeTranscriptStore( const sqlDeleteOldItems = db.prepare(` DELETE FROM transcriptItems - WHERE vatID = ? AND position < ? + WHERE vatID = ? AND position >= ? AND position < ? `); - function doSpanRollover(vatID, isNewIncarnation) { + /** + * Finalize a span, setting isCurrent to null, marking the resulting record + * for export, and effecting disk archival and database cleanup as + * configured. + * Note that creation of a new DB row and removal/replacement of the + * transcript.${vatID}.current export record are responsibility of the caller. + * + * @param {string} vatID + * @param {ReturnType} bounds + */ + async function closeSpan(vatID, bounds) { ensureTxn(); - const { hash, startPos, endPos, incarnation } = getCurrentSpanBounds(vatID); - const rec = spanRec(vatID, startPos, endPos, hash, 0, incarnation); + const { startPos, endPos, hash, incarnation } = bounds; + const rec = spanRec(vatID, startPos, endPos, hash, false, incarnation); + + // add a new export record for the now-old span noteExport(spanMetadataKey(rec), JSON.stringify(rec)); + + // and change its DB row to isCurrent=null sqlEndCurrentSpan.run(vatID); - const incarnationToUse = isNewIncarnation ? incarnation + 1 : incarnation; - sqlWriteSpan.run(vatID, endPos, endPos, initialHash, 1, incarnationToUse); - const newRec = spanRec( + + await null; + if (archiveTranscript) { + const spanName = spanArtifactName(rec); + const entries = exportSpan(spanName); + await archiveTranscript(spanName, entries); + } + if (!keepTranscripts) { + // Delete items of the previously-current span. + // There may still be items associated with even older spans, but we leave + // those, to avoid excessive DB churn (for details, see #9387 and #9174). + // Recovery of space claimed by such ancient items is expected to use an + // external mechanism such as restoration from an operational snapshot + // that doesn't include them. + sqlDeleteOldItems.run(vatID, startPos, endPos); + } + } + + async function doSpanRollover(vatID, isNewIncarnation) { + ensureTxn(); + const bounds = getCurrentSpanBounds(vatID); + const { endPos, incarnation } = bounds; + + // deal with the now-old span + await closeSpan(vatID, bounds); + + // create a new (empty) DB row, with isCurrent=1 + const newSpanIncarnation = isNewIncarnation ? incarnation + 1 : incarnation; + sqlWriteSpan.run(vatID, endPos, endPos, initialHash, 1, newSpanIncarnation); + + // overwrite the transcript.${vatID}.current record with new span + const rec = spanRec( vatID, endPos, endPos, initialHash, - 1, - incarnationToUse, + true, + newSpanIncarnation, ); - noteExport(spanMetadataKey(newRec), JSON.stringify(newRec)); - if (!keepTranscripts) { - sqlDeleteOldItems.run(vatID, endPos); - } - return incarnationToUse; + noteExport(spanMetadataKey(rec), JSON.stringify(rec)); + + return newSpanIncarnation; } /** @@ -278,9 +425,9 @@ export function makeTranscriptStore( * @param {string} vatID The vat whose transcript is to rollover to a new * span. * - * @returns {number} the new incarnation number + * @returns {Promise} the new incarnation number */ - function rolloverIncarnation(vatID) { + async function rolloverIncarnation(vatID) { return doSpanRollover(vatID, true); } @@ -291,9 +438,9 @@ export function makeTranscriptStore( * @param {string} vatID The vat whose transcript is to rollover to a new * span. * - * @returns {number} the incarnation number + * @returns {Promise} the incarnation number */ - function rolloverSpan(vatID) { + async function rolloverSpan(vatID) { return doSpanRollover(vatID, false); } @@ -314,19 +461,94 @@ export function makeTranscriptStore( ORDER BY startPos `); + // This query is ORDER BY startPos DESC, so deleteVatTranscripts + // will delete the newest spans first. If the kernel failed to call + // stopUsingTranscript, that will delete the isCurrent=1 span first, + // which lets us stop including span artifacts in exports sooner. + + const sqlGetSomeVatSpans = db.prepare(` + SELECT vatID, startPos, endPos, isCurrent + FROM transcriptSpans + WHERE vatID = ? + ORDER BY startPos DESC + LIMIT ? + `); + + const sqlDeleteVatSpan = db.prepare(` + DELETE FROM transcriptSpans + WHERE vatID = ? AND startPos = ? + `); + + const sqlDeleteSomeItems = db.prepare(` + DELETE FROM transcriptItems + WHERE vatID = ? AND position >= ? AND position < ? + `); + /** - * Delete all transcript data for a given vat (for use when, e.g., a vat is terminated) + * Prepare for vat deletion by marking the isCurrent=1 span as not current. + * Idempotent. * + * @param {string} vatID The vat being terminated/deleted. + */ + async function stopUsingTranscript(vatID) { + ensureTxn(); + const bounds = sqlGetCurrentSpanBounds.get(vatID); + if (!bounds) return; + + // deal with the now-old span + await closeSpan(vatID, bounds); + + // remove the transcript.${vatID}.current record + noteExport(spanMetadataKey({ vatID, isCurrent: true }), undefined); + } + + /** * @param {string} vatID + * @returns {boolean} */ - function deleteVatTranscripts(vatID) { + function hasSpans(vatID) { + // the LIMIT 1 means we aren't really getting all spans + return sqlGetSomeVatSpans.all(vatID, 1).length > 0; + } + + /** + * Delete some or all transcript data for a given vat (for use when, + * e.g., a vat is terminated) + * + * @param {string} vatID + * @param {number} [budget] + * @returns {{ done: boolean, cleanups: number }} + */ + function deleteVatTranscripts(vatID, budget = Infinity) { ensureTxn(); - const deletions = sqlGetVatSpans.all(vatID); + const deleteAll = budget === Infinity; + assert(deleteAll || budget >= 1, 'budget must be undefined or positive'); + // We can't use .iterate because noteExport can write to the DB, + // and overlapping queries are not supported. + const deletions = deleteAll + ? sqlGetVatSpans.all(vatID) + : sqlGetSomeVatSpans.all(vatID, budget); for (const rec of deletions) { + // If rec.isCurrent is true, this will remove the + // transcript.$vatID.current export-data record. If false, it + // will remove the transcript.$vatID.$startPos record. noteExport(spanMetadataKey(rec), undefined); + + // Budgeted deletion must delete rows one by one, + // but full deletion is handled all at once after this loop. + if (!deleteAll) { + sqlDeleteVatSpan.run(vatID, rec.startPos); + sqlDeleteSomeItems.run(vatID, rec.startPos, rec.endPos); + } + } + if (deleteAll) { + sqlDeleteVatItems.run(vatID); + sqlDeleteVatSpans.run(vatID); } - sqlDeleteVatItems.run(vatID); - sqlDeleteVatSpans.run(vatID); + return { + done: deleteAll || deletions.length === 0 || !hasSpans(vatID), + cleanups: deletions.length, + }; } const sqlGetAllSpanMetadata = db.prepare(` @@ -379,6 +601,12 @@ export function makeTranscriptStore( * The only code path which could use 'false' would be `swingstore.dump()`, * which takes the same flag. * + * Note that when a vat is terminated and has been partially + * deleted, we will retain (and return) a subset of the metadata + * records, because they must be deleted in-consensus and with + * updates to the noteExport hook. But we don't create any artifacts + * for the terminated vats, even for the spans that remain, + * * @yields {readonly [key: string, value: string]} * @returns {IterableIterator} * An iterator over pairs of [spanMetadataKey, rec], where `rec` is a @@ -432,9 +660,16 @@ export function makeTranscriptStore( } } } else if (artifactMode === 'archival') { - // everything + // every span for all vatIDs that have an isCurrent=1 span (to + // ignore terminated/partially-deleted vats) + const vatIDs = new Set(); + for (const { vatID } of sqlGetCurrentSpanMetadata.iterate()) { + vatIDs.add(vatID); + } for (const rec of sqlGetAllSpanMetadata.iterate()) { - yield spanArtifactName(rec); + if (vatIDs.has(rec.vatID)) { + yield spanArtifactName(rec); + } } } else if (artifactMode === 'debug') { // everything that is a complete span @@ -452,102 +687,6 @@ export function makeTranscriptStore( } harden(getArtifactNames); - const sqlGetSpanEndPos = db.prepare(` - SELECT endPos - FROM transcriptSpans - WHERE vatID = ? AND startPos = ? - `); - sqlGetSpanEndPos.pluck(true); - - const sqlReadSpanItems = db.prepare(` - SELECT item - FROM transcriptItems - WHERE vatID = ? AND ? <= position AND position < ? - ORDER BY position - `); - - /** - * Read the items in a transcript span - * - * @param {string} vatID The vat whose transcript is being read - * @param {number} [startPos] A start position identifying the span to be - * read; defaults to the current span, whatever it is - * - * @returns {IterableIterator} An iterator over the items in the indicated span - */ - function readSpan(vatID, startPos) { - /** @type {number | undefined} */ - let endPos; - if (startPos === undefined) { - ({ startPos, endPos } = getCurrentSpanBounds(vatID)); - } else { - insistTranscriptPosition(startPos); - endPos = sqlGetSpanEndPos.get(vatID, startPos); - if (typeof endPos !== 'number') { - throw Fail`no transcript span for ${q(vatID)} at ${q(startPos)}`; - } - } - startPos <= endPos || Fail`${q(startPos)} <= ${q(endPos)}}`; - const expectedCount = endPos - startPos; - - function* reader() { - let count = 0; - for (const { item } of sqlReadSpanItems.iterate( - vatID, - startPos, - endPos, - )) { - yield item; - count += 1; - } - count === expectedCount || - Fail`read ${q(count)} transcript entries (expected ${q( - expectedCount, - )})`; - } - harden(reader); - - if (startPos === endPos) { - return empty(); - } - - return reader(); - } - - const sqlGetSpanIsCurrent = db.prepare(` - SELECT isCurrent - FROM transcriptSpans - WHERE vatID = ? AND startPos = ? - `); - sqlGetSpanIsCurrent.pluck(true); - - /** - * Read a transcript span and return it as a stream of data suitable for - * export to another store. Transcript items are terminated by newlines. - * - * Transcript span artifact names should be strings of the form: - * `transcript.${vatID}.${startPos}.${endPos}` - * - * @param {string} name The name of the transcript artifact to be read - * @returns {AsyncIterableIterator} - * @yields {Uint8Array} - */ - async function* exportSpan(name) { - typeof name === 'string' || Fail`artifact name must be a string`; - const parts = name.split('.'); - const [type, vatID, pos] = parts; - // prettier-ignore - (parts.length === 4 && type === 'transcript') || - Fail`expected artifact name of the form 'transcript.{vatID}.{startPos}.{endPos}', saw ${q(name)}`; - const isCurrent = sqlGetSpanIsCurrent.get(vatID, pos); - isCurrent !== undefined || Fail`transcript span ${q(name)} not available`; - const startPos = Number(pos); - for (const entry of readSpan(vatID, startPos)) { - yield Buffer.from(`${entry}\n`); - } - } - harden(exportSpan); - const sqlAddItem = db.prepare(` INSERT INTO transcriptItems (vatID, item, position, incarnation) VALUES (?, ?, ?, ?) @@ -572,7 +711,7 @@ export function makeTranscriptStore( const newEndPos = endPos + 1; const newHash = updateSpanHash(hash, item); sqlUpdateSpan.run(newEndPos, newHash, vatID); - const rec = spanRec(vatID, startPos, newEndPos, newHash, 1, incarnation); + const rec = spanRec(vatID, startPos, newEndPos, newHash, true, incarnation); noteExport(spanMetadataKey(rec), JSON.stringify(rec)); }; @@ -774,6 +913,7 @@ export function makeTranscriptStore( getCurrentSpanBounds, addItem, readSpan, + stopUsingTranscript, deleteVatTranscripts, exportSpan, diff --git a/packages/swing-store/test/deletion.test.js b/packages/swing-store/test/deletion.test.js index 58e08bf727b..19baf048d5c 100644 --- a/packages/swing-store/test/deletion.test.js +++ b/packages/swing-store/test/deletion.test.js @@ -1,52 +1,86 @@ // @ts-check import test from 'ava'; + import { Buffer } from 'node:buffer'; +import path from 'node:path'; +import fs from 'node:fs'; +import zlib from 'node:zlib'; +import sqlite3 from 'better-sqlite3'; +import tmp from 'tmp'; +import { arrayIsLike } from '@agoric/internal/tools/ava-assertions.js'; +import { tmpDir } from './util.js'; import { initSwingStore } from '../src/swingStore.js'; +import { makeArchiveSnapshot, makeArchiveTranscript } from '../src/archiver.js'; +import { makeSwingStoreExporter } from '../src/exporter.js'; +import { importSwingStore } from '../src/importer.js'; async function* getSnapshotStream() { yield Buffer.from('abc'); } harden(getSnapshotStream); +// update 'data' with the callback deltas to get a new current +// export-data record +const mergeExportDeltas = (data, exports) => { + for (const [key, value] of exports) { + if (value) { + data[key] = value; + } else { + delete data[key]; + } + } +}; + +const mapToObj = map => Object.fromEntries(map.entries()); + test('delete snapshots with export callback', async t => { const exportLog = []; + const exportData = {}; const exportCallback = exports => { for (const [key, value] of exports) { exportLog.push([key, value]); } + mergeExportDeltas(exportData, exports); }; const store = initSwingStore(null, { exportCallback }); const { kernelStorage, hostStorage } = store; const { snapStore } = kernelStorage; const { commit } = hostStorage; - - await snapStore.saveSnapshot('v1', 10, getSnapshotStream()); - await snapStore.saveSnapshot('v1', 11, getSnapshotStream()); - await snapStore.saveSnapshot('v1', 12, getSnapshotStream()); + const vatID = 'v1'; + await snapStore.saveSnapshot(vatID, 10, getSnapshotStream()); + await snapStore.saveSnapshot(vatID, 11, getSnapshotStream()); + await snapStore.saveSnapshot(vatID, 12, getSnapshotStream()); // nothing is written to exportCallback until endCrank() or commit() t.deepEqual(exportLog, []); await commit(); - t.is(exportLog.length, 4); - t.is(exportLog[0][0], 'snapshot.v1.10'); - t.is(exportLog[1][0], 'snapshot.v1.11'); - t.is(exportLog[2][0], 'snapshot.v1.12'); - t.is(exportLog[3][0], 'snapshot.v1.current'); - exportLog.length = 0; + const hash = JSON.parse(exportLog[0][1]).hash; + arrayIsLike(t, exportLog.splice(0), [ + ['snapshot.v1.10'], + ['snapshot.v1.11'], + ['snapshot.v1.12'], + ['snapshot.v1.current'], + ]); + t.deepEqual(exportData, { + 'snapshot.v1.10': JSON.stringify({ vatID, snapPos: 10, hash, inUse: 0 }), + 'snapshot.v1.11': JSON.stringify({ vatID, snapPos: 11, hash, inUse: 0 }), + 'snapshot.v1.12': JSON.stringify({ vatID, snapPos: 12, hash, inUse: 1 }), + 'snapshot.v1.current': 'snapshot.v1.12', + }); // in a previous version, deleteVatSnapshots caused overlapping SQL // queries, and failed - snapStore.deleteVatSnapshots('v1'); + snapStore.deleteVatSnapshots(vatID); await commit(); - t.deepEqual(exportLog, [ + t.deepEqual(exportLog.splice(0), [ ['snapshot.v1.10', null], ['snapshot.v1.11', null], ['snapshot.v1.12', null], ['snapshot.v1.current', null], ]); - exportLog.length = 0; + t.deepEqual(exportData, {}); }); test('delete transcripts with export callback', async t => { @@ -65,7 +99,7 @@ test('delete transcripts with export callback', async t => { transcriptStore.addItem('v1', 'aaa'); transcriptStore.addItem('v1', 'bbb'); transcriptStore.addItem('v1', 'ccc'); - transcriptStore.rolloverSpan('v1'); + await transcriptStore.rolloverSpan('v1'); transcriptStore.addItem('v1', 'ddd'); transcriptStore.addItem('v1', 'eee'); transcriptStore.addItem('v1', 'fff'); @@ -74,20 +108,610 @@ test('delete transcripts with export callback', async t => { await commit(); - t.is(exportLog.length, 2); - t.is(exportLog[0][0], 'transcript.v1.0'); - t.is(exportLog[1][0], 'transcript.v1.current'); - exportLog.length = 0; + arrayIsLike(t, exportLog.splice(0), [ + ['transcript.v1.0'], + ['transcript.v1.current'], + ]); // in a previous version, deleteVatTranscripts caused overlapping SQL // queries, and failed transcriptStore.deleteVatTranscripts('v1'); await commit(); - t.deepEqual(exportLog, [ + t.deepEqual(exportLog.splice(0), [ ['transcript.v1.0', null], ['transcript.v1.current', null], ]); +}); + +const getExport = async (dbDir, artifactMode) => { + const exporter = makeSwingStoreExporter(dbDir, { artifactMode }); + const exportData = new Map(); + for await (const [key, value] of exporter.getExportData()) { + exportData.set(key, value); + } + const artifactNames = []; + for await (const name of exporter.getArtifactNames()) { + artifactNames.push(name); + } + await exporter.close(); + return { exportData, artifactNames }; +}; + +const reImport = async (t, dbDir, artifactMode) => { + const [dbDir2, cleanup] = await tmpDir('testdb2'); + t.teardown(cleanup); + const exporter = makeSwingStoreExporter(dbDir, { artifactMode }); + const ss2 = await importSwingStore(exporter, dbDir2, { artifactMode }); + await ss2.hostStorage.commit(); + return sqlite3(path.join(dbDir2, 'swingstore.sqlite')); +}; + +const stripHashes = exportData => { + const stripped = {}; + const entries = + exportData instanceof Map + ? exportData.entries() + : Object.entries(exportData); + for (const [key, value] of entries) { + const { hash: _, ...data } = JSON.parse(value); + stripped[key] = data; + } + return stripped; +}; + +const setupTranscript = async (t, keepTranscripts) => { + const vatID = 'v1'; + const exportLog = []; + const currentExportData = {}; + const exportCallback = exports => { + for (const [key, value] of exports) { + exportLog.push([key, value]); + } + mergeExportDeltas(currentExportData, exports); + }; + const [dbDir, cleanup] = await tmpDir('testdb'); + t.teardown(cleanup); + const [archiveDir, cleanupArchives] = await tmpDir('archives'); + t.teardown(cleanupArchives); + const fsPowers = { fs, path, tmp }; + const archiveSnapshot = makeArchiveSnapshot(archiveDir, fsPowers); + const archiveTranscript = makeArchiveTranscript(archiveDir, fsPowers); + const store = initSwingStore(dbDir, { + exportCallback, + keepTranscripts, + archiveSnapshot, + archiveTranscript, + }); + const { kernelStorage, hostStorage } = store; + const { transcriptStore } = kernelStorage; + const { commit } = hostStorage; + // look directly at DB to confirm changes + const db = sqlite3(path.join(dbDir, 'swingstore.sqlite')); + + // two incarnations, two spans each + transcriptStore.initTranscript(vatID); + transcriptStore.addItem(vatID, 'aaa'); + transcriptStore.addItem(vatID, 'bbb'); + await transcriptStore.rolloverSpan(vatID); + transcriptStore.addItem(vatID, 'ccc'); + transcriptStore.addItem(vatID, 'ddd'); + await transcriptStore.rolloverIncarnation(vatID); + transcriptStore.addItem(vatID, 'eee'); + transcriptStore.addItem(vatID, 'fff'); + await transcriptStore.rolloverSpan(vatID); + transcriptStore.addItem(vatID, 'ggg'); + transcriptStore.addItem(vatID, 'hhh'); + await commit(); + + return { + db, + dbDir, + archiveDir, + commit, + transcriptStore, + exportLog, + currentExportData, + vatID, + }; +}; + +/** + * @param {import('ava').ExecutionContext} t + * @param {{ keepTranscripts: boolean }} config + */ +const execSlowTranscriptDeletion = async (t, { keepTranscripts }) => { + // slow transcript deletion should remove export-data as it removes + // transcript spans and their items + + const { + db, + dbDir, + archiveDir, + commit, + transcriptStore, + exportLog, + currentExportData, + vatID, + } = await setupTranscript(t, keepTranscripts); + + arrayIsLike(t, exportLog.splice(0), [ + ['transcript.v1.0'], + ['transcript.v1.2'], + ['transcript.v1.4'], + ['transcript.v1.current'], + ]); + const t0 = { vatID, startPos: 0, endPos: 2, isCurrent: 0, incarnation: 0 }; + const t2 = { vatID, startPos: 2, endPos: 4, isCurrent: 0, incarnation: 0 }; + const t4 = { vatID, startPos: 4, endPos: 6, isCurrent: 0, incarnation: 1 }; + const t6 = { vatID, startPos: 6, endPos: 8, isCurrent: 0, incarnation: 1 }; + const expectedLiveExportData = { + 'transcript.v1.0': t0, + 'transcript.v1.2': t2, + 'transcript.v1.4': t4, + 'transcript.v1.current': { ...t6, isCurrent: 1 }, + }; + const expectedStoppedExportData = { + 'transcript.v1.0': t0, + 'transcript.v1.2': t2, + 'transcript.v1.4': t4, + 'transcript.v1.6': t6, + }; + const expectedArtifactContents = { + 'transcript.v1.0.2': 'aaa\nbbb\n', + 'transcript.v1.2.4': 'ccc\nddd\n', + 'transcript.v1.4.6': 'eee\nfff\n', + 'transcript.v1.6.8': 'ggg\nhhh\n', + }; + const expectedArtifactNames = Object.keys(expectedArtifactContents); + + t.deepEqual(stripHashes(currentExportData), expectedLiveExportData); + t.is( + db.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), + keepTranscripts ? 8 : 2, + ); + t.is(db.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 4); + + // verify archived transcripts + t.deepEqual( + fs.readdirSync(archiveDir), + expectedArtifactNames.slice(0, -1).map(name => `${name}.gz`), + ); + for (const name of expectedArtifactNames.slice(0, -1)) { + const filePath = path.join(archiveDir, `${name}.gz`); + const contents = zlib.gunzipSync(fs.readFileSync(filePath)).toString(); + t.is(contents, expectedArtifactContents[name], `${filePath} contents`); + } + + // an "operational"-mode export should list all spans, but only have + // artifacts for the current one + { + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(currentExportData, mapToObj(exportData)); + t.deepEqual(stripHashes(exportData), expectedLiveExportData); + t.deepEqual(artifactNames, expectedArtifactNames.slice(-1)); + const db2 = await reImport(t, dbDir, 'operational'); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), 2); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 4); + } + + // an "archival"-mode export should list all four spans with + // artifacts for each, but is only available with keepTranscripts=true + if (!keepTranscripts) { + await t.throwsAsync(getExport(dbDir, 'archival')); + } else { + const { exportData, artifactNames } = await getExport(dbDir, 'archival'); + t.deepEqual(stripHashes(exportData), expectedLiveExportData); + t.deepEqual(artifactNames, expectedArtifactNames); + const db2 = await reImport(t, dbDir, 'archival'); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), 8); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 4); + } + + // prepare for deletion, this adds a new "closed" record, and + // deletes the .current record (i.e. it transforms .current into a + // closed record) + { + await transcriptStore.stopUsingTranscript(vatID); + await commit(); + t.deepEqual(stripHashes(currentExportData), expectedStoppedExportData); + exportLog.length = 0; + // stopUsingTranscript is idempotent + await transcriptStore.stopUsingTranscript(vatID); + await commit(); + t.deepEqual(exportLog, []); + } + t.deepEqual( + fs.readdirSync(archiveDir), + expectedArtifactNames.map(name => `${name}.gz`), + ); + for (const name of expectedArtifactNames) { + const filePath = path.join(archiveDir, `${name}.gz`); + const contents = zlib.gunzipSync(fs.readFileSync(filePath)).toString(); + t.is(contents, expectedArtifactContents[name], `${filePath} contents`); + } + + // All exports (debug and non-debug) in this "terminated but not + // deleted" state will still have the export-data keys. Only + // debug-mode will have artifacts (and only with keepTranscripts=true). + for (const mode of ['operational', 'replay', 'archival', 'debug']) { + const { exportData, artifactNames } = await getExport(dbDir, mode); + t.deepEqual( + stripHashes(exportData), + expectedStoppedExportData, + `${mode} stopped-vat export data`, + ); + t.deepEqual( + artifactNames, + mode === 'debug' && keepTranscripts ? expectedArtifactNames : [], + `${mode} stopped-vat export artifacts`, + ); + const db2 = await reImport(t, dbDir, 'operational'); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), 0); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 4); + } + + // first deletion + const expectedTruncatedExportData1 = Object.fromEntries( + Object.entries(expectedStoppedExportData).slice(0, -1), + ); + { + // budget=1 will let it delete one span, the last one + const dc = transcriptStore.deleteVatTranscripts(vatID, 1); + t.false(dc.done); + t.is(dc.cleanups, 1); + await commit(); + t.deepEqual(stripHashes(currentExportData), expectedTruncatedExportData1); + t.is( + db.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), + keepTranscripts ? 6 : 0, + ); + t.is(db.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 3); + } + + // Exports in this partially-deleted state should be coherent: they + // provide a subset of the older spans (the not-yet-deleted ones, + // all of which have isCurrent=0) and no items (even for + // not-yet-deleted spans). The import-time assertComplete() test + // must be satisfied. + + for (const mode of ['operational', 'replay', 'archival', 'debug']) { + const { exportData, artifactNames } = await getExport(dbDir, mode); + t.deepEqual( + stripHashes(exportData), + expectedTruncatedExportData1, + `${mode} first-deletion export data`, + ); + t.deepEqual( + artifactNames, + mode === 'debug' && keepTranscripts + ? expectedArtifactNames.slice(0, -1) + : [], + `${mode} first-deletion export artifacts`, + ); + const db2 = await reImport(t, dbDir, 'operational'); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), 0); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 3); + } + + // second deletion + const expectedTruncatedExportData2 = Object.fromEntries( + Object.entries(expectedStoppedExportData).slice(0, -2), + ); + { + const dc = transcriptStore.deleteVatTranscripts(vatID, 1); + t.false(dc.done); + t.is(dc.cleanups, 1); + await commit(); + t.deepEqual(stripHashes(currentExportData), expectedTruncatedExportData2); + t.is( + db.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), + keepTranscripts ? 4 : 0, + ); + t.is(db.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 2); + } + for (const mode of ['operational', 'replay', 'archival', 'debug']) { + const { exportData, artifactNames } = await getExport(dbDir, mode); + t.deepEqual( + stripHashes(exportData), + expectedTruncatedExportData2, + `${mode} second-deletion export data`, + ); + t.deepEqual( + artifactNames, + mode === 'debug' && keepTranscripts + ? expectedArtifactNames.slice(0, -2) + : [], + `${mode} second-deletion export artifacts`, + ); + const db2 = await reImport(t, dbDir, 'operational'); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), 0); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 2); + } + + // last deletion, enough budget to finish + { + const dc = transcriptStore.deleteVatTranscripts(vatID, 5); + t.true(dc.done); + t.is(dc.cleanups, 2); + await commit(); + t.deepEqual(stripHashes(currentExportData), {}); + t.is(db.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), 0); + t.is(db.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 0); + } + for (const mode of ['operational', 'replay', 'archival', 'debug']) { + const { exportData, artifactNames } = await getExport(dbDir, mode); + t.deepEqual( + stripHashes(exportData), + {}, + `${mode} final-deletion export data`, + ); + t.deepEqual(artifactNames, [], `${mode} final-deletion export artifacts`); + const db2 = await reImport(t, dbDir, 'operational'); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptItems').pluck().get(), 0); + t.is(db2.prepare('SELECT COUNT(*) FROM transcriptSpans').pluck().get(), 0); + } + + // deleteVatTranscripts is idempotent + { + exportLog.length = 0; + const dc = transcriptStore.deleteVatTranscripts(vatID, 5); + t.true(dc.done); + t.is(dc.cleanups, 0); + await commit(); + t.deepEqual(exportLog, []); + } +}; +const testSlowTranscriptDeletion = test.macro({ + title(extra = '', { keepTranscripts }) { + const detail = keepTranscripts ? 'with retention' : 'without retention'; + return `slow deletion of transcripts ${detail}${extra.replace(/.$/, ' $&')}`; + }, + exec: execSlowTranscriptDeletion, +}); +test(testSlowTranscriptDeletion, { keepTranscripts: true }); +test(testSlowTranscriptDeletion, { keepTranscripts: false }); + +test('slow deletion without stopUsingTranscript', async t => { + // slow deletion should work even without stopUsingTranscript + const { dbDir, commit, transcriptStore, currentExportData, vatID } = + await setupTranscript(t); + + // first deletion + { + // budget=1 will let it delete one span, the last one. Because we + // didn't call stopUsingTranscript, this also removes the .current + // record + const dc = transcriptStore.deleteVatTranscripts(vatID, 1); + t.false(dc.done); + t.is(dc.cleanups, 1); + await commit(); + const t0 = { vatID, startPos: 0, endPos: 2, isCurrent: 0, incarnation: 0 }; + const t2 = { vatID, startPos: 2, endPos: 4, isCurrent: 0, incarnation: 0 }; + const t4 = { vatID, startPos: 4, endPos: 6, isCurrent: 0, incarnation: 1 }; + t.deepEqual(stripHashes(currentExportData), { + 'transcript.v1.0': t0, + 'transcript.v1.2': t2, + 'transcript.v1.4': t4, + }); + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(mapToObj(exportData), currentExportData); + t.deepEqual(artifactNames, []); + } + transcriptStore.deleteVatTranscripts(vatID); + await commit(); + t.deepEqual(currentExportData, {}); + { + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(exportData, new Map()); + t.deepEqual(artifactNames, []); + } +}); + +test('full deletion without stopUsingTranscript', async t => { + // full deletion should work even without stopUsingTranscript + const { dbDir, commit, transcriptStore, currentExportData, vatID } = + await setupTranscript(t); + const dc = transcriptStore.deleteVatTranscripts(vatID); + t.true(dc.done); + await commit(); + t.deepEqual(currentExportData, {}); + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(exportData, new Map()); + t.deepEqual(artifactNames, []); +}); + +const setupSnapshots = async t => { + const vatID = 'v1'; + const exportLog = []; + const currentExportData = {}; + const exportCallback = exports => { + for (const [key, value] of exports) { + exportLog.push([key, value]); + } + mergeExportDeltas(currentExportData, exports); + }; + const [dbDir, cleanup] = await tmpDir('testdb'); + t.teardown(cleanup); + const store = initSwingStore(dbDir, { exportCallback }); + const { kernelStorage, hostStorage } = store; + const { snapStore } = kernelStorage; + const { commit } = hostStorage; + // look directly at DB to confirm changes + const db = sqlite3(path.join(dbDir, 'swingstore.sqlite')); + + await snapStore.saveSnapshot(vatID, 10, getSnapshotStream()); + await snapStore.saveSnapshot(vatID, 11, getSnapshotStream()); + await snapStore.saveSnapshot(vatID, 12, getSnapshotStream()); + // nothing is written to exportCallback until endCrank() or commit() + t.deepEqual(exportLog, []); + await commit(); + const hash = JSON.parse(exportLog[0][1]).hash; + + return { + db, + dbDir, + commit, + snapStore, + exportLog, + currentExportData, + vatID, + hash, + }; +}; + +test('slow deletion of snapshots', async t => { + // slow snapshot deletion should remove export-data as it removes + // snapshots + const { + db, + dbDir, + commit, + snapStore, + exportLog, + currentExportData, + vatID, + hash, + } = await setupSnapshots(t); + t.deepEqual(currentExportData, { + 'snapshot.v1.10': JSON.stringify({ vatID, snapPos: 10, hash, inUse: 0 }), + 'snapshot.v1.11': JSON.stringify({ vatID, snapPos: 11, hash, inUse: 0 }), + 'snapshot.v1.12': JSON.stringify({ vatID, snapPos: 12, hash, inUse: 1 }), + 'snapshot.v1.current': 'snapshot.v1.12', + }); + + t.is(db.prepare('SELECT COUNT(*) FROM snapshots').pluck().get(), 3); + { + // export should mention all spans, with a single current artifact + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(currentExportData, mapToObj(exportData)); + t.is(exportData.get('snapshot.v1.current'), 'snapshot.v1.12'); + t.deepEqual(artifactNames, ['snapshot.v1.12']); + } + + // Prepare for deletion, this clears the .inUse flag on the latest + // record, and deletes the .current record. Exports stop including + // any artifacts. + { + snapStore.stopUsingLastSnapshot(vatID); + await commit(); + t.deepEqual(currentExportData, { + 'snapshot.v1.10': JSON.stringify({ vatID, snapPos: 10, hash, inUse: 0 }), + 'snapshot.v1.11': JSON.stringify({ vatID, snapPos: 11, hash, inUse: 0 }), + 'snapshot.v1.12': JSON.stringify({ vatID, snapPos: 12, hash, inUse: 0 }), + }); + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(currentExportData, mapToObj(exportData)); + t.deepEqual(artifactNames, []); + exportLog.length = 0; + // stopUsingLastSnapshot is idempotent + snapStore.stopUsingLastSnapshot(vatID); + await commit(); + t.deepEqual(exportLog, []); + } + + // first deletion + { + // budget=1 will let it delete one snapshot + const dc = snapStore.deleteVatSnapshots(vatID, 1); + t.false(dc.done); + t.is(dc.cleanups, 1); + await commit(); + t.deepEqual(currentExportData, { + 'snapshot.v1.10': JSON.stringify({ vatID, snapPos: 10, hash, inUse: 0 }), + 'snapshot.v1.11': JSON.stringify({ vatID, snapPos: 11, hash, inUse: 0 }), + }); + t.is(db.prepare('SELECT COUNT(*) FROM snapshots').pluck().get(), 2); + // export should mention fewer spans, have no .current or + // artifacts + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(currentExportData, mapToObj(exportData)); + t.deepEqual(artifactNames, []); + // and it should be importable + const db2 = await reImport(t, dbDir, 'operational'); + t.is(db2.prepare('SELECT COUNT(*) FROM snapshots').pluck().get(), 2); + const db3 = await reImport(t, dbDir, 'archival'); + t.is(db3.prepare('SELECT COUNT(*) FROM snapshots').pluck().get(), 2); + } + + // second+last deletion, enough budget to delete both remaining + // snapshots + { + const dc = snapStore.deleteVatSnapshots(vatID, 5); + t.true(dc.done); + t.is(dc.cleanups, 2); + await commit(); + t.deepEqual(currentExportData, {}); + t.is(db.prepare('SELECT COUNT(*) FROM snapshots').pluck().get(), 0); + // export should mention nothing + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(currentExportData, mapToObj(exportData)); + t.deepEqual(artifactNames, []); + } +}); + +test('slow deletion without stopUsingLastSnapshot', async t => { + // slow snapshot deletion should work even without + // stopUsingLastSnapshot + const { dbDir, commit, snapStore, currentExportData, vatID, hash } = + await setupSnapshots(t); + + { + // budget=1 will let it delete one snapshot, the last one. Because + // we didn't call stopUsingLastSnapshot, this also removes the + // .current record + const dc = snapStore.deleteVatSnapshots(vatID, 1); + t.false(dc.done); + t.is(dc.cleanups, 1); + await commit(); + t.deepEqual(currentExportData, { + 'snapshot.v1.10': JSON.stringify({ vatID, snapPos: 10, hash, inUse: 0 }), + 'snapshot.v1.11': JSON.stringify({ vatID, snapPos: 11, hash, inUse: 0 }), + }); + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(mapToObj(exportData), currentExportData); + t.deepEqual(artifactNames, []); + } + + { + const dc = snapStore.deleteVatSnapshots(vatID, 1); + t.false(dc.done); + t.is(dc.cleanups, 1); + await commit(); + t.deepEqual(currentExportData, { + 'snapshot.v1.10': JSON.stringify({ vatID, snapPos: 10, hash, inUse: 0 }), + }); + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(mapToObj(exportData), currentExportData); + t.deepEqual(artifactNames, []); + } + + { + const dc = snapStore.deleteVatSnapshots(vatID, 1); + t.true(dc.done); + t.is(dc.cleanups, 1); + await commit(); + t.deepEqual(currentExportData, {}); + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(mapToObj(exportData), currentExportData); + t.deepEqual(artifactNames, []); + } +}); + +test('full deletion without stopUsingLastSnapshot', async t => { + // full snapshot deletion should work even without + // stopUsingLastSnapshot + const { dbDir, commit, snapStore, currentExportData, vatID } = + await setupSnapshots(t); - exportLog.length = 0; + { + const dc = snapStore.deleteVatSnapshots(vatID); + t.true(dc.done); + // no budget means no accounting, ignore dc.cleanups + await commit(); + t.deepEqual(currentExportData, {}); + const { exportData, artifactNames } = await getExport(dbDir, 'operational'); + t.deepEqual(mapToObj(exportData), currentExportData); + t.deepEqual(artifactNames, []); + } }); diff --git a/packages/swing-store/test/export.test.js b/packages/swing-store/test/export.test.js index c4f81d661fa..b0457665310 100644 --- a/packages/swing-store/test/export.test.js +++ b/packages/swing-store/test/export.test.js @@ -47,7 +47,7 @@ const exportTest = test.macro(async (t, mode) => { // incarnation 0 ks.transcriptStore.addItem('v1', 'start-worker'); // 0 ks.transcriptStore.addItem('v1', 'shutdown-worker'); // 1 - ks.transcriptStore.rolloverIncarnation('v1'); + await ks.transcriptStore.rolloverIncarnation('v1'); const spanHash0 = '5bee0f44eca02f23eab03703e84ed2647d5d117fed99e1c30a3b424b7f082ab9'; @@ -56,7 +56,7 @@ const exportTest = test.macro(async (t, mode) => { ks.transcriptStore.addItem('v1', 'delivery1'); // 3 await ks.snapStore.saveSnapshot('v1', 4, getSnapshotStream(snapshotData)); ks.transcriptStore.addItem('v1', 'save-snapshot'); // 4 - ks.transcriptStore.rolloverSpan('v1'); // range= 2..5 + await ks.transcriptStore.rolloverSpan('v1'); // range= 2..5 const spanHash1 = '57152efdd7fdf75c03371d2b4f1088d5bf3eae7fe643babce527ff81df38998c'; @@ -64,7 +64,7 @@ const exportTest = test.macro(async (t, mode) => { ks.transcriptStore.addItem('v1', 'delivery2'); // 6 await ks.snapStore.saveSnapshot('v1', 7, getSnapshotStream(snapshotData)); ks.transcriptStore.addItem('v1', 'save-snapshot'); // 7 - ks.transcriptStore.rolloverSpan('v1'); // range= 5..8 + await ks.transcriptStore.rolloverSpan('v1'); // range= 5..8 const spanHash2 = '1947001e78e01bd1e773feb22b4ffc530447373b9de9274d5d5fbda3f23dbf2b'; @@ -251,7 +251,7 @@ test('export omits pruned span artifacts', async t => { ks.transcriptStore.addItem('v1', 'delivery1'); // 1 await ks.snapStore.saveSnapshot('v1', 2, getSnapshotStream(snapshotData)); ks.transcriptStore.addItem('v1', 'save-snapshot'); // 2 - ks.transcriptStore.rolloverSpan('v1'); // range= 0..3 + await ks.transcriptStore.rolloverSpan('v1'); // range= 0..3 const spanHash1 = '57152efdd7fdf75c03371d2b4f1088d5bf3eae7fe643babce527ff81df38998c'; // rolloverSpan prunes the contents of the old span diff --git a/packages/swing-store/test/exportImport.test.js b/packages/swing-store/test/exportImport.test.js index 271c359661d..2458de32c55 100644 --- a/packages/swing-store/test/exportImport.test.js +++ b/packages/swing-store/test/exportImport.test.js @@ -87,7 +87,7 @@ async function fakeAVatSnapshot(vat, ks) { await ks.snapStore.saveSnapshot(vat.vatID, vat.endPos, getSnapshotStream()); ks.transcriptStore.addItem(vat.vatID, 'save-snapshot'); vat.endPos += 1; - ks.transcriptStore.rolloverSpan(vat.vatID); + await ks.transcriptStore.rolloverSpan(vat.vatID); ks.transcriptStore.addItem(vat.vatID, 'load-snapshot'); vat.endPos += 1; } diff --git a/packages/swing-store/test/snapstore.test.js b/packages/swing-store/test/snapstore.test.js index 7bcba1e8ed2..1f27151be24 100644 --- a/packages/swing-store/test/snapstore.test.js +++ b/packages/swing-store/test/snapstore.test.js @@ -1,12 +1,17 @@ // @ts-check +import test from 'ava'; import { Buffer } from 'node:buffer'; -import zlib from 'zlib'; +import fs from 'node:fs'; +import path from 'node:path'; +import zlib from 'node:zlib'; import sqlite3 from 'better-sqlite3'; +import tmp from 'tmp'; -import test from 'ava'; import { makeMeasureSeconds } from '@agoric/internal'; import { makeSnapStore } from '../src/snapStore.js'; +import { makeArchiveSnapshot } from '../src/archiver.js'; +import { tmpDir } from './util.js'; function makeExportLog() { const exportLog = []; @@ -31,6 +36,10 @@ harden(getSnapshotStream); test('compress to cache file; closes snapshot stream', async t => { const db = sqlite3(':memory:'); const exportLog = makeExportLog(); + const [archiveDir, cleanupArchives] = await tmpDir('archives'); + t.teardown(cleanupArchives); + const fsPowers = { fs, path, tmp }; + const archiveSnapshot = makeArchiveSnapshot(archiveDir, fsPowers); const store = makeSnapStore( db, ensureTxn, @@ -38,6 +47,7 @@ test('compress to cache file; closes snapshot stream', async t => { measureSeconds: makeMeasureSeconds(() => 0), }, exportLog.noteExport, + { archiveSnapshot }, ); const snapshotStream = getSnapshotStream('abc'); @@ -50,6 +60,7 @@ test('compress to cache file; closes snapshot stream', async t => { uncompressedSize: 3, compressedSize: 23, dbSaveSeconds: 0, + archiveWriteSeconds: 0, compressSeconds: 0, }); const snapshotInfo = store.getSnapshotInfo('fakeVatID'); @@ -89,6 +100,26 @@ test('compress to cache file; closes snapshot stream', async t => { ['snapshot.fakeVatID.47', JSON.stringify(logInfo)], ['snapshot.fakeVatID.current', `snapshot.fakeVatID.47`], ]); + + // verify disk archive + t.deepEqual( + fs.readdirSync(archiveDir), + ['snapshot.fakeVatID.47.gz'], + 'archive must be written to disk', + ); + const fileContents = fs.readFileSync( + path.join(archiveDir, 'snapshot.fakeVatID.47.gz'), + ); + t.is( + fileContents.length, + dbInfo.compressedSize, + 'file size must match database compressedSize', + ); + t.is( + zlib.gunzipSync(fileContents).toString(), + 'abc', + 'gunzip(fileContents) must match input data', + ); }); test('snapStore prepare / commit delete is robust', async t => { @@ -96,11 +127,17 @@ test('snapStore prepare / commit delete is robust', async t => { measureSeconds: makeMeasureSeconds(() => 0), }; const db = sqlite3(':memory:'); + const [archiveDir, cleanupArchives] = await tmpDir('archives'); + t.teardown(cleanupArchives); + const fsPowers = { fs, path, tmp }; + const archiveSnapshot = makeArchiveSnapshot(archiveDir, fsPowers); const store = makeSnapStore(db, ensureTxn, io, () => {}, { keepSnapshots: true, + archiveSnapshot, }); const hashes = []; + const expectedFiles = []; for (let i = 0; i < 5; i += 1) { const { hash } = await store.saveSnapshot( 'fakeVatID2', @@ -108,6 +145,7 @@ test('snapStore prepare / commit delete is robust', async t => { getSnapshotStream(`file ${i}`), ); hashes.push(hash); + expectedFiles.push(`snapshot.fakeVatID2.${i}.gz`); } const sqlCountSnapshots = db.prepare(` SELECT COUNT(*) @@ -116,19 +154,24 @@ test('snapStore prepare / commit delete is robust', async t => { sqlCountSnapshots.pluck(true); t.is(sqlCountSnapshots.get(), 5); + t.deepEqual(fs.readdirSync(archiveDir), expectedFiles); store.deleteSnapshotByHash('fakeVatID2', hashes[2]); t.is(sqlCountSnapshots.get(), 4); + t.deepEqual(fs.readdirSync(archiveDir), expectedFiles); // Restore (re-save) between prepare and commit. store.deleteSnapshotByHash('fakeVatID2', hashes[3]); await store.saveSnapshot('fakeVatID3', 29, getSnapshotStream(`file 3`)); + expectedFiles.push(`snapshot.fakeVatID3.29.gz`); t.true(store.hasHash('fakeVatID3', hashes[3])); + t.deepEqual(fs.readdirSync(archiveDir), expectedFiles); store.deleteVatSnapshots('fakeVatID2'); t.is(sqlCountSnapshots.get(), 1); store.deleteVatSnapshots('fakeVatID3'); t.is(sqlCountSnapshots.get(), 0); + t.deepEqual(fs.readdirSync(archiveDir), expectedFiles); for (let i = 0; i < 5; i += 1) { const { hash } = await store.saveSnapshot( @@ -137,8 +180,10 @@ test('snapStore prepare / commit delete is robust', async t => { getSnapshotStream(`file ${i}`), ); hashes.push(hash); + expectedFiles.push(`snapshot.fakeVatID4.${i}.gz`); } t.is(sqlCountSnapshots.get(), 5); store.deleteAllUnusedSnapshots(); t.is(sqlCountSnapshots.get(), 1); + t.deepEqual(fs.readdirSync(archiveDir), expectedFiles); }); diff --git a/packages/swing-store/test/state.test.js b/packages/swing-store/test/state.test.js index 490f7953035..08f3213eb3b 100644 --- a/packages/swing-store/test/state.test.js +++ b/packages/swing-store/test/state.test.js @@ -155,82 +155,106 @@ test('persistent kvStore maxKeySize write', async t => { await hostStorage.close(); }); -async function testTranscriptStore(t, dbDir) { - const exportLog = makeExportLog(); - const { kernelStorage, hostStorage } = initSwingStore(dbDir, { - exportCallback: exportLog.callback, - keepTranscripts: true, // XXX need to vary - }); - const { transcriptStore } = kernelStorage; - const { commit, close } = hostStorage; +const testTranscriptStore = test.macro({ + title(prefix = '', { ephemeral, keepTranscripts }) { + const type = ephemeral ? 'in-memory' : 'persistent'; + const detail = keepTranscripts ? 'with retention' : 'without retention'; + return `${prefix.replace(/.$/, '$& ')}${type} transcriptStore ${detail}`; + }, + async exec(t, { ephemeral, keepTranscripts }) { + let dbDir = null; + if (!ephemeral) { + const [tmpPath, cleanup] = await tmpDir('testdb'); + t.teardown(cleanup); + t.is(isSwingStore(tmpPath), false); + dbDir = tmpPath; + } - transcriptStore.initTranscript('st1'); - transcriptStore.initTranscript('st2'); - transcriptStore.addItem('st1', 'first'); - transcriptStore.addItem('st1', 'second'); - transcriptStore.rolloverSpan('st1'); - transcriptStore.addItem('st1', 'third'); - transcriptStore.addItem('st2', 'oneth'); - transcriptStore.addItem('st1', 'fourth'); - transcriptStore.addItem('st2', 'twoth'); - transcriptStore.addItem('st2', 'threeth'); - transcriptStore.addItem('st2', 'fourst'); - const reader1 = transcriptStore.readSpan('st1', 0); - t.deepEqual(Array.from(reader1), ['first', 'second']); - const reader2 = transcriptStore.readSpan('st2', 0); - t.deepEqual(Array.from(reader2), ['oneth', 'twoth', 'threeth', 'fourst']); - - t.throws(() => transcriptStore.readSpan('st2', 3), { - message: 'no transcript span for "st2" at 3', - }); + const exportLog = makeExportLog(); + const { kernelStorage, hostStorage } = initSwingStore(dbDir, { + exportCallback: exportLog.callback, + keepTranscripts, + }); + const { transcriptStore } = kernelStorage; + const { commit, close } = hostStorage; + + transcriptStore.initTranscript('st1'); + transcriptStore.initTranscript('st2'); + transcriptStore.addItem('st1', 'zeroth'); + await transcriptStore.rolloverSpan('st1'); + transcriptStore.addItem('st1', 'first'); + transcriptStore.addItem('st1', 'second'); + await transcriptStore.rolloverSpan('st1'); + transcriptStore.addItem('st1', 'third'); + transcriptStore.addItem('st2', 'oneth'); + transcriptStore.addItem('st1', 'fourth'); + transcriptStore.addItem('st2', 'twoth'); + transcriptStore.addItem('st2', 'threeth'); + transcriptStore.addItem('st2', 'fourst'); + const reader1a = transcriptStore.readSpan('st1', 0); + const reader1b = transcriptStore.readSpan('st1', 1); + if (keepTranscripts) { + t.deepEqual(Array.from(reader1a), ['zeroth']); + t.deepEqual(Array.from(reader1b), ['first', 'second']); + } else { + const fna = async () => Array.from(reader1a); + const fnb = async () => Array.from(reader1b); + await t.throwsAsync(fna, undefined, 'pruned spans must not be readable'); + await t.throwsAsync(fnb, undefined, 'pruned spans must not be readable'); + } + const reader2 = transcriptStore.readSpan('st2', 0); + t.deepEqual(Array.from(reader2), ['oneth', 'twoth', 'threeth', 'fourst']); - const reader1alt = transcriptStore.readSpan('st1'); - t.deepEqual(Array.from(reader1alt), ['third', 'fourth']); - const reader1alt2 = transcriptStore.readSpan('st1', 2); - t.deepEqual(Array.from(reader1alt2), ['third', 'fourth']); + t.throws(() => transcriptStore.readSpan('st2', 3), { + message: 'no transcript span for "st2" at 3', + }); - transcriptStore.initTranscript('empty'); - const readerEmpty = transcriptStore.readSpan('empty'); - t.deepEqual(Array.from(readerEmpty), []); + const reader1alt = transcriptStore.readSpan('st1'); + t.deepEqual(Array.from(reader1alt), ['third', 'fourth']); + const reader1alt2 = transcriptStore.readSpan('st1', 3); + t.deepEqual(Array.from(reader1alt2), ['third', 'fourth']); - t.throws(() => transcriptStore.readSpan('nonexistent'), { - message: 'no current transcript for "nonexistent"', - }); + transcriptStore.initTranscript('empty'); + const readerEmpty = transcriptStore.readSpan('empty'); + t.deepEqual(Array.from(readerEmpty), []); - await commit(); - t.deepEqual(exportLog.getLog(), [ - [ - [ - 'transcript.empty.current', - '{"vatID":"empty","startPos":0,"endPos":0,"hash":"43e6be43a3a34d60c0ebeb8498b5849b094fc20fc68483a7aeb3624fa10f79f6","isCurrent":1,"incarnation":0}', - ], - [ - 'transcript.st1.0', - '{"vatID":"st1","startPos":0,"endPos":2,"hash":"d385c43882cfb5611d255e362a9a98626ba4e55dfc308fc346c144c696ae734e","isCurrent":0,"incarnation":0}', - ], - [ - 'transcript.st1.current', - '{"vatID":"st1","startPos":2,"endPos":4,"hash":"789342fab468506c624c713c46953992f53a7eaae390d634790d791636b96cab","isCurrent":1,"incarnation":0}', - ], + t.throws(() => transcriptStore.readSpan('nonexistent'), { + message: 'no current transcript for "nonexistent"', + }); + + await commit(); + t.deepEqual(exportLog.getLog(), [ [ - 'transcript.st2.current', - '{"vatID":"st2","startPos":0,"endPos":4,"hash":"45de7ae9d2be34148f9cf3000052e5d1374932d663442fe9f39a342d221cebf1","isCurrent":1,"incarnation":0}', + [ + 'transcript.empty.current', + '{"vatID":"empty","startPos":0,"endPos":0,"hash":"43e6be43a3a34d60c0ebeb8498b5849b094fc20fc68483a7aeb3624fa10f79f6","isCurrent":1,"incarnation":0}', + ], + [ + 'transcript.st1.0', + '{"vatID":"st1","startPos":0,"endPos":1,"hash":"92d0cf6ecd39b60b4e32dc65d4c6f343495928cb041f25b19e2825b17f4daa9a","isCurrent":0,"incarnation":0}', + ], + [ + 'transcript.st1.1', + '{"vatID":"st1","startPos":1,"endPos":3,"hash":"d385c43882cfb5611d255e362a9a98626ba4e55dfc308fc346c144c696ae734e","isCurrent":0,"incarnation":0}', + ], + [ + 'transcript.st1.current', + '{"vatID":"st1","startPos":3,"endPos":5,"hash":"789342fab468506c624c713c46953992f53a7eaae390d634790d791636b96cab","isCurrent":1,"incarnation":0}', + ], + [ + 'transcript.st2.current', + '{"vatID":"st2","startPos":0,"endPos":4,"hash":"45de7ae9d2be34148f9cf3000052e5d1374932d663442fe9f39a342d221cebf1","isCurrent":1,"incarnation":0}', + ], ], - ], - ]); - await close(); -} - -test('in-memory transcriptStore read/write', async t => { - await testTranscriptStore(t, null); + ]); + await close(); + }, }); -test('persistent transcriptStore read/write', async t => { - const [dbDir, cleanup] = await tmpDir('testdb'); - t.teardown(cleanup); - t.is(isSwingStore(dbDir), false); - await testTranscriptStore(t, dbDir); -}); +test(testTranscriptStore, { ephemeral: true, keepTranscripts: true }); +test(testTranscriptStore, { ephemeral: true, keepTranscripts: false }); +test(testTranscriptStore, { ephemeral: false, keepTranscripts: true }); +test(testTranscriptStore, { ephemeral: false, keepTranscripts: false }); test('transcriptStore abort', async t => { const [dbDir, cleanup] = await tmpDir('testdb'); diff --git a/packages/swingset-liveslots/package.json b/packages/swingset-liveslots/package.json index f9eea238ed8..a0d032f6ccb 100644 --- a/packages/swingset-liveslots/package.json +++ b/packages/swingset-liveslots/package.json @@ -17,19 +17,19 @@ "lint:eslint": "eslint ." }, "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/internal": "^0.3.2", "@agoric/store": "^0.9.2", - "@endo/env-options": "^1.1.4", - "@endo/eventual-send": "^1.2.2", - "@endo/exo": "^1.5.0", - "@endo/far": "^1.1.2", - "@endo/init": "^1.1.2", - "@endo/marshal": "^1.5.0", - "@endo/nat": "^5.0.7", - "@endo/pass-style": "^1.4.0", - "@endo/patterns": "^1.4.0", - "@endo/promise-kit": "^1.1.2" + "@endo/env-options": "^1.1.6", + "@endo/eventual-send": "^1.2.5", + "@endo/exo": "^1.5.3", + "@endo/far": "^1.1.5", + "@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" }, "devDependencies": { "ava": "^5.3.0", @@ -66,6 +66,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 75.35 + "atLeast": 75.1 } } diff --git a/packages/swingset-liveslots/src/boyd-gc.js b/packages/swingset-liveslots/src/boyd-gc.js new file mode 100644 index 00000000000..1b6d8e1b13d --- /dev/null +++ b/packages/swingset-liveslots/src/boyd-gc.js @@ -0,0 +1,598 @@ +import { parseVatSlot } from './parseVatSlots.js'; + +/* + Theory of Operation (vref logical objects) + + Liveslots coordinates access to "logical objects", sometimes known + as "vref objects" because each one is named with a distinct vref + identifier (o+1, o-2, o+d3/4, etc). The SwingSet kernel coordinates + access to the objects between vats, using a kref identifier (ko56), + but vats never see krefs. + + When vat code (written in JavaScript) needs to interact with a + logical object, it needs some JS `Object` to pass in arguments, or + to invoke methods upon, or to receive in the arguments of a method + call. We use Presence objects for imported vrefs, Remotable/heap + objects for locally-created (potentially-exported) ephemeral + objects, and Representatives for virtual/durable objects initially + created by calling the Kind's maker function. Liveslots is + responsible for recognizing these `Object` objects when they appear + at its doorstep (e.g. in a remote method send, or when assigned to + the `state` of a virtual object), and knowing which vref is being + referenced. Liveslots is also the one to create all Presences and + Representatives (vat code creates the Remotable/heap objects, by + calling `Far()`). + + For garbage-collection purposes, liveslots tracks the "reachable" + and "recognizable" status for these logical objects. A logical + object is either VREF-REACHABLE, VREF-RECOGNIZABLE, or + nothing. Strong references from a VREF-REACHABLE object makes the + target also VREF-REACHABLE. Weak references from a VREF-REACHABLE + makes the target at least VREF-RECOGNIZABLE, although it might be + VREF-REACHABLE if there is also a strong reference to it. + + Weak collections provide weak access to their keys, and strong + access to their values. Strong collections provide strong access to + both keys and values. Virtual/durable objects provide strong access + to their `state`. The "reachable set" is the transitive closure of + strong edges, given a set of anchors. There will also be a + "recognizable set", with weak edges from some members of the + reachable set. + + Liveslots needs to keep track of the reachable or recognizable + status of logical objects to limit storage consumption. It must + preserve all reachable data, but it can delete data that can no + longer be reached. Liveslots also needs to coordinate status updates + with the kernel, to enable the kernel to do the same. + + The logical object for an imported vref (known as a "Presence-style + vref", o-NN) can be kept alive by either the existence of an actual + Presence `Object`, or by a (strong) virtual/durable collection that + uses the vref as its key or inside its value, or by a (weak) + collection that uses the vref inside its value, or by a + virtual/durable object that uses the vref inside its `state`. We + call the Presence the "RAM pillar", and the virtual/durable + references the "vdata pillar". The "vdata pillar" is tracked as a + record in the vatstore DB. We say the logical object is + VREF-REACHABLE if either pillar is up, and it becomes + VREF-UNREACHABLE if all pillars are down. + + The logical object for a virtual/durable object (known as + "Representative-style", o+vKK/II or o+dKK/II) can be kept alive by + any of three pillars: the Representative (RAM pillar), a + virtual/durable collection or object state (vdata pillar), or by + virtue of being exported to the kernel (export pillar). Sending a + Representative in a message to some other vat will cause the vref to + be exported, and the kernel will tell us if/when that other vat ever + drops their strong reference, which will then drop the export + pillar. The "export status" for a vref is one of EXPORT-REACHABLE, + EXPORT-RECOGNIZABLE, or nothing. + + The third category of vrefs (o+NN) are for locally-created ephmeral + objects, created by calling `Far()`. Liveslots frequently calls + these "Remotable-style vrefs", although "heap" might be a less + ambiguous term. They have only the RAM pillar: the lifetime of the + logical object is the same as that of the "Remotable" heap value. + + Once all pillars for a logical object have dropped, liveslots needs + to delete the logical object. For virtual/durable objects, this + means deleting the `state` data, and since the state can hold + references to other objects, it means decrementing refcounts and + dropping vdata pillars, which might trigger more deletions. For + logical objects that have been imported from the kernel, it must + also notify the kernel of the transition from "reachable" status to + "unreachable", so the kernel can propagate the event outwards to the + upstream vat that exported the object, deleting table entries all + the way. + + Objects which are unreachable by our vat might still be reachable by + others, or by something in the exporting vat, so becoming + unreachable is not the end of the story. The logical object might + still be *recognizable* by our vat, as a key in one or more weak + collections. While in this VREF-RECOGNIZABLE state, three things + might happen: + + * The owner, or someone who still has access, may send it to us in a + message. The vat code receives a newly-minted Presence or + Representative object, and now the logical object is + VREF-REACHABLE once more. + * The owner may declare the object "retired", meaning they've + deleted it. We should drop our matching WeakMap entries, and free + their data (which might make other objects become + unreachable). This is triggered by "dispatch.retireImports". + * We might delete our last WeakMap that recognized the vref, + allowing us to tell the kernel that we don't care about the vref + anymore, so it can remove the bookkeeping records. This uses + "possiblyRetiredSet", and may invoke "syscall.retireImports". + + We track recognizability status using "recognizer records". When the + recognizer is a virtual/durable collection or object, the record is + stored in the vatstore DB. + + The kernel tracks the vat's imported vrefs with an "import status", + one of IMPORT-REACHABLE, IMPORT-RECOGNIZABLE, or nothing. This + status is stored in the c-list entry, and is not visible to the + vat. It changes when the vat receives a vref in a delivery, or + performs syscall.dropImports or syscall.retireImports, or receives a + dispatch.retireImports. + +/* + Theory of Operation (imports/Presences) + + This describes the states that a Presence `Object` might be in, and + how we track changes in that status. The Presence forms the "RAM + pillar" that may support the logical object (vref). + + A Presence object is in one of 5 states: UNKNOWN, REACHABLE, + UNREACHABLE, COLLECTED, FINALIZED. Note that there's no actual state + machine with those values, and we can't observe all of the + transitions from JavaScript, but we can describe what operations + could cause a transition, and what our observations allow us to + deduce about the state: + + * UNKNOWN moves to REACHABLE when a crank introduces a new import + * userspace holds a reference only in REACHABLE + * REACHABLE moves to UNREACHABLE only during a userspace crank + * UNREACHABLE moves to COLLECTED when engine GC runs, which queues the finalizer + * COLLECTED moves to FINALIZED when a new turn runs the finalizer + * FINALIZED moves to UNKNOWN when liveslots sends a dropImports syscall + + convertSlotToVal either imports a vref for the first time, or + re-introduces a previously-seen vref. It transitions from: + + * UNKNOWN to REACHABLE by creating a new Presence + * UNREACHABLE to REACHABLE by re-using the old Presence that userspace + forgot about + * COLLECTED/FINALIZED to REACHABLE by creating a new Presence + + Our tracking tables hold data that depends on the current state: + + * slotToVal holds a WeakRef only in [REACHABLE, UNREACHABLE, COLLECTED] + * that WeakRef .deref()s into something only in [REACHABLE, UNREACHABLE] + * possiblyDeadSet holds the vref only in FINALIZED + * (TODO) re-introduction could remove the vref from possiblyDeadSet + + Each state thus has a set of perhaps-measurable properties: + + * UNKNOWN: slotToVal[baseRef] is missing, baseRef not in possiblyDeadSet + * REACHABLE: slotToVal[baseRef] has live weakref, userspace can reach + * UNREACHABLE: slotToVal[baseRef] has live weakref, userspace cannot reach + * COLLECTED: slotToVal[baseRef] has dead weakref + * FINALIZED: slotToVal[baseRef] is missing, baseRef is in possiblyDeadSet + + Our finalizer callback is queued by the engine's transition from + UNREACHABLE to COLLECTED, but the baseRef might be re-introduced + before the callback has a chance to run. There might even be + multiple copies of the finalizer callback queued. So the callback + must deduce the current state and only perform cleanup (i.e. delete + the slotToVal entry and add the baseRef to possiblyDeadSet) in the + COLLECTED state. + + Our general rule is "trust the finalizer". The GC code below + considers a Presence to be reachable (the vref's "RAM pillar" + remains "up") until it moves to the FINALIZED state. We do this to + avoid race conditions between some other pillar dropping (and a BOYD + sampling the WeakRef) while it is in the COLLECTED state. If we + treated COLLECTED as the RAM pillar being "down"), then the + subsequent finalizer callback would examine the vref a second time, + potentially causing a vat-fatal double syscall.dropImports. This + rule may change if/when we use FinalizationRegistry better, by + explicitly de-registering the vref when we drop it, which JS + guarantees will remove and pending callback from the queue. This may + help us avoid probing the WeakRef during BOYD (instead relying upon + the fired/not-fired state of the FR), since that probing can cause + engines to retain objects longer than necessary. + +*/ + +/* + Additional notes: + + There are three categories of vrefs: + * Presence-style (o-NN, imports, durable) + * Remotable-style (o+NN, exportable, ephemeral) + * Representative-style (o+vKK/II or o+dKK/II, exportable, virtual/durable) + + We don't necessarily have a Presence for every o-NN vref that the + vat can reach, because the vref might be held in virtual/durable + data ("vdata") while the in-RAM `Presence` object was + dropped. Likewise the in-RAM `Representative` can be dropped while + the o+dKK/II vref is kept VREF-REACHABLE by either vdata or an + export to the kernel. We *do* always have a Remotable for every o+NN + vref that the vat knows about, because Remotables are ephemeral. + + The vat does not record any information about the kernel-facing + import status (c-list state) for Presence-style vrefs (o-NN), and + cannot ask the kernel for it, so we rely upon the invariant that you + only add a vref to possiblyDeadSet if it was VREF-REACHABLE + first. That way, possiblyDeadSet.has(vref) means that the c-list + import status was IMPORT-REACHABLE. Likewise, code should only add + to possiblyRetiredSet if the vref was at least VREF-RECOGNIZABLE + beforehand, meaning the c-list status was at least + IMPORT-RECOGNIZABLE. This helps us avoid a vat-fatal duplicate + dropImports or retireImports syscall. + + For imports, the lifetime is controlled by the upstream vat: we + might drop VREF-REACHABLE today and maintain VREF-RECOGNIZABLE for + days until the object is finally retired. For exports *we* control + the lifetime, so when we determine an export is no longer + VREF-REACHABLE, we delete it and retire the vref immediately, and it + does not observably linger in the VREF-RECOGNIZABLE state. This + simplifies our tracking, and allows the deletion of Remotables and + Representative-type vrefs to be idempotent. + + Each vref's reachability status is determined by a set of + "pillars". For Presence-style vrefs, there are two: the RAM pillar + (the `Presence` object), and the vdata pillar. The vdata pillar is + tracked in a vatstore key named `vom.rc.${vref}`, which stores the + reachable/recognizable refcounts. + + For Representative-style vrefs, we add the export-status pillar, + because anything that we've exported to the kernel must be kept + alive until the kernel issues a dispatch.dropExports. That gives us + three pillars: + * the RAM pillar is the `Representative` object + * the vdata pillar is stored in `vom.rc.${vref}` + * the export-status pillar is stored in `vom.es.${vref}` + + Remotables have only the RAM pillar. When a Remotable-style vref is + exported to the kernel, the Remotable is added to the + `exportedRemotables` set. And when it is stored in vdata, it appears + as a key of the `remotableRefCounts` map. That keeps the Remotable + itself alive until the other reachability pathways have gone + away. We don't do this for Representatives because it would violate + our "don't use RAM for inactive virtual objects" rule. + + When an imported Presence becomes VREF-UNREACHABLE, it might still + be VREF-RECOGNIZABLE, by virtue of being the key of one or more weak + collections. If not, it might transit from VREF-REACHABLE directly + to NONE. The code that reacts to the VREF-UNREACHABLE transition + must check for recognizers, and do a retireImports right away if + there are none. Otherwise, recognizer will remain until either the + kernel retires the object (dispatch.retireImports), or the weak + collection is deleted, in which case possiblyRetiredSet will be + updated with the vref that might no longer be recognized. There will + be a race between us ceasing to recognize the vref (which should + trigger a syscall.retireImports), and the kernel telling us the + object has been deleted (via dispatch.retireImports). Either one + must inhibit the other. + + possiblyRetiredSet only cares about Presence-style vrefs, because + they represent imports, whose lifetime is not under our control. The + collection-deletion code will add Remotable- and Representative- + style vrefs in possiblyRetiredSet, but we can remove and ignore + them. + + We use slotToVal.has(vref) everywhere for our "is it still + reachable" check, which returns true for the Presence's REACHABLE / + UNREACHABLE / COLLECTED states, and false for the FINALIZED + state. In contrast, getValForSlot(vref) returns false for both + COLLECTED and FINALIZED. We want COLLECTED to qualify as "still + reachable" because it means there's still a finalizer callback + queued, which will be run eventually, and we need that callback to + not trigger a duplicate drop. We use slotToVal.has() in the + possiblyRetiredSet loop (to inhibit retirement of imported vrefs + whose Presences are in the COLLECTED state, and which just lost a + recognizer), because getValForSlot would allow such COLLECTED vrefs + to be retired, even before the finalizer had fired and could do a + dropImports. + + When we decide to delete a virtual object, we will delete its + `state`, decrementing the refcounts of any objects therein, which + might shake loose more data. So we keep looping until we've stopped + adding things to possiblyDeadSet. The same can happen when we use + vrm.ceaseRecognition() to delete any weak collection values keyed by + it. We also call ceaseRecognition when we realize that a Remotable + has been deleted. But the possiblyDeadSet processing loop cannot + make the decision to retire a Presence-style vref: those are deleted + outside our vat, and the kernel notifies us of the vref's retirement + with dispatch.retireImports (which also calls ceaseRecognition). The + only thing possiblyDeadSet can tell us about Presences is that our + vat can no longer *reach* the vref, which means we need to do a + syscall.dropImports, which cannot immediately release more data. + + When the kernel sends us a dispatch.bringOutYourDead (or "BOYD" for + short), this scanForDeadObjects() will be called. This is the only + appropriate time for the syscall behavior to depend upon engine GC + behavior: during all other deliveries, we want the syscalls to be a + deterministic function of delivery contents, userspace behavior, and + vatstore data. + + During BOYD, we still try to minimize the variation of behavior as + much as possible. The first step is to ask the engine to perform a + full GC sweep, to collect any remaining UNREACHABLE objects, and + allow the finalizer callbacks to run before looking at the + results. We also sort the vrefs before processing them, to remove + sensitivity to the exact order of finalizer invocation. + + That makes BOYD a safe time to look inside WeakRefs and make + syscalls based on the contents, or to read the sets that are + modified during FinalizationRegistry callbacks and make syscalls to + query their state further. This this is the only time we examine and + clear possiblyDeadSet and possiblyRetiredSet, or probe + slotToVal. Outside of BOYD, in convertSlotToVal, we must probe the + WeakRefs to see whether we must build a new Presence or + Representative, or not, but we have carefully designed that code to + avoid making syscalls during the unmarshalling process, so the only + consequence of GC differences should be differences in metering and + memory allocation patterns. + + Our general strategy is to look at the baseRefs/vrefs whose state + might have changed, determine their new reachability / + recognizability status, and then resolve any discrepancies between + that status and that of other parties who need to match. + + The kernel is one such party. If the kernel thinks we can reach an + imported o-NN vref, but we've now determined that we cannot, we must + send a syscall.dropImports to resolve the difference. Once sent, the + kernel will update our c-list entry to reflect the unreachable (but + still recognizable) status. Likewise, if the kernel thinks *it* can + recognize an exported o+NN vref, but we've just retired it, we need + to update the kernel with a syscall.retireExports, so it can notify + downstream vats that have weak collections with our vref as a key. + + The DB-backed `state` of a virtual object is another such party. If + the object is unreachable, but still has state data, we must delete + that state, and decrement refcounts it might have held. + + Our plan is summarized as: + * outer loop + * gcAndFinalize + * sort possiblyDeadSet, examine each by type + * all: remove from possiblyDeadSet + * presence (vref): + * if unreachable: + * dropImports + * add to possiblyRetiredSet + * remotable (vref): + * if unreachable: + * retireExports if kernelRecognizableRemotables + * vrm.ceaseRecognition + * VOM (baseRef) + * if unreachable: + * deleteVirtualObject (and retireExports retirees) + * repeat loop if gcAgain or possiblyDeadSet.size > 0 + * now sort and process possiblyRetiredSet. for each: + * ignore unless presence + * if unreachable and unrecognizable: retireImport + (that's a duplicate reachability check, but note the answer might + be different now) +*/ + +/* + BaseRef vs vref + + For multi-faceted virtual/durable objects (eg `defineKind()` with + faceted `behavior` argument), each time userspace create a new + instance, we create a full "cohort" of facets, passing a record of + Representative objects (one per facet) back to the caller. Each + facet gets its own vref, but they all share a common prefix, known + as the "baseRef". For example, `o+d44/2` is a BaseRef for a cohort, + the second instance created of the `o+d44` Kind, whose individual + facets would have vrefs of `o+d44/2:0` and `o+d44/2:1`. + + We use a WeakMap to ensure that holding any facet will keep all the + others alive, so the cohort lives and dies as a group. The GC + tracking code needs to track the whole cohort at once, not the + individual facets, and any data structure which refers to cohorts + will use the BaseRef instead of a single vref. So `slotToVal` is + keyed by a BaseRef, and its values are a cohort of facets. But + `valToSlot` is keyed by the facets, and its values are the + individual facet's vref. + + For Presence- and Remotable- style objects, the baseRef is just the + vref (i.e., every baseRef is either a cohort-identifying prefix or + an isolated-object vref, and every vref either has a baseRef prefix + and identifies one facet of a cohort or has no such prefix and + identifies an isolated object). + + Most of the GC-related APIs that appear here take vrefs, but the + exceptions are: + * slotToVal is keyed by BaseRef + * possiblyDeadSet holds BaseRefs, that's what our WeakRefs track + * vrm.isVirtualObjectReachable takes baseRef + * vrm.deleteVirtualObject takes baseRef, returns [bool, retireees=vrefs] + * vrm.ceaseRecognition takes either baseRef or vref + (if given a baseRef, it will process all the facets) + +*/ + +export const makeBOYDKit = ({ + gcTools, + slotToVal, + vrm, + kernelRecognizableRemotables, + syscall, + possiblyDeadSet, + possiblyRetiredSet, +}) => { + // Representative (o+dNN/II or o+vNN/II) lifetimes are also + // controlled by us. We allow the Representative object to go away + // without deleting the vref, so we must track all three pillars: + // Representative (RAM), export, and vdata. When we decide the vref + // is unreachable, we must delete the virtual object's state, as + // well as retiring the object (by telling the kernel it has been + // retired, if the kernel cares, and removing any local recognition + // records). + + const checkExportRepresentative = baseRef => { + // RAM pillar || (vdata pillar || export pillar) + const isReachable = + slotToVal.has(baseRef) || vrm.isVirtualObjectReachable(baseRef); + let gcAgain = false; + let exportsToRetire = []; + if (!isReachable) { + // again, we own the object, so we retire it immediately + [gcAgain, exportsToRetire] = vrm.deleteVirtualObject(baseRef); + } + return { gcAgain, exportsToRetire }; + }; + + // Remotable (o+NN) lifetimes are controlled by us: we delete/retire + // the object as soon as it becomes unreachable. We only track the + // Remotable/Far object (the RAM pillar) directly: exports retain + // the Remotable in the exportedRemotables set, and vdata retains it + // as keys of the remotableRefCounts map. So when we decide the vref + // is unreachable, the Remotable is already gone, and it had no + // other data we need to delete, so our task is to remove any local + // recognition records, and to inform the kernel with a + // retireExports if kernelRecognizableRemotables says that the + // kernel still cares. + // + // note: we track export status for remotables in the + // kernelRecognizableRemotables set, not vom.es.VREF records. We + // don't currently track recognition records with + // vom.ir.VREF|COLLECTION, but we should, see #9956 + + const checkExportRemotable = vref => { + let gcAgain = false; + let exportsToRetire = []; + + // Remotables have only the RAM pillar + const isReachable = slotToVal.has(vref); + if (!isReachable) { + // We own the object, so retire it immediately. If the kernel + // was recognizing it, we tell them it is now retired + if (kernelRecognizableRemotables.has(vref)) { + kernelRecognizableRemotables.delete(vref); + exportsToRetire = [vref]; + // the kernel must not have been able to reach the object, + // else it would still be pinned by exportedRemotables + } + // and remove it from any local weak collections + gcAgain = vrm.ceaseRecognition(vref); + } + return { gcAgain, exportsToRetire }; + }; + + // Presence (o-NN) lifetimes are controlled by the upstream vat, or + // the kernel. If the vref was in possiblyDeadSet, then it *was* + // reachable before, so we can safely presume the kernel to think we + // can reach it. + + const checkImportPresence = vref => { + // RAM pillar || vdata pillar + // use slotToVal.has, not getSlotForVal(), to avoid duplicate drop + const isReachable = slotToVal.has(vref) || vrm.isPresenceReachable(vref); + let dropImport; + if (!isReachable) { + dropImport = vref; + } + return { dropImport }; + }; + + const scanForDeadObjects = async () => { + await null; + + // `possiblyDeadSet` holds vrefs which have lost a supporting + // pillar (in-memory, export, or virtualized data refcount) since + // the last call to scanForDeadObjects. The vref might still be + // supported by a remaining pillar, or the pillar which was + // dropped might have been restored (e.g., re-exported after a + // drop, or given a new in-memory manifestation). + + const importsToDrop = new Set(); + const importsToRetire = new Set(); + const exportsToRetire = new Set(); + let gcAgain = false; + + do { + gcAgain = false; + await gcTools.gcAndFinalize(); + + // process a sorted list of vref/baseRefs we need to check for + // reachability, one at a time + + for (const vrefOrBaseRef of [...possiblyDeadSet].sort()) { + // remove the vref now, but some deleteVirtualObject might + // shake it loose again for a future pass to investigate + possiblyDeadSet.delete(vrefOrBaseRef); + + const parsed = parseVatSlot(vrefOrBaseRef); + assert.equal(parsed.type, 'object', vrefOrBaseRef); + + let res = {}; + if (parsed.virtual || parsed.durable) { + const baseRef = vrefOrBaseRef; + res = checkExportRepresentative(baseRef); + } else if (parsed.allocatedByVat) { + const vref = vrefOrBaseRef; + res = checkExportRemotable(vref); + } else { + const vref = vrefOrBaseRef; + res = checkImportPresence(vref); + } + + // prepare our end-of-crank syscalls + if (res.dropImport) { + importsToDrop.add(res.dropImport); + possiblyRetiredSet.add(res.dropImport); + } + for (const facetVref of res.exportsToRetire || []) { + exportsToRetire.add(facetVref); + } + gcAgain ||= !!res.gcAgain; + } + + // Deleting virtual object state, or freeing weak-keyed + // collection entries, might shake loose more + // objects. possiblyDeadSet and possiblyRetiredSet are added + // when a vdata vref decrefs to zero, and gcAgain means that + // something in RAM might now be free. In both cases we should + // do another pass, including gcAndFinalize(), until we've + // cleared everything we can. + } while (possiblyDeadSet.size > 0 || gcAgain); + + // Now we process potential retirements, by which we really mean + // de-recognitions, where this vat has ceased to even recognize a + // previously unreachable-yet-recognizable + // vref. addToPossiblyRetiredSet() is called from + // ceaseRecognition() when a recognizer goes away, such when a + // weak collection being deleted and it no longer recognizes all + // its former keys. ceaseRecognition() can be called from the loop + // above (when a Remotable-style object is deleted, or from within + // deleteVirtualObject), or in response to a retireImport() + // delivery. We assume possiblyRetiredSet is given vrefs of all + // sorts, but we only care about Presence-type, because we must do + // retireImports for them: the kernel doesn't care if/when we stop + // recognizing our own (maybe-exported) Remotable- and + // Representative- type vrefs. + + for (const vref of [...possiblyRetiredSet].sort()) { + possiblyRetiredSet.delete(vref); + const parsed = parseVatSlot(vref); + assert.equal(parsed.type, 'object', vref); + // ignore non-Presences + if (parsed.allocatedByVat) continue; + + // if we're dropping the vref, checkImportPresence() already + // did our isReachable check, so we can safely skip it (and + // save a vatstore syscall) + const isReachable = + !importsToDrop.has(vref) && + // Use slotToVal.has, not getValForSlot(), to avoid retirement + // before the finalizer fires and does dropImport + (slotToVal.has(vref) || vrm.isPresenceReachable(vref)); + const isRecognizable = isReachable || vrm.isVrefRecognizable(vref); + if (!isRecognizable) { + importsToRetire.add(vref); + } + } + + // note that retiring Presence-type vrefs cannot shake loose any + // local data, so we don't need to loop back around + + if (importsToDrop.size) { + syscall.dropImports([...importsToDrop].sort()); + } + if (importsToRetire.size) { + syscall.retireImports([...importsToRetire].sort()); + } + if (exportsToRetire.size) { + syscall.retireExports([...exportsToRetire].sort()); + } + }; + + return { scanForDeadObjects }; +}; +harden(makeBOYDKit); diff --git a/packages/swingset-liveslots/src/collectionManager.js b/packages/swingset-liveslots/src/collectionManager.js index 8aa7ddd6e57..9b8b6d4ff2e 100644 --- a/packages/swingset-liveslots/src/collectionManager.js +++ b/packages/swingset-liveslots/src/collectionManager.js @@ -4,7 +4,6 @@ import { zeroPad, makeEncodePassable, makeDecodePassable, - isEncodedRemotable, compareRank, } from '@endo/marshal'; import { @@ -66,6 +65,12 @@ function prefixc(collectionID, dbEntryKey) { return `vc.${collectionID}.${dbEntryKey}`; } +export const collectionMetaKeys = new Set([ + '|entryCount', + '|nextOrdinal', + '|schemata', +]); + /** * @typedef {object} SchemaCacheValue * @property {Pattern} keyShape @@ -293,6 +298,20 @@ export function makeCollectionManager( return `${dbKeyPrefix}${dbEntryKey}`; } + // A "vref" is a string like "o-4" or "o+d44/2:0" + // An "EncodedKey" is the output of encode-passable: + // * strings become `s${string}`, like "foo" -> "sfoo" + // * small positive BigInts become `p${len}:${digits}`, like 47n -> "p2:47" + // * refs are assigned an "ordinal" and use `r${fixedLengthOrdinal}:${vref}` + // * e.g. vref(o-4) becomes "r0000000001:o-4" + // A "DBKey" is used to index the vatstore. DBKeys for collection + // entries join a collection prefix and an EncodedKey. Some + // possible DBKeys for entries of collection "5", using collection + // prefix "vc.5.", are: + // * "foo" -> "vc.5.sfoo" + // * 47n -> "vc.5.p2:47" + // * vref(o-4) -> "vc.5.r0000000001:o-4" + const encodeRemotable = remotable => { // eslint-disable-next-line no-use-before-define const ordinal = getOrdinal(remotable); @@ -308,10 +327,11 @@ export function makeCollectionManager( // the resulting function will encode only `Key` arguments. const encodeKey = makeEncodePassable({ encodeRemotable }); - const vrefFromDBKey = dbKey => dbKey.substring(BIGINT_TAG_LEN + 2); + const vrefFromEncodedKey = encodedKey => + encodedKey.substring(1 + BIGINT_TAG_LEN + 1); const decodeRemotable = encodedKey => - convertSlotToVal(vrefFromDBKey(encodedKey)); + convertSlotToVal(vrefFromEncodedKey(encodedKey)); // `makeDecodePassable` has three named options: // `decodeRemotable`, `decodeError`, and `decodePromise`. @@ -347,10 +367,16 @@ export function makeCollectionManager( } function dbKeyToKey(dbKey) { + // convert e.g. vc.5.r0000000001:o+v10/1 to r0000000001:o+v10/1 const dbEntryKey = dbKey.substring(dbKeyPrefix.length); return decodeKey(dbEntryKey); } + function dbKeyToEncodedKey(dbKey) { + assert(dbKey.startsWith(dbKeyPrefix), dbKey); + return dbKey.substring(dbKeyPrefix.length); + } + function has(key) { const { keyShape } = getSchema(); if (!matches(key, keyShape)) { @@ -553,40 +579,58 @@ export function makeCollectionManager( */ function clearInternalFull() { let doMoreGC = false; - const [coverStart, coverEnd] = getRankCover(M.any(), encodeKey); - const start = prefix(coverStart); - const end = prefix(coverEnd); - - // this yields all keys for which (start <= key < end) - for (const dbKey of enumerateKeysStartEnd(syscall, start, end)) { - const value = JSON.parse(syscall.vatstoreGet(dbKey)); - doMoreGC = - value.slots.map(vrm.removeReachableVref).some(b => b) || doMoreGC; - syscall.vatstoreDelete(dbKey); - if (isEncodedRemotable(dbKey)) { - const keyVref = vrefFromDBKey(dbKey); + + // visit every DB entry associated with the collection, which + // (due to sorting) will be collection entries first, and then a + // mixture of ordinal-assignment mappings and size-independent + // metadata (both of which start with "|"). + for (const dbKey of enumerateKeysWithPrefix(syscall, dbKeyPrefix)) { + const encodedKey = dbKeyToEncodedKey(dbKey); + + // preserve general metadata ("|entryCount" and friends are + // cleared by our caller) + if (collectionMetaKeys.has(encodedKey)) continue; + + if (encodedKey.startsWith('|')) { + // ordinal assignment; decref or de-recognize its vref + const keyVref = encodedKey.substring(1); + parseVatSlot(keyVref); if (hasWeakKeys) { vrm.removeRecognizableVref(keyVref, `${collectionID}`, true); } else { doMoreGC = vrm.removeReachableVref(keyVref) || doMoreGC; } - syscall.vatstoreDelete(prefix(`|${keyVref}`)); + } else { + // a collection entry; decref slots from its value + const value = JSON.parse(syscall.vatstoreGet(dbKey)); + doMoreGC = + value.slots.map(vrm.removeReachableVref).some(b => b) || doMoreGC; } + + // in either case, delete the DB entry + syscall.vatstoreDelete(dbKey); } + return doMoreGC; } function clearInternal(isDeleting, keyPatt, valuePatt) { let doMoreGC = false; - if (isDeleting || (matchAny(keyPatt) && matchAny(valuePatt))) { + if (isDeleting) { doMoreGC = clearInternalFull(); + // |entryCount will be deleted along with metadata keys + } else if (matchAny(keyPatt) && matchAny(valuePatt)) { + doMoreGC = clearInternalFull(); + if (!hasWeakKeys) { + syscall.vatstoreSet(prefix('|entryCount'), '0'); + } } else { + let numDeleted = 0; for (const k of keys(keyPatt, valuePatt)) { + numDeleted += 1; doMoreGC = deleteInternal(k) || doMoreGC; } - } - if (!hasWeakKeys && !isDeleting) { - syscall.vatstoreSet(prefix('|entryCount'), '0'); + updateEntryCount(-numDeleted); } return doMoreGC; } diff --git a/packages/swingset-liveslots/src/liveslots.js b/packages/swingset-liveslots/src/liveslots.js index 7246f41f2d8..9363b15e027 100644 --- a/packages/swingset-liveslots/src/liveslots.js +++ b/packages/swingset-liveslots/src/liveslots.js @@ -1,10 +1,7 @@ import { annotateError, assert, Fail, makeError, X } from '@endo/errors'; -import { - Remotable, - passStyleOf, - getInterfaceOf, - makeMarshal, -} from '@endo/marshal'; +import { passStyleOf } from '@endo/pass-style'; +import { PassStyleOfEndowmentSymbol } from '@endo/pass-style/endow.js'; +import { Remotable, getInterfaceOf, makeMarshal } from '@endo/marshal'; import { isPromise } from '@endo/promise-kit'; import { E, HandledPromise } from '@endo/eventual-send'; import { insistVatType, makeVatSlot, parseVatSlot } from './parseVatSlots.js'; @@ -15,6 +12,7 @@ import { makeVirtualReferenceManager } from './virtualReferences.js'; import { makeVirtualObjectManager } from './virtualObjectManager.js'; import { makeCollectionManager } from './collectionManager.js'; import { makeWatchedPromiseManager } from './watchedPromises.js'; +import { makeBOYDKit } from './boyd-gc.js'; const SYSCALL_CAPDATA_BODY_SIZE_LIMIT = 10_000_000; const SYSCALL_CAPDATA_SLOTS_LENGTH_LIMIT = 10_000; @@ -168,52 +166,6 @@ function build( } } - /* - Imports are in one of 5 states: UNKNOWN, REACHABLE, UNREACHABLE, - COLLECTED, FINALIZED. Note that there's no actual state machine with those - values, and we can't observe all of the transitions from JavaScript, but - we can describe what operations could cause a transition, and what our - observations allow us to deduce about the state: - - * UNKNOWN moves to REACHABLE when a crank introduces a new import - * userspace holds a reference only in REACHABLE - * REACHABLE moves to UNREACHABLE only during a userspace crank - * UNREACHABLE moves to COLLECTED when GC runs, which queues the finalizer - * COLLECTED moves to FINALIZED when a new turn runs the finalizer - * liveslots moves from FINALIZED to UNKNOWN by syscalling dropImports - - convertSlotToVal either imports a vref for the first time, or - re-introduces a previously-seen vref. It transitions from: - - * UNKNOWN to REACHABLE by creating a new Presence - * UNREACHABLE to REACHABLE by re-using the old Presence that userspace - forgot about - * COLLECTED/FINALIZED to REACHABLE by creating a new Presence - - Our tracking tables hold data that depends on the current state: - - * slotToVal holds a WeakRef in [REACHABLE, UNREACHABLE, COLLECTED] - * that WeakRef .deref()s into something in [REACHABLE, UNREACHABLE] - * deadSet holds the vref only in FINALIZED - * re-introduction must ensure the vref is not in the deadSet - - Each state thus has a set of perhaps-measurable properties: - - * UNKNOWN: slotToVal[baseRef] is missing, baseRef not in deadSet - * REACHABLE: slotToVal has live weakref, userspace can reach - * UNREACHABLE: slotToVal has live weakref, userspace cannot reach - * COLLECTED: slotToVal[baseRef] has dead weakref - * FINALIZED: slotToVal[baseRef] is missing, baseRef is in deadSet - - Our finalizer callback is queued by the engine's transition from - UNREACHABLE to COLLECTED, but the baseRef might be re-introduced before the - callback has a chance to run. There might even be multiple copies of the - finalizer callback queued. So the callback must deduce the current state - and only perform cleanup (i.e. delete the slotToVal entry and add the - baseRef to the deadSet) in the COLLECTED state. - - */ - function finalizeDroppedObject(baseRef) { // TODO: Ideally this function should assert that it is not metered. This // appears to be fine in practice, but it breaks a number of unit tests in @@ -238,113 +190,6 @@ function build( } const vreffedObjectRegistry = new FinalizationRegistry(finalizeDroppedObject); - async function scanForDeadObjects() { - // `possiblyDeadSet` accumulates vrefs which have lost a supporting - // pillar (in-memory, export, or virtualized data refcount) since the - // last call to scanForDeadObjects. The vref might still be supported - // by a remaining pillar, or the pillar which was dropped might be back - // (e.g., given a new in-memory manifestation). - - const importsToDrop = new Set(); - const importsToRetire = new Set(); - const exportsToRetire = new Set(); - let doMore; - await null; - do { - doMore = false; - - await gcTools.gcAndFinalize(); - - // possiblyDeadSet contains a baseref for everything (Presences, - // Remotables, Representatives) that might have lost a - // pillar. The object might still be supported by other pillars, - // and the lost pillar might have been reinstantiated by the - // time we get here. The first step is to filter this down to a - // list of definitely dead baserefs. - - const deadSet = new Set(); - - for (const baseRef of possiblyDeadSet) { - if (slotToVal.has(baseRef)) { - continue; // RAM pillar remains - } - const { virtual, durable, type } = parseVatSlot(baseRef); - assert(type === 'object', `unprepared to track ${type}`); - if (virtual || durable) { - // eslint-disable-next-line no-use-before-define - if (vrm.isVirtualObjectReachable(baseRef)) { - continue; // vdata or export pillar remains - } - } - deadSet.add(baseRef); - } - possiblyDeadSet.clear(); - - // deadSet now contains objects which are certainly dead - - // possiblyRetiredSet holds (a subset of??) baserefs which have - // lost a recognizer recently. TODO recheck this - - for (const vref of possiblyRetiredSet) { - // eslint-disable-next-line no-use-before-define - if (!getValForSlot(vref) && !deadSet.has(vref)) { - // Don't retire things that haven't yet made the transition to dead, - // i.e., always drop before retiring - // eslint-disable-next-line no-use-before-define - if (!vrm.isVrefRecognizable(vref)) { - importsToRetire.add(vref); - } - } - } - possiblyRetiredSet.clear(); - - const deadBaseRefs = Array.from(deadSet); - deadBaseRefs.sort(); - for (const baseRef of deadBaseRefs) { - const { virtual, durable, allocatedByVat, type } = - parseVatSlot(baseRef); - type === 'object' || Fail`unprepared to track ${type}`; - if (virtual || durable) { - // Representative: send nothing, but perform refcount checking - // eslint-disable-next-line no-use-before-define - const [gcAgain, retirees] = vrm.deleteVirtualObject(baseRef); - if (retirees) { - retirees.map(retiree => exportsToRetire.add(retiree)); - } - doMore = doMore || gcAgain; - } else if (allocatedByVat) { - // Remotable: send retireExport - // for remotables, vref === baseRef - if (kernelRecognizableRemotables.has(baseRef)) { - kernelRecognizableRemotables.delete(baseRef); - exportsToRetire.add(baseRef); - } - } else { - // Presence: send dropImport unless reachable by VOM - // eslint-disable-next-line no-lonely-if, no-use-before-define - if (!vrm.isPresenceReachable(baseRef)) { - importsToDrop.add(baseRef); - // eslint-disable-next-line no-use-before-define - if (!vrm.isVrefRecognizable(baseRef)) { - // for presences, baseRef === vref - importsToRetire.add(baseRef); - } - } - } - } - } while (possiblyDeadSet.size > 0 || possiblyRetiredSet.size > 0 || doMore); - - if (importsToDrop.size) { - syscall.dropImports(Array.from(importsToDrop).sort()); - } - if (importsToRetire.size) { - syscall.retireImports(Array.from(importsToRetire).sort()); - } - if (exportsToRetire.size) { - syscall.retireExports(Array.from(exportsToRetire).sort()); - } - } - /** * Remember disavowed Presences which will kill the vat if you try to talk * to them @@ -752,32 +597,43 @@ function build( if (facet !== undefined) { result = vrm.getFacet(id, val, facet); } - } else { + } else if (type === 'object') { + // Note: an abandonned (e.g. by an upgrade) exported ephemeral or virtual + // object would appear as an import if re-introduced. In the future we + // may need to change that if we want to keep recognizing such references + // In that case we'd need to create an imported presence for these + // unknown vrefs allocated by the vat. + // See https://github.com/Agoric/agoric-sdk/issues/9746 !allocatedByVat || Fail`I don't remember allocating ${slot}`; - if (type === 'object') { - // this is a new import value - val = makeImportedPresence(slot, iface); - } else if (type === 'promise') { - const pRec = makePipelinablePromise(slot); - importedVPIDs.set(slot, pRec); - val = pRec.promise; - // ideally we'd wait until .then is called on p before subscribing, - // but the current Promise API doesn't give us a way to discover - // this, so we must subscribe right away. If we were using Vows or - // some other then-able, we could just hook then() to notify us. - if (importedPromises) { - // leave the subscribe() up to dispatch.notify() - importedPromises.add(slot); - } else { - // probably in dispatch.deliver(), so subscribe now - syscall.subscribe(slot); - } - } else if (type === 'device') { - val = makeDeviceNode(slot, iface); - importedDevices.add(val); + // this is a new import value + val = makeImportedPresence(slot, iface); + } else if (type === 'promise') { + // We unconditionally create a promise record, even if the promise looks + // like it was allocated by us. This can happen when re-importing a + // promise created by the previous incarnation. We may or may not have + // been the decider of the promise. If we were, the kernel will be + // rejecting the promise on our behalf. We may have previously been + // subscribed to that promise, but subscription is idempotent. + const pRec = makePipelinablePromise(slot); + importedVPIDs.set(slot, pRec); + val = pRec.promise; + // ideally we'd wait until .then is called on p before subscribing, + // but the current Promise API doesn't give us a way to discover + // this, so we must subscribe right away. If we were using Vows or + // some other then-able, we could just hook then() to notify us. + if (importedPromises) { + // leave the subscribe() up to dispatch.notify() + importedPromises.add(slot); } else { - Fail`unrecognized slot type '${type}'`; + // probably in dispatch.deliver(), so subscribe now + syscall.subscribe(slot); } + } else if (type === 'device') { + !allocatedByVat || Fail`unexpected device ${slot} allocated by vat`; + val = makeDeviceNode(slot, iface); + importedDevices.add(val); + } else { + Fail`unrecognized slot type '${type}'`; } registerValue(baseRef, val, facet !== undefined); if (!result) { @@ -790,7 +646,25 @@ function build( meterControl.assertNotMetered(); const { type } = parseVatSlot(slot); type === 'promise' || Fail`revivePromise called on non-promise ${slot}`; - !getValForSlot(slot) || Fail`revivePromise called on pre-existing ${slot}`; + const val = getValForSlot(slot); + if (val) { + // revivePromise is only called by loadWatchedPromiseTable, which runs + // after buildRootObject(), which is given the deserialized vatParameters. + // The only way revivePromise() might encounter a pre-existing vpid is if + // these vatParameters include a promise that the previous incarnation + // watched, but that `buildRootObject` in the new incarnation didn't + // explicitly watch again. This can be either a previously imported + // promise, or a promise the previous incarnation exported, regardless of + // who the decider now is. + // + // In that case convertSlotToVal() has already deserialized the vpid, but + // since `buildRootObject` didn't explicitely call watchPromise on it, no + // registration exists so loadWatchedPromiseTable attempts to revive the + // promise. + return val; + } + // NOTE: it is important that this code not do anything *more* + // than what convertSlotToVal(vpid) would do const pRec = makePipelinablePromise(slot); importedVPIDs.set(slot, pRec); const p = pRec.promise; @@ -1339,6 +1213,7 @@ function build( const inescapableGlobalProperties = harden({ WeakMap: vom.VirtualObjectAwareWeakMap, WeakSet: vom.VirtualObjectAwareWeakSet, + [PassStyleOfEndowmentSymbol]: passStyleOf, }); function getRetentionStats() { @@ -1518,16 +1393,15 @@ function build( // metered const unmeteredDispatch = meterControl.unmetered(dispatchToUserspace); - async function bringOutYourDead() { - await scanForDeadObjects(); - // Now flush all the vatstore changes (deletions and refcounts) we - // made. dispatch() calls afterDispatchActions() automatically for - // most methods, but not bringOutYourDead(). - // eslint-disable-next-line no-use-before-define - afterDispatchActions(); - // XXX TODO: make this conditional on a config setting - return getRetentionStats(); - } + const { scanForDeadObjects } = makeBOYDKit({ + gcTools, + slotToVal, + vrm, + kernelRecognizableRemotables, + syscall, + possiblyDeadSet, + possiblyRetiredSet, + }); /** * @param { import('./types.js').SwingSetCapData } _disconnectObjectCapData @@ -1547,6 +1421,16 @@ function build( vom.flushStateCache(); } + const bringOutYourDead = async () => { + await scanForDeadObjects(); + // Now flush all the vatstore changes (deletions and refcounts) we + // made. dispatch() calls afterDispatchActions() automatically for + // most methods, but not bringOutYourDead(). + afterDispatchActions(); + // XXX TODO: make this conditional on a config setting + return getRetentionStats(); + }; + /** * This 'dispatch' function is the entry point for the vat as a whole: the * vat-worker supervisor gives us VatDeliveryObjects (like @@ -1593,12 +1477,10 @@ function build( } else if (delivery[0] === 'stopVat') { return meterControl.runWithoutMeteringAsync(() => stopVat(delivery[1])); } else { - let complete = false; // Start user code running, record any internal liveslots errors. We do // *not* directly wait for the userspace function to complete, nor for // any promise it returns to fire. const p = Promise.resolve(delivery).then(unmeteredDispatch); - void p.finally(() => (complete = true)); // Instead, we wait for userspace to become idle by draining the // promise queue. We clean up and then examine/return 'p' so any @@ -1609,10 +1491,11 @@ function build( return gcTools.waitUntilQuiescent().then(() => { afterDispatchActions(); // eslint-disable-next-line prefer-promise-reject-errors - return complete ? p : Promise.reject('buildRootObject unresolved'); + return Promise.race([p, Promise.reject('buildRootObject unresolved')]); // the only delivery that pays attention to a user-provided // Promise is startVat, so the error message is specialized to - // the only user problem that could cause complete===false + // the only user problem that could cause the promise to not be + // settled. }); } } diff --git a/packages/swingset-liveslots/src/virtualReferences.js b/packages/swingset-liveslots/src/virtualReferences.js index 09f78ff2ac9..ffe0daca3bb 100644 --- a/packages/swingset-liveslots/src/virtualReferences.js +++ b/packages/swingset-liveslots/src/virtualReferences.js @@ -500,26 +500,51 @@ export function makeVirtualReferenceManager( } /** - * A vref is "recognizable" when it is used as the key of a weak Map - * or Set: that Map/Set can be used to query whether a future - * specimen matches the original or not, without holding onto the - * original. + * A vref is "recognizable" when it is used as the key of a weak + * collection, like a virtual/durable WeakMapStore or WeakSetStore, + * or the ephemeral voAwareWeakMap/Set that we impose upon userspace + * as "WeakMap/WeakSet". The collection can be used to query whether + * a future specimen matches the original or not, without holding + * onto the original. * - * This 'vrefRecognizers' is a Map from those vrefs to the set of - * recognizing weak collections, for virtual keys and non-virtual - * collections. Specifically, the vrefs correspond to imported - * Presences or virtual-object Representatives (Remotables do not - * participate: they are keyed by the actual Remotable object, not - * its vref). The collections are either a VirtualObjectAwareWeakMap - * or a VirtualObjectAwareWeakSet. We remove the entry when the key - * is removed from the collection, and when the entire collection is - * deleted. + * We need "recognition records" to map from the vref to the + * collection that can recognize it. When the vref is retired, we + * use the record to find all the collections from which we need to + * delete entries, so we can release the matching values. This might + * happen because the vref was for a Presence and the kernel just + * told us the upstream vat has deleted it (dispatch.retireImports), + * or because it was for a locally-managed object (an ephemeral + * Remotable or a virtual/durable Representative) and we decided to + * delete it. * - * It is critical that each collection have exactly one recognizer that is - * unique to that collection, because the recognizers themselves will be - * tracked by their object identities, but the recognizer cannot be the - * collection itself else it would prevent the collection from being garbage - * collected. + * The virtual/durable collections track their "recognition records" + * in the vatstore, in keys like "vom.ir.${vref}|${collectionID}". + * These records do not contribute to our RAM usage. + * + * voAwareWeakMap and voAwareWeakSet store their recognition records + * in RAM, using this Map named 'vrefRecognizers'. Each key is a + * vref, and the value is a Set of recognizers. Each recognizer is + * the internal 'virtualObjectMap' in which the collection maps from + * vref to value. These in-RAM collections only use virtualObjectMap + * to track Presence-style (imports) and Representative-style + * (virtual/durable) vrefs: any Remotable-style keys are stored in + * the collection's internal (real) WeakMap under the Remotable + * object itself (because the engine handles the bookkeeping, and + * there is no virtual data in the value that we need to clean up at + * deletion time). + * + * Each voAwareWeakMap/Set must have a distinct recognizer, so we + * can remove the key from the right ones. The recognizer is held + * strongly by the recognition record, so it must not be the + * voAwareWeakMap/Set itself (which would inhibit GC). + * + * When an individual entry is deleted from the weak collection, we + * must also delete the recognition record. When the collection + * itself is deleted (i.e. because nothing was referencing it), we + * must both delete all recognition records and also notify the + * kernel about any Presence-style vrefs that we can no longer + * recognize (syscall.retireImports). The kernel doesn't care about + * Remotable- or Representative- style vrefs, only the imports. * * TODO: all the "recognizers" in principle could be, and probably should be, * reduced to deleter functions. However, since the VirtualObjectAware @@ -535,14 +560,24 @@ export function makeVirtualReferenceManager( /** @type {Map>} */ const vrefRecognizers = new Map(); + /** + * @param {*} value The vref-bearing object used as the collection key + * @param {string|Recognizer} recognizer The collectionID or virtualObjectMap for the collection + * @param {boolean} [recognizerIsVirtual] true for virtual/durable Stores, false for voAwareWeakMap/Set + */ function addRecognizableValue(value, recognizer, recognizerIsVirtual) { const vref = getSlotForVal(value); if (vref) { const { type, allocatedByVat, virtual, durable } = parseVatSlot(vref); - if (type === 'object' && (!allocatedByVat || virtual || durable)) { + if (type === 'object') { + // recognizerSet (voAwareWeakMap/Set) doesn't track Remotables + const notRemotable = !allocatedByVat || virtual || durable; + if (recognizerIsVirtual) { + assert.typeof(recognizer, 'string'); syscall.vatstoreSet(`vom.ir.${vref}|${recognizer}`, '1'); - } else { + } else if (notRemotable) { + assert.typeof(recognizer, 'object'); let recognizerSet = vrefRecognizers.get(vref); if (!recognizerSet) { recognizerSet = new Set(); @@ -554,18 +589,33 @@ export function makeVirtualReferenceManager( } } + /** + * @param {string} vref The vref or the object used as the collection key + * @param {string|Recognizer} recognizer The collectionID or virtualObjectMap for the collection + * @param {boolean} [recognizerIsVirtual] true for virtual/durable Stores, false for voAwareWeakMap/Set + */ function removeRecognizableVref(vref, recognizer, recognizerIsVirtual) { const { type, allocatedByVat, virtual, durable } = parseVatSlot(vref); - if (type === 'object' && (!allocatedByVat || virtual || durable)) { + if (type === 'object') { + // addToPossiblyDeadSet only needs Presence-style vrefs + const isPresence = !allocatedByVat; + // recognizerSet (voAwareWeakMap/Set) doesn't track Remotables + const notRemotable = !allocatedByVat || virtual || durable; + if (recognizerIsVirtual) { + assert.typeof(recognizer, 'string'); syscall.vatstoreDelete(`vom.ir.${vref}|${recognizer}`); - } else { + if (isPresence) { + addToPossiblyRetiredSet(vref); + } + } else if (notRemotable) { + assert.typeof(recognizer, 'object'); const recognizerSet = vrefRecognizers.get(vref); assert(recognizerSet && recognizerSet.has(recognizer)); recognizerSet.delete(recognizer); if (recognizerSet.size === 0) { vrefRecognizers.delete(vref); - if (!allocatedByVat) { + if (isPresence) { addToPossiblyRetiredSet(vref); } } @@ -573,6 +623,11 @@ export function makeVirtualReferenceManager( } } + /** + * @param {*} value The vref-bearing object used as the collection key + * @param {string|Recognizer} recognizer The collectionID or virtualObjectMap for the collection + * @param {boolean} [recognizerIsVirtual] true for virtual/durable Stores, false for voAwareWeakMap/Set + */ function removeRecognizableValue(value, recognizer, recognizerIsVirtual) { const vref = getSlotForVal(value); if (vref) { diff --git a/packages/swingset-liveslots/src/watchedPromises.js b/packages/swingset-liveslots/src/watchedPromises.js index e6ccad5d755..799171f5d99 100644 --- a/packages/swingset-liveslots/src/watchedPromises.js +++ b/packages/swingset-liveslots/src/watchedPromises.js @@ -139,6 +139,12 @@ export function makeWatchedPromiseManager({ */ function loadWatchedPromiseTable(revivePromise) { for (const vpid of watchedPromiseTable.keys()) { + if (promiseRegistrations.has(vpid)) { + // We're only interested in reconnecting the promises from the previous + // incarnation. Any promise watched during buildRootObject would have + // already created a registration. + continue; + } const p = revivePromise(vpid); promiseRegistrations.init(vpid, p); pseudoThen(p, vpid); diff --git a/packages/swingset-liveslots/test/clear-collection.test.js b/packages/swingset-liveslots/test/clear-collection.test.js new file mode 100644 index 00000000000..313f0d941df --- /dev/null +++ b/packages/swingset-liveslots/test/clear-collection.test.js @@ -0,0 +1,586 @@ +import test from 'ava'; + +import { Far } from '@endo/marshal'; +import { kser, kslot } from '@agoric/kmarshal'; +import { makeLiveSlots } from '../src/liveslots.js'; +import { parseVatSlot } from '../src/parseVatSlots.js'; +import { buildSyscall } from './liveslots-helpers.js'; +import { makeMessage, makeStartVat, makeBringOutYourDead } from './util.js'; +import { makeMockGC } from './mock-gc.js'; + +const getPrefixedKeys = (map, prefix) => { + const keys = []; + for (const key of map.keys()) { + if (key.startsWith(prefix)) { + keys.push(key.substring(prefix.length)); + } + } + return keys; +}; + +const collectionMetaKeys = new Set([ + '|nextOrdinal', + '|entryCount', + '|schemata', +]); + +const scanCollection = (kvStore, collectionID) => { + const collectionPrefix = `vc.${collectionID}.`; + const ordinalAssignments = []; + const entries = []; + const metaKeys = []; + let totalKeys = 0; + for (const key of getPrefixedKeys(kvStore, collectionPrefix)) { + totalKeys += 1; + if (key.startsWith('|')) { + if (collectionMetaKeys.has(key)) { + metaKeys.push(key); + } else { + ordinalAssignments.push(key); + } + } else { + entries.push(key); + } + } + const keyVrefs = []; + const refcounts = {}; + for (const ordinalKey of ordinalAssignments) { + const vref = ordinalKey.substring(1); + keyVrefs.push(vref); + const rcKey = `vom.rc.${vref}`; + refcounts[vref] = kvStore.get(rcKey); + } + return { + totalKeys, + metaKeys, + ordinalAssignments, + entries, + keyVrefs, + refcounts, + }; +}; + +const GC = ['dropImports', 'retireImports', 'retireExports']; + +const doTest = async (t, mode) => { + assert(['strong-clear', 'strong-delete', 'weak-delete'].includes(mode)); + const kvStore = new Map(); + const { syscall, log } = buildSyscall({ kvStore }); + const gcTools = makeMockGC(); + const COUNT = 5; + + // we'll either call holder.clear() to exercise manual clearing, or + // gcTools.kill(holder) to exercise the collection itself being + // deleted + + let holder; + + function build(vatPowers) { + const { defineKind, makeScalarBigSetStore } = vatPowers.VatData; + const make = defineKind('target', () => ({}), {}); + holder = makeScalarBigSetStore('holder'); + const root = Far('root', { + create() { + for (let i = 0; i < COUNT; i += 1) { + // vrefs are all `o+v10/${N}`, N=1..10 + const target = make(); + holder.add(target); + // we immediately delete the presence, but the finalizers + // won't run until gcTools.flushAllFRs() + gcTools.kill(target); + } + }, + clear() { + holder.clear(); + }, + }); + return root; + } + + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, () => ({ + buildRootObject: build, + })); + const { dispatch, testHooks } = ls; + const { valToSlot } = testHooks; + await dispatch(makeStartVat(kser())); + log.length = 0; + + const rootA = 'o+0'; + + await dispatch(makeMessage(rootA, 'create', [])); + log.length = 0; + + const holderVref = valToSlot.get(holder); + const collectionID = Number(parseVatSlot(holderVref).subid); + const populated = scanCollection(kvStore, collectionID); + t.is(populated.ordinalAssignments.length, COUNT); + t.is(populated.entries.length, COUNT); + t.is(populated.keyVrefs.length, COUNT); + t.true(populated.keyVrefs.every(vref => populated.refcounts[vref] === '1')); + + // Collect the representatives, leaving only the virtual-data + // pillar. This BOYD finds non-zero virtual-data refcounts for all + // five VOs, so they are not deleted. + gcTools.flushAllFRs(); + const boyd1 = await dispatch(makeBringOutYourDead()); + t.is(boyd1.possiblyDeadSet, 0); + t.is(boyd1.possiblyRetiredSet, 0); + log.length = 0; + t.is(scanCollection(kvStore, collectionID).totalKeys, populated.totalKeys); + + if (mode === 'strong-clear') { + // clearing the collections should delete both the data key and the + // ordinal key for each entry, but it won't delete the values, that + // is deferred until BOYD. The metadata is retained, because the + // collection has been cleared, not deleted. + await dispatch(makeMessage(rootA, 'clear', [])); + } else if (mode === 'strong-delete') { + gcTools.kill(holder); + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + // that should clear everything, both the holder and the referenced + // targets + } + + const scan2 = scanCollection(kvStore, collectionID); + + // all entries should be gone + t.is(scan2.ordinalAssignments.length, 0); + t.is(scan2.entries.length, 0); + t.is(scan2.keyVrefs.length, 0); + + if (mode === 'strong-clear') { + // but the collection itself is still present + t.is(scan2.metaKeys.length, populated.metaKeys.length); + for (const vref of populated.keyVrefs) { + const rcKey = `vom.rc.${vref}`; + const rc = kvStore.get(rcKey); + // the target refcounts should be zero (= undefined) + t.is(rc, undefined); + // but the data should still be present + const dataKey = `vom.${vref}`; + const data = kvStore.get(dataKey); + t.is(data, '{}'); + } + // and we need one more BOYD to notice the zero refcounts and + // delete the data + await dispatch(makeBringOutYourDead()); + } else if (mode === 'strong-delete') { + // the collection should be gone + t.is(scan2.metaKeys.length, 0); + t.is(scan2.totalKeys, 0); + } + + // all the targets should be collected now + for (const vref of populated.keyVrefs) { + const rcKey = `vom.rc.${vref}`; + const rc = kvStore.get(rcKey); + // the target refcounts should be zero (= undefined) + t.is(rc, undefined); + const dataKey = `vom.${vref}`; + const data = kvStore.get(dataKey); + t.is(data, undefined); + } + + // none of the Presences were exported, so no GC syscalls + const gcCalls1 = log.filter(l => GC.includes(l.type)); + t.deepEqual(gcCalls1, []); +}; + +// When a virtual collection's keys are the only reference to a +// virtual object, collection.clear() should let them be deleted. Bug +// #8756 caused the keys to be retained by mistake. + +test('collection.clear() deletes keys', async t => { + await doTest(t, 'strong-clear'); +}); + +// Allowing GC to delete a strong collection should delete/release the +// keys too + +test('deleting a strong collection will delete the keys', async t => { + await doTest(t, 'strong-delete'); +}); + +// Allowing GC to delete a weak collection should retire the keys, and +// delete/release the contents. + +test('deleting a weak collection will retire the keys', async t => { + const kvStore = new Map(); + const { syscall, log } = buildSyscall({ kvStore }); + const gcTools = makeMockGC(); + const COUNT = 5; + const allVrefs = []; + const allKslots = []; + for (let i = 0; i < COUNT; i += 1) { + const vref = `o-${i + 1}`; + allVrefs.push(vref); + allKslots.push(kslot(vref, 'imported')); + } + + let recognizer; + + // Import a bunch of Presences and hold them in a weakset. Drop the + // imports, but retain recognition, until we drop the weakset, which + // should delete the collection and notify the kernel that we aren't + // recognizing the keys (syscall.retireImports) + function build(vatPowers) { + const { makeScalarBigWeakSetStore } = vatPowers.VatData; + recognizer = makeScalarBigWeakSetStore('recognizer'); + const root = Far('root', { + create(presences) { + for (const p of presences) { + recognizer.add(p); + // we immediately delete the presence, but the finalizers + // won't run until gcTools.flushAllFRs() + gcTools.kill(p); + } + }, + }); + return root; + } + + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, () => ({ + buildRootObject: build, + })); + const { dispatch, testHooks } = ls; + const { valToSlot } = testHooks; + await dispatch(makeStartVat(kser())); + log.length = 0; + + const rootA = 'o+0'; + + await dispatch(makeMessage(rootA, 'create', [allKslots])); + log.length = 0; + + const recognizerVref = valToSlot.get(recognizer); + const collectionID = Number(parseVatSlot(recognizerVref).subid); + + // all the Presences should be recognized by the collection, but not + // referenced + const populated = scanCollection(kvStore, collectionID); + t.is(populated.ordinalAssignments.length, COUNT); + t.is(populated.entries.length, COUNT); + t.is(populated.keyVrefs.length, COUNT); + t.true( + populated.keyVrefs.every(vref => populated.refcounts[vref] === undefined), + ); + // and there should be recognizer (.ir) entries for each vref|collection pair + t.true( + populated.keyVrefs.every(vref => + kvStore.has(`vom.ir.${vref}|${collectionID}`), + ), + ); + + // collect the Presences, which was the only remaining reachability + // pillar, leaving just the recognizers + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + // no changes to the collection + t.deepEqual(scanCollection(kvStore, collectionID), populated); + // but the Presence vrefs should be dropped + const gcCalls1 = log.filter(l => GC.includes(l.type)); + t.deepEqual(gcCalls1, [{ type: 'dropImports', slots: allVrefs }]); + log.length = 0; + + // now free the whole collection + gcTools.kill(recognizer); + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + + // the collection should be gone + const scan2 = scanCollection(kvStore, collectionID); + t.is(scan2.totalKeys, 0); + + // and the .ir entries + t.true( + populated.keyVrefs.every( + vref => !kvStore.has(`vom.ir.${vref}|${collectionID}`), + ), + ); + + // and the kernel should be notified that we don't care anymore + const gcCalls2 = log.filter(l => GC.includes(l.type)); + t.deepEqual(gcCalls2, [{ type: 'retireImports', slots: allVrefs }]); +}); + +// Allowing GC to delete a voAwareWeakSet (or Map) should retire the +// keys, and delete/release the contents. + +test('deleting a voAwareWeakSet will retire the keys', async t => { + const kvStore = new Map(); + const { syscall, log } = buildSyscall({ kvStore }); + const gcTools = makeMockGC(); + const COUNT = 5; + const allVrefs = []; + const allKslots = []; + for (let i = 0; i < COUNT; i += 1) { + const vref = `o-${i + 1}`; + allVrefs.push(vref); + allKslots.push(kslot(vref, 'imported')); + } + + let recognizer; + + // Import a bunch of Presences and hold them in a weakset. Drop the + // imports, but retain recognition, until we drop the weakset, which + // should delete the collection and notify the kernel that we aren't + // recognizing the keys (syscall.retireImports) + function build(vatPowers) { + recognizer = new vatPowers.WeakSet(); + const root = Far('root', { + create(presences) { + for (const p of presences) { + recognizer.add(p); + // we immediately delete the presence, but the finalizers + // won't run until gcTools.flushAllFRs() + gcTools.kill(p); + } + }, + }); + return root; + } + + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, () => ({ + buildRootObject: build, + })); + const { dispatch, testHooks } = ls; + const { vrefRecognizers } = testHooks; + await dispatch(makeStartVat(kser())); + log.length = 0; + + const rootA = 'o+0'; + + await dispatch(makeMessage(rootA, 'create', [allKslots])); + log.length = 0; + + // the WeakSet has no vref, and doesn't store anything like ".ir" + // entries in vatstore, but we can snoop on its internal + // tables. vrefRecognizers is a Map, keyed by vref, with an entry + // for every vref that is tracked by any voAwareWeakMap/Set. The + // value is a Set of virtualObjectMaps, the internal/hidden Set used + // by voAwareWeakMap/Sets. + + const vrefKeys = [...vrefRecognizers.keys()].sort(); + + // we should be tracking all the presences + t.is(vrefKeys.length, COUNT); + // each vref should have a single recognizer + t.true(vrefKeys.every(vref => vrefRecognizers.get(vref).size === 1)); + // that single recognizer should be the virtualObjectMap for our voAwareWeakSet + const virtualObjectMap = [...vrefRecognizers.get(vrefKeys[0])][0]; + // they should all point to the same one + t.true( + vrefKeys.every( + vref => [...vrefRecognizers.get(vref)][0] === virtualObjectMap, + ), + ); + + // collect the Presences, which was the only remaining reachability + // pillar, leaving just the recognizers + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + // no changes to the collection + t.is(vrefKeys.length, COUNT); + t.true(vrefKeys.every(vref => vrefRecognizers.get(vref).size === 1)); + t.true( + vrefKeys.every( + vref => [...vrefRecognizers.get(vref)][0] === virtualObjectMap, + ), + ); + + // but the Presence vrefs should be dropped + const gcCalls1 = log.filter(l => GC.includes(l.type)); + t.deepEqual(gcCalls1, [{ type: 'dropImports', slots: allVrefs }]); + log.length = 0; + + // now free the whole collection + gcTools.kill(recognizer); + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + + // the collection should be gone + t.is(vrefRecognizers.size, 0); + + // and the kernel should be notified that we don't care anymore + const gcCalls2 = log.filter(l => GC.includes(l.type)); + t.deepEqual(gcCalls2, [{ type: 'retireImports', slots: allVrefs }]); +}); + +// explore remediation/leftover problems from bugs #7355, #8756, #9956 +// where the DB has corrupted data leftover from before they were fixed + +test('missing recognition record during delete', async t => { + const kvStore = new Map(); + const { syscall, log } = buildSyscall({ kvStore }); + const gcTools = makeMockGC(); + + let recognizer; + let target; + + // liveslots didn't always add "vom.ir." recognition-records for + // Remotable-style keys, nor remove them when the key was + // deleted. So a kernel which adds a key, upgrades to the current + // (fixed) version, then attempts to delete the key, will not see + // the record it is expecting. Make sure this doesn't cause + // problems. + + function build(vatPowers) { + const { makeScalarBigWeakSetStore } = vatPowers.VatData; + recognizer = makeScalarBigWeakSetStore('recognizer'); + target = Far('target', {}); + const root = Far('root', { + store() { + recognizer.add(target); + }, + delete() { + recognizer.delete(target); + }, + }); + return root; + } + + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, () => ({ + buildRootObject: build, + })); + const { dispatch, testHooks } = ls; + const { valToSlot } = testHooks; + await dispatch(makeStartVat(kser())); + log.length = 0; + + const rootA = 'o+0'; + + await dispatch(makeMessage(rootA, 'store')); + log.length = 0; + + const targetVref = valToSlot.get(target); + const recognizerVref = valToSlot.get(recognizer); + const collectionID = Number(parseVatSlot(recognizerVref).subid); + const ordinalAssignmentKey = `vc.${collectionID}.|${targetVref}`; + const ordinalNumber = kvStore.get(ordinalAssignmentKey); + t.is(ordinalNumber, '1'); + const dataKey = `vc.${collectionID}.r0000000001:${targetVref}`; + const value = kvStore.get(dataKey); + t.deepEqual(JSON.parse(value), { body: '#null', slots: [] }); + + // the correct recognition record key + const rrKey = `vom.ir.${targetVref}|${collectionID}`; + + // our fixed version creates one + t.is(kvStore.get(rrKey), '1'); + + // now simulate data from the broken version, by deleting the + // recognition record + kvStore.delete(rrKey); + + // check that deleting the same Remotable doesn't break + await dispatch(makeMessage(rootA, 'delete')); + t.false(kvStore.has(ordinalAssignmentKey)); + t.false(kvStore.has(dataKey)); +}); + +// This test is marked as failing because we do not have any +// remediation code for #8756. Collections which were cleared before +// the fix will be corrupted, such that the old keys appear to still +// be present, even after the fix has been applied. This test +// demonstrates that we can still *not* handle the following sequence: +// +// * (in old version, without fix for #8756): +// * const c = makeScalarBigMapStore(); +// * const key = Far(); // or any remotable +// * c.add(key, 'value'); +// * c.clear(); +// * (then in new version, with fix) +// * assert.equal(c.has(key), false); +// * c.init(key, 'new value'); + +test.failing('leftover ordinal-assignment record during init', async t => { + const kvStore = new Map(); + const { syscall, log } = buildSyscall({ kvStore }); + const gcTools = makeMockGC(); + + let store; + let target; + /** @type {any} */ + let result; + + // liveslots didn't always remove the "vc.${collectionID}.|${vref}" + // ordinal-assignment records when clearing or deleting a + // collection. So a kernel which adds a key, upgrades to the current + // (fixed) version, then clears the collection, will have a leftover + // record. See if this will cause problems when iterating keys or + // re-adding the same key later. + + function build(vatPowers) { + const { makeScalarBigMapStore } = vatPowers.VatData; + store = makeScalarBigMapStore('store'); + target = Far('target', {}); + const root = Far('root', { + store() { + try { + store.init(target, 123); + result = 'ok'; + } catch (e) { + result = e; + } + }, + clear() { + store.clear(); + }, + has() { + result = store.has(target); + }, + }); + return root; + } + + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, () => ({ + buildRootObject: build, + })); + const { dispatch, testHooks } = ls; + const { valToSlot } = testHooks; + await dispatch(makeStartVat(kser())); + log.length = 0; + + const rootA = 'o+0'; + + result = undefined; + await dispatch(makeMessage(rootA, 'store')); + t.is(result, 'ok'); + + const targetVref = valToSlot.get(target); + const storeVref = valToSlot.get(store); + const collectionID = Number(parseVatSlot(storeVref).subid); + const ordinalAssignmentKey = `vc.${collectionID}.|${targetVref}`; + const ordinalNumber = kvStore.get(ordinalAssignmentKey); + t.is(ordinalNumber, '1'); + const dataKey = `vc.${collectionID}.r0000000001:${targetVref}`; + const value = kvStore.get(dataKey); + t.deepEqual(JSON.parse(value), { body: '#123', slots: [] }); + + result = undefined; + await dispatch(makeMessage(rootA, 'clear')); + + // now simulate data from the broken version, by restoring the + // ordinal-assignment record, as if the code failed to delete it + + kvStore.set(ordinalAssignmentKey, '1'); + + // problem 1: store.has() should report "false", but incorrectly + // returns "true" + + result = undefined; + await dispatch(makeMessage(rootA, 'has')); + t.is(result, false); + + // problem 2: store.init() to re-add the old key should succeed, but + // incorrectly fails (because the store thinks the key is already + // present) + + result = undefined; + await dispatch(makeMessage(rootA, 'store')); + t.is(result, 'ok'); + + // other likely problems: store.keys() will report the old key, + // store.get(oldkey) will probably crash +}); diff --git a/packages/swingset-liveslots/test/collections.test.js b/packages/swingset-liveslots/test/collections.test.js index 9a70d129b95..f4cc62bfbb9 100644 --- a/packages/swingset-liveslots/test/collections.test.js +++ b/packages/swingset-liveslots/test/collections.test.js @@ -145,6 +145,14 @@ function exerciseMapOperations(t, collectionName, testStore) { `key "[Alleged: something missing]" not found in collection "${collectionName}"`, ), ); + if (collectionName === 'map') { + // strong map, so we can .clear + testStore.clear(); + for (const [key, _value] of stuff) { + t.false(testStore.has(key)); + } + fillBasicMapStore(testStore); + } } function exerciseSetOperations(t, collectionName, testStore) { @@ -172,6 +180,14 @@ function exerciseSetOperations(t, collectionName, testStore) { `key "[Alleged: something missing]" not found in collection "${collectionName}"`, ), ); + if (collectionName === 'set') { + // strong set, so we can .clear + testStore.clear(); + for (const [key, _value] of stuff) { + t.false(testStore.has(key)); + } + fillBasicSetStore(testStore); + } } test('basic map operations', t => { @@ -487,6 +503,19 @@ test('map clear', t => { t.is(testStore.getSize(), 0); }); +test('map clear with pattern', t => { + const testStore = makeScalarBigMapStore('cmap', { keyShape: M.any() }); + testStore.init('a', 'ax'); + testStore.init('b', 'bx'); + testStore.init('c', 'cx'); + console.log(`M is`, M); + testStore.clear(M.eq('c')); + t.true(testStore.has('a')); + t.true(testStore.has('b')); + t.false(testStore.has('c')); + t.is(testStore.getSize(), 2); +}); + test('set clear', t => { const testStore = makeScalarBigSetStore('cset', { keyShape: M.any() }); testStore.add('a'); @@ -499,6 +528,18 @@ test('set clear', t => { t.is(testStore.getSize(), 0); }); +test('set clear with pattern', t => { + const testStore = makeScalarBigSetStore('cset', { keyShape: M.any() }); + testStore.add('a'); + testStore.add('b'); + testStore.add('c'); + testStore.clear(M.eq('c')); + t.true(testStore.has('a')); + t.true(testStore.has('b')); + t.false(testStore.has('c')); + t.is(testStore.getSize(), 2); +}); + test('map fail on concurrent modification', t => { const primeMap = makeScalarBigMapStore('fmap', { keyShape: M.number(), diff --git a/packages/swingset-liveslots/test/dropped-weakset-9939.test.js b/packages/swingset-liveslots/test/dropped-weakset-9939.test.js new file mode 100644 index 00000000000..251bfcaff4e --- /dev/null +++ b/packages/swingset-liveslots/test/dropped-weakset-9939.test.js @@ -0,0 +1,80 @@ +import test from 'ava'; +import { Far } from '@endo/marshal'; +import { kser, kslot } from '@agoric/kmarshal'; +import { makeLiveSlots } from '../src/liveslots.js'; +import { buildSyscall } from './liveslots-helpers.js'; +import { makeStartVat, makeMessage, makeBringOutYourDead } from './util.js'; +import { makeMockGC } from './mock-gc.js'; + +// Test for https://github.com/Agoric/agoric-sdk/issues/9939 + +test('weakset deletion vs retire', async t => { + const { syscall, log } = buildSyscall(); + const gcTools = makeMockGC(); + + // #9939 was a bug in liveslots that caused a vat to emit + // syscall.retireImports despite not having done dropImports + // first. The setup is: + // + // * import a Presence (raising the RAM pillar) + // * store it in a virtual object (raising the vdata pillar) + // * use it as a key of a voAwareWeakMap or voAwareWeakSet + // * drop the Presence (dropping the RAM pillar) + // * do a BOYD + // * delete the voAwareWeakSet + // * do a BOYD + // + // When the voAwareWeakSet is collected, a finalizer callback named + // finalizeDroppedCollection is called, which clears the entries, + // and adds all its vref keys to possiblyRetiredSet. Later, during + // BOYD, a loop examines possiblyRetiredSet and adds qualified vrefs + // to importsToRetire, for the syscall.retireImports at the end. + // + // That qualification check was sufficient to prevent the retirement + // of vrefs that still have a RAM pillar, and also vrefs that were + // being dropped in this particular BOYD, but it was not sufficient + // to protect vrefs that still have a vdata pillar. + + let myVOAwareWeakSet; + let myPresence; + function buildRootObject(vatPowers, _vatParameters, baggage) { + const { WeakSet } = vatPowers; + myVOAwareWeakSet = new WeakSet(); + return Far('root', { + store: p => { + myPresence = p; + myVOAwareWeakSet.add(p); + baggage.init('presence', p); + }, + }); + } + + const makeNS = () => ({ buildRootObject }); + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, makeNS); + const { dispatch } = ls; + await dispatch(makeStartVat(kser())); + t.truthy(myVOAwareWeakSet); + + await dispatch(makeMessage('o+0', 'store', [kslot('o-1')])); + t.truthy(myPresence); + + log.length = 0; + gcTools.kill(myPresence); + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + + log.length = 0; + gcTools.kill(myVOAwareWeakSet); + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + + // The imported vref is still reachable by the 'baggage' durable + // store, so it must not be dropped or retired yet. The bug caused + // the vref to be retired without first doing a drop, which is a + // vat-fatal syscall error + const gcCalls = log.filter( + l => l.type === 'dropImports' || l.type === 'retireImports', + ); + t.deepEqual(gcCalls, []); + log.length = 0; +}); diff --git a/packages/swingset-liveslots/test/gc-before-finalizer.test.js b/packages/swingset-liveslots/test/gc-before-finalizer.test.js new file mode 100644 index 00000000000..92a0955fb3d --- /dev/null +++ b/packages/swingset-liveslots/test/gc-before-finalizer.test.js @@ -0,0 +1,230 @@ +import test from 'ava'; +import { Far } from '@endo/marshal'; +import { kser, kslot } from '@agoric/kmarshal'; +import { makeLiveSlots } from '../src/liveslots.js'; +import { buildSyscall } from './liveslots-helpers.js'; +import { makeStartVat, makeMessage, makeBringOutYourDead } from './util.js'; +import { makeMockGC } from './mock-gc.js'; + +const justGC = log => + log.filter( + l => + l.type === 'dropImports' || + l.type === 'retireImports' || + l.type === 'retireExports', + ); + +test('presence in COLLECTED state is not dropped yet', async t => { + const { syscall, log } = buildSyscall(); + const gcTools = makeMockGC(); + + // our GC terminology (see boyd-gc.js for notes): + // * REACHABLE means userspace can reach a Presence + // * UNREACHABLE means it cannot + // * COLLECTED means the engine GC has noticed, so the + // slotToVal.get(vref) WeakRef is empty, even though + // slotToVal.has(vref) is still true. A finalizer + // callback has been queued. + // * FINALIZED means the callback has been run. Our callback does + // slotToVal.delete(vref) before adding the vref to + // possiblyDeadSet + + // slotToVal.has() returns true for REACHABLE / UNREACHABLE / + // COLLECTED, and false for FINALIZED. getValForSlot() is another + // way to probe for reachability, but it also looks to see if the + // WeakRef is full, so it returns false for both COLLECTED and + // FINALIZED. + + // We use slotToVal.has(vref) as the "is it still reachable" probe + // in scanForDeadObjects(), because if we have a Presence in the + // COLLECTED state, we must not dropImports it during this BOYD. The + // finalizer is still enqueued, so some future turn will run it, and + // the vref will be added to possiblyDeadSet again. We want the drop + // to happen exactly once, and we don't remove the finalizer from + // the queue, which means the drop must happen in the future BOYD. + + // We can get into this situation with the following sequence: + // 1: vref is held by both Presence and vdata + // 2: Presence is dropped by userspace (->UNREACHABLE) + // 3: userspace store.delete(), drops vdata refcount, addToPossiblyDeadSet + // 4: organic GC happens (->COLLECTED, WeakRef is empty) + // 5: BOYD is called (finalizer has not run yet) + + // The order of steps 3 and 4 is not important. What matters is that + // the WeakRef is empty, but the finalizer has not yet run, at the + // time that BOYD happens. And that the vref is in possiblyDeadSet + // (because of the vdata drop, not the finalizer), so this BOYD will + // examine the vref. + + // This test simulates this case with our mockGC tools. It would + // fail if boyd-gc.js used getValForSlot instead of slotToVal.has. + + // The GC code used to call getValForSlot() instead of + // slotToVal.has(), in the possiblyRetiredSet. The second test + // exercises this case, and would fail if it still used + // getValForSlot + + let myPresence; + function buildRootObject(vatPowers) { + const { VatData } = vatPowers; + const { makeScalarBigMapStore } = VatData; + const store = makeScalarBigMapStore(); + return Far('root', { + store: p => { + myPresence = p; + store.init('presence', p); + }, + drop: () => store.delete('presence'), + }); + } + + const makeNS = () => ({ buildRootObject }); + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, makeNS); + const { dispatch } = ls; + await dispatch(makeStartVat(kser())); + + await dispatch(makeMessage('o+0', 'store', [kslot('o-1')])); + t.truthy(myPresence); + + // clear out everything before our check + await dispatch(makeBringOutYourDead()); + log.length = 0; + + // drop the vdata reference + await dispatch(makeMessage('o+0', 'drop', [])); + log.length = 0; + + // and, before BOYD can happen, collect (but do not finalize) the Presence + gcTools.kill(myPresence); + + // now BOYD + await dispatch(makeBringOutYourDead()); + + // the BOYD must not have done dropImports or retireImports + t.deepEqual(log, []); + + // eventually, the finalizer runs + gcTools.flushAllFRs(); + + // *now* a BOYD will drop+retire + await dispatch(makeBringOutYourDead()); + t.deepEqual(justGC(log), [ + { type: 'dropImports', slots: ['o-1'] }, + { type: 'retireImports', slots: ['o-1'] }, + ]); +}); + +test('presence in COLLECTED state is not retired early', async t => { + const { syscall, log } = buildSyscall(); + const gcTools = makeMockGC(); + + // The GC code used to call getValForSlot() instead of + // slotToVal.has(), in the possiblyRetiredSet. This test would fail + // if it still used getValForSlot. + + // The setup is a Presence in the COLLECTED state as the only + // pillar, but not in possiblyDeadSet, whose vref also appears in + // possiblyRetiredSet (because a recognizer was just deleted). On + // the BOYD that handles the possiblyRetiredSet, the "reachability + // inhibits retirement" check should treat the COLLECTED state as + // reachable, so the retirement is deferred for a later BOYD (which + // would drop the vref first) + // + // To build this, we have an anchored (virtual) MapStore msA holding + // the only reference (vdata) to a (virtual) WeakSetStore wssB. wssB + // has one (weak) key, o-1, for which there is a Presence P. + // + // 1: Construct everything, kill the wssB Representative, BOYD. That + // will process wssB, but leave it alive because of the vdata in + // msA. + + // 2: Use msA.delete(key) to drop its vdata ref to wssB (adding wssB + // to possiblyDeadSet), and use gcTools.kill(P) to mock-mark it + // as COLLECTED (but not finalized) + + // 3: Do a BOYD. The first pass will see wssB is unreachable, and + // delete it. The collection deleter will put o-1 in + // possiblyRetiredSet. There might be a second pass (doMore=1), + // but it won't have anything in possiblyDeadSet and will do + // nothing. Then the post-deadSet loop will process + // possiblyRetiredSet, which will contain our o-1. That + // processing step contains the valToSlot.has (or the + // would-be-incorrect getValForSlot) that we want to exercise. + + let myPresence; + let myWeakStore; + + function buildRootObject(vatPowers) { + const { VatData } = vatPowers; + const { makeScalarBigMapStore, makeScalarBigWeakSetStore } = VatData; + const store = makeScalarBigMapStore(); + myWeakStore = makeScalarBigWeakSetStore(); + return Far('root', { + store: p => { + myPresence = p; + myWeakStore.add(p); + t.truthy(myWeakStore.has(p)); + store.init('weakstore', myWeakStore); + }, + dropWeakStore: () => store.delete('weakstore'), + }); + } + + const makeNS = () => ({ buildRootObject }); + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, makeNS); + const { dispatch, testHooks } = ls; + const { possiblyDeadSet, possiblyRetiredSet, slotToVal } = testHooks; + await dispatch(makeStartVat(kser())); + + // step 1 (setup): store, kill WeakSetStore representative, BOYD + await dispatch(makeMessage('o+0', 'store', [kslot('o-1')])); + t.truthy(myPresence); + gcTools.kill(myWeakStore); + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + log.length = 0; + + // myPresence vref is held by the Presence, and recognized by myWeakStore + t.is(possiblyDeadSet.size, 0); + t.is(possiblyRetiredSet.size, 0); + + // step 2: delete vdata ref to weakstore, make myPresence COLLECTED + await dispatch(makeMessage('o+0', 'dropWeakStore', [])); + gcTools.kill(myPresence); + log.length = 0; + // weakstore is possiblyDead (NARRATORS VOICE: it's dead). Presence + // is not, because the finalizer hasn't run. + t.is(possiblyDeadSet.size, 1); + t.is(possiblyRetiredSet.size, 0); + t.not([...possiblyDeadSet][0], 'o-1'); + // the empty weakref is still there + t.true(slotToVal.has('o-1')); + + // step 3: BOYD. It will collect myWeakStore on the first pass, + // whose deleter should clear all entries, which will add its + // recognized vrefs to possiblyRetiredSet. The post-pass will check + // o-1 for reachability with slotToVal.has, and because that says it + // is reachable, it will not be retired (even though it has no + // recognizer by now). + // + // *If* scanForDeadObjects() were mistakenly using getValForSlot() + // *instead of slotToVal.has(), we would see a retireImports here, + // *which would be a vat-fatal error, because we haven't seen a + // *dropImports yet. + await dispatch(makeBringOutYourDead()); + // I tested this manually, by modifying boyd-gc.js *to use + // getValForSlot, and observed that this deepEqual(justGC(log), []) + // failed: it had an unexpected retireImports + t.deepEqual(justGC(log), []); + log.length = 0; + + // eventually, the finalizer runs + gcTools.flushAllFRs(); + + // *now* a BOYD will drop+retire + await dispatch(makeBringOutYourDead()); + t.deepEqual(justGC(log), [ + { type: 'dropImports', slots: ['o-1'] }, + { type: 'retireImports', slots: ['o-1'] }, + ]); +}); diff --git a/packages/swingset-liveslots/test/handled-promises.test.js b/packages/swingset-liveslots/test/handled-promises.test.js index be97ea4219b..e9e7bd3c29e 100644 --- a/packages/swingset-liveslots/test/handled-promises.test.js +++ b/packages/swingset-liveslots/test/handled-promises.test.js @@ -84,7 +84,7 @@ const makeExoUtils = VatData => { }; // cf. packages/SwingSet/test/vat-durable-promise-watcher.js -const buildPromiseWatcherRootObject = (vatPowers, _vatParameters, baggage) => { +const buildPromiseWatcherRootObject = (vatPowers, vatParameters, baggage) => { const { VatData } = vatPowers; const { watchPromise } = VatData; const { prepareExo } = makeExoUtils(VatData); @@ -93,37 +93,62 @@ const buildPromiseWatcherRootObject = (vatPowers, _vatParameters, baggage) => { onFulfilled: M.call(M.any(), M.string()).returns(), onRejected: M.call(M.any(), M.string()).returns(), }); + const watchResolutions = new Map(); const watcher = prepareExo( baggage, + // No longer ignoring, but the name is set in stone in `kvStoreDataV1` 'DurablePromiseIgnorer', PromiseWatcherI, { - onFulfilled(_value, _name) {}, - onRejected(_reason, _name) {}, + onFulfilled(value, name) { + watchResolutions.set(name, { status: 'fulfilled', value }); + }, + onRejected(reason, name) { + watchResolutions.set(name, { status: 'rejected', reason }); + }, }, ); - const localPromises = new Map(); + const knownPromises = new Map(); - return Far('root', { - exportPromise: () => [Promise.resolve()], + const root = Far('root', { + getPromise: name => { + const promise = knownPromises.get(name); + promise || Fail`promise doesn't exists: ${name}`; + return { promise }; + }, + importPromise: (name, promise) => { + !knownPromises.has(name) || Fail`promise already exists: ${name}`; + knownPromises.set(name, promise); + return `imported promise: ${name}`; + }, createLocalPromise: (name, fulfillment, rejection) => { - !localPromises.has(name) || Fail`local promise already exists: ${name}`; + !knownPromises.has(name) || Fail`promise already exists: ${name}`; const { promise, resolve, reject } = makePromiseKit(); if (fulfillment !== undefined) { resolve(fulfillment); } else if (rejection !== undefined) { reject(rejection); } - localPromises.set(name, promise); + knownPromises.set(name, promise); return `created local promise: ${name}`; }, - watchLocalPromise: name => { - localPromises.has(name) || Fail`local promise not found: ${name}`; - watchPromise(localPromises.get(name), watcher, name); - return `watched local promise: ${name}`; + watchPromise: name => { + knownPromises.has(name) || Fail`promise not found: ${name}`; + watchPromise(knownPromises.get(name), watcher, name); + return `watched promise: ${name}`; + }, + getWatchResolution: name => { + return watchResolutions.get(name); }, }); + + const startOperations = vatParameters?.startOperations || []; + for (const [method, ...args] of startOperations) { + root[method](...args); + } + + return root; }; const kvStoreDataV1 = Object.entries({ baggageID: 'o+d6/1', @@ -176,23 +201,55 @@ const kvStoreDataV1VpidsToKeep = ['p-8']; const kvStoreDataV1KeysToKeep = ['vc.4.sp-8']; test('past-incarnation watched promises', async t => { + const S = 'settlement'; + // Anchor promise counters upon which the other assertions depend. + const firstPImport = 9; + // cf. src/liveslots.js:initialIDCounters + const firstPExport = 5; + + const startImportedP = firstPImport - 2; + + const v1StartOperations = [ + ['createLocalPromise', 'start orphaned'], + ['watchPromise', 'start orphaned'], + ['createLocalPromise', 'start fulfilled', S], + ['watchPromise', 'start fulfilled'], + ['importPromise', 'start imported', kslot(`p-${startImportedP}`)], + ['watchPromise', 'start imported'], + ]; const kvStore = new Map(); - let { v, dispatch, dispatchMessage } = await setupTestLiveslots( + let { + v, + dispatch, + dispatchMessage: rawDispatch, + } = await setupTestLiveslots( t, buildPromiseWatcherRootObject, 'durable-promise-watcher', - { kvStore }, + { + kvStore, + nextPromiseImportNumber: firstPImport, + vatParameters: { startOperations: v1StartOperations }, + }, ); let vatLogs = v.log; - // Anchor promise counters upon which the other assertions depend. - const firstPImport = 1; - // cf. src/liveslots.js:initialIDCounters - const firstPExport = 5; let lastPImport = firstPImport - 1; let lastPExport = firstPExport - 1; + let dispatches = 0; + const exportedPromises = new Set(); + const v1OrphanedPExports = []; const nextPImport = () => (lastPImport += 1); const nextPExport = () => (lastPExport += 1); + /** @type {typeof rawDispatch} */ + const dispatchMessage = (...args) => { + dispatches += 1; + return rawDispatch(...args); + }; + const recordExportedPromise = name => { + exportedPromises.add(name); + return name; + }; // Ignore vatstore syscalls. const getDispatchLogs = () => vatLogs.splice(0).filter(m => !m.type.startsWith('vatstore')); @@ -208,18 +265,55 @@ test('past-incarnation watched promises', async t => { type: 'subscribe', target: vpid, }); - vatLogs.length = 0; - await dispatchMessage('exportPromise'); + + // startVat logs + v1OrphanedPExports.push(nextPExport()); + recordExportedPromise('start orphaned'); + v1OrphanedPExports.push(nextPExport()); + recordExportedPromise('start fulfilled'); t.deepEqual(getDispatchLogs(), [ - fulfillmentMessage(`p-${nextPImport()}`, [kslot(`p+${nextPExport()}`)]), - fulfillmentMessage(`p+${lastPExport}`, undefined), + subscribeMessage(`p-${startImportedP}`), + subscribeMessage(`p+${lastPExport - 1}`), + subscribeMessage(`p+${lastPExport}`), + fulfillmentMessage(`p+${lastPExport}`, S), + ]); + await dispatchMessage('createLocalPromise', 'exported', S); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, 'created local promise: exported'), + ]); + await dispatchMessage('getPromise', recordExportedPromise('exported')); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + promise: kslot(`p+${nextPExport()}`), + }), + fulfillmentMessage(`p+${lastPExport}`, S), + ]); + const importedP = firstPImport - 1; + await dispatchMessage('importPromise', 'imported', kslot(`p-${importedP}`)); + t.deepEqual(getDispatchLogs(), [ + subscribeMessage(`p-${importedP}`), + fulfillmentMessage(`p-${nextPImport()}`, 'imported promise: imported'), ]); - - const S = 'settlement'; await dispatchMessage('createLocalPromise', 'orphaned'); t.deepEqual(getDispatchLogs(), [ fulfillmentMessage(`p-${nextPImport()}`, 'created local promise: orphaned'), ]); + await dispatchMessage('createLocalPromise', 'orphaned exported'); + await dispatchMessage( + 'getPromise', + recordExportedPromise('orphaned exported'), + ); + const orphanedExportedP = nextPExport(); + v1OrphanedPExports.push(orphanedExportedP); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage( + `p-${nextPImport()}`, + 'created local promise: orphaned exported', + ), + fulfillmentMessage(`p-${nextPImport()}`, { + promise: kslot(`p+${orphanedExportedP}`), + }), + ]); await dispatchMessage('createLocalPromise', 'fulfilled', S); t.deepEqual(getDispatchLogs(), [ fulfillmentMessage( @@ -233,68 +327,185 @@ test('past-incarnation watched promises', async t => { ]); t.is( lastPImport - firstPImport + 1, - 4, - 'imported 4 promises (1 per dispatch)', + dispatches, + `imported ${dispatches} promises (1 per dispatch)`, + ); + t.is( + lastPExport - firstPExport + 1, + exportedPromises.size, + `exported ${exportedPromises.size} promises: ${[...exportedPromises].join(', ')}`, ); - t.is(lastPExport - firstPExport + 1, 1, 'exported 1 promise: first'); - await dispatchMessage('watchLocalPromise', 'orphaned'); + await dispatchMessage('watchPromise', recordExportedPromise('orphaned')); + v1OrphanedPExports.push(nextPExport()); t.deepEqual(getDispatchLogs(), [ - subscribeMessage(`p+${nextPExport()}`), - fulfillmentMessage(`p-${nextPImport()}`, 'watched local promise: orphaned'), + subscribeMessage(`p+${lastPExport}`), + fulfillmentMessage(`p-${nextPImport()}`, 'watched promise: orphaned'), ]); - await dispatchMessage('watchLocalPromise', 'fulfilled'); + await dispatchMessage('watchPromise', recordExportedPromise('fulfilled')); t.deepEqual(getDispatchLogs(), [ subscribeMessage(`p+${nextPExport()}`), - fulfillmentMessage( - `p-${nextPImport()}`, - 'watched local promise: fulfilled', - ), + fulfillmentMessage(`p-${nextPImport()}`, 'watched promise: fulfilled'), fulfillmentMessage(`p+${lastPExport}`, S), ]); - await dispatchMessage('watchLocalPromise', 'rejected'); + await dispatchMessage('watchPromise', recordExportedPromise('rejected')); t.deepEqual(getDispatchLogs(), [ subscribeMessage(`p+${nextPExport()}`), - fulfillmentMessage(`p-${nextPImport()}`, 'watched local promise: rejected'), + fulfillmentMessage(`p-${nextPImport()}`, 'watched promise: rejected'), rejectionMessage(`p+${lastPExport}`, S), ]); + await dispatchMessage('watchPromise', 'imported'); + t.deepEqual(getDispatchLogs(), [ + // no subscribe, we already did at import + fulfillmentMessage(`p-${nextPImport()}`, 'watched promise: imported'), + ]); + await dispatchMessage('getWatchResolution', 'fulfilled'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'fulfilled', + value: S, + }), + ]); + await dispatchMessage('getWatchResolution', 'rejected'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'rejected', + reason: S, + }), + ]); + await dispatchMessage('getWatchResolution', 'start fulfilled'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'fulfilled', + value: S, + }), + ]); + t.is( lastPImport - firstPImport + 1, - 7, - 'imported 7 promises (1 per dispatch)', + dispatches, + `imported ${dispatches} promises (1 per dispatch)`, ); t.is( lastPExport - firstPExport + 1, - 4, - 'exported 4 promises: first, orphaned, fulfilled, rejected', + exportedPromises.size, + `exported ${exportedPromises.size} promises: ${[...exportedPromises].join(', ')}`, ); // Simulate upgrade by starting from the non-empty kvStore. // t.log(Object.fromEntries([...kvStore.entries()].sort(compareEntriesByKey))); const clonedStore = new Map(kvStore); - ({ v, dispatch, dispatchMessage } = await setupTestLiveslots( + const startImported2P = firstPImport - 3; + const v2StartOperations = [ + ['importPromise', 'start imported 2', kslot(`p-${startImported2P}`)], // import of new promise + ['importPromise', 'imported', kslot(`p-${importedP}`)], // import previously imported and watched promise + ['importPromise', 'orphaned exported', kslot(`p+${orphanedExportedP}`)], // import previously exported but unwatched promise + ['watchPromise', 'orphaned exported'], + ]; + ({ + v, + dispatch, + dispatchMessage: rawDispatch, + } = await setupTestLiveslots( t, buildPromiseWatcherRootObject, 'durable-promise-watcher-v2', - { kvStore: clonedStore, nextPromiseImportNumber: lastPImport + 1 }, + { + kvStore: clonedStore, + nextPromiseImportNumber: lastPImport + 1, + vatParameters: { startOperations: v2StartOperations }, + }, )); vatLogs = v.log; + // startVat logs + t.deepEqual(getDispatchLogs(), [ + subscribeMessage(`p-${startImported2P}`), + subscribeMessage(`p-${importedP}`), + subscribeMessage(`p+${orphanedExportedP}`), + ]); // Simulate kernel rejection of promises orphaned by termination/upgrade of their decider vat. const expectedDeletions = [...clonedStore.entries()].filter(entry => entry[1].includes('orphaned'), ); t.true(expectedDeletions.length >= 1); - await dispatch( - makeReject(`p+${firstPExport + 1}`, kser('tomorrow never came')), - ); + for (const orphanedPExport of v1OrphanedPExports) { + await dispatch( + makeReject(`p+${orphanedPExport}`, kser('tomorrow never came')), + ); + } + await dispatchMessage('getWatchResolution', 'orphaned'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'rejected', + reason: 'tomorrow never came', + }), + ]); + await dispatchMessage('getWatchResolution', 'start orphaned'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'rejected', + reason: 'tomorrow never came', + }), + ]); + await dispatchMessage('getWatchResolution', 'orphaned exported'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'rejected', + reason: 'tomorrow never came', + }), + ]); for (const [key, value] of expectedDeletions) { t.false(clonedStore.has(key), `entry should be removed: ${key}: ${value}`); } + // Simulate resolution of imported promises watched in previous incarnation + await dispatch(makeResolve(`p-${importedP}`, kser(undefined))); + await dispatchMessage('getWatchResolution', 'imported'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'fulfilled', + value: undefined, + }), + ]); + await dispatch(makeResolve(`p-${startImportedP}`, kser(undefined))); + await dispatchMessage('getWatchResolution', 'start imported'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'fulfilled', + value: undefined, + }), + ]); + await dispatch(makeResolve(`p-${startImported2P}`, kser(undefined))); + await dispatchMessage('getWatchResolution', 'start imported 2'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, undefined), + ]); + // simulate resolution of imported promise watched after resolution + await dispatchMessage('watchPromise', 'start imported 2'); + t.deepEqual(getDispatchLogs(), [ + // Promise was previously resolved, so it is re-exported + subscribeMessage(`p+${nextPExport()}`), + fulfillmentMessage( + `p-${nextPImport()}`, + 'watched promise: start imported 2', + ), + fulfillmentMessage(`p+${lastPExport}`, undefined), + ]); + await dispatchMessage('getWatchResolution', 'start imported 2'); + t.deepEqual(getDispatchLogs(), [ + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'fulfilled', + value: undefined, + }), + ]); // Verify that the data is still in loadable condition. const finalClonedStore = new Map(clonedStore); - ({ v, dispatch, dispatchMessage } = await setupTestLiveslots( + ({ + v, + dispatch, + dispatchMessage: rawDispatch, + } = await setupTestLiveslots( t, buildPromiseWatcherRootObject, 'durable-promise-watcher-final', @@ -303,12 +514,17 @@ test('past-incarnation watched promises', async t => { vatLogs = v.log; vatLogs.length = 0; await dispatchMessage('createLocalPromise', 'final', S); - await dispatchMessage('watchLocalPromise', 'final'); + await dispatchMessage('watchPromise', 'final'); + await dispatchMessage('getWatchResolution', 'final'); t.deepEqual(getDispatchLogs(), [ fulfillmentMessage(`p-${nextPImport()}`, 'created local promise: final'), subscribeMessage(`p+${nextPExport()}`), - fulfillmentMessage(`p-${nextPImport()}`, 'watched local promise: final'), + fulfillmentMessage(`p-${nextPImport()}`, 'watched promise: final'), fulfillmentMessage(`p+${lastPExport}`, S), + fulfillmentMessage(`p-${nextPImport()}`, { + status: 'fulfilled', + value: S, + }), ]); }); diff --git a/packages/swingset-liveslots/test/liveslots-helpers.js b/packages/swingset-liveslots/test/liveslots-helpers.js index 8926bf72d16..e2f8c41feb7 100644 --- a/packages/swingset-liveslots/test/liveslots-helpers.js +++ b/packages/swingset-liveslots/test/liveslots-helpers.js @@ -131,6 +131,7 @@ export async function makeDispatch( build, vatID = 'vatA', liveSlotsOptions = {}, + vatParameters = undefined, ) { const gcTools = harden({ WeakRef, @@ -150,7 +151,7 @@ export async function makeDispatch( return { buildRootObject: build }; }, ); - await dispatch(['startVat', kser()]); + await dispatch(['startVat', kser(vatParameters)]); return { dispatch, testHooks }; } @@ -171,6 +172,7 @@ function makeRPMaker(nextNumber = 1) { * @param {Map} [options.kvStore] * @param {number} [options.nextPromiseImportNumber] * @param {boolean} [options.skipLogging] + * @param {any} [options.vatParameters] */ export async function setupTestLiveslots( t, @@ -183,6 +185,7 @@ export async function setupTestLiveslots( kvStore = new Map(), nextPromiseImportNumber, skipLogging = false, + vatParameters, } = options; const { log, syscall, fakestore } = buildSyscall({ skipLogging, kvStore }); const nextRP = makeRPMaker(nextPromiseImportNumber); @@ -190,6 +193,8 @@ export async function setupTestLiveslots( syscall, buildRootObject, vatName, + {}, + vatParameters, ); async function dispatchMessage(message, ...args) { diff --git a/packages/swingset-liveslots/test/liveslots-mock-gc.test.js b/packages/swingset-liveslots/test/liveslots-mock-gc.test.js index d7cff5d0967..1ab290c621b 100644 --- a/packages/swingset-liveslots/test/liveslots-mock-gc.test.js +++ b/packages/swingset-liveslots/test/liveslots-mock-gc.test.js @@ -11,6 +11,7 @@ import { makeStartVat, makeBringOutYourDead, makeResolve, + makeRetireImports, } from './util.js'; import { makeMockGC } from './mock-gc.js'; @@ -465,3 +466,101 @@ for (const firstType of ['object', 'collection']) { } // test('double-free', doublefreetest, { firstType: 'object', lastType: 'collection', order: 'first->last' }); + +test('retirement', async t => { + const { syscall, fakestore, log } = buildSyscall(); + const gcTools = makeMockGC(); + + // A is a weak collection, with one entry, whose key is B (a + // Presence). We drop the RAM pillar for B and do a BOYD, which + // should provoke a syscall.dropImports. Then, when we delete A (by + // dropping the RAM pillar), the next BOYD should see a + // `syscall.retireImports`. + + let weakmapA; + let presenceB; + + function buildRootObject(vatPowers) { + const { VatData } = vatPowers; + const { makeScalarBigWeakMapStore } = VatData; + + weakmapA = makeScalarBigWeakMapStore(); + + return Far('root', { + add: p => { + presenceB = p; + weakmapA.init(presenceB, 'value'); + }, + }); + } + + const makeNS = () => ({ buildRootObject }); + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, makeNS); + const { dispatch, testHooks } = ls; + const { valToSlot } = testHooks; + + await dispatch(makeStartVat(kser())); + log.length = 0; + const weakmapAvref = valToSlot.get(weakmapA); + const { subid } = parseVatSlot(weakmapAvref); + const collectionID = String(subid); + + const rootA = 'o+0'; + const presenceBvref = 'o-1'; + await dispatch(makeMessage(rootA, 'add', [kslot(presenceBvref)])); + log.length = 0; + + // the fact that weakmapA can recognize presenceA is recorded in a + // vatstore key + const recognizerKey = `vom.ir.${presenceBvref}|${collectionID}`; + t.is(fakestore.get(recognizerKey), '1'); + + // tell mockGC that userspace has dropped presenceB + gcTools.kill(presenceB); + gcTools.flushAllFRs(); + + await dispatch(makeBringOutYourDead()); + const priorKey = `vom.ir.${presenceBvref}|`; + + t.deepEqual(log.splice(0), [ + // when a Presence is dropped, scanForDeadObjects can't drop the + // underlying vref import until it knows that virtual data isn't + // holding a reference, so we expect a refcount check + { type: 'vatstoreGet', key: `vom.rc.${presenceBvref}`, result: undefined }, + + // the vref is now in importsToDrop, but since this commonly means + // it can be retired too, scanForDeadObjects goes ahead and checks + // for recognizers + { type: 'vatstoreGetNextKey', priorKey, result: recognizerKey }, + + // it found a recognizer, so the vref cannot be retired + // yet. scanForDeadObjects finishes the BOYD by emitting the + // dropImports, but should keep watching for an opportunity to + // retire it too + { type: 'dropImports', slots: [presenceBvref] }, + ]); + + // now tell mockGC that we're dropping the weakmap too + gcTools.kill(weakmapA); + gcTools.flushAllFRs(); + + // this will provoke the deletion of the collection and all its + // data. It should *also* trigger a syscall.retireImports of the + // no-longer-recognizable key + await dispatch(makeBringOutYourDead()); + const retires = log.filter(e => e.type === 'retireImports'); + + t.deepEqual(retires, [{ type: 'retireImports', slots: [presenceBvref] }]); + + // If the bug is present, the vat won't send `syscall.retireImports` + // to the kernel. In a full system, that means the kernel can + // eventually send a `dispatch.retireImports` into the vat, if/when + // the object's hosting vat decides to drop it. Make sure that won't + // cause a crash. + + if (!retires.length) { + console.log(`testing kernel's dispatch.retireImports`); + await dispatch(makeRetireImports(presenceBvref)); + console.log(`dispatch.retireImports did not crash`); + } +}); diff --git a/packages/swingset-liveslots/test/liveslots-real-gc.test.js b/packages/swingset-liveslots/test/liveslots-real-gc.test.js index 8832eb04546..80641d82a44 100644 --- a/packages/swingset-liveslots/test/liveslots-real-gc.test.js +++ b/packages/swingset-liveslots/test/liveslots-real-gc.test.js @@ -308,6 +308,14 @@ test.serial('GC dispatch.dropExports', async t => { // that should allow ex1 to be collected t.true(collected.result); + // upon collection, the vat should scan for local recognizers (weak + // collection keys) in case any need to be dropped, and find none + t.deepEqual(log.shift(), { + type: 'vatstoreGetNextKey', + priorKey: `vom.ir.${ex1}|`, + result: 'vom.rc.o+d6/1', + }); + // and once it's collected, the vat should emit `syscall.retireExport` // because nobody else will be able to recognize it again const l2 = log.shift(); @@ -394,8 +402,16 @@ test.serial( // which should let the export be collected t.true(collected.result); - // the vat should *not* emit `syscall.retireExport`, because it already - // received a dispatch.retireExport + // the vat should scan for local recognizers (weak collection + // keys) in case any need to be dropped, and find none + t.deepEqual(log.shift(), { + type: 'vatstoreGetNextKey', + priorKey: 'vom.ir.o+10|', + result: 'vom.rc.o+d6/1', + }); + + // the vat should *not* emit `syscall.retireExport`, because it + // already received a dispatch.retireExport t.deepEqual(log, []); }, ); diff --git a/packages/swingset-liveslots/test/vat-environment.test.js b/packages/swingset-liveslots/test/vat-environment.test.js new file mode 100644 index 00000000000..96b7f111089 --- /dev/null +++ b/packages/swingset-liveslots/test/vat-environment.test.js @@ -0,0 +1,65 @@ +// @ts-nocheck +import '@endo/init/debug.js'; +import test from 'ava'; +import { Far } from '@endo/marshal'; +import { kser } from '@agoric/kmarshal'; +import { passStyleOf } from '@endo/pass-style'; +import { PassStyleOfEndowmentSymbol } from '@endo/pass-style/endow.js'; +import { makeLiveSlots } from '../src/index.js'; +import { makeStartVat } from './util.js'; +import { buildSyscall } from './liveslots-helpers.js'; +import { makeMockGC } from './mock-gc.js'; + +test('vat globals', async t => { + const { syscall } = buildSyscall(); + const gcTools = makeMockGC(); + const buildRootObject = () => Far('root', {}); + let called = 0; + let vatGlobals; + let inescapableGlobalProperties; + const vatNS = harden({ buildRootObject }); + // buildVatNamespace + const bVN = async (vG, iGP) => { + called += 1; + vatGlobals = vG; + inescapableGlobalProperties = iGP; + return vatNS; + }; + + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, bVN); + t.is(called, 0); // not called yet + await ls.dispatch(makeStartVat(kser())); + t.is(called, 1); + t.truthy(vatGlobals); + + // 'harden' is provided by SES (installed by the lockdown bundle), + // not liveslots + t.is(typeof vatGlobals.harden, 'undefined'); + + // but liveslots provides VatData + t.is(typeof vatGlobals.VatData, 'object'); + t.is(typeof vatGlobals.VatData, 'object'); + t.is(typeof vatGlobals.VatData.defineKind, 'function'); + t.is(typeof vatGlobals.VatData.defineKindMulti, 'function'); + t.is(typeof vatGlobals.VatData.defineDurableKind, 'function'); + t.is(typeof vatGlobals.VatData.defineDurableKindMulti, 'function'); + t.is(typeof vatGlobals.VatData.makeKindHandle, 'function'); + t.is(typeof vatGlobals.VatData.canBeDurable, 'function'); + t.is(typeof vatGlobals.VatData.providePromiseWatcher, 'function'); + t.is(typeof vatGlobals.VatData.watchPromise, 'function'); + t.is(typeof vatGlobals.VatData.makeScalarBigMapStore, 'function'); + t.is(typeof vatGlobals.VatData.makeScalarBigWeakMapStore, 'function'); + t.is(typeof vatGlobals.VatData.makeScalarBigSetStore, 'function'); + t.is(typeof vatGlobals.VatData.makeScalarBigWeakSetStore, 'function'); + + t.is(typeof inescapableGlobalProperties.WeakMap, 'function'); + t.not(inescapableGlobalProperties.WeakMap, WeakMap); + t.is(typeof inescapableGlobalProperties.WeakSet, 'function'); + t.not(inescapableGlobalProperties.WeakSet, WeakSet); + t.is( + typeof inescapableGlobalProperties[PassStyleOfEndowmentSymbol], + 'function', + ); + // this is the passStyleOf created by liveslots, with a real WeakMap + t.is(inescapableGlobalProperties[PassStyleOfEndowmentSymbol], passStyleOf); +}); diff --git a/packages/swingset-liveslots/test/vpid-liveslots.test.js b/packages/swingset-liveslots/test/vpid-liveslots.test.js index 2aa0f5d6275..9257a15cdbc 100644 --- a/packages/swingset-liveslots/test/vpid-liveslots.test.js +++ b/packages/swingset-liveslots/test/vpid-liveslots.test.js @@ -898,3 +898,104 @@ test('inter-vat circular promise references', async t => { // }); // t.deepEqual(log, []); }); + +test('accept previously allocated promise', async t => { + function build(vatPowers, vatParameters) { + const { target } = vatParameters; + return Far('root', { + call() { + const promise = E(target).foo(); + // wrap to avoid adoption + return { promise }; + }, + async waitFor(promise2) { + // if we're in the same incarnation as the `E(target).foo()`, this + // `promise2` will be the same JS Promise as the `promise` above + const v = await promise2; + return v; + }, + }); + } + + let log; + let syscall; + let dispatch; + + const kvStore = new Map(); + ({ log, syscall } = buildSyscall({ kvStore })); + + const target = 'o-1'; + ({ dispatch } = await makeDispatch( + syscall, + build, + 'reimport-promise', + {}, + { target: kslot(target) }, + )); + log.length = 0; // assume pre-build vatstore operations are correct + + const root = 'o+0'; + const callResultP = 'p-1'; + const waitForResultP = 'p-2'; + const expectedP1 = 'p+5'; + + await dispatch(makeMessage(root, 'call', [], callResultP)); + + // The vat should send 'foo', subscribe to the result promise, and resolve with that promise + t.deepEqual(log.splice(0, 3), [ + { + type: 'send', + targetSlot: target, + methargs: kser(['foo', []]), + resultSlot: expectedP1, + }, + { type: 'subscribe', target: expectedP1 }, + { + type: 'resolve', + resolutions: [[callResultP, false, kser({ promise: kslot(expectedP1) })]], + }, + ]); + matchIDCounterSet(t, log); + t.deepEqual(log, []); + + // snapshot the store at this point + const clonedStore = new Map(kvStore); + + const verifyPromiseReImport = async shouldSubscribe => { + await dispatch( + makeMessage(root, 'waitFor', [kslot(expectedP1)], waitForResultP), + ); + + // The vat will only subscribe if it was upgraded; if the vat still + // remembers it, receiving the vref will merely look it up in slotToVal and + // not create a new Promise (and trigger a subscribe) + if (shouldSubscribe) { + t.deepEqual(log.shift(), { type: 'subscribe', target: expectedP1 }); + } + + // waitFor will suspend until promise is resolved + t.deepEqual(log, []); + + // Resolution propagates the value to the waitFor result + await dispatch(makeResolve(expectedP1, kser('success'))); + t.deepEqual(log.shift(), { + type: 'resolve', + resolutions: [[waitForResultP, false, kser('success')]], + }); + t.deepEqual(log, []); + }; + + await verifyPromiseReImport(false); + ({ log, syscall } = buildSyscall({ kvStore: clonedStore })); + ({ dispatch } = await makeDispatch( + syscall, + build, + 'reimport-promise-v2', + {}, + {}, + )); + log.length = 0; + + // verify this works the same in the restarted vat + await verifyPromiseReImport(true); +}); diff --git a/packages/swingset-liveslots/test/weakset-dropped-remotable.test.js b/packages/swingset-liveslots/test/weakset-dropped-remotable.test.js new file mode 100644 index 00000000000..76618297370 --- /dev/null +++ b/packages/swingset-liveslots/test/weakset-dropped-remotable.test.js @@ -0,0 +1,50 @@ +import test from 'ava'; +import { Far } from '@endo/marshal'; +import { kser, kslot } from '@agoric/kmarshal'; +import { makeLiveSlots } from '../src/liveslots.js'; +import { buildSyscall } from './liveslots-helpers.js'; +import { makeStartVat, makeMessage, makeBringOutYourDead } from './util.js'; +import { makeMockGC } from './mock-gc.js'; + +// Test for https://github.com/Agoric/agoric-sdk/issues/9956 + +test('delete remotable key from weakset', async t => { + const { syscall, log } = buildSyscall(); + const gcTools = makeMockGC(); + const rem = Far('remotable', {}); + + function buildRootObject(vatPowers) { + const { VatData } = vatPowers; + const { makeScalarBigWeakMapStore } = VatData; + const wms = makeScalarBigWeakMapStore(); + return Far('root', { + store: p => { + wms.init(rem, p); + gcTools.kill(p); + }, + }); + } + + const makeNS = () => ({ buildRootObject }); + const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, makeNS); + const { dispatch } = ls; + await dispatch(makeStartVat(kser())); + + await dispatch(makeMessage('o+0', 'store', [kslot('o-1')])); + + // pretend the Remotable was dropped from RAM + log.length = 0; + gcTools.kill(rem); + gcTools.flushAllFRs(); + await dispatch(makeBringOutYourDead()); + + // that ought to emit a drop and retire for the presence + const gcCalls = log.filter( + l => l.type === 'dropImports' || l.type === 'retireImports', + ); + t.deepEqual(gcCalls, [ + { type: 'dropImports', slots: ['o-1'] }, + { type: 'retireImports', slots: ['o-1'] }, + ]); + log.length = 0; +}); diff --git a/packages/swingset-liveslots/tools/setup-vat-data.js b/packages/swingset-liveslots/tools/setup-vat-data.js index 7ffa9e37224..c3781d904ce 100644 --- a/packages/swingset-liveslots/tools/setup-vat-data.js +++ b/packages/swingset-liveslots/tools/setup-vat-data.js @@ -1,8 +1,13 @@ // @ts-check /* global globalThis */ -// This file produces the globalThis.VatData property outside of a running -// SwingSet so that it can be used by '@agoric/vat-data' (which only *consumes* -// `globalThis.VatData`) in code under test. + +// This file produces the globalThis.VatData property outside of a +// running SwingSet so that it can be used by '@agoric/vat-data' +// (which only *consumes* `globalThis.VatData`) in code under test. It +// also populates the passStyleOf symbol-named property. + +import { passStyleOf } from '@endo/pass-style'; +import { PassStyleOfEndowmentSymbol } from '@endo/pass-style/endow.js'; import { makeFakeVirtualStuff } from './fakeVirtualSupport.js'; const { WeakMap, WeakSet } = globalThis; @@ -37,6 +42,8 @@ globalThis.VatData = harden({ fakeVomKit.cm.makeScalarBigWeakSetStore(...args), }); +globalThis[PassStyleOfEndowmentSymbol] = passStyleOf; + export const reincarnate = (options = {}) => { const { fakeStore = new Map(), fakeVomKit: fvk } = options; diff --git a/packages/swingset-runner/package.json b/packages/swingset-runner/package.json index e5315a01019..71e2b3a378b 100644 --- a/packages/swingset-runner/package.json +++ b/packages/swingset-runner/package.json @@ -19,7 +19,7 @@ "ci:autobench": "./autobench.js" }, "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/deploy-script-support": "^0.10.3", "@agoric/ertp": "^0.16.2", "@agoric/internal": "^0.3.2", @@ -32,11 +32,11 @@ "@agoric/telemetry": "^0.6.2", "@agoric/vat-data": "^0.5.2", "@agoric/zoe": "^0.26.2", - "@endo/bundle-source": "^3.2.3", - "@endo/eventual-send": "^1.2.2", - "@endo/init": "^1.1.2", - "@endo/marshal": "^1.5.0", - "@endo/nat": "^5.0.7", + "@endo/bundle-source": "^3.4.0", + "@endo/eventual-send": "^1.2.5", + "@endo/init": "^1.1.4", + "@endo/marshal": "^1.5.3", + "@endo/nat": "^5.0.10", "expose-gc": "^1.0.0", "n-readlines": "^1.0.1", "yargs": "^16.1.0" diff --git a/packages/swingset-xsnap-supervisor/package.json b/packages/swingset-xsnap-supervisor/package.json index eeaddddf5ae..2e5b416796c 100644 --- a/packages/swingset-xsnap-supervisor/package.json +++ b/packages/swingset-xsnap-supervisor/package.json @@ -23,12 +23,12 @@ "test:xs": "exit 0" }, "devDependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/swingset-liveslots": "^0.10.2", - "@endo/bundle-source": "^3.2.3", - "@endo/import-bundle": "^1.1.2", - "@endo/init": "^1.1.2", - "@endo/marshal": "^1.5.0", + "@endo/bundle-source": "^3.4.0", + "@endo/import-bundle": "^1.2.2", + "@endo/init": "^1.1.4", + "@endo/marshal": "^1.5.3", "ava": "^5.3.0", "c8": "^9.1.0" }, diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index f4d3b6e189f..2527ceb50a2 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -22,12 +22,12 @@ "author": "Agoric", "license": "Apache-2.0", "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/internal": "^0.3.2", "@agoric/store": "^0.9.2", - "@endo/init": "^1.1.2", - "@endo/marshal": "^1.5.0", - "@endo/stream": "^1.2.2", + "@endo/init": "^1.1.4", + "@endo/marshal": "^1.5.3", + "@endo/stream": "^1.2.5", "@opentelemetry/api": "~1.3.0", "@opentelemetry/exporter-prometheus": "~0.35.0", "@opentelemetry/exporter-trace-otlp-http": "~0.35.0", @@ -40,8 +40,8 @@ "tmp": "^0.2.1" }, "devDependencies": { - "@endo/lockdown": "^1.0.7", - "@endo/ses-ava": "^1.2.2", + "@endo/lockdown": "^1.0.10", + "@endo/ses-ava": "^1.2.5", "ava": "^5.3.0", "c8": "^9.1.0", "tmp": "^0.2.1" diff --git a/packages/telemetry/src/make-slog-sender.js b/packages/telemetry/src/make-slog-sender.js index 5eb56aa65c5..94693661087 100644 --- a/packages/telemetry/src/make-slog-sender.js +++ b/packages/telemetry/src/make-slog-sender.js @@ -1,6 +1,6 @@ import path from 'path'; import tmp from 'tmp'; -import { PromiseAllOrErrors } from '@agoric/internal/src/node/utils.js'; +import { PromiseAllOrErrors } from '@agoric/internal'; import { serializeSlogObj } from './serialize-slog-obj.js'; export const DEFAULT_SLOGSENDER_MODULE = diff --git a/packages/time/package.json b/packages/time/package.json index 12501d1b485..9939d21af71 100644 --- a/packages/time/package.json +++ b/packages/time/package.json @@ -32,13 +32,13 @@ "homepage": "https://github.com/Agoric/agoric-sdk#readme", "dependencies": { "@agoric/store": "^0.9.2", - "@endo/errors": "^1.2.2", - "@endo/nat": "^5.0.7", - "@endo/patterns": "^1.4.0" + "@endo/errors": "^1.2.5", + "@endo/nat": "^5.0.10", + "@endo/patterns": "^1.4.3" }, "devDependencies": { - "@endo/far": "^1.1.2", - "@endo/init": "^1.1.2", + "@endo/far": "^1.1.5", + "@endo/init": "^1.1.4", "ava": "^5.3.0" }, "ava": { diff --git a/packages/vat-data/package.json b/packages/vat-data/package.json index 3cff9699f89..52a7ab0dab4 100644 --- a/packages/vat-data/package.json +++ b/packages/vat-data/package.json @@ -8,7 +8,6 @@ "scripts": { "build": "exit 0", "test": "ava", - "test:c8": "exit 0", "test:xs": "exit 0", "lint-fix": "yarn lint:eslint --fix", "lint": "run-s --continue-on-error lint:*", @@ -19,17 +18,17 @@ "author": "Agoric", "license": "Apache-2.0", "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/base-zone": "^0.1.0", "@agoric/store": "^0.9.2", "@agoric/swingset-liveslots": "^0.10.2", - "@endo/exo": "^1.5.0", - "@endo/patterns": "^1.4.0" + "@endo/exo": "^1.5.3", + "@endo/patterns": "^1.4.3" }, "devDependencies": { - "@endo/init": "^1.1.2", - "@endo/far": "^1.1.2", - "@endo/ses-ava": "^1.2.2", + "@endo/init": "^1.1.4", + "@endo/far": "^1.1.5", + "@endo/ses-ava": "^1.2.5", "ava": "^5.3.0", "tsd": "^0.31.1" }, diff --git a/packages/vats/package.json b/packages/vats/package.json index d77dc771cfd..a00da337223 100644 --- a/packages/vats/package.json +++ b/packages/vats/package.json @@ -9,7 +9,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", "test:xs": "exit 0", @@ -22,7 +22,7 @@ "author": "Agoric", "license": "Apache-2.0", "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/cosmic-proto": "^0.4.0", "@agoric/ertp": "^0.16.2", "@agoric/governance": "^0.10.3", @@ -36,19 +36,20 @@ "@agoric/vow": "^0.1.0", "@agoric/zoe": "^0.26.2", "@agoric/zone": "^0.2.2", - "@endo/far": "^1.1.2", - "@endo/import-bundle": "^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/far": "^1.1.5", + "@endo/import-bundle": "^1.2.2", + "@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", "import-meta-resolve": "^2.2.1", "jessie.js": "^0.3.4" }, "devDependencies": { "@agoric/swingset-liveslots": "^0.10.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" }, @@ -76,6 +77,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 91.41 + "atLeast": 91.51 } } diff --git a/packages/vats/src/core/client-behaviors.js b/packages/vats/src/core/client-behaviors.js index 5fae7cfced0..d7071a0bae3 100644 --- a/packages/vats/src/core/client-behaviors.js +++ b/packages/vats/src/core/client-behaviors.js @@ -1,4 +1,3 @@ -import { Fail } from '@endo/errors'; import { E, Far } from '@endo/far'; import { makePluginManager } from '@agoric/swingset-vat/src/vats/plugin-manager.js'; import { observeNotifier } from '@agoric/notifier'; @@ -136,7 +135,13 @@ export const startClient = async ({ } const addChainPresences = async () => { - FIXME_GCI || Fail`client must be given GCI`; + if (!FIXME_GCI) { + chainBundle = { + DISCONNECTED: `Chain is disconnected: no GCI provided`, + }; + void updatePresences(); + return; + } await addRemote(FIXME_GCI); // addEgress(..., index, ...) is called in vat-provisioning. const chainProvider = E(vats.comms).addIngress( diff --git a/packages/vats/src/core/lib-boot.js b/packages/vats/src/core/lib-boot.js index 5cf6771eb8d..486a7f12603 100644 --- a/packages/vats/src/core/lib-boot.js +++ b/packages/vats/src/core/lib-boot.js @@ -187,6 +187,7 @@ export const makeBootstrap = ( throw e; }); }, + /** @param {string} name } */ consumeItem: name => { assert.typeof(name, 'string'); return consume[name]; @@ -195,6 +196,7 @@ export const makeBootstrap = ( assert.typeof(name, 'string'); produce[name].resolve(resolution); }, + /** @param {string} name } */ resetItem: name => { assert.typeof(name, 'string'); produce[name].reset(); diff --git a/packages/vats/src/core/types-ambient.d.ts b/packages/vats/src/core/types-ambient.d.ts index ee27e97924b..f87f529db5a 100644 --- a/packages/vats/src/core/types-ambient.d.ts +++ b/packages/vats/src/core/types-ambient.d.ts @@ -371,8 +371,10 @@ type ChainBootstrapSpaceT = { namesByAddress: import('../types.js').NameHub; namesByAddressAdmin: import('../types.js').NamesByAddressAdmin; networkVat: NetworkVat; + orchestration?: CosmosInterchainService; pegasusConnections: import('@agoric/vats').NameHubKit; pegasusConnectionsAdmin: import('@agoric/vats').NameAdmin; + powerStore: MapStore; priceAuthorityVat: Awaited; priceAuthority: import('@agoric/zoe/tools/types.js').PriceAuthority; priceAuthorityAdmin: import('@agoric/vats/src/priceAuthorityRegistry').PriceAuthorityRegistryAdmin; diff --git a/packages/vats/src/ibc.js b/packages/vats/src/ibc.js index 475cabda795..52ec6a8d566 100644 --- a/packages/vats/src/ibc.js +++ b/packages/vats/src/ibc.js @@ -140,26 +140,32 @@ export const prepareIBCConnectionHandler = zone => { return protocolUtils.ibcSendPacket(packet, relativeTimeoutNs); }, /** @type {Required['onClose']} */ - async onClose() { + onClose(_conn, _reason) { const { portID, channelID } = this.state; - const { protocolUtils, channelKeyToSeqAck } = this.state; + const { protocolUtils, channelKeyToSeqAck, channelKeyToConnP } = + this.state; const packet = { source_port: portID, source_channel: channelID, }; - await protocolUtils.downcall('startChannelCloseInit', { - packet, - }); - const rejectReason = Error('Connection closed'); const channelKey = `${channelID}:${portID}`; - + const rejectReason = Error('Connection closed'); const seqToAck = channelKeyToSeqAck.get(channelKey); for (const ackKit of seqToAck.values()) { ackKit.resolver.reject(rejectReason); } channelKeyToSeqAck.delete(channelKey); + + // This Connection object is initiating the close event + if (channelKeyToConnP.has(channelKey)) { + channelKeyToConnP.delete(channelKey); + return protocolUtils.downcall('startChannelCloseInit', { + packet, + }); + } + return Promise.resolve(); }, }, ); @@ -586,11 +592,16 @@ export const prepareIBCProtocol = (zone, powers) => { break; } - case 'channelCloseInit': + // We ignore the close init tx message, since any decision to + // close should be left to the VM... + case 'channelCloseInit': { + break; + } + + // ... or received from the other side. case 'channelCloseConfirm': { const { portID, channelID } = - // could be either but that complicates line wrapping - /** @type {IBCEvent<'channelCloseInit'>} */ (obj); + /** @type {IBCEvent<'channelCloseConfirm'>} */ (obj); const channelKey = `${channelID}:${portID}`; if (channelKeyToConnP.has(channelKey)) { const conn = channelKeyToConnP.get(channelKey); diff --git a/packages/vats/src/localchain.js b/packages/vats/src/localchain.js index b9aae359835..0f7543b59ec 100644 --- a/packages/vats/src/localchain.js +++ b/packages/vats/src/localchain.js @@ -2,7 +2,12 @@ import { Fail } from '@endo/errors'; import { E } from '@endo/far'; import { M } from '@endo/patterns'; -import { AmountShape, BrandShape, PaymentShape } from '@agoric/ertp'; +import { + AmountPatternShape, + AmountShape, + BrandShape, + PaymentShape, +} from '@agoric/ertp'; import { Shape as NetworkShape } from '@agoric/network'; const { Vow$ } = NetworkShape; @@ -29,6 +34,21 @@ const { Vow$ } = NetworkShape; * '[Symbol.iterator]()' method that returns an iterator. */ +/** + * Send a batch of query requests to the local chain. Unless there is a system + * error, will return all results to indicate their success or failure. + * + * @template {TypedJson[]} [RT=TypedJson[]] + * @callback QueryManyFn + * @param {RT} requests + * @returns {PromiseVowOfTupleMappedToGenerics<{ + * [K in keyof RT]: JsonSafe<{ + * error?: string; + * reply: ResponseTo; + * }>; + * }>} + */ + /** * @typedef {{ * system: ScopedBridgeManager<'vlocalchain'>; @@ -49,7 +69,7 @@ export const LocalChainAccountI = M.interface('LocalChainAccount', { getAddress: M.callWhen().returns(Vow$(M.string())), getBalance: M.callWhen(BrandShape).returns(Vow$(AmountShape)), deposit: M.callWhen(PaymentShape) - .optional(M.pattern()) + .optional(AmountPatternShape) .returns(Vow$(AmountShape)), withdraw: M.callWhen(AmountShape).returns(Vow$(PaymentShape)), executeTx: M.callWhen(M.arrayOf(M.record())).returns( @@ -115,12 +135,15 @@ export const prepareLocalChainAccountKit = (zone, { watch }) => const purse = E(bank).getPurse(brand); return E(purse).getCurrentAmount(); }, + + // TODO The payment parameter type below should be Payment<'nat'>. + // https://github.com/Agoric/agoric-sdk/issues/9828 /** * Deposit a payment into the bank purse that matches the alleged brand. * This is safe, since even if the payment lies about its brand, ERTP * will reject spoofed payment objects when depositing into a purse. * - * @param {Payment<'nat'>} payment + * @param {ERef>} payment * @param {Pattern} [optAmountShape] throws if the Amount of the Payment * does not match the provided Pattern * @returns {PromiseVow>} @@ -148,10 +171,14 @@ export const prepareLocalChainAccountKit = (zone, { watch }) => return E(purse).withdraw(amount); }, /** - * Execute a batch of messages in order as a single atomic transaction - * and return the responses. If any of the messages fails, the entire - * batch will be rolled back. Use `typedJson()` on the arguments to get - * typed return values. + * Execute a batch of messages on the local chain. Note in particular, + * that for IBC `MsgTransfer`, execution only queues a packet for the + * local chain's IBC stack, and returns a `MsgTransferResponse` + * immediately, not waiting for the confirmation on the other chain. + * + * Messages are executed in order as a single atomic transaction and + * returns the responses. If any of the messages fails, the entire batch + * will be rolled back on the local chain. * * @template {TypedJson[]} MT messages tuple (use const with multiple * elements or it will be a mixed array) @@ -159,6 +186,9 @@ export const prepareLocalChainAccountKit = (zone, { watch }) => * @returns {PromiseVowOfTupleMappedToGenerics<{ * [K in keyof MT]: JsonSafe>; * }>} + * + * @see {typedJson} which can be used on arguments to get typed return + * values. */ async executeTx(messages) { const { address, system } = this.state; @@ -257,20 +287,7 @@ const prepareLocalChain = (zone, makeAccountKit, { watch }) => { this.facets.extractFirstQueryResultWatcher, ); }, - /** - * Send a batch of query requests to the local chain. Unless there is a - * system error, will return all results to indicate their success or - * failure. - * - * @template {import('@agoric/cosmic-proto').TypedJson[]} RT - * @param {RT} requests - * @returns {PromiseVowOfTupleMappedToGenerics<{ - * [K in keyof RT]: JsonSafe<{ - * error?: string; - * reply: ResponseTo; - * }>; - * }>} - */ + /** @type {QueryManyFn} */ async queryMany(requests) { const { system } = this.state; return E(system).toBridge({ diff --git a/packages/vats/src/proposals/localchain-test.js b/packages/vats/src/proposals/localchain-test.js index 8d0de02bb5f..201de2e38d2 100644 --- a/packages/vats/src/proposals/localchain-test.js +++ b/packages/vats/src/proposals/localchain-test.js @@ -1,6 +1,6 @@ // @ts-check import { heapVowE as E } from '@agoric/vow/vat.js'; -import { typedJson } from '@agoric/cosmic-proto/vatsafe'; +import { typedJson } from '@agoric/cosmic-proto'; /** * @param {BootstrapPowers & { @@ -20,7 +20,7 @@ export const testLocalChain = async ( let node = await chainStorage; if (!node) { console.error('testLocalChain no chainStorage'); - throw new Error('no chainStorage'); + throw Error('no chainStorage'); } let result; @@ -58,7 +58,7 @@ export const testLocalChain = async ( const emptyQuery = await E(localchain).queryMany([]); console.info('emptyQuery', emptyQuery); if (emptyQuery.length !== 0) { - throw new Error('emptyQuery results should be empty'); + throw Error('emptyQuery results should be empty'); } result = { success: true }; diff --git a/packages/vats/src/proposals/upgrade-orch-core-proposal.js b/packages/vats/src/proposals/upgrade-orch-core-proposal.js new file mode 100644 index 00000000000..3d57869e9bd --- /dev/null +++ b/packages/vats/src/proposals/upgrade-orch-core-proposal.js @@ -0,0 +1,43 @@ +import { E } from '@endo/far'; + +/** + * @param {BootstrapPowers & { + * consume: { + * vatAdminSvc: VatAdminSvc; + * vatStore: MapStore< + * string, + * import('@agoric/swingset-vat').CreateVatResults + * >; + * }; + * }} powers + * @param {object} options + * @param {{ bundleRefs: { [vatName: string]: VatSourceRef } }} options.options + */ +export const upgradeOrchCore = async ( + { consume: { vatAdminSvc, vatStore } }, + options, +) => { + const { bundleRefs } = options.options; + + for await (const [name, ref] of Object.entries(bundleRefs)) { + assert(ref.bundleID, `bundleID missing for ${name}`); + console.log(name, `BUNDLE ID: `, ref.bundleID); + const bundleCap = await E(vatAdminSvc).getBundleCap(ref.bundleID); + + const { adminNode } = await E(vatStore).get(name); + await E(adminNode).upgrade(bundleCap, {}); + } +}; + +export const getManifestForUpgradingOrchCore = (_powers, { bundleRefs }) => ({ + manifest: { + [upgradeOrchCore.name]: { + consume: { + vatAdminSvc: 'vatAdminSvc', + vatStore: 'vatStore', + }, + produce: {}, + }, + }, + options: { bundleRefs }, +}); diff --git a/packages/vats/src/proposals/upgrade-provisionPool-proposal.js b/packages/vats/src/proposals/upgrade-provisionPool-proposal.js index aea588dece8..9d31c752607 100644 --- a/packages/vats/src/proposals/upgrade-provisionPool-proposal.js +++ b/packages/vats/src/proposals/upgrade-provisionPool-proposal.js @@ -32,6 +32,8 @@ export const upgradeProvisionPool = async ( const { adminFacet, instance } = provisionPoolStartResult; const [originalPrivateArgs, poserInvitation] = await Promise.all([ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore Local tsc sees this as an error but typedoc does not deeplyFulfilled(instancePrivateArgs.get(instance)), E(electorateCreatorFacet).getPoserInvitation(), ]); diff --git a/packages/vats/src/types.d.ts b/packages/vats/src/types.d.ts index 5931569378d..e4a7f330ace 100644 --- a/packages/vats/src/types.d.ts +++ b/packages/vats/src/types.d.ts @@ -142,9 +142,9 @@ export type IBCPacket = { source_port: IBCPortID; destination_channel: IBCChannelID; destination_port: IBCPortID; - sequence?: number; - timeout_height?: number; - timeout_timestamp?: number; + sequence?: PacketSDKType['sequence']; + timeout_height?: PacketSDKType['timeout_height']; + timeout_timestamp?: PacketSDKType['timeout_timestamp']; }; export type IBCCounterParty = { @@ -192,8 +192,8 @@ type IBCPacketEvents = { timeoutPacket: { packet: IBCPacket; }; - channelCloseInit: ConnectingInfo; // TODO update - channelCloseConfirm: ConnectingInfo; // TODO update + channelCloseInit: { channelID: IBCChannelID; portID: IBCPortID }; + channelCloseConfirm: { channelID: IBCChannelID; portID: IBCPortID }; sendPacket: { relativeTimeoutNs: bigint; packet: IBCPacket }; }; @@ -223,7 +223,7 @@ type IBCMethodEvents = { receiveExecuted: {}; // TODO update startChannelOpenInit: ChannelOpenInitDowncall; startChannelCloseInit: {}; // TODO update - bindPort: {}; // TODO update + bindPort: { packet: { source_port: IBCPortID } }; timeoutExecuted: {}; // TODO update // XXX why isn't this in receiver.go? initOpenExecuted: ChannelOpenAckDowncall; diff --git a/packages/vats/src/vat-network.js b/packages/vats/src/vat-network.js index a76ac575f57..2b42b1c9b1c 100644 --- a/packages/vats/src/vat-network.js +++ b/packages/vats/src/vat-network.js @@ -3,6 +3,7 @@ import { makeDurableZone } from '@agoric/zone/durable.js'; import { prepareEchoConnectionKit, prepareLoopbackProtocolHandler, + prepareNetworkPowers, preparePortAllocator, prepareRouterProtocol, } from '@agoric/network'; @@ -11,7 +12,8 @@ import { Far } from '@endo/far'; export function buildRootObject(_vatPowers, _args, baggage) { const zone = makeDurableZone(baggage); - const powers = prepareVowTools(zone.subZone('vow')); + const vowTools = prepareVowTools(zone.subZone('vow')); + const powers = prepareNetworkPowers(zone, vowTools); const makeRouterProtocol = prepareRouterProtocol( zone.subZone('network'), diff --git a/packages/vats/src/virtual-purse.js b/packages/vats/src/virtual-purse.js index 68addb78ceb..155f29e31a9 100644 --- a/packages/vats/src/virtual-purse.js +++ b/packages/vats/src/virtual-purse.js @@ -1,16 +1,17 @@ import { Fail } from '@endo/errors'; import { E } from '@endo/far'; import { isPromise } from '@endo/promise-kit'; -import { getInterfaceGuardPayload } from '@endo/patterns'; +import { getInterfaceGuardPayload, matches } from '@endo/patterns'; import { M } from '@agoric/store'; import { + AmountPatternShape, AmountShape, BrandShape, DepositFacetShape, NotifierShape, PaymentShape, -} from '@agoric/ertp/src/typeGuards.js'; +} from '@agoric/ertp'; /** * @param {Pattern} [brandShape] @@ -35,7 +36,7 @@ export const makeVirtualPurseKitIKit = ( // to this raw method to validate that this remotable is actually // a live payment of the correct brand with sufficient funds. deposit: M.callWhen(PaymentShape) - .optional(M.pattern()) + .optional(AmountPatternShape) .returns(amountShape), getDepositFacet: M.callWhen().returns(DepositFacetShape), withdraw: M.callWhen(amountShape).returns(PaymentShape), @@ -48,7 +49,9 @@ export const makeVirtualPurseKitIKit = ( }); const RetainRedeemI = M.interface('RetainRedeem', { - retain: M.callWhen(PaymentShape).optional(amountShape).returns(amountShape), + retain: M.callWhen(PaymentShape) + .optional(AmountPatternShape) + .returns(amountShape), redeem: M.callWhen(amountShape).returns(PaymentShape), }); @@ -56,7 +59,7 @@ export const makeVirtualPurseKitIKit = ( retain: getInterfaceGuardPayload(RetainRedeemI).methodGuards.retain, redeem: getInterfaceGuardPayload(RetainRedeemI).methodGuards.redeem, recoverableClaim: M.callWhen(M.await(PaymentShape)) - .optional(amountShape) + .optional(AmountPatternShape) .returns(PaymentShape), }); @@ -102,6 +105,22 @@ export const makeVirtualPurseKitIKit = ( * current balance iterable for a given brand. */ +/** + * Until https://github.com/Agoric/agoric-sdk/issues/9407 is fixed, this + * function restricts the `optAmountShape`, if provided, to be a concrete + * `Amount` rather than a `Pattern` as it is supposed to be. + * + * TODO: Once https://github.com/Agoric/agoric-sdk/issues/9407 is fixed, remove + * this function and all calls to it. + * + * @param {Pattern} [optAmountShape] + */ +const legacyRestrictAmountShapeArg = optAmountShape => { + if (optAmountShape && !matches(optAmountShape, AmountShape)) { + throw Fail`optAmountShape if provided, must still be a concrete Amount due to https://github.com/Agoric/agoric-sdk/issues/9407`; + } +}; + /** @param {import('@agoric/zone').Zone} zone */ const prepareVirtualPurseKit = zone => zone.exoClassKit( @@ -139,6 +158,7 @@ const prepareVirtualPurseKit = zone => * @returns {Promise>} */ async recoverableClaim(payment, optAmountShape) { + legacyRestrictAmountShapeArg(optAmountShape); const { state: { recoveryPurse }, } = this; @@ -166,6 +186,7 @@ const prepareVirtualPurseKit = zone => minter: { /** @type {Retain} */ async retain(payment, optAmountShape) { + legacyRestrictAmountShapeArg(optAmountShape); !!this.state.mint || Fail`minter cannot retain without a mint.`; return E(this.state.issuer).burn(payment, optAmountShape); }, diff --git a/packages/vats/test/localchain.test.js b/packages/vats/test/localchain.test.js index f8ea6048d1d..05abdadab11 100644 --- a/packages/vats/test/localchain.test.js +++ b/packages/vats/test/localchain.test.js @@ -99,8 +99,11 @@ test('localchain - deposit and withdraw', async t => { const boot = async () => { const { bankManager } = await t.context; - await t.notThrowsAsync( - E(bankManager).addAsset('ubld', 'BLD', 'Staking Token', bld.issuerKit), + await E(bankManager).addAsset( + 'ubld', + 'BLD', + 'Staking Token', + bld.issuerKit, ); }; await boot(); diff --git a/packages/vats/test/network.test.js b/packages/vats/test/network.test.js index 84532ee4c28..7f4b739db1d 100644 --- a/packages/vats/test/network.test.js +++ b/packages/vats/test/network.test.js @@ -10,6 +10,7 @@ import { prepareVowTools } from '@agoric/vow/vat.js'; import { makeDurableZone } from '@agoric/zone/durable.js'; import { E } from '@endo/far'; +import { prepareNetworkPowers } from '@agoric/network'; import { buildRootObject as ibcBuildRootObject } from '../src/vat-ibc.js'; import { buildRootObject as networkBuildRootObject } from '../src/vat-network.js'; import { makeFakeIbcBridge } from '../tools/fake-bridge.js'; @@ -80,7 +81,8 @@ test('network - ibc', async t => { const ibcVat = E(ibcBuildRootObject)(null, null, provideBaggage('ibc')); const baggage = provideBaggage('network - ibc'); const zone = makeDurableZone(baggage); - const powers = prepareVowTools(zone); + const vowTools = prepareVowTools(zone); + const powers = prepareNetworkPowers(zone, vowTools); const { when } = powers; const makeDurablePublishKit = prepareDurablePublishKit( @@ -117,7 +119,10 @@ test('network - ibc', async t => { const makeIBCListener = prepareIBCListener(zone, makePlusOne); const testEcho = async () => { - await E(p).addListener(makeIBCListener({ publisher })); + const { publisher: voidP } = makeDurablePublishKit(); + + const listener = makeIBCListener({ publisher: voidP }); + await E(p).addListener(listener); t.log('Accepting an Inbound Connection'); const c = await when(E(p).connect('/ibc-port/port-1/unordered/foo')); @@ -128,26 +133,20 @@ test('network - ibc', async t => { t.log('Closing the Connection'); await when(E(c).close()); + await E(p).removeListener(listener); }; await testEcho(); const testIBCOutbound = async () => { + const listener = makeIBCListener({ publisher }); + await E(p).addListener(listener); + t.log('Connecting to a Remote Port'); const [hopName, portName, version] = ['connection-11', 'port-98', 'bar']; const remoteEndpoint = `/ibc-hop/${hopName}/ibc-port/${portName}/unordered/${version}`; const cP = E(p).connect(remoteEndpoint); - const evopen = await events.next(); - t.assert(!evopen.done); - t.deepEqual(evopen.value, [ - 'plusOne-open', - { - localAddr: '/ibc-port/port-1/unordered/foo', - remoteAddr: '/ibc-port/port-1', - }, - ]); - const ev2 = await events.next(); t.assert(!ev2.done); t.deepEqual(ev2.value, [ @@ -169,7 +168,11 @@ test('network - ibc', async t => { connectionHops: ['connection-11'], }); + t.log('Waiting for Connection'); const c = await when(cP); + + t.log('Waiting for events'); + const remoteAddress = c.getRemoteAddress(); const localAddress = c.getLocalAddress(); t.is( @@ -215,7 +218,21 @@ test('network - ibc', async t => { t.is(await when(ack), 'a-transfer-reply'); - await E(c).close(); + t.log('Closing the Connection'); + const closeV = E(c).close(); + const evclose = await events.next(); + t.assert(!evclose.done); + t.deepEqual(evclose.value, [ + 'startChannelCloseInit', + { + packet: { + source_channel: 'channel-1', + source_port: 'port-1', + }, + }, + ]); + + await when(closeV); }; await testIBCOutbound(); diff --git a/packages/vats/test/vpurse.test.js b/packages/vats/test/vpurse.test.js index 053e65e06cc..ca0da5744ea 100644 --- a/packages/vats/test/vpurse.test.js +++ b/packages/vats/test/vpurse.test.js @@ -1,3 +1,4 @@ +import { M } from '@endo/patterns'; import { test as rawTest } from '@agoric/swingset-vat/tools/prepare-test-env-ava.js'; import { reincarnate } from '@agoric/swingset-liveslots/tools/setup-vat-data.js'; @@ -176,6 +177,86 @@ test('makeVirtualPurse', async t => { .then(checkWithdrawal); }); +// TODO Once https://github.com/Agoric/agoric-sdk/issues/9407 is fixed, +// This test should replace the similar one above. +test.failing('makeVirtualPurse with optAmountShape pattern', async t => { + t.plan(22); + const { baggage } = t.context; + const zone = makeDurableZone(baggage).subZone('makeVirtualPurse'); + + const { expected, balanceUpdater, issuer, mint, brand, vpurse } = setup( + t, + zone, + ); + + const payment = mint.mintPayment(AmountMath.make(brand, 837n)); + + const notifier = E(vpurse).getCurrentAmountNotifier(); + let nextUpdateP = E(notifier).getUpdateSince(); + + const checkNotifier = async () => { + const { value: balance, updateCount } = await nextUpdateP; + t.assert( + AmountMath.isEqual(await E(vpurse).getCurrentAmount(), balance), + `the notifier balance is the same as the purse`, + ); + nextUpdateP = E(notifier).getUpdateSince(updateCount); + }; + + balanceUpdater.updateState(AmountMath.makeEmpty(brand)); + await checkNotifier(); + t.assert( + AmountMath.isEqual( + await E(vpurse).getCurrentAmount(), + AmountMath.makeEmpty(brand), + ), + `empty purse is empty`, + ); + t.is(await E(vpurse).getAllegedBrand(), brand, `purse's brand is correct`); + const fungible837 = AmountMath.make(brand, 837n); + + const checkDeposit = async newPurseBalance => { + t.assert( + AmountMath.isEqual(newPurseBalance, fungible837), + `the amount returned is the payment amount`, + ); + await checkNotifier(); + t.assert( + AmountMath.isEqual(await E(vpurse).getCurrentAmount(), fungible837), + `the new purse balance is the payment's old balance`, + ); + }; + + const performWithdrawal = () => { + expected.pullAmount(fungible837); + return E(vpurse).withdraw(fungible837); + }; + + const checkWithdrawal = async newPayment => { + await issuer.getAmountOf(newPayment).then(amount => { + t.assert( + AmountMath.isEqual(amount, fungible837), + `the withdrawn payment has the right balance`, + ); + }); + await checkNotifier(); + t.assert( + AmountMath.isEqual( + await E(vpurse).getCurrentAmount(), + AmountMath.makeEmpty(brand), + ), + `the purse is empty again`, + ); + }; + + expected.pushAmount(fungible837); + await E(vpurse) + .deposit(payment, M.and(fungible837)) + .then(checkDeposit) + .then(performWithdrawal) + .then(checkWithdrawal); +}); + test('makeVirtualPurse withdraw from escrowPurse', async t => { const { baggage } = t.context; const zone = makeDurableZone(baggage).subZone('withdraw from escrowPurse'); diff --git a/packages/vats/tools/bank-utils.js b/packages/vats/tools/bank-utils.js index cf077e6807d..eb0ec53dc11 100644 --- a/packages/vats/tools/bank-utils.js +++ b/packages/vats/tools/bank-utils.js @@ -64,7 +64,8 @@ export const makeFakeBankKit = issuerKits => { /** * @param {object} [opts] - * @param {import('./fake-bridge.js').Balances} opts.balances initial balances + * @param {import('./fake-bridge.js').Balances} [opts.balances] initial balances + * @param {(obj) => unknown} [opts.onToBridge] handler for toBridge messages */ export const makeFakeBankManagerKit = async opts => { const baggage = makeScalarBigMapStore('baggage'); diff --git a/packages/vats/tools/fake-bridge.js b/packages/vats/tools/fake-bridge.js index d1736f85953..d8e1585d6a7 100644 --- a/packages/vats/tools/fake-bridge.js +++ b/packages/vats/tools/fake-bridge.js @@ -8,6 +8,7 @@ import { Nat } from '@endo/nat'; /** * @import {JsonSafe} from '@agoric/cosmic-proto'; * @import {MsgDelegateResponse, MsgUndelegateResponse} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js'; + * @import {MsgSendResponse} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/tx.js'; * @import {BridgeHandler, ScopedBridgeManager} from '../src/types.js'; * @import {Remote} from '@agoric/vow'; */ @@ -26,14 +27,16 @@ const INFINITE_AMOUNT = 99999999999n; * transaction outside the Agoric VM. (Similarly for deposits.) * * @param {import('@agoric/zone').Zone} zone - * @param {object} opts - * @param {Balances} opts.balances initial balances + * @param {object} [opts] + * @param {Balances} [opts.balances] initial balances + * @param {(obj) => void} [opts.onToBridge] * @returns {ScopedBridgeManager<'bank'>} * @see {makeFakeBankManagerKit} and its `pourPayment` for a helper */ -export const makeFakeBankBridge = (zone, opts = { balances: {} }) => { - const { balances } = opts; - +export const makeFakeBankBridge = ( + zone, + { balances = {}, onToBridge = () => {} } = {}, +) => { const currentBalance = ({ address, denom }) => address === FAUCET_ADDRESS ? INFINITE_AMOUNT @@ -45,6 +48,7 @@ export const makeFakeBankBridge = (zone, opts = { balances: {} }) => { return zone.exo('Fake Bank Bridge Manager', undefined, { getBridgeId: () => 'bank', toBridge: async obj => { + onToBridge(obj); const { method, type, ...params } = obj; trace('toBridge', type, method, params); switch (obj.type) { @@ -137,6 +141,16 @@ export const makeFakeIbcBridge = (zone, onToBridge) => { if (method === 'sendPacket') { const { packet } = params; return { ...packet, sequence: '39' }; + } else if (method === 'startChannelCloseInit') { + const { packet } = params; + if (hndlr) + E(hndlr) + .fromBridge({ + type: 'IBC_EVENT', + event: 'channelCloseConfirm', + packet, + }) + .catch(e => console.error(e)); } return undefined; }, @@ -157,6 +171,123 @@ export const makeFakeIbcBridge = (zone, onToBridge) => { export const LOCALCHAIN_DEFAULT_ADDRESS = 'agoric1fakeLCAAddress'; +/** + * Constants that can be used to force an error state in a bridge transaction. + * Typically used for the LocalChainBridge which currently accepts all messages + * unless specified otherwise. Less useful for the DibcBridge which rejects all + * messages unless specified otherwise. + */ +export const SIMULATED_ERRORS = { + TIMEOUT: 504n, + BAD_REQUEST: 400n, +}; + +/** + * Used to mock responses from Cosmos Golang back to SwingSet for for + * E(lca).executeTx(). + * + * Returns an empty object per message unless specified. + * + * @param {object} message + * @param {number} sequence + * @returns {unknown} + * @throws {Error} to simulate failures in certain cases + */ +export const fakeLocalChainBridgeTxMsgHandler = (message, sequence) => { + switch (message['@type']) { + // TODO #9402 reference bank to ensure caller has tokens they are transferring + case '/ibc.applications.transfer.v1.MsgTransfer': { + if (message.token.amount === String(SIMULATED_ERRORS.TIMEOUT)) { + throw Error('simulated unexpected MsgTransfer packet timeout'); + } + // like `JsonSafe`, but bigints are converted to numbers + // FIXME should vlocalchain return a string instead of number for bigint? + return { + sequence, + }; + } + case '/cosmos.bank.v1beta1.MsgSend': { + if (message.amount[0].amount === String(SIMULATED_ERRORS.BAD_REQUEST)) { + throw Error('simulated error'); + } + return /** @type {JsonSafe} */ ({}); + } + case '/cosmos.staking.v1beta1.MsgDelegate': { + if (message.amount.amount === String(SIMULATED_ERRORS.TIMEOUT)) { + throw Error('simulated packet timeout'); + } + return /** @type {JsonSafe} */ ({}); + } + case '/cosmos.staking.v1beta1.MsgUndelegate': { + return /** @type {JsonSafe} */ ({ + // 5 seconds from unix epoch + completionTime: { seconds: '5', nanos: 0 }, + }); + } + // returns one empty object per message unless specified + default: + return {}; + } +}; + +export const LOCALCHAIN_QUERY_ALL_BALANCES_RESPONSE = [ + { + value: 10n, + denom: 'ubld', + }, + { + value: 10n, + denom: 'uist', + }, +]; + +/** + * Used to mock responses from Cosmos Golang back to SwingSet for for + * E(lca).query() and E(lca).queryMany(). + * + * Returns an empty object per query message unless specified. + * + * @param {object} message + * @returns {unknown} + */ +export const fakeLocalChainBridgeQueryHandler = message => { + switch (message['@type']) { + case '/cosmos.bank.v1beta1.QueryAllBalancesRequest': { + return { + error: '', + height: '1', + reply: { + '@type': '/cosmos.bank.v1beta1.QueryAllBalancesResponse', + balances: LOCALCHAIN_QUERY_ALL_BALANCES_RESPONSE.map(x => ({ + denom: x.denom, + amount: String(x.value), + })), + pagination: { nextKey: null, total: '2' }, + }, + }; + } + case '/cosmos.bank.v1beta1.QueryBalanceRequest': { + return { + error: '', + height: '1', + reply: { + '@type': '/cosmos.bank.v1beta1.QueryBalanceResponse', + balance: { + denom: message.denom, + // return 10 for all denoms, somewhat arbitrarily. + // if a denom is not known to cosmos bank, we'd expect to see + // `{denom, amount: '0'}` returned + amount: '10', + }, + }, + }; + } + // returns one empty object per message unless specified + default: + return {}; + } +}; + /** * @param {import('@agoric/zone').Zone} zone * @param {(obj) => void} [onToBridge] @@ -181,38 +312,14 @@ export const makeFakeLocalchainBridge = (zone, onToBridge = () => {}) => { } case 'VLOCALCHAIN_EXECUTE_TX': { lcaExecuteTxSequence += 1; - return obj.messages.map(message => { - switch (message['@type']) { - // TODO #9402 reference bank to ensure caller has tokens they are transferring - case '/ibc.applications.transfer.v1.MsgTransfer': { - if (message.token.amount === '504') { - throw Error( - 'simulated unexpected MsgTransfer packet timeout', - ); - } - // like `JsonSafe`, but bigints are converted to numbers - // XXX should vlocalchain return a string instead of number for bigint? - return { - sequence: lcaExecuteTxSequence, - }; - } - case '/cosmos.staking.v1beta1.MsgDelegate': { - if (message.amount.amount === '504') { - throw Error('simulated packet timeout'); - } - return /** @type {JsonSafe} */ ({}); - } - case '/cosmos.staking.v1beta1.MsgUndelegate': { - return /** @type {JsonSafe} */ ({ - // 5 seconds from unix epoch - completionTime: { seconds: 5n, nanos: 0 }, - }); - } - // returns one empty object per message unless specified - default: - return {}; - } - }); + return obj.messages.map(message => + fakeLocalChainBridgeTxMsgHandler(message, lcaExecuteTxSequence), + ); + } + case 'VLOCALCHAIN_QUERY_MANY': { + return obj.messages.map(message => + fakeLocalChainBridgeQueryHandler(message), + ); } default: Fail`unknown type ${type}`; diff --git a/packages/vm-config/decentral-devnet-config.json b/packages/vm-config/decentral-devnet-config.json index 232420684cc..1295b8eea9d 100644 --- a/packages/vm-config/decentral-devnet-config.json +++ b/packages/vm-config/decentral-devnet-config.json @@ -13,7 +13,8 @@ "@agoric/builders/scripts/vats/init-transfer.js" ], [ - "@agoric/builders/scripts/vats/init-orchestration.js" + "@agoric/builders/scripts/vats/init-orchestration.js", + "@agoric/builders/scripts/orchestration/write-chain-info.js" ], [ { diff --git a/packages/vm-config/decentral-itest-orchestration-config.json b/packages/vm-config/decentral-itest-orchestration-config.json index f0db27308e5..ff410f43245 100644 --- a/packages/vm-config/decentral-itest-orchestration-config.json +++ b/packages/vm-config/decentral-itest-orchestration-config.json @@ -8,6 +8,7 @@ "@agoric/builders/scripts/vats/init-localchain.js", "@agoric/builders/scripts/vats/init-transfer.js", "@agoric/builders/scripts/vats/init-orchestration.js", + "@agoric/builders/scripts/orchestration/write-chain-info.js", { "module": "@agoric/builders/scripts/inter-protocol/init-core.js", "entrypoint": "defaultProposalBuilder", diff --git a/packages/vow/README.md b/packages/vow/README.md index b34dc1db902..08d32ef3d13 100644 --- a/packages/vow/README.md +++ b/packages/vow/README.md @@ -26,12 +26,12 @@ Here they are: { } ``` -On Agoric, you can use `V` exported from `@agoric/vow/vat.js`, which -converts a chain of promises and vows to a promise for its final -fulfilment, by unwrapping any intermediate vows: +You can use `heapVowE` exported from `@agoric/vow`, which converts a chain of +promises and vows to a promise for its final fulfillment, by unwrapping any +intermediate vows: ```js -import { V as E } from '@agoric/vow/vat.js'; +import { heapVowE as E } from '@agoric/vow'; [...] const a = await E.when(w1); const b = await E(w2).something(...args); @@ -40,12 +40,13 @@ const b = await E(w2).something(...args); ## Vow Producer -On Agoric, use the following to create and resolve a vow: +Use the following to create and resolve a vow: ```js -// CAVEAT: `V` uses internal ephemeral promises, so while it is convenient, +// CAVEAT: `heapVow*` uses internal ephemeral promises, so while it is convenient, // it cannot be used by upgradable vats. See "Durability" below: -import { V as E, makeVowKit } from '@agoric/vow/vat.js'; +import { heapVowE, heapVowTools } from '@agoric/vow'; +const { makeVowKit } = heapVowTools; [...] const { resolver, vow } = makeVowKit(); // Send vow to a potentially different vat. @@ -56,15 +57,15 @@ resolver.resolve('now you know the answer'); ## Durability -The `@agoric/vow/vat.js` module allows vows to integrate Agoric's vat upgrade -mechanism. To create vow tools that deal with durable objects: +By default, the `@agoric/vow` module allows vows to integrate with Agoric's vat +upgrade mechanism. To create vow tools that deal with durable objects: ```js // NOTE: Cannot use `V` as it has non-durable internal state when unwrapping // vows. Instead, use the default vow-exposing `E` with the `watch` // operator. import { E } from '@endo/far'; -import { prepareVowTools } from '@agoric/vow/vat.js'; +import { prepareVowTools } from '@agoric/vow'; import { makeDurableZone } from '@agoric/zone'; // Only do the following once at the start of a new vat incarnation: @@ -76,6 +77,67 @@ const { watch, makeVowKit } = prepareVowTools(vowZone); // Vows and resolvers you create can be saved in durable stores. ``` +## VowTools + +VowTools are a set of utility functions for working with Vows in Agoric smart contracts and vats. These tools help manage asynchronous operations in a way that's resilient to vat upgrades, ensuring your smart contract can handle long-running processes reliably. + +### Usage + +VowTools are typically prepared in the start function of a smart contract or vat and passed in as a power to exos. + + +```javascript +import { prepareVowTools } from '@agoric/vow/vat.js'; +import { makeDurableZone } from '@agoric/zone/durable.js'; + +export const start = async (zcf, privateArgs, baggage) => { + const zone = makeDurableZone(baggage); + const vowTools = prepareVowTools(zone.subZone('vows')); + + // Use vowTools here... +} +``` + +### Available Tools + +#### `when(vowOrPromise)` +Returns a Promise for the fulfillment of the very end of the `vowOrPromise` chain. It can retry disconnections due to upgrades of other vats, but cannot survive the upgrade of the calling vat. + +#### `watch(promiseOrVow, [watcher], [context])` +Watch a Vow and optionally provide a `watcher` with `onFulfilled`/`onRejected` handlers and a `context` value for the handlers. When handlers are not provided the fulfillment or rejection will simply pass through. + +It also registers pending Promises, so if the current vat is upgraded, the watcher is rejected because the Promise was lost when the heap was reset. + +#### `all(arrayOfPassables, [watcher], [context])` +Vow-tolerant implementation of Promise.all that takes an iterable of vows and other Passables and returns a single Vow. It resolves with an array of values when all of the input's promises or vows are fulfilled and rejects with the first rejection reason when any of the input's promises or vows are rejected. + +#### `allSettled(arrayOfPassables, [watcher], [context])` +Vow-tolerant implementation of Promise.allSettled that takes an iterable of vows and other Passables and returns a single Vow. It resolves when all of the input's promises or vows are settled with an array of settled outcome objects. + +#### `asVow(fn)` +Takes a function that might return synchronously, throw an Error, or return a Promise or Vow and returns a Vow. + +#### `asPromise(vow)` +Converts a Vow back into a Promise. + +### Example + +```javascript +const { when, watch, all, allSettled } = vowTools; + +// Using watch to create a Vow +const myVow = watch(someAsyncOperation()); + +// Using when to resolve a Vow +const result = await when(myVow); + +// Using all +const results = await when(all([vow, vowForVow, promise])); + +// Using allSettled +const outcomes = await when(allSettled([vow, vowForVow, promise])); +``` + ## Internals The current "version 0" vow internals expose a `shorten()` method, returning a @@ -94,20 +156,25 @@ final result: // that may not be side-effect free. let result = await specimenP; let vowInternals = getVowInternals(result); +let disconnectionState = undefined; // Loop until the result is no longer a vow. while (vowInternals) { try { - const shortened = await E(internals.vowV0).shorten(); + // WARNING: Do not use `shorten()` in your own code. This is an example + // for didactic purposes only. + const shortened = await E(vowInternals.vowV0).shorten(); const nextInternals = getVowInternals(shortened); // Atomically update the state. result = shortened; vowInternals = nextInternals; } catch (e) { - if (!isDisconnectionReason(e)) { + const nextDisconnectionState = isDisconnectionReason(e, disconnectionState); + if (!nextDisconnectionState) { // Not a disconnect, so abort. throw e; } - // It was a disconnect, so try again with the same state. + // It was a disconnect, so try again with the updated state. + disconnectionState = nextDisconnectionState; } } return result; diff --git a/packages/vow/package.json b/packages/vow/package.json index b17ecbb86c6..7acbfa1b4dc 100755 --- a/packages/vow/package.json +++ b/packages/vow/package.json @@ -10,9 +10,8 @@ "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", "lint-fix": "yarn lint:eslint --fix", "lint": "run-s --continue-on-error lint:*", @@ -22,17 +21,17 @@ "dependencies": { "@agoric/base-zone": "^0.1.0", "@agoric/internal": "^0.3.2", - "@endo/env-options": "^1.1.4", - "@endo/errors": "^1.2.2", - "@endo/eventual-send": "^1.2.2", - "@endo/pass-style": "^1.4.0", - "@endo/patterns": "^1.4.0", - "@endo/promise-kit": "^1.1.2" + "@endo/env-options": "^1.1.6", + "@endo/errors": "^1.2.5", + "@endo/eventual-send": "^1.2.5", + "@endo/pass-style": "^1.4.3", + "@endo/patterns": "^1.4.3", + "@endo/promise-kit": "^1.1.5" }, "devDependencies": { "@agoric/internal": "^0.3.2", - "@endo/far": "^1.1.2", - "@endo/init": "^1.1.2", + "@endo/far": "^1.1.5", + "@endo/init": "^1.1.4", "ava": "^5.3.0", "tsd": "^0.31.1" }, @@ -54,6 +53,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 89.93 + "atLeast": 89.96 } } diff --git a/packages/vow/src/index.js b/packages/vow/src/index.js index 4b41d02b15a..5b14dd2afd2 100644 --- a/packages/vow/src/index.js +++ b/packages/vow/src/index.js @@ -1,8 +1,15 @@ // @ts-check -export * from './tools.js'; + +// We default to the vat-compatible version of this package, which is easy to +// reconfigure if not running under SwingSet. +export * from '../vat.js'; export { default as makeE } from './E.js'; export { VowShape, toPassableCap } from './vow-utils.js'; +/** + * @typedef {import('./tools.js').VowTools} VowTools + */ + // eslint-disable-next-line import/export export * from './types.js'; diff --git a/packages/vow/src/tools.js b/packages/vow/src/tools.js index ec224cbe078..275d274c615 100644 --- a/packages/vow/src/tools.js +++ b/packages/vow/src/tools.js @@ -7,6 +7,7 @@ import { makeWhen } from './when.js'; /** * @import {Zone} from '@agoric/base-zone'; + * @import {Passable} from '@endo/pass-style'; * @import {IsRetryableReason, AsPromiseFunction, EVow, Vow, ERef} from './types.js'; */ @@ -18,7 +19,7 @@ import { makeWhen } from './when.js'; * @param {object} [powers] * @param {IsRetryableReason} [powers.isRetryableReason] */ -export const prepareVowTools = (zone, powers = {}) => { +export const prepareBasicVowTools = (zone, powers = {}) => { const { isRetryableReason = /** @type {IsRetryableReason} */ (() => false) } = powers; const makeVowKit = prepareVowKit(zone); @@ -52,11 +53,31 @@ export const prepareVowTools = (zone, powers = {}) => { }; /** - * Vow-tolerant implementation of Promise.all. + * Vow-tolerant implementation of Promise.all that takes an iterable of vows + * and other {@link Passable}s and returns a single {@link Vow}. It resolves + * with an array of values when all of the input's promises or vows are + * fulfilled and rejects when any of the input's promises or vows are + * rejected with the first rejection reason. * - * @param {EVow[]} maybeVows + * @param {unknown[]} maybeVows */ - const allVows = maybeVows => watchUtils.all(maybeVows); + const all = maybeVows => watchUtils.all(maybeVows); + + /** + * @param {unknown[]} maybeVows + * @deprecated use `vowTools.all` + */ + const allVows = all; + + /** + * Vow-tolerant implementation of Promise.allSettled that takes an iterable + * of vows and other {@link Passable}s and returns a single {@link Vow}. It + * resolves when all of the input's promises or vows are settled with an + * array of settled outcome objects. + * + * @param {unknown[]} maybeVows + */ + const allSettled = maybeVows => watchUtils.allSettled(maybeVows); /** @type {AsPromiseFunction} */ const asPromise = (specimenP, ...watcherArgs) => @@ -66,12 +87,14 @@ export const prepareVowTools = (zone, powers = {}) => { when, watch, makeVowKit, + all, allVows, + allSettled, asVow, asPromise, retriable, }); }; -harden(prepareVowTools); +harden(prepareBasicVowTools); -/** @typedef {ReturnType} VowTools */ +/** @typedef {ReturnType} VowTools */ diff --git a/packages/vow/src/types.js b/packages/vow/src/types.js index 15b894b244e..1370be6bd1c 100644 --- a/packages/vow/src/types.js +++ b/packages/vow/src/types.js @@ -66,6 +66,7 @@ export {}; */ /** + * Vows are objects that represent promises that can be stored durably. * @template [T=any] * @typedef {CopyTagged<'Vow', VowPayload>} Vow */ diff --git a/packages/vow/src/vow.js b/packages/vow/src/vow.js index 2b4013eb0cb..e2539baf06f 100644 --- a/packages/vow/src/vow.js +++ b/packages/vow/src/vow.js @@ -120,7 +120,7 @@ export const prepareVowKit = zone => { case 'pending': return provideCurrentKit(this.facets.resolver).promise; default: - throw new TypeError(`unexpected stepStatus ${stepStatus}`); + throw TypeError(`unexpected stepStatus ${stepStatus}`); } }, }, diff --git a/packages/vow/src/watch-utils.js b/packages/vow/src/watch-utils.js index 0bb740530bc..24b809f5a67 100644 --- a/packages/vow/src/watch-utils.js +++ b/packages/vow/src/watch-utils.js @@ -10,7 +10,7 @@ const { Fail, bare, details: X } = assert; * @import {Zone} from '@agoric/base-zone'; * @import {Watch} from './watch.js'; * @import {When} from './when.js'; - * @import {VowKit, AsPromiseFunction, IsRetryableReason, EVow} from './types.js'; + * @import {VowKit, AsPromiseFunction, IsRetryableReason, Vow} from './types.js'; */ const VowShape = M.tagged( @@ -54,11 +54,16 @@ export const prepareWatchUtils = ( { utils: M.interface('Utils', { all: M.call(M.arrayOf(M.any())).returns(VowShape), + allSettled: M.call(M.arrayOf(M.any())).returns(VowShape), asPromise: M.call(M.raw()).rest(M.raw()).returns(M.promise()), }), watcher: M.interface('Watcher', { - onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()), - onRejected: M.call(M.any()).rest(M.any()).returns(M.any()), + onFulfilled: M.call(M.raw()).rest(M.raw()).returns(M.raw()), + onRejected: M.call(M.raw()).rest(M.raw()).returns(M.raw()), + }), + helper: M.interface('Helper', { + createVow: M.call(M.arrayOf(M.any()), M.boolean()).returns(VowShape), + processResult: M.call(M.raw()).rest(M.raw()).returns(M.undefined()), }), retryRejectionPromiseWatcher: PromiseWatcherI, }, @@ -68,6 +73,7 @@ export const prepareWatchUtils = ( * @property {number} remaining * @property {MapStore} resultsMap * @property {VowKit['resolver']} resolver + * @property {boolean} [isAllSettled] */ /** @type {MapStore} */ const idToVowState = detached.mapStore('idToVowState'); @@ -79,32 +85,83 @@ export const prepareWatchUtils = ( }, { utils: { + /** @param {unknown[]} specimens */ + all(specimens) { + return this.facets.helper.createVow(specimens, false); + }, + /** @param {unknown[]} specimens */ + allSettled(specimens) { + return /** @type {Vow<({status: 'fulfilled', value: any} | {status: 'rejected', reason: any})[]>} */ ( + this.facets.helper.createVow(specimens, true) + ); + }, + /** @type {AsPromiseFunction} */ + asPromise(specimenP, ...watcherArgs) { + // Watch the specimen in case it is an ephemeral promise. + const vow = watch(specimenP, ...watcherArgs); + const promise = when(vow); + // Watch the ephemeral result promise to ensure that if its settlement is + // lost due to upgrade of this incarnation, we will at least cause an + // unhandled rejection in the new incarnation. + zone.watchPromise(promise, this.facets.retryRejectionPromiseWatcher); + + return promise; + }, + }, + watcher: { /** - * @param {EVow[]} vows + * @param {unknown} value + * @param {object} ctx + * @param {bigint} ctx.id + * @param {number} ctx.index + * @param {number} ctx.numResults + * @param {boolean} ctx.isAllSettled */ - all(vows) { + onFulfilled(value, ctx) { + this.facets.helper.processResult(value, ctx, 'fulfilled'); + }, + /** + * @param {unknown} reason + * @param {object} ctx + * @param {bigint} ctx.id + * @param {number} ctx.index + * @param {number} ctx.numResults + * @param {boolean} ctx.isAllSettled + */ + onRejected(reason, ctx) { + this.facets.helper.processResult(reason, ctx, 'rejected'); + }, + }, + helper: { + /** + * @param {unknown[]} specimens + * @param {boolean} isAllSettled + */ + createVow(specimens, isAllSettled) { const { nextId: id, idToVowState } = this.state; /** @type {VowKit} */ const kit = makeVowKit(); - // Preserve the order of the vow results. - for (let index = 0; index < vows.length; index += 1) { - watch(vows[index], this.facets.watcher, { + // Preserve the order of the results. + for (let index = 0; index < specimens.length; index += 1) { + watch(specimens[index], this.facets.watcher, { id, index, - numResults: vows.length, + numResults: specimens.length, + isAllSettled, }); } - if (vows.length > 0) { + if (specimens.length > 0) { // Save the state until rejection or all fulfilled. this.state.nextId += 1n; idToVowState.init( id, harden({ resolver: kit.resolver, - remaining: vows.length, + remaining: specimens.length, resultsMap: detached.mapStore('resultsMap'), + isAllSettled, }), ); const idToNonStorableResults = provideLazyMap( @@ -119,27 +176,36 @@ export const prepareWatchUtils = ( } return kit.vow; }, - /** @type {AsPromiseFunction} */ - asPromise(specimenP, ...watcherArgs) { - // Watch the specimen in case it is an ephemeral promise. - const vow = watch(specimenP, ...watcherArgs); - const promise = when(vow); - // Watch the ephemeral result promise to ensure that if its settlement is - // lost due to upgrade of this incarnation, we will at least cause an - // unhandled rejection in the new incarnation. - zone.watchPromise(promise, this.facets.retryRejectionPromiseWatcher); - - return promise; - }, - }, - watcher: { - onFulfilled(value, { id, index, numResults }) { + /** + * @param {unknown} result + * @param {object} ctx + * @param {bigint} ctx.id + * @param {number} ctx.index + * @param {number} ctx.numResults + * @param {boolean} ctx.isAllSettled + * @param {'fulfilled' | 'rejected'} status + */ + processResult(result, { id, index, numResults, isAllSettled }, status) { const { idToVowState } = this.state; if (!idToVowState.has(id)) { // Resolution of the returned vow happened already. return; } const { remaining, resultsMap, resolver } = idToVowState.get(id); + if (!isAllSettled && status === 'rejected') { + // For 'all', we reject immediately on the first rejection + idToVowState.delete(id); + resolver.reject(result); + return; + } + + const possiblyWrappedResult = isAllSettled + ? harden({ + status, + [status === 'fulfilled' ? 'value' : 'reason']: result, + }) + : result; + const idToNonStorableResults = provideLazyMap( utilsToNonStorableResults, this.facets.utils, @@ -152,15 +218,16 @@ export const prepareWatchUtils = ( ); // Capture the fulfilled value. - if (zone.isStorable(value)) { - resultsMap.init(index, value); + if (zone.isStorable(possiblyWrappedResult)) { + resultsMap.init(index, possiblyWrappedResult); } else { - nonStorableResults.set(index, value); + nonStorableResults.set(index, possiblyWrappedResult); } const vowState = harden({ remaining: remaining - 1, resultsMap, resolver, + isAllSettled, }); if (vowState.remaining > 0) { idToVowState.set(id, vowState); @@ -177,9 +244,12 @@ export const prepareWatchUtils = ( results[i] = resultsMap.get(i); } else { numLost += 1; + results[i] = isAllSettled + ? { status: 'rejected', reason: 'Unstorable result was lost' } + : undefined; } } - if (numLost > 0) { + if (numLost > 0 && !isAllSettled) { resolver.reject( assert.error(X`${numLost} unstorable results were lost`), ); @@ -187,16 +257,6 @@ export const prepareWatchUtils = ( resolver.resolve(harden(results)); } }, - onRejected(value, { id, index: _index, numResults: _numResults }) { - const { idToVowState } = this.state; - if (!idToVowState.has(id)) { - // First rejection wins. - return; - } - const { resolver } = idToVowState.get(id); - idToVowState.delete(id); - resolver.reject(value); - }, }, retryRejectionPromiseWatcher: { onFulfilled(_result) {}, diff --git a/packages/vow/test/asVow.test.js b/packages/vow/test/asVow.test.js index 3109c74e027..35756da0dd3 100644 --- a/packages/vow/test/asVow.test.js +++ b/packages/vow/test/asVow.test.js @@ -4,11 +4,11 @@ import test from 'ava'; import { E } from '@endo/far'; import { makeHeapZone } from '@agoric/base-zone/heap.js'; -import { prepareVowTools } from '../src/tools.js'; +import { prepareBasicVowTools } from '../src/tools.js'; import { getVowPayload, isVow } from '../src/vow-utils.js'; test('asVow takes a function that throws/returns synchronously and returns a vow', async t => { - const { watch, when, asVow } = prepareVowTools(makeHeapZone()); + const { watch, when, asVow } = prepareBasicVowTools(makeHeapZone()); const fnThatThrows = () => { throw Error('fail'); @@ -36,7 +36,7 @@ test('asVow takes a function that throws/returns synchronously and returns a vow }); test('asVow does not resolve a vow to a vow', async t => { - const { watch, when, asVow } = prepareVowTools(makeHeapZone()); + const { watch, when, asVow } = prepareBasicVowTools(makeHeapZone()); const testVow = watch(Promise.resolve('payload')); const testVowAsVow = asVow(() => testVow); diff --git a/packages/vow/test/disconnect.test.js b/packages/vow/test/disconnect.test.js index 35713076214..5ea0e73e4c3 100644 --- a/packages/vow/test/disconnect.test.js +++ b/packages/vow/test/disconnect.test.js @@ -3,7 +3,7 @@ import test from 'ava'; import { makeHeapZone } from '@agoric/base-zone/heap.js'; import { makeTagged } from '@endo/pass-style'; -import { prepareVowTools } from '../src/tools.js'; +import { prepareBasicVowTools } from '../src/tools.js'; /** @import {Vow} from '../src/types.js' */ @@ -11,7 +11,7 @@ test('retry on disconnection', async t => { const zone = makeHeapZone(); const isRetryableReason = e => e && e.message === 'disconnected'; - const { watch, when } = prepareVowTools(zone, { + const { watch, when } = prepareBasicVowTools(zone, { isRetryableReason, }); const makeTestVowV0 = zone.exoClass( diff --git a/packages/vow/test/types.test-d.ts b/packages/vow/test/types.test-d.ts index 8a859348caf..6f2968a7631 100644 --- a/packages/vow/test/types.test-d.ts +++ b/packages/vow/test/types.test-d.ts @@ -16,3 +16,18 @@ expectType<(p1: number, p2: string) => Vow<{ someValue: 'bar' }>>( Promise.resolve({ someValue: 'bar' } as const), ), ); + +expectType< + Vow< + ( + | { status: 'fulfilled'; value: any } + | { status: 'rejected'; reason: any } + )[] + > +>( + vt.allSettled([ + Promise.resolve(1), + Promise.reject(new Error('test')), + Promise.resolve('hello'), + ]), +); diff --git a/packages/vow/test/vat.test.js b/packages/vow/test/vat.test.js index 019742ec4e5..4babdb3a04b 100644 --- a/packages/vow/test/vat.test.js +++ b/packages/vow/test/vat.test.js @@ -2,7 +2,7 @@ import test from 'ava'; import { E, Far } from '@endo/far'; -import { heapVowE, heapVowTools } from '../vat.js'; +import { heapVowE as VE, heapVowTools } from '../vat.js'; const { makeVowKit } = heapVowTools; @@ -13,7 +13,7 @@ test('heap messages', async t => { /** @type {ReturnType>} */ const { vow, resolver } = makeVowKit(); - const retP = heapVowE(vow).hello('World'); + const retP = VE(vow).hello('World'); resolver.resolve(greeter); // Happy path: WE(vow)[method](...args) calls the method. @@ -29,10 +29,10 @@ test('heap messages', async t => { ); // Happy path: await WE.when unwraps the vow. - t.is(await heapVowE.when(vow), greeter); + t.is(await VE.when(vow), greeter); t.is( - await heapVowE.when(vow, res => { + await VE.when(vow, res => { t.is(res, greeter); return 'done'; }), diff --git a/packages/vow/test/watch-utils.test.js b/packages/vow/test/watch-utils.test.js index e92809ac040..4a622f37195 100644 --- a/packages/vow/test/watch-utils.test.js +++ b/packages/vow/test/watch-utils.test.js @@ -1,26 +1,29 @@ // @ts-check +/* global setTimeout */ import test from 'ava'; import { makeHeapZone } from '@agoric/base-zone/heap.js'; import { E, getInterfaceOf } from '@endo/far'; -import { prepareVowTools } from '../src/tools.js'; +import { prepareBasicVowTools } from '../src/tools.js'; -test('allVows waits for a single vow to complete', async t => { +const setTimeoutAmbient = setTimeout; + +test('vowTools.all waits for a single vow to complete', async t => { const zone = makeHeapZone(); - const { watch, when, allVows } = prepareVowTools(zone); + const { watch, when, all } = prepareBasicVowTools(zone); const testPromiseP = Promise.resolve('promise'); const vowA = watch(testPromiseP); - const result = await when(allVows([vowA])); + const result = await when(all([vowA])); t.is(result.length, 1); t.is(result[0], 'promise'); }); -test('allVows waits for an array of vows to complete', async t => { +test('vowTools.all waits for an array of vows to complete', async t => { const zone = makeHeapZone(); - const { watch, when, allVows } = prepareVowTools(zone); + const { watch, when, all } = prepareBasicVowTools(zone); const testPromiseAP = Promise.resolve('promiseA'); const testPromiseBP = Promise.resolve('promiseB'); @@ -29,14 +32,14 @@ test('allVows waits for an array of vows to complete', async t => { const vowB = watch(testPromiseBP); const vowC = watch(testPromiseCP); - const result = await when(allVows([vowA, vowB, vowC])); + const result = await when(all([vowA, vowB, vowC])); t.is(result.length, 3); t.like(result, ['promiseA', 'promiseB', 'promiseC']); }); -test('allVows returns vows in order', async t => { +test('vowTools.all returns vows in order', async t => { const zone = makeHeapZone(); - const { watch, when, allVows, makeVowKit } = prepareVowTools(zone); + const { watch, when, all, makeVowKit } = prepareBasicVowTools(zone); const kit = makeVowKit(); const testPromiseAP = Promise.resolve('promiseA'); @@ -48,14 +51,14 @@ test('allVows returns vows in order', async t => { // test promie A and B should already be resolved. kit.resolver.resolve('promiseC'); - const result = await when(allVows([vowA, vowC, vowB])); + const result = await when(all([vowA, vowC, vowB])); t.is(result.length, 3); t.like(result, ['promiseA', 'promiseC', 'promiseB']); }); -test('allVows rejects upon first rejection', async t => { +test('vowTools.all rejects upon first rejection', async t => { const zone = makeHeapZone(); - const { watch, when, allVows } = prepareVowTools(zone); + const { watch, when, all } = prepareBasicVowTools(zone); const testPromiseAP = Promise.resolve('promiseA'); const testPromiseBP = Promise.reject(Error('rejectedA')); @@ -70,60 +73,75 @@ test('allVows rejects upon first rejection', async t => { }, }); - await when(watch(allVows([vowA, vowB, vowC]), watcher)); + await when(watch(all([vowA, vowB, vowC]), watcher)); }); -test('allVows can accept vows awaiting other vows', async t => { +test('vowTools.all can accept vows awaiting other vows', async t => { const zone = makeHeapZone(); - const { watch, when, allVows } = prepareVowTools(zone); + const { watch, when, all } = prepareBasicVowTools(zone); const testPromiseAP = Promise.resolve('promiseA'); const testPromiseBP = Promise.resolve('promiseB'); const vowA = watch(testPromiseAP); const vowB = watch(testPromiseBP); - const resultA = allVows([vowA, vowB]); + const resultA = all([vowA, vowB]); const testPromiseCP = Promise.resolve('promiseC'); const vowC = when(watch(testPromiseCP)); - const resultB = await when(allVows([resultA, vowC])); + const resultB = await when(all([resultA, vowC])); t.is(resultB.length, 2); t.like(resultB, [['promiseA', 'promiseB'], 'promiseC']); }); -test('allVows - works with just promises', async t => { +test('vowTools.all - works with just promises', async t => { const zone = makeHeapZone(); - const { when, allVows } = prepareVowTools(zone); + const { when, all } = prepareBasicVowTools(zone); const result = await when( - allVows([Promise.resolve('promiseA'), Promise.resolve('promiseB')]), + all([Promise.resolve('promiseA'), Promise.resolve('promiseB')]), ); t.is(result.length, 2); t.like(result, ['promiseA', 'promiseB']); }); -test('allVows - watch promises mixed with vows', async t => { +test('vowTools.all - watch promises mixed with vows', async t => { const zone = makeHeapZone(); - const { watch, when, allVows } = prepareVowTools(zone); + const { watch, when, all } = prepareBasicVowTools(zone); const testPromiseP = Promise.resolve('vow'); const vowA = watch(testPromiseP); - const result = await when(allVows([vowA, Promise.resolve('promise')])); + const result = await when(all([vowA, Promise.resolve('promise')])); t.is(result.length, 2); t.like(result, ['vow', 'promise']); }); -test('allVows can accept passable data (PureData)', async t => { +test('vowTools.all can accept passable data (PureData)', async t => { const zone = makeHeapZone(); - const { watch, when, allVows } = prepareVowTools(zone); - - const testPromiseP = Promise.resolve('vow'); - const vowA = watch(testPromiseP); + const { when, all } = prepareBasicVowTools(zone); - const result = await when(allVows([vowA, 'string', 1n, { obj: true }])); + const result = await when( + all([Promise.resolve('promise'), 'string', 1n, { obj: true }]), + ); t.is(result.length, 4); - t.deepEqual(result, ['vow', 'string', 1n, { obj: true }]); + t.deepEqual(result, ['promise', 'string', 1n, { obj: true }]); +}); + +test('vowTools.all rejects on the first settled rejection', async t => { + const zone = makeHeapZone(); + const { when, all } = prepareBasicVowTools(zone); + + await t.throwsAsync( + when( + all([ + Promise.resolve('yes'), + Promise.reject(new Error('no')), + Promise.reject(new Error('no again')), + ]), + ), + { message: 'no' }, + ); }); const prepareAccount = zone => @@ -133,9 +151,9 @@ const prepareAccount = zone => }, }); -test('allVows supports Promise pipelining', async t => { +test('vowTools.all supports Promise pipelining', async t => { const zone = makeHeapZone(); - const { watch, when, allVows } = prepareVowTools(zone); + const { watch, when, all } = prepareBasicVowTools(zone); // makeAccount returns a Promise const prepareLocalChain = makeAccount => { @@ -157,7 +175,7 @@ test('allVows supports Promise pipelining', async t => { const Localchain = prepareLocalChain(prepareAccount(zone)); const lcaP = E(Localchain).makeAccount(); - const results = await when(watch(allVows([lcaP, E(lcaP).getAddress()]))); + const results = await when(watch(all([lcaP, E(lcaP).getAddress()]))); t.is(results.length, 2); const [acct, address] = results; t.is(getInterfaceOf(acct), 'Alleged: Account'); @@ -168,9 +186,9 @@ test('allVows supports Promise pipelining', async t => { ); }); -test('allVows does NOT support Vow pipelining', async t => { +test('vowTools.all does NOT support Vow pipelining', async t => { const zone = makeHeapZone(); - const { watch, when, allVows } = prepareVowTools(zone); + const { watch, when, all } = prepareBasicVowTools(zone); // makeAccount returns a Vow const prepareLocalChainVowish = makeAccount => { @@ -195,14 +213,14 @@ test('allVows does NOT support Vow pipelining', async t => { const lcaP = E(Localchain).makeAccount(); // @ts-expect-error Property 'getAddress' does not exist on type // 'EMethods & { payload: VowPayload; }>>'. - await t.throwsAsync(when(watch(allVows([lcaP, E(lcaP).getAddress()]))), { + await t.throwsAsync(when(watch(all([lcaP, E(lcaP).getAddress()]))), { message: 'target has no method "getAddress", has []', }); }); test('asPromise converts a vow to a promise', async t => { const zone = makeHeapZone(); - const { watch, asPromise } = prepareVowTools(zone); + const { watch, asPromise } = prepareBasicVowTools(zone); const testPromiseP = Promise.resolve('test value'); const vow = watch(testPromiseP); @@ -213,9 +231,9 @@ test('asPromise converts a vow to a promise', async t => { test('asPromise handles vow rejection', async t => { const zone = makeHeapZone(); - const { watch, asPromise } = prepareVowTools(zone); + const { watch, asPromise } = prepareBasicVowTools(zone); - const testPromiseP = Promise.reject(new Error('test error')); + const testPromiseP = Promise.reject(Error('test error')); const vow = watch(testPromiseP); await t.throwsAsync(asPromise(vow), { message: 'test error' }); @@ -223,7 +241,7 @@ test('asPromise handles vow rejection', async t => { test('asPromise accepts and resolves promises', async t => { const zone = makeHeapZone(); - const { asPromise } = prepareVowTools(zone); + const { asPromise } = prepareBasicVowTools(zone); const p = Promise.resolve('a promise'); const result = await asPromise(p); @@ -232,7 +250,7 @@ test('asPromise accepts and resolves promises', async t => { test('asPromise handles watcher arguments', async t => { const zone = makeHeapZone(); - const { watch, asPromise } = prepareVowTools(zone); + const { watch, asPromise } = prepareBasicVowTools(zone); const testPromiseP = Promise.resolve('watcher test'); const vow = watch(testPromiseP); @@ -252,3 +270,109 @@ test('asPromise handles watcher arguments', async t => { t.is(result, 'watcher test'); t.true(watcherCalled); }); + +test('vowTools.all handles unstorable results', async t => { + const zone = makeHeapZone(); + const { watch, when, all } = prepareBasicVowTools(zone); + + const nonPassable = () => 'i am a function'; + + const specimenA = Promise.resolve('i am a promise'); + const specimenB = watch(nonPassable); + + const result = await when(all([specimenA, specimenB])); + t.is(result.length, 2); + t.is(result[0], 'i am a promise'); + t.is(result[1], nonPassable); + t.is(result[1](), 'i am a function'); +}); + +test('vowTools.allSettled handles mixed fulfilled and rejected vows', async t => { + const zone = makeHeapZone(); + const { watch, when, allSettled } = prepareBasicVowTools(zone); + + const vowA = watch(Promise.resolve('a')); + const vowB = watch(Promise.reject(new Error('b'))); + const vowC = watch(Promise.resolve('c')); + + const result = await when(allSettled([vowA, vowB, vowC])); + t.is(result.length, 3); + t.deepEqual(result[0], { status: 'fulfilled', value: 'a' }); + t.deepEqual(result[1], { + status: 'rejected', + reason: new Error('b'), + }); + t.deepEqual(result[2], { status: 'fulfilled', value: 'c' }); +}); + +test('vowTools.allSettled accepts any passables', async t => { + const zone = makeHeapZone(); + const { watch, when, allSettled } = prepareBasicVowTools(zone); + + const result = await when( + allSettled([ + watch(Promise.resolve('a')), + watch(Promise.reject(new Error('b'))), + Promise.resolve('c'), + 1n, + { foo: 'e' }, + new Error('f'), + 'g', + undefined, + ]), + ); + t.is(result.length, 8); + t.deepEqual(result[0], { status: 'fulfilled', value: 'a' }); + t.deepEqual(result[1], { + status: 'rejected', + reason: Error('b'), + }); + t.deepEqual(result[2], { status: 'fulfilled', value: 'c' }); + t.deepEqual(result[3], { status: 'fulfilled', value: 1n }); + t.deepEqual(result[4], { status: 'fulfilled', value: { foo: 'e' } }); + t.deepEqual(result[5], { status: 'fulfilled', value: Error('f') }); + t.deepEqual(result[6], { status: 'fulfilled', value: 'g' }); + t.deepEqual(result[7], { status: 'fulfilled', value: undefined }); +}); + +test('vowTools.allSettled returns vows in order', async t => { + const zone = makeHeapZone(); + const { watch, when, allSettled, makeVowKit } = prepareBasicVowTools(zone); + const kit = makeVowKit(); + + const vowA = watch(kit.vow); + const vowB = watch(Promise.resolve('b')); + const vowC = watch(Promise.reject(new Error('c'))); + const allSettledV = allSettled([vowA, vowB, vowC]); + setTimeoutAmbient(() => kit.resolver.resolve('a'), 250); + + const result = await when(allSettledV); + t.is(result.length, 3); + t.deepEqual(result[0], { status: 'fulfilled', value: 'a' }); + t.deepEqual(result[1], { status: 'fulfilled', value: 'b' }); + t.deepEqual(result[2], { + status: 'rejected', + reason: new Error('c'), + }); +}); + +test('vowTools.allSettled handles unstorable results', async t => { + const zone = makeHeapZone(); + const { watch, when, allSettled } = prepareBasicVowTools(zone); + + // it's not recommended to use non-passables with allVows or allSettled, + // but an attempt will be made to store the value + const nonPassable = () => 'im a function'; + t.is(zone.isStorable(nonPassable), false); + + const vowA = watch(Promise.resolve('a')); + const vowB = watch(nonPassable); + + const result = await when(allSettled([vowA, vowB])); + + t.is(result.length, 2); + t.deepEqual(result[0], { status: 'fulfilled', value: 'a' }); + t.deepEqual(result[1], { status: 'fulfilled', value: nonPassable }); + // @ts-expect-error narrowed in line above + t.is(result[1].value(), 'im a function'); +}); diff --git a/packages/vow/test/watch.test.js b/packages/vow/test/watch.test.js index 851b43ae9f4..61ccec95a9b 100644 --- a/packages/vow/test/watch.test.js +++ b/packages/vow/test/watch.test.js @@ -3,7 +3,7 @@ import test from 'ava'; import { makeHeapZone } from '@agoric/base-zone/heap.js'; -import { prepareVowTools } from '../src/tools.js'; +import { prepareBasicVowTools } from '../src/tools.js'; /** * @import {ExecutionContext} from 'ava' @@ -59,7 +59,7 @@ const prepareArityCheckWatcher = (zone, t) => { */ test('ack watcher - shim', async t => { const zone = makeHeapZone(); - const { watch, when, makeVowKit } = prepareVowTools(zone); + const { watch, when, makeVowKit } = prepareBasicVowTools(zone); const makeAckWatcher = prepareAckWatcher(zone, t); const packet = harden({ portId: 'port-1', channelId: 'channel-1' }); @@ -112,7 +112,7 @@ test('ack watcher - shim', async t => { */ test('watcher args arity - shim', async t => { const zone = makeHeapZone(); - const { watch, when, makeVowKit } = prepareVowTools(zone); + const { watch, when, makeVowKit } = prepareBasicVowTools(zone); const makeArityCheckWatcher = prepareArityCheckWatcher(zone, t); const testCases = /** @type {const} */ ({ @@ -173,7 +173,7 @@ test('watcher args arity - shim', async t => { test('vow self resolution', async t => { const zone = makeHeapZone(); - const { watch, when, makeVowKit } = prepareVowTools(zone); + const { watch, when, makeVowKit } = prepareBasicVowTools(zone); // A direct self vow resolution const { vow: vow1, resolver: resolver1 } = makeVowKit(); @@ -226,7 +226,7 @@ test('vow self resolution', async t => { test('disconnection of non-vow informs watcher', async t => { const zone = makeHeapZone(); - const { watch, when } = prepareVowTools(zone, { + const { watch, when } = prepareBasicVowTools(zone, { isRetryableReason: reason => reason === 'disconnected', }); diff --git a/packages/vow/vat.js b/packages/vow/vat.js index cc1170eaa7e..a486730b9c4 100644 --- a/packages/vow/vat.js +++ b/packages/vow/vat.js @@ -7,7 +7,9 @@ // @ts-check import { isUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js'; import { makeHeapZone } from '@agoric/base-zone/heap.js'; -import { makeE, prepareVowTools as rawPrepareVowTools } from './src/index.js'; + +import { prepareBasicVowTools } from './src/tools.js'; +import makeE from './src/E.js'; /** @type {import('./src/types.js').IsRetryableReason} */ const isRetryableReason = (reason, priorRetryValue) => { @@ -28,13 +30,17 @@ export const defaultPowers = harden({ /** * Produce SwingSet-compatible vowTools, with an arbitrary Zone type * - * @type {typeof rawPrepareVowTools} + * @type {typeof prepareBasicVowTools} */ export const prepareSwingsetVowTools = (zone, powers = {}) => - rawPrepareVowTools(zone, { ...defaultPowers, ...powers }); + prepareBasicVowTools(zone, { ...defaultPowers, ...powers }); +harden(prepareSwingsetVowTools); -/** @deprecated */ -export const prepareVowTools = prepareSwingsetVowTools; +/** + * Reexport as prepareVowTools, since that's the thing that people find easiest + * to reach. + */ +export { prepareSwingsetVowTools as prepareVowTools }; /** * `vowTools` that are not durable, but are useful in non-durable clients that diff --git a/packages/wallet/api/deploy.js b/packages/wallet/api/deploy.js index deb72b241c7..0ee5eb17d48 100644 --- a/packages/wallet/api/deploy.js +++ b/packages/wallet/api/deploy.js @@ -16,6 +16,7 @@ export default async function deployWallet( // console.log('have home', home); const { agoric: { + DISCONNECTED, agoricNames, bank, namesByAddress, @@ -27,6 +28,11 @@ export default async function deployWallet( local: { http, localTimerService, spawner, wallet: oldWallet, scratch }, } = home; + if (DISCONNECTED) { + console.warn(DISCONNECTED); + return; + } + let walletVat = await E(scratch).get('wallet/api'); if (!walletVat) { // Bundle the wallet sources. diff --git a/packages/wallet/api/package.json b/packages/wallet/api/package.json index 572196f329a..1c7873b3c2d 100644 --- a/packages/wallet/api/package.json +++ b/packages/wallet/api/package.json @@ -15,13 +15,13 @@ }, "devDependencies": { "@agoric/vats": "^0.15.1", - "@endo/bundle-source": "^3.2.3", - "@endo/far": "^1.1.2", - "@endo/init": "^1.1.2", + "@endo/bundle-source": "^3.4.0", + "@endo/far": "^1.1.5", + "@endo/init": "^1.1.4", "ava": "^5.3.0" }, "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/cache": "^0.3.2", "@agoric/ertp": "^0.16.2", "@agoric/internal": "^0.3.2", @@ -32,10 +32,10 @@ "@agoric/vat-data": "^0.5.2", "@agoric/zoe": "^0.26.2", "@agoric/zone": "^0.2.2", - "@endo/eventual-send": "^1.2.2", - "@endo/marshal": "^1.5.0", - "@endo/nat": "^5.0.7", - "@endo/promise-kit": "^1.1.2", + "@endo/eventual-send": "^1.2.5", + "@endo/marshal": "^1.5.3", + "@endo/nat": "^5.0.10", + "@endo/promise-kit": "^1.1.5", "import-meta-resolve": "^2.2.1" }, "keywords": [], diff --git a/packages/xsnap-lockdown/package.json b/packages/xsnap-lockdown/package.json index 19dd8d1d515..ea9d612118e 100644 --- a/packages/xsnap-lockdown/package.json +++ b/packages/xsnap-lockdown/package.json @@ -20,8 +20,8 @@ "test:xs": "exit 0" }, "devDependencies": { - "@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", "rollup": "^2.58.0", diff --git a/packages/xsnap/api.js b/packages/xsnap/api.js index 9c0140bbab7..627cf7e4465 100644 --- a/packages/xsnap/api.js +++ b/packages/xsnap/api.js @@ -7,7 +7,7 @@ * Also, update golden master test/xs-perf.test.js to reflect new meter * version. */ -export const METER_TYPE = 'xs-meter-28'; +export const METER_TYPE = 'xs-meter-30'; export const ExitCode = { E_UNKNOWN_ERROR: -1, diff --git a/packages/xsnap/package.json b/packages/xsnap/package.json index eb2914b77d2..c3b9db78cc3 100644 --- a/packages/xsnap/package.json +++ b/packages/xsnap/package.json @@ -28,22 +28,22 @@ "test:xs": "exit 0" }, "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/internal": "^0.3.2", "@agoric/xsnap-lockdown": "^0.14.0", - "@endo/bundle-source": "^3.2.3", - "@endo/eventual-send": "^1.2.2", - "@endo/init": "^1.1.2", - "@endo/netstring": "^1.0.7", - "@endo/promise-kit": "^1.1.2", - "@endo/stream": "^1.2.2", - "@endo/stream-node": "^1.1.2", + "@endo/bundle-source": "^3.4.0", + "@endo/eventual-send": "^1.2.5", + "@endo/init": "^1.1.4", + "@endo/netstring": "^1.0.10", + "@endo/promise-kit": "^1.1.5", + "@endo/stream": "^1.2.5", + "@endo/stream-node": "^1.1.5", "glob": "^7.1.6", "tmp": "^0.2.1" }, "devDependencies": { - "@endo/base64": "^1.0.5", - "@endo/nat": "^5.0.7", + "@endo/base64": "^1.0.7", + "@endo/nat": "^5.0.10", "@types/glob": "^8.1.0", "ava": "^5.3.0", "c8": "^9.1.0" @@ -76,6 +76,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 93.99 + "atLeast": 94.04 } } diff --git a/packages/xsnap/src/avaXS.js b/packages/xsnap/src/avaXS.js index cf70025394f..28bb74df5b7 100644 --- a/packages/xsnap/src/avaXS.js +++ b/packages/xsnap/src/avaXS.js @@ -9,6 +9,7 @@ Usage: import '@endo/init'; import fs from 'fs'; +import { fileURLToPath } from 'url'; import { tmpName } from 'tmp'; import { assert, q, Fail } from '@endo/errors'; @@ -21,7 +22,7 @@ const avaHandler = `./avaHandler.cjs`; /** @type { (ref: string, readFile: typeof import('fs').promises.readFile ) => Promise } */ const asset = (ref, readFile) => - readFile(new URL(ref, import.meta.url).pathname, 'utf8'); + readFile(fileURLToPath(new URL(ref, import.meta.url)), 'utf8'); /** * When we bundle test scripts, we leave these externals diff --git a/packages/xsnap/src/build.js b/packages/xsnap/src/build.js index 23032349121..5583d74d868 100644 --- a/packages/xsnap/src/build.js +++ b/packages/xsnap/src/build.js @@ -1,13 +1,14 @@ #!/usr/bin/env node /* global process */ import * as childProcessTop from 'child_process'; +import { fileURLToPath } from 'url'; import fsTop from 'fs'; import osTop from 'os'; const { freeze } = Object; /** @param {string} path */ -const asset = path => new URL(path, import.meta.url).pathname; +const asset = path => fileURLToPath(new URL(path, import.meta.url)); const ModdableSDK = { MODDABLE: asset('../moddable'), @@ -341,7 +342,7 @@ async function main(args, { env, stdout, spawn, fs, os }) { if (isWorkingCopy || showEnv) { if (showEnv && !isWorkingCopy) { - throw new Error('XSnap requires a working copy and git to --show-env'); + throw Error('XSnap requires a working copy and git to --show-env'); } await updateSubmodules(showEnv, { env, stdout, spawn, fs }); hasSource = true; @@ -362,7 +363,7 @@ async function main(args, { env, stdout, spawn, fs, os }) { } await makeXsnap({ spawn, fs, os }, { forceBuild }); } else if (!hasBin) { - throw new Error( + throw Error( 'XSnap has neither sources nor a pre-built binary. Docker? .dockerignore? npm files?', ); } diff --git a/packages/xsnap/src/replay.js b/packages/xsnap/src/replay.js index e8843a39453..c806743ee16 100644 --- a/packages/xsnap/src/replay.js +++ b/packages/xsnap/src/replay.js @@ -13,6 +13,7 @@ import osPowers from 'os'; import fsPowers from 'fs'; import { Readable } from 'stream'; import { tmpName as tmpNamePower } from 'tmp'; +import { fileURLToPath } from 'url'; import { makeQueue } from '@endo/stream'; import { xsnap, DEFAULT_CRANK_METERING_LIMIT } from './xsnap.js'; @@ -38,7 +39,9 @@ function makeSyncStorage(path, { writeFileSync }) { file: fn => { /** @param {Uint8Array} data */ const put = data => - writeFileSync(new URL(fn, base).pathname, data, { flag: 'wx' }); + writeFileSync(fileURLToPath(new URL(fn, base)), data, { + flag: 'wx', + }); return freeze({ put, @@ -60,14 +63,18 @@ function makeSyncAccess(path, { readdirSync, readFileSync }) { const base = new URL(path, 'file://'); /** @param {string} fn */ const file = fn => { - const fullname = new URL(fn, base).pathname; + const fullname = fileURLToPath(new URL(fn, base)); return freeze({ getData: () => readFileSync(fullname), getText: () => readFileSync(fullname, 'utf-8'), }); }; - return freeze({ path, file, readdir: () => readdirSync(base.pathname) }); + return freeze({ + path, + file, + readdir: () => readdirSync(fileURLToPath(base)), + }); } /** @@ -320,7 +327,7 @@ export async function main( } /* global process */ -if (process.argv[1] === new URL(import.meta.url).pathname) { +if (process.argv[1] === fileURLToPath(new URL(import.meta.url))) { main([...process.argv.slice(2)], { spawn: childProcessPowers.spawn, fs: { ...fsPowers, ...fsPowers.promises }, diff --git a/packages/xsnap/src/xsnap.js b/packages/xsnap/src/xsnap.js index a6a87223330..dcce6295a07 100644 --- a/packages/xsnap/src/xsnap.js +++ b/packages/xsnap/src/xsnap.js @@ -4,6 +4,7 @@ import { finished } from 'stream/promises'; import { PassThrough, Readable } from 'stream'; import { promisify } from 'util'; +import { fileURLToPath } from 'url'; import { Fail, q } from '@endo/errors'; import { makeNetstringReader, makeNetstringWriter } from '@endo/netstring'; import { makeNodeReader, makeNodeWriter } from '@endo/stream-node'; @@ -174,12 +175,14 @@ export async function xsnap(options) { throw Error(`xsnap does not support platform ${os}`); } - let bin = new URL( - `../xsnap-native/xsnap/build/bin/${platform}/${ - debug ? 'debug' : 'release' - }/xsnap-worker`, - import.meta.url, - ).pathname; + let bin = fileURLToPath( + new URL( + `../xsnap-native/xsnap/build/bin/${platform}/${ + debug ? 'debug' : 'release' + }/xsnap-worker`, + import.meta.url, + ), + ); /** @type {PromiseKit} */ const vatExit = makePromiseKit(); @@ -287,7 +290,7 @@ export async function xsnap(options) { * @template T * @typedef {object} RunResult * @property {T} reply - * @property {{ meterType: string, allocate: number|null, compute: number|null, timestamps: number[]|null }} meterUsage + * @property {{ meterType: string, allocate: number|null, compute: number|null, currentHeapCount: number|null, timestamps: number[]|null }} meterUsage */ /** @@ -312,7 +315,12 @@ export async function xsnap(options) { xsnapProcess.kill(); throw Error('xsnap protocol error: received empty message'); } else if (message[0] === OK) { - let meterInfo = { compute: null, allocate: null, timestamps: [] }; + let meterInfo = { + compute: null, + allocate: null, + currentHeapCount: null, + timestamps: [], + }; const meterSeparator = message.indexOf(OK_SEPARATOR, 1); if (meterSeparator >= 0) { // The message is `.meterdata\1reply`. diff --git a/packages/xsnap/test/leakiness.mjs b/packages/xsnap/test/leakiness.mjs index 96534df237b..5b588268387 100644 --- a/packages/xsnap/test/leakiness.mjs +++ b/packages/xsnap/test/leakiness.mjs @@ -4,6 +4,7 @@ // See below for usage detail about the latter. import 'ses'; import '@endo/eventual-send/shim.js'; +// @ts-expect-error Cannot find module import 'data:text/javascript,try { lockdown(); } catch (_err) {}'; import * as proc from 'child_process'; diff --git a/packages/xsnap/test/xs-limits.test.js b/packages/xsnap/test/xs-limits.test.js index 58aa10522ba..7f9b6613cd7 100644 --- a/packages/xsnap/test/xs-limits.test.js +++ b/packages/xsnap/test/xs-limits.test.js @@ -89,7 +89,7 @@ test.skip('property name space exhaustion: orderly fail-stop', async t => { const vat = await xsnap({ ...opts, parserBufferSize }); t.teardown(() => vat.terminate()); const expected = failure ? [failure] : [qty * 4 + 2]; - await t.notThrowsAsync(vat.evaluate(grow(qty))); + await vat.evaluate(grow(qty)); t.deepEqual( expected, opts.messages.map(txt => JSON.parse(txt)), diff --git a/packages/xsnap/test/xs-perf.test.js b/packages/xsnap/test/xs-perf.test.js index 761316dacd9..b1fe95bf7d4 100644 --- a/packages/xsnap/test/xs-perf.test.js +++ b/packages/xsnap/test/xs-perf.test.js @@ -47,7 +47,7 @@ test('meter details', async t => { t.like( meters, - { compute: 1_380_185, allocate: 42_074_144 }, + { compute: 1_380_185, allocate: 42_074_144, currentHeapCount: 103_930 }, 'compute, allocate meters should be stable; update METER_TYPE?', ); diff --git a/packages/zoe/package.json b/packages/zoe/package.json index ea3d903a602..0f1c34fc306 100644 --- a/packages/zoe/package.json +++ b/packages/zoe/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 --verbose", "test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js", "test:unit": "ava 'test/unitTests' -T 1m --verbose", @@ -43,7 +43,7 @@ }, "homepage": "https://github.com/Agoric/agoric-sdk#readme", "dependencies": { - "@endo/errors": "^1.2.2", + "@endo/errors": "^1.2.5", "@agoric/base-zone": "^0.1.0", "@agoric/ertp": "^0.16.2", "@agoric/internal": "^0.3.2", @@ -55,22 +55,22 @@ "@agoric/vat-data": "^0.5.2", "@agoric/vow": "^0.1.0", "@agoric/zone": "^0.2.2", - "@endo/bundle-source": "^3.2.3", - "@endo/common": "^1.2.2", - "@endo/captp": "^4.2.0", - "@endo/eventual-send": "^1.2.2", - "@endo/exo": "^1.5.0", - "@endo/far": "^1.1.2", - "@endo/import-bundle": "^1.1.2", - "@endo/marshal": "^1.5.0", - "@endo/nat": "^5.0.7", - "@endo/pass-style": "^1.4.0", - "@endo/patterns": "^1.4.0", - "@endo/promise-kit": "^1.1.2", + "@endo/bundle-source": "^3.4.0", + "@endo/common": "^1.2.5", + "@endo/captp": "^4.3.0", + "@endo/eventual-send": "^1.2.5", + "@endo/exo": "^1.5.3", + "@endo/far": "^1.1.5", + "@endo/import-bundle": "^1.2.2", + "@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", "yargs-parser": "^21.1.1" }, "devDependencies": { - "@endo/init": "^1.1.2", + "@endo/init": "^1.1.4", "@agoric/kmarshal": "^0.1.0", "ava": "^5.3.0", "c8": "^9.1.0", @@ -141,6 +141,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 84.99 + "atLeast": 85.01 } } diff --git a/packages/zoe/src/contractFacet/types-ambient.d.ts b/packages/zoe/src/contractFacet/types-ambient.d.ts index bb41fe7e823..d7de2903eb6 100644 --- a/packages/zoe/src/contractFacet/types-ambient.d.ts +++ b/packages/zoe/src/contractFacet/types-ambient.d.ts @@ -85,7 +85,10 @@ type ZCF> = { getOfferFilter: () => Promise>; getInstance: () => Instance; }; + /** + * @deprecated Use atomicRearrange instead + * * The contract can reallocate over seats, which commits the staged * allocation for each seat. On commit, the staged allocation becomes * the current allocation and the staged allocation is deleted. @@ -209,7 +212,7 @@ type ZCFSeat = import('@endo/pass-style').RemotableObject & { }; type ZcfSeatKit = { zcfSeat: ZCFSeat; - userSeat: ERef; + userSeat: Promise; }; type HandleOffer = (seat: ZCFSeat, offerArgs: OA) => OR; type OfferHandler = diff --git a/packages/zoe/src/contractFacet/zcfMint.js b/packages/zoe/src/contractFacet/zcfMint.js index 085747285cf..1c07c0d0dc4 100644 --- a/packages/zoe/src/contractFacet/zcfMint.js +++ b/packages/zoe/src/contractFacet/zcfMint.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { Fail } from '@endo/errors'; import { E } from '@endo/eventual-send'; import { AmountMath } from '@agoric/ertp'; diff --git a/packages/zoe/src/contractFacet/zcfSeat.js b/packages/zoe/src/contractFacet/zcfSeat.js index 4e9e5b59fce..1e304abdfa3 100644 --- a/packages/zoe/src/contractFacet/zcfSeat.js +++ b/packages/zoe/src/contractFacet/zcfSeat.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { annotateError, Fail } from '@endo/errors'; import { E } from '@endo/eventual-send'; import { diff --git a/packages/zoe/src/contractFacet/zcfZygote.js b/packages/zoe/src/contractFacet/zcfZygote.js index b044f311ee7..a63a25e9fbb 100644 --- a/packages/zoe/src/contractFacet/zcfZygote.js +++ b/packages/zoe/src/contractFacet/zcfZygote.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { Fail } from '@endo/errors'; import { E } from '@endo/eventual-send'; import { passStyleOf } from '@endo/pass-style'; diff --git a/packages/zoe/src/contractSupport/priceAuthority.js b/packages/zoe/src/contractSupport/priceAuthority.js index ae88e854ab0..82be9565080 100644 --- a/packages/zoe/src/contractSupport/priceAuthority.js +++ b/packages/zoe/src/contractSupport/priceAuthority.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { q, Fail } from '@endo/errors'; import { E } from '@endo/eventual-send'; import { Far } from '@endo/marshal'; diff --git a/packages/zoe/src/contractSupport/priceAuthorityInitial.js b/packages/zoe/src/contractSupport/priceAuthorityInitial.js index 110c5affc9b..b5378654542 100644 --- a/packages/zoe/src/contractSupport/priceAuthorityInitial.js +++ b/packages/zoe/src/contractSupport/priceAuthorityInitial.js @@ -1,6 +1,5 @@ // @ts-check // @jessie-check -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { E } from '@endo/far'; import { Far } from '@endo/marshal'; diff --git a/packages/zoe/src/contractSupport/ratio.js b/packages/zoe/src/contractSupport/ratio.js index 9beb84852c5..72dd7b22498 100644 --- a/packages/zoe/src/contractSupport/ratio.js +++ b/packages/zoe/src/contractSupport/ratio.js @@ -158,17 +158,26 @@ const divideHelper = (amount, ratio, divideOp) => { ); }; -/** @type {ScaleAmount} */ +/** + * Divide the amount by the ratio, truncating the remainder. + * @type {ScaleAmount} + */ export const floorDivideBy = (amount, ratio) => { return divideHelper(amount, ratio, floorDivide); }; -/** @type {ScaleAmount} */ +/** + * Divide the amount by the ratio, rounding up the remainder. + * @type {ScaleAmount} + */ export const ceilDivideBy = (amount, ratio) => { return divideHelper(amount, ratio, ceilDivide); }; -/** @type {ScaleAmount} */ +/** + * Divide the amount by the ratio, rounding to nearest with ties to even (aka Banker's Rounding) as in IEEE 754 default rounding. + * @type {ScaleAmount} + */ export const divideBy = (amount, ratio) => { return divideHelper(amount, ratio, bankersDivide); }; @@ -334,7 +343,8 @@ export const ratiosSame = (left, right) => { }; /** - * Make an equivalant ratio with a new denominator + * Make a new ratio with a smaller denominator that approximates the ratio. If + * the proposed denominator is larger than the current one, return the original. * * @param {Ratio} ratio * @param {bigint} newDen @@ -343,6 +353,10 @@ export const ratiosSame = (left, right) => { export const quantize = (ratio, newDen) => { const oldDen = ratio.denominator.value; const oldNum = ratio.numerator.value; + if (newDen > oldDen) { + return ratio; + } + const newNum = newDen === oldDen ? oldNum : bankersDivide(oldNum * newDen, oldDen); return makeRatio( diff --git a/packages/zoe/src/contractSupport/topics.js b/packages/zoe/src/contractSupport/topics.js index b2a93d83bb9..5c25b28976f 100644 --- a/packages/zoe/src/contractSupport/topics.js +++ b/packages/zoe/src/contractSupport/topics.js @@ -2,6 +2,10 @@ import { SubscriberShape } from '@agoric/notifier'; import { M } from '@agoric/store'; import { E } from '@endo/far'; +/** + * @import {Remote} from '@agoric/internal'; + */ + export { SubscriberShape }; export const PublicTopicShape = M.splitRecord( @@ -22,14 +26,14 @@ export const PublicTopicShape = M.splitRecord( */ /** - * A {PublicTopic} in which the `storagePath` is always a resolved string. + * A {PublicTopic} in which the `storagePath` is always a resolved string and the `subscriber is remote. * * Useful when working with Vows and async-flow. * * @template {object} T topic value * @typedef {{ * description?: string, - * subscriber: Subscriber, + * subscriber: Remote>, * storagePath: string, * }} ResolvedPublicTopic */ diff --git a/packages/zoe/src/contractSupport/zoeHelpers.js b/packages/zoe/src/contractSupport/zoeHelpers.js index 46886ba5c3f..45a0c5c5732 100644 --- a/packages/zoe/src/contractSupport/zoeHelpers.js +++ b/packages/zoe/src/contractSupport/zoeHelpers.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { Fail } from '@endo/errors'; import { E } from '@endo/eventual-send'; import { makePromiseKit } from '@endo/promise-kit'; diff --git a/packages/zoe/src/contracts/auction/index.js b/packages/zoe/src/contracts/auction/index.js index d6b2f432960..fd3bc2060ca 100644 --- a/packages/zoe/src/contracts/auction/index.js +++ b/packages/zoe/src/contracts/auction/index.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { Fail } from '@endo/errors'; import { E } from '@endo/eventual-send'; import { mustMatch } from '@endo/patterns'; diff --git a/packages/zoe/src/contracts/callSpread/payoffHandler.js b/packages/zoe/src/contracts/callSpread/payoffHandler.js index e8b6619e443..5825b494bab 100644 --- a/packages/zoe/src/contracts/callSpread/payoffHandler.js +++ b/packages/zoe/src/contracts/callSpread/payoffHandler.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ /// import { E } from '@endo/eventual-send'; diff --git a/packages/zoe/src/contracts/callSpread/pricedCallSpread.js b/packages/zoe/src/contracts/callSpread/pricedCallSpread.js index 358124b2da3..93838be87ea 100644 --- a/packages/zoe/src/contracts/callSpread/pricedCallSpread.js +++ b/packages/zoe/src/contracts/callSpread/pricedCallSpread.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ /// import { Fail } from '@endo/errors'; diff --git a/packages/zoe/src/contracts/loan/scheduleLiquidation.js b/packages/zoe/src/contracts/loan/scheduleLiquidation.js index 6ec50838cb1..cf040bb2c9f 100644 --- a/packages/zoe/src/contracts/loan/scheduleLiquidation.js +++ b/packages/zoe/src/contracts/loan/scheduleLiquidation.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { E } from '@endo/eventual-send'; import { AmountMath } from '@agoric/ertp'; diff --git a/packages/zoe/src/contracts/oracle.js b/packages/zoe/src/contracts/oracle.js index f9338017418..96f7c6cdd15 100644 --- a/packages/zoe/src/contracts/oracle.js +++ b/packages/zoe/src/contracts/oracle.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { assert, Fail } from '@endo/errors'; import { Far } from '@endo/marshal'; import { AmountMath } from '@agoric/ertp'; diff --git a/packages/zoe/src/contracts/priceAggregator.js b/packages/zoe/src/contracts/priceAggregator.js index fe291e24898..0a50a514c82 100644 --- a/packages/zoe/src/contracts/priceAggregator.js +++ b/packages/zoe/src/contracts/priceAggregator.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { Fail, q } from '@endo/errors'; import { AmountMath, AssetKind, makeIssuerKit } from '@agoric/ertp'; import { assertAllDefined } from '@agoric/internal'; diff --git a/packages/zoe/src/contracts/sellItems.js b/packages/zoe/src/contracts/sellItems.js index 4a53a8536c1..2376011a2cf 100644 --- a/packages/zoe/src/contracts/sellItems.js +++ b/packages/zoe/src/contracts/sellItems.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { Fail } from '@endo/errors'; import { Far } from '@endo/marshal'; import { Nat } from '@endo/nat'; diff --git a/packages/zoe/src/zoeService/instanceAdminStorage.js b/packages/zoe/src/zoeService/instanceAdminStorage.js index 632da3f92ad..65ff6ae1dc4 100644 --- a/packages/zoe/src/zoeService/instanceAdminStorage.js +++ b/packages/zoe/src/zoeService/instanceAdminStorage.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { canBeDurable, makeScalarBigSetStore, diff --git a/packages/zoe/src/zoeService/originalZoeSeat.js b/packages/zoe/src/zoeService/originalZoeSeat.js index cee45bd20dc..f60d02057a6 100644 --- a/packages/zoe/src/zoeService/originalZoeSeat.js +++ b/packages/zoe/src/zoeService/originalZoeSeat.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { Fail } from '@endo/errors'; import { SubscriberShape } from '@agoric/notifier'; import { E } from '@endo/eventual-send'; diff --git a/packages/zoe/src/zoeService/startInstance.js b/packages/zoe/src/zoeService/startInstance.js index 79d1d8470f9..ae3d1487cf5 100644 --- a/packages/zoe/src/zoeService/startInstance.js +++ b/packages/zoe/src/zoeService/startInstance.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { E } from '@endo/eventual-send'; import { passStyleOf } from '@endo/marshal'; import { diff --git a/packages/zoe/src/zoeService/utils.d.ts b/packages/zoe/src/zoeService/utils.d.ts index 6ef63ce49a8..1b27843320c 100644 --- a/packages/zoe/src/zoeService/utils.d.ts +++ b/packages/zoe/src/zoeService/utils.d.ts @@ -7,6 +7,7 @@ import type { TagContainer } from '@agoric/internal/src/tagged.js'; import type { Baggage } from '@agoric/swingset-liveslots'; import type { VatUpgradeResults } from '@agoric/swingset-vat'; import type { RemotableObject } from '@endo/marshal'; +import type { FarRef } from '@endo/far'; // XXX https://github.com/Agoric/agoric-sdk/issues/4565 type SourceBundle = Record; @@ -33,7 +34,7 @@ export type ContractStartFunction = ( baggage?: Baggage, ) => ERef<{ creatorFacet?: {}; publicFacet?: {} }>; -export type AdminFacet = RemotableObject & { +export type AdminFacet = FarRef<{ // Completion, which is currently any getVatShutdownPromise: () => Promise; upgradeContract: Parameters[1] extends undefined @@ -45,7 +46,7 @@ export type AdminFacet = RemotableObject & { restartContract: Parameters[1] extends undefined ? () => Promise : (newPrivateArgs: Parameters[1]) => Promise; -}; +}>; export type StartParams = SF extends ContractStartFunction ? Parameters[1] extends undefined diff --git a/packages/zoe/src/zoeService/utils.test-d.ts b/packages/zoe/src/zoeService/utils.test-d.ts index f92a163e30f..90c61472899 100644 --- a/packages/zoe/src/zoeService/utils.test-d.ts +++ b/packages/zoe/src/zoeService/utils.test-d.ts @@ -1,3 +1,4 @@ +import { E } from '@endo/far'; import type { StartedInstanceKit } from './utils'; const someContractStartFn = ( @@ -10,24 +11,24 @@ type PsmInstanceKit = StartedInstanceKit; const psmInstanceKit: PsmInstanceKit = null as any; // @ts-expect-error missing privateArgs argument -void psmInstanceKit.adminFacet.restartContract(); +void E(psmInstanceKit.adminFacet).restartContract(); const partial = { someNumber: 1, }; // @ts-expect-error missing member of privateArgs argument -void psmInstanceKit.adminFacet.restartContract(partial); +void E(psmInstanceKit.adminFacet).restartContract(partial); // valid privateArgs now with 'marshaller' -void psmInstanceKit.adminFacet.restartContract({ +void E(psmInstanceKit.adminFacet).restartContract({ ...partial, someString: 'str', }); // @ts-expect-error missing member of privateArgs argument -void psmInstanceKit.adminFacet.upgradeContract('whatever', partial); +void E(psmInstanceKit.adminFacet).upgradeContract('whatever', partial); // valid privateArgs now with 'marshaller' -void psmInstanceKit.adminFacet.upgradeContract('whatever', { +void E(psmInstanceKit.adminFacet).upgradeContract('whatever', { ...partial, someString: 'str', }); diff --git a/packages/zoe/src/zoeService/zoe.js b/packages/zoe/src/zoeService/zoe.js index 24a64f85a04..44990d6e4c1 100644 --- a/packages/zoe/src/zoeService/zoe.js +++ b/packages/zoe/src/zoeService/zoe.js @@ -1,5 +1,4 @@ // @jessie-check -/* eslint @typescript-eslint/no-floating-promises: "warn" */ /** * Zoe uses ERTP, the Electronic Rights Transfer Protocol diff --git a/packages/zoe/src/zoeService/zoeSeat.js b/packages/zoe/src/zoeService/zoeSeat.js index c6d58c6d29d..acaae2e2c20 100644 --- a/packages/zoe/src/zoeService/zoeSeat.js +++ b/packages/zoe/src/zoeService/zoeSeat.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { Fail } from '@endo/errors'; import { prepareDurablePublishKit } from '@agoric/notifier'; import { E } from '@endo/eventual-send'; diff --git a/packages/zoe/test/unitTests/contractSupport/ratio.test.js b/packages/zoe/test/unitTests/contractSupport/ratio.test.js index 2c7896a5ad6..8a4632b5fc5 100644 --- a/packages/zoe/test/unitTests/contractSupport/ratio.test.js +++ b/packages/zoe/test/unitTests/contractSupport/ratio.test.js @@ -16,6 +16,7 @@ import { multiplyBy, subtractRatios, parseRatio, + divideBy, } from '../../../src/contractSupport/ratio.js'; /** @@ -461,6 +462,20 @@ test('ratio - rounding', t => { assertRounding(25n, 2n, 12n, floorMultiplyBy); assertRounding(25n, 2n, 12n, multiplyBy); assertRounding(25n, 2n, 13n, ceilMultiplyBy); + + // 23 / 12 = 1.9 + const twelve = makeRatioFromAmounts(moe(12n), moe(1n)); + amountsEqual(t, floorDivideBy(moe(23n), twelve), moe(1n), brand); + amountsEqual(t, ceilDivideBy(moe(23n), twelve), moe(2n), brand); + amountsEqual(t, divideBy(moe(23n), twelve), moe(2n), brand); + + // banker's rounding + const divideByTen = n => + divideBy(moe(n), makeRatioFromAmounts(moe(10n), moe(1n))); + amountsEqual(t, divideByTen(114n), moe(11n), brand); // 11.4 -> 11 + amountsEqual(t, divideByTen(115n), moe(12n), brand); // 11.5 -> 12 + amountsEqual(t, divideByTen(125n), moe(12n), brand); // 12.5 -> 12 + amountsEqual(t, divideByTen(126n), moe(13n), brand); // 12.6 -> 13 }); test('ratio - oneMinus', t => { @@ -486,25 +501,25 @@ const { brand } = makeIssuerKit('moe'); test('ratio - quantize', t => { /** @type {Array<[numBefore: bigint, denBefore: bigint, numAfter: bigint, denAfter: bigint]>} */ - const cases = /** @type {const} */ [ + const cases = [ [1n, 1n, 1n, 1n], [10n, 10n, 10n, 10n], [2n * 10n ** 9n, 1n * 10n ** 9n, 20n, 10n], - [12345n, 12345n, 100n, 100n], - [12345n, 12345n, 100000n, 100000n], - [12345n, 12345n, 10n ** 15n, 10n ** 15n], - - [12345n, 123n, 100365854n, 10n ** 6n], - [12345n, 123n, 10036585n, 10n ** 5n], - [12345n, 123n, 1003659n, 10n ** 4n], - [12345n, 123n, 100366n, 10n ** 3n], [12345n, 123n, 10037n, 10n ** 2n], [12345n, 123n, 1004n, 10n ** 1n], [12345n, 123n, 100n, 10n ** 0n], + + [12345n, 12345n, 100n, 100n], ]; - for (const [numBefore, denBefore, numAfter, denAfter] of cases) { + for (const [ + numBefore, + denBefore, + numAfter, + target, + denAfter = target, + ] of cases) { const before = makeRatio(numBefore, brand, denBefore, brand); const after = makeRatio(numAfter, brand, denAfter, brand); t.deepEqual( @@ -515,6 +530,27 @@ test('ratio - quantize', t => { } }); +test('ratio - quantize - leave it alone', t => { + const cases = [ + [12345n, 123n, 10n ** 5n, 12345n, 123n], + [12345n, 123n, 10n ** 4n, 12345n, 123n], + [12345n, 123n, 10n ** 3n, 12345n, 123n], + + [12345n, 12345n, 100_000n, 12345n, 12345n], + [12345n, 12345n, 10n ** 15n, 12345n, 12345n], + ]; + + for (const [numPre, denPre, qTarget, numAfter, denAfter] of cases) { + const before = makeRatio(numPre, brand, denPre, brand); + const after = makeRatio(numAfter, brand, denAfter, brand); + t.deepEqual( + quantize(before, qTarget), + after, + `${numPre}/${denPre} quantized to ${qTarget} should be ${numAfter}/${denAfter}`, + ); + } +}); + test('ratio - parse', t => { const { brand: moeBrand } = makeIssuerKit('moe'); const { brand: larryBrand } = makeIssuerKit('larry'); diff --git a/packages/zoe/tools/manualPriceAuthority.js b/packages/zoe/tools/manualPriceAuthority.js index 0e0c71308ac..9203130fc7e 100644 --- a/packages/zoe/tools/manualPriceAuthority.js +++ b/packages/zoe/tools/manualPriceAuthority.js @@ -1,5 +1,4 @@ // @jessie-check -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { AmountMath, makeIssuerKit, AssetKind } from '@agoric/ertp'; import { E } from '@endo/eventual-send'; diff --git a/packages/zoe/tools/scriptedPriceAuthority.js b/packages/zoe/tools/scriptedPriceAuthority.js index 0d5350860c7..1d01dac4b9a 100644 --- a/packages/zoe/tools/scriptedPriceAuthority.js +++ b/packages/zoe/tools/scriptedPriceAuthority.js @@ -1,4 +1,3 @@ -/* eslint @typescript-eslint/no-floating-promises: "warn" */ import { AmountMath, makeIssuerKit, AssetKind } from '@agoric/ertp'; import { E } from '@endo/eventual-send'; import { Far } from '@endo/marshal'; diff --git a/packages/zone/package.json b/packages/zone/package.json index 32851e8aa00..29bfa7d5445 100644 --- a/packages/zone/package.json +++ b/packages/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", @@ -29,13 +29,13 @@ "dependencies": { "@agoric/base-zone": "^0.1.0", "@agoric/vat-data": "^0.5.2", - "@endo/errors": "^1.2.2", - "@endo/far": "^1.1.2", - "@endo/pass-style": "^1.4.0" + "@endo/errors": "^1.2.5", + "@endo/far": "^1.1.5", + "@endo/pass-style": "^1.4.3" }, "devDependencies": { "@agoric/swingset-liveslots": "^0.10.2", - "@endo/patterns": "^1.4.0", + "@endo/patterns": "^1.4.3", "ava": "^5.3.0" }, "publishConfig": { diff --git a/patches/@agoric+orchestration++@noble+hashes+1.4.0.patch b/patches/@agoric+orchestration++@noble+hashes+1.4.0.patch deleted file mode 100644 index 5c534e1d5bb..00000000000 --- a/patches/@agoric+orchestration++@noble+hashes+1.4.0.patch +++ /dev/null @@ -1,9910 +0,0 @@ -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.d.ts -new file mode 100644 -index 0000000..f66656f ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.d.ts -@@ -0,0 +1,24 @@ -+declare function number(n: number): void; -+declare function bool(b: boolean): void; -+export declare function isBytes(a: unknown): a is Uint8Array; -+declare function bytes(b: Uint8Array | undefined, ...lengths: number[]): void; -+type Hash = { -+ (data: Uint8Array): Uint8Array; -+ blockLen: number; -+ outputLen: number; -+ create: any; -+}; -+declare function hash(h: Hash): void; -+declare function exists(instance: any, checkFinished?: boolean): void; -+declare function output(out: any, instance: any): void; -+export { number, bool, bytes, hash, exists, output }; -+declare const assert: { -+ number: typeof number; -+ bool: typeof bool; -+ bytes: typeof bytes; -+ hash: typeof hash; -+ exists: typeof exists; -+ output: typeof output; -+}; -+export default assert; -+//# sourceMappingURL=_assert.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.d.ts.map -new file mode 100644 -index 0000000..f3420f1 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_assert.d.ts","sourceRoot":"","sources":["src/_assert.ts"],"names":[],"mappings":"AAAA,iBAAS,MAAM,CAAC,CAAC,EAAE,MAAM,QAExB;AAED,iBAAS,IAAI,CAAC,CAAC,EAAE,OAAO,QAEvB;AAGD,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,UAAU,CAKnD;AAED,iBAAS,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,QAI7D;AAED,KAAK,IAAI,GAAG;IACV,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;CACb,CAAC;AACF,iBAAS,IAAI,CAAC,CAAC,EAAE,IAAI,QAKpB;AAED,iBAAS,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,UAAO,QAGlD;AACD,iBAAS,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,QAMtC;AAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAErD,QAAA,MAAM,MAAM;;;;;;;CAAgD,CAAC;AAC7D,eAAe,MAAM,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.js -new file mode 100644 -index 0000000..8740278 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.js -@@ -0,0 +1,50 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.isBytes = isBytes; -+exports.number = number; -+exports.bool = bool; -+exports.bytes = bytes; -+exports.hash = hash; -+exports.exists = exists; -+exports.output = output; -+function number(n) { -+ if (!Number.isSafeInteger(n) || n < 0) -+ throw new Error(`positive integer expected, not ${n}`); -+} -+function bool(b) { -+ if (typeof b !== 'boolean') -+ throw new Error(`boolean expected, not ${b}`); -+} -+// copied from utils -+function isBytes(a) { -+ return (a instanceof Uint8Array || -+ (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array')); -+} -+function bytes(b, ...lengths) { -+ if (!isBytes(b)) -+ throw new Error('Uint8Array expected'); -+ if (lengths.length > 0 && !lengths.includes(b.length)) -+ throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`); -+} -+function hash(h) { -+ if (typeof h !== 'function' || typeof h.create !== 'function') -+ throw new Error('Hash should be wrapped by utils.wrapConstructor'); -+ number(h.outputLen); -+ number(h.blockLen); -+} -+function exists(instance, checkFinished = true) { -+ if (instance.destroyed) -+ throw new Error('Hash instance has been destroyed'); -+ if (checkFinished && instance.finished) -+ throw new Error('Hash#digest() has already been called'); -+} -+function output(out, instance) { -+ bytes(out); -+ const min = instance.outputLen; -+ if (out.length < min) { -+ throw new Error(`digestInto() expects output buffer of length at least ${min}`); -+ } -+} -+const assert = { number, bool, bytes, hash, exists, output }; -+exports.default = assert; -+//# sourceMappingURL=_assert.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.js.map -new file mode 100644 -index 0000000..ac2d77a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_assert.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_assert.js","sourceRoot":"","sources":["src/_assert.ts"],"names":[],"mappings":";;AASA,0BAKC;AAiCQ,wBAAM;AAAE,oBAAI;AAAE,sBAAK;AAAE,oBAAI;AAAE,wBAAM;AAAE,wBAAM;AA/ClD,SAAS,MAAM,CAAC,CAAS;IACvB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,EAAE,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,IAAI,CAAC,CAAU;IACtB,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,oBAAoB;AACpB,SAAgB,OAAO,CAAC,CAAU;IAChC,OAAO,CACL,CAAC,YAAY,UAAU;QACvB,CAAC,CAAC,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,YAAY,CAAC,CAC5E,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,CAAyB,EAAE,GAAG,OAAiB;IAC5D,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,mBAAmB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAC3F,CAAC;AAQD,SAAS,IAAI,CAAC,CAAO;IACnB,IAAI,OAAO,CAAC,KAAK,UAAU,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU;QAC3D,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACpB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,MAAM,CAAC,QAAa,EAAE,aAAa,GAAG,IAAI;IACjD,IAAI,QAAQ,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC5E,IAAI,aAAa,IAAI,QAAQ,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;AACnG,CAAC;AACD,SAAS,MAAM,CAAC,GAAQ,EAAE,QAAa;IACrC,KAAK,CAAC,GAAG,CAAC,CAAC;IACX,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC;IAC/B,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yDAAyD,GAAG,EAAE,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAID,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC7D,kBAAe,MAAM,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.d.ts -new file mode 100644 -index 0000000..ddb3f3a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.d.ts -@@ -0,0 +1,28 @@ -+import { Hash, Input } from './utils.js'; -+export declare const SIGMA: Uint8Array; -+export type BlakeOpts = { -+ dkLen?: number; -+ key?: Input; -+ salt?: Input; -+ personalization?: Input; -+}; -+export declare abstract class BLAKE> extends Hash { -+ readonly blockLen: number; -+ outputLen: number; -+ protected abstract compress(msg: Uint32Array, offset: number, isLast: boolean): void; -+ protected abstract get(): number[]; -+ protected abstract set(...args: number[]): void; -+ abstract destroy(): void; -+ protected buffer: Uint8Array; -+ protected buffer32: Uint32Array; -+ protected length: number; -+ protected pos: number; -+ protected finished: boolean; -+ protected destroyed: boolean; -+ constructor(blockLen: number, outputLen: number, opts: BlakeOpts | undefined, keyLen: number, saltLen: number, persLen: number); -+ update(data: Input): this; -+ digestInto(out: Uint8Array): void; -+ digest(): Uint8Array; -+ _cloneInto(to?: T): T; -+} -+//# sourceMappingURL=_blake.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.d.ts.map -new file mode 100644 -index 0000000..5227d84 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_blake.d.ts","sourceRoot":"","sources":["src/_blake.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAgD,MAAM,YAAY,CAAC;AAMvF,eAAO,MAAM,KAAK,YAahB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,eAAe,CAAC,EAAE,KAAK,CAAC;CACzB,CAAC;AAEF,8BAAsB,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,CAAC,CAAC;IAa3D,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IAb1B,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IACpF,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,MAAM,EAAE;IAClC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAC/C,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC;IAChC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAK;IAC7B,SAAS,CAAC,GAAG,EAAE,MAAM,CAAK;IAC1B,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,SAAS,UAAS;gBAGjB,QAAQ,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACxB,IAAI,EAAE,SAAS,YAAK,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM;IAejB,MAAM,CAAC,IAAI,EAAE,KAAK;IAuClB,UAAU,CAAC,GAAG,EAAE,UAAU;IAa1B,MAAM;IAON,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;CAYtB"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.js -new file mode 100644 -index 0000000..1ecb94c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.js -@@ -0,0 +1,124 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.BLAKE = exports.SIGMA = void 0; -+const _assert_js_1 = require("./_assert.js"); -+const utils_js_1 = require("./utils.js"); -+// Blake is based on ChaCha permutation. -+// For BLAKE2b, the two extra permutations for rounds 10 and 11 are SIGMA[10..11] = SIGMA[0..1]. -+// prettier-ignore -+exports.SIGMA = new Uint8Array([ -+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -+ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, -+ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, -+ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, -+ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, -+ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, -+ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, -+ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, -+ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, -+ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, -+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -+ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, -+]); -+class BLAKE extends utils_js_1.Hash { -+ constructor(blockLen, outputLen, opts = {}, keyLen, saltLen, persLen) { -+ super(); -+ this.blockLen = blockLen; -+ this.outputLen = outputLen; -+ this.length = 0; -+ this.pos = 0; -+ this.finished = false; -+ this.destroyed = false; -+ (0, _assert_js_1.number)(blockLen); -+ (0, _assert_js_1.number)(outputLen); -+ (0, _assert_js_1.number)(keyLen); -+ if (outputLen < 0 || outputLen > keyLen) -+ throw new Error('outputLen bigger than keyLen'); -+ if (opts.key !== undefined && (opts.key.length < 1 || opts.key.length > keyLen)) -+ throw new Error(`key must be up 1..${keyLen} byte long or undefined`); -+ if (opts.salt !== undefined && opts.salt.length !== saltLen) -+ throw new Error(`salt must be ${saltLen} byte long or undefined`); -+ if (opts.personalization !== undefined && opts.personalization.length !== persLen) -+ throw new Error(`personalization must be ${persLen} byte long or undefined`); -+ this.buffer32 = (0, utils_js_1.u32)((this.buffer = new Uint8Array(blockLen))); -+ } -+ update(data) { -+ (0, _assert_js_1.exists)(this); -+ // Main difference with other hashes: there is flag for last block, -+ // so we cannot process current block before we know that there -+ // is the next one. This significantly complicates logic and reduces ability -+ // to do zero-copy processing -+ const { blockLen, buffer, buffer32 } = this; -+ data = (0, utils_js_1.toBytes)(data); -+ const len = data.length; -+ const offset = data.byteOffset; -+ const buf = data.buffer; -+ for (let pos = 0; pos < len;) { -+ // If buffer is full and we still have input (don't process last block, same as blake2s) -+ if (this.pos === blockLen) { -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(buffer32); -+ this.compress(buffer32, 0, false); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(buffer32); -+ this.pos = 0; -+ } -+ const take = Math.min(blockLen - this.pos, len - pos); -+ const dataOffset = offset + pos; -+ // full block && aligned to 4 bytes && not last in input -+ if (take === blockLen && !(dataOffset % 4) && pos + take < len) { -+ const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4)); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(data32); -+ for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) { -+ this.length += blockLen; -+ this.compress(data32, pos32, false); -+ } -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(data32); -+ continue; -+ } -+ buffer.set(data.subarray(pos, pos + take), this.pos); -+ this.pos += take; -+ this.length += take; -+ pos += take; -+ } -+ return this; -+ } -+ digestInto(out) { -+ (0, _assert_js_1.exists)(this); -+ (0, _assert_js_1.output)(out, this); -+ const { pos, buffer32 } = this; -+ this.finished = true; -+ // Padding -+ this.buffer.subarray(pos).fill(0); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(buffer32); -+ this.compress(buffer32, 0, true); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(buffer32); -+ const out32 = (0, utils_js_1.u32)(out); -+ this.get().forEach((v, i) => (out32[i] = (0, utils_js_1.byteSwapIfBE)(v))); -+ } -+ digest() { -+ const { buffer, outputLen } = this; -+ this.digestInto(buffer); -+ const res = buffer.slice(0, outputLen); -+ this.destroy(); -+ return res; -+ } -+ _cloneInto(to) { -+ const { buffer, length, finished, destroyed, outputLen, pos } = this; -+ to || (to = new this.constructor({ dkLen: outputLen })); -+ to.set(...this.get()); -+ to.length = length; -+ to.finished = finished; -+ to.destroyed = destroyed; -+ to.outputLen = outputLen; -+ to.buffer.set(buffer); -+ to.pos = pos; -+ return to; -+ } -+} -+exports.BLAKE = BLAKE; -+//# sourceMappingURL=_blake.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.js.map -new file mode 100644 -index 0000000..38b815b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_blake.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_blake.js","sourceRoot":"","sources":["src/_blake.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.d.ts -new file mode 100644 -index 0000000..1c34636 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.d.ts -@@ -0,0 +1,36 @@ -+import { Hash, Input } from './utils.js'; -+/** -+ * Choice: a ? b : c -+ */ -+export declare const Chi: (a: number, b: number, c: number) => number; -+/** -+ * Majority function, true if any two inputs is true -+ */ -+export declare const Maj: (a: number, b: number, c: number) => number; -+/** -+ * Merkle-Damgard hash construction base class. -+ * Could be used to create MD5, RIPEMD, SHA1, SHA2. -+ */ -+export declare abstract class HashMD> extends Hash { -+ readonly blockLen: number; -+ outputLen: number; -+ readonly padOffset: number; -+ readonly isLE: boolean; -+ protected abstract process(buf: DataView, offset: number): void; -+ protected abstract get(): number[]; -+ protected abstract set(...args: number[]): void; -+ abstract destroy(): void; -+ protected abstract roundClean(): void; -+ protected buffer: Uint8Array; -+ protected view: DataView; -+ protected finished: boolean; -+ protected length: number; -+ protected pos: number; -+ protected destroyed: boolean; -+ constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean); -+ update(data: Input): this; -+ digestInto(out: Uint8Array): void; -+ digest(): Uint8Array; -+ _cloneInto(to?: T): T; -+} -+//# sourceMappingURL=_md.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.d.ts.map -new file mode 100644 -index 0000000..de94f66 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_md.d.ts","sourceRoot":"","sources":["src/_md.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAc,KAAK,EAAW,MAAM,YAAY,CAAC;AAiB9D;;GAEG;AACH,eAAO,MAAM,GAAG,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAuB,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,GAAG,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAgC,CAAC;AAEpF;;;GAGG;AACH,8BAAsB,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,CAAC,CAAC;IAe7D,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO;IAjBxB,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAC/D,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,MAAM,EAAE;IAClC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAC/C,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,SAAS,CAAC,QAAQ,CAAC,UAAU,IAAI,IAAI;IAErC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;IACzB,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,MAAM,SAAK;IACrB,SAAS,CAAC,GAAG,SAAK;IAClB,SAAS,CAAC,SAAS,UAAS;gBAGjB,QAAQ,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO;IAMxB,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI;IAyBzB,UAAU,CAAC,GAAG,EAAE,UAAU;IAkC1B,MAAM;IAON,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;CAWtB"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.js -new file mode 100644 -index 0000000..6ef2bc7 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.js -@@ -0,0 +1,134 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.HashMD = exports.Maj = exports.Chi = void 0; -+const _assert_js_1 = require("./_assert.js"); -+const utils_js_1 = require("./utils.js"); -+/** -+ * Polyfill for Safari 14 -+ */ -+function setBigUint64(view, byteOffset, value, isLE) { -+ if (typeof view.setBigUint64 === 'function') -+ return view.setBigUint64(byteOffset, value, isLE); -+ const _32n = BigInt(32); -+ const _u32_max = BigInt(0xffffffff); -+ const wh = Number((value >> _32n) & _u32_max); -+ const wl = Number(value & _u32_max); -+ const h = isLE ? 4 : 0; -+ const l = isLE ? 0 : 4; -+ view.setUint32(byteOffset + h, wh, isLE); -+ view.setUint32(byteOffset + l, wl, isLE); -+} -+/** -+ * Choice: a ? b : c -+ */ -+const Chi = (a, b, c) => (a & b) ^ (~a & c); -+exports.Chi = Chi; -+/** -+ * Majority function, true if any two inputs is true -+ */ -+const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c); -+exports.Maj = Maj; -+/** -+ * Merkle-Damgard hash construction base class. -+ * Could be used to create MD5, RIPEMD, SHA1, SHA2. -+ */ -+class HashMD extends utils_js_1.Hash { -+ constructor(blockLen, outputLen, padOffset, isLE) { -+ super(); -+ this.blockLen = blockLen; -+ this.outputLen = outputLen; -+ this.padOffset = padOffset; -+ this.isLE = isLE; -+ this.finished = false; -+ this.length = 0; -+ this.pos = 0; -+ this.destroyed = false; -+ this.buffer = new Uint8Array(blockLen); -+ this.view = (0, utils_js_1.createView)(this.buffer); -+ } -+ update(data) { -+ (0, _assert_js_1.exists)(this); -+ const { view, buffer, blockLen } = this; -+ data = (0, utils_js_1.toBytes)(data); -+ const len = data.length; -+ for (let pos = 0; pos < len;) { -+ const take = Math.min(blockLen - this.pos, len - pos); -+ // Fast path: we have at least one block in input, cast it to view and process -+ if (take === blockLen) { -+ const dataView = (0, utils_js_1.createView)(data); -+ for (; blockLen <= len - pos; pos += blockLen) -+ this.process(dataView, pos); -+ continue; -+ } -+ buffer.set(data.subarray(pos, pos + take), this.pos); -+ this.pos += take; -+ pos += take; -+ if (this.pos === blockLen) { -+ this.process(view, 0); -+ this.pos = 0; -+ } -+ } -+ this.length += data.length; -+ this.roundClean(); -+ return this; -+ } -+ digestInto(out) { -+ (0, _assert_js_1.exists)(this); -+ (0, _assert_js_1.output)(out, this); -+ this.finished = true; -+ // Padding -+ // We can avoid allocation of buffer for padding completely if it -+ // was previously not allocated here. But it won't change performance. -+ const { buffer, view, blockLen, isLE } = this; -+ let { pos } = this; -+ // append the bit '1' to the message -+ buffer[pos++] = 0b10000000; -+ this.buffer.subarray(pos).fill(0); -+ // we have less than padOffset left in buffer, so we cannot put length in -+ // current block, need process it and pad again -+ if (this.padOffset > blockLen - pos) { -+ this.process(view, 0); -+ pos = 0; -+ } -+ // Pad until full block byte with zeros -+ for (let i = pos; i < blockLen; i++) -+ buffer[i] = 0; -+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that -+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen. -+ // So we just write lowest 64 bits of that value. -+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE); -+ this.process(view, 0); -+ const oview = (0, utils_js_1.createView)(out); -+ const len = this.outputLen; -+ // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT -+ if (len % 4) -+ throw new Error('_sha2: outputLen should be aligned to 32bit'); -+ const outLen = len / 4; -+ const state = this.get(); -+ if (outLen > state.length) -+ throw new Error('_sha2: outputLen bigger than state'); -+ for (let i = 0; i < outLen; i++) -+ oview.setUint32(4 * i, state[i], isLE); -+ } -+ digest() { -+ const { buffer, outputLen } = this; -+ this.digestInto(buffer); -+ const res = buffer.slice(0, outputLen); -+ this.destroy(); -+ return res; -+ } -+ _cloneInto(to) { -+ to || (to = new this.constructor()); -+ to.set(...this.get()); -+ const { blockLen, buffer, length, finished, destroyed, pos } = this; -+ to.length = length; -+ to.pos = pos; -+ to.finished = finished; -+ to.destroyed = destroyed; -+ if (length % blockLen) -+ to.buffer.set(buffer); -+ return to; -+ } -+} -+exports.HashMD = HashMD; -+//# sourceMappingURL=_md.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.js.map -new file mode 100644 -index 0000000..95bf1ec ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_md.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_md.js","sourceRoot":"","sources":["src/_md.ts"],"names":[],"mappings":";;;AAAA,6CAA8C;AAC9C,yCAA8D;AAE9D;;GAEG;AACH,SAAS,YAAY,CAAC,IAAc,EAAE,UAAkB,EAAE,KAAa,EAAE,IAAa;IACpF,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC/F,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC9C,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;IACpC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACI,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAA9D,QAAA,GAAG,OAA2D;AAE3E;;GAEG;AACI,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAAvE,QAAA,GAAG,OAAoE;AAEpF;;;GAGG;AACH,MAAsB,MAA4B,SAAQ,eAAO;IAc/D,YACW,QAAgB,EAClB,SAAiB,EACf,SAAiB,EACjB,IAAa;QAEtB,KAAK,EAAE,CAAC;QALC,aAAQ,GAAR,QAAQ,CAAQ;QAClB,cAAS,GAAT,SAAS,CAAQ;QACf,cAAS,GAAT,SAAS,CAAQ;QACjB,SAAI,GAAJ,IAAI,CAAS;QATd,aAAQ,GAAG,KAAK,CAAC;QACjB,WAAM,GAAG,CAAC,CAAC;QACX,QAAG,GAAG,CAAC,CAAC;QACR,cAAS,GAAG,KAAK,CAAC;QAS1B,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,IAAA,qBAAU,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,CAAC,IAAW;QAChB,IAAA,mBAAM,EAAC,IAAI,CAAC,CAAC;QACb,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QACxC,IAAI,GAAG,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,GAAI,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;YACtD,8EAA8E;YAC9E,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,QAAQ,GAAG,IAAA,qBAAU,EAAC,IAAI,CAAC,CAAC;gBAClC,OAAO,QAAQ,IAAI,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,QAAQ;oBAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAC3E,SAAS;YACX,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACrD,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC;YACjB,GAAG,IAAI,IAAI,CAAC;YACZ,IAAI,IAAI,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBACtB,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;YACf,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,UAAU,CAAC,GAAe;QACxB,IAAA,mBAAM,EAAC,IAAI,CAAC,CAAC;QACb,IAAA,mBAAM,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,UAAU;QACV,iEAAiE;QACjE,sEAAsE;QACtE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QAC9C,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACnB,oCAAoC;QACpC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,UAAU,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,yEAAyE;QACzE,+CAA+C;QAC/C,IAAI,IAAI,CAAC,SAAS,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC;YACpC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACtB,GAAG,GAAG,CAAC,CAAC;QACV,CAAC;QACD,uCAAuC;QACvC,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE;YAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACnD,gGAAgG;QAChG,oFAAoF;QACpF,iDAAiD;QACjD,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACtB,MAAM,KAAK,GAAG,IAAA,qBAAU,EAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC;QAC3B,yFAAyF;QACzF,IAAI,GAAG,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACjF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE;YAAE,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM;QACJ,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;QACnC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,OAAO,GAAG,CAAC;IACb,CAAC;IACD,UAAU,CAAC,EAAM;QACf,EAAE,KAAF,EAAE,GAAK,IAAK,IAAI,CAAC,WAAmB,EAAO,EAAC;QAC5C,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACtB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACpE,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC;QACnB,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC;QACb,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACvB,EAAE,CAAC,SAAS,GAAG,SAAS,CAAC;QACzB,IAAI,MAAM,GAAG,QAAQ;YAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7C,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AArGD,wBAqGC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.d.ts -new file mode 100644 -index 0000000..6b8c273 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.d.ts -@@ -0,0 +1,55 @@ -+declare function fromBig(n: bigint, le?: boolean): { -+ h: number; -+ l: number; -+}; -+declare function split(lst: bigint[], le?: boolean): Uint32Array[]; -+declare const toBig: (h: number, l: number) => bigint; -+declare const shrSH: (h: number, _l: number, s: number) => number; -+declare const shrSL: (h: number, l: number, s: number) => number; -+declare const rotrSH: (h: number, l: number, s: number) => number; -+declare const rotrSL: (h: number, l: number, s: number) => number; -+declare const rotrBH: (h: number, l: number, s: number) => number; -+declare const rotrBL: (h: number, l: number, s: number) => number; -+declare const rotr32H: (_h: number, l: number) => number; -+declare const rotr32L: (h: number, _l: number) => number; -+declare const rotlSH: (h: number, l: number, s: number) => number; -+declare const rotlSL: (h: number, l: number, s: number) => number; -+declare const rotlBH: (h: number, l: number, s: number) => number; -+declare const rotlBL: (h: number, l: number, s: number) => number; -+declare function add(Ah: number, Al: number, Bh: number, Bl: number): { -+ h: number; -+ l: number; -+}; -+declare const add3L: (Al: number, Bl: number, Cl: number) => number; -+declare const add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; -+declare const add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; -+declare const add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; -+declare const add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; -+declare const add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; -+export { fromBig, split, toBig, shrSH, shrSL, rotrSH, rotrSL, rotrBH, rotrBL, rotr32H, rotr32L, rotlSH, rotlSL, rotlBH, rotlBL, add, add3L, add3H, add4L, add4H, add5H, add5L, }; -+declare const u64: { -+ fromBig: typeof fromBig; -+ split: typeof split; -+ toBig: (h: number, l: number) => bigint; -+ shrSH: (h: number, _l: number, s: number) => number; -+ shrSL: (h: number, l: number, s: number) => number; -+ rotrSH: (h: number, l: number, s: number) => number; -+ rotrSL: (h: number, l: number, s: number) => number; -+ rotrBH: (h: number, l: number, s: number) => number; -+ rotrBL: (h: number, l: number, s: number) => number; -+ rotr32H: (_h: number, l: number) => number; -+ rotr32L: (h: number, _l: number) => number; -+ rotlSH: (h: number, l: number, s: number) => number; -+ rotlSL: (h: number, l: number, s: number) => number; -+ rotlBH: (h: number, l: number, s: number) => number; -+ rotlBL: (h: number, l: number, s: number) => number; -+ add: typeof add; -+ add3L: (Al: number, Bl: number, Cl: number) => number; -+ add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; -+ add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; -+ add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; -+ add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; -+ add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; -+}; -+export default u64; -+//# sourceMappingURL=_u64.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.d.ts.map -new file mode 100644 -index 0000000..63a4e15 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_u64.d.ts","sourceRoot":"","sources":["src/_u64.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.js -new file mode 100644 -index 0000000..ae296cc ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.js -@@ -0,0 +1,85 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.add5L = exports.add5H = exports.add4H = exports.add4L = exports.add3H = exports.add3L = exports.rotlBL = exports.rotlBH = exports.rotlSL = exports.rotlSH = exports.rotr32L = exports.rotr32H = exports.rotrBL = exports.rotrBH = exports.rotrSL = exports.rotrSH = exports.shrSL = exports.shrSH = exports.toBig = void 0; -+exports.fromBig = fromBig; -+exports.split = split; -+exports.add = add; -+const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1); -+const _32n = /* @__PURE__ */ BigInt(32); -+// We are not using BigUint64Array, because they are extremely slow as per 2022 -+function fromBig(n, le = false) { -+ if (le) -+ return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) }; -+ return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 }; -+} -+function split(lst, le = false) { -+ let Ah = new Uint32Array(lst.length); -+ let Al = new Uint32Array(lst.length); -+ for (let i = 0; i < lst.length; i++) { -+ const { h, l } = fromBig(lst[i], le); -+ [Ah[i], Al[i]] = [h, l]; -+ } -+ return [Ah, Al]; -+} -+const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0); -+exports.toBig = toBig; -+// for Shift in [0, 32) -+const shrSH = (h, _l, s) => h >>> s; -+exports.shrSH = shrSH; -+const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s); -+exports.shrSL = shrSL; -+// Right rotate for Shift in [1, 32) -+const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s)); -+exports.rotrSH = rotrSH; -+const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s); -+exports.rotrSL = rotrSL; -+// Right rotate for Shift in (32, 64), NOTE: 32 is special case. -+const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32)); -+exports.rotrBH = rotrBH; -+const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s)); -+exports.rotrBL = rotrBL; -+// Right rotate for shift===32 (just swaps l&h) -+const rotr32H = (_h, l) => l; -+exports.rotr32H = rotr32H; -+const rotr32L = (h, _l) => h; -+exports.rotr32L = rotr32L; -+// Left rotate for Shift in [1, 32) -+const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s)); -+exports.rotlSH = rotlSH; -+const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s)); -+exports.rotlSL = rotlSL; -+// Left rotate for Shift in (32, 64), NOTE: 32 is special case. -+const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s)); -+exports.rotlBH = rotlBH; -+const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s)); -+exports.rotlBL = rotlBL; -+// JS uses 32-bit signed integers for bitwise operations which means we cannot -+// simple take carry out of low bit sum by shift, we need to use division. -+function add(Ah, Al, Bh, Bl) { -+ const l = (Al >>> 0) + (Bl >>> 0); -+ return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 }; -+} -+// Addition with more than 2 elements -+const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0); -+exports.add3L = add3L; -+const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0; -+exports.add3H = add3H; -+const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0); -+exports.add4L = add4L; -+const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0; -+exports.add4H = add4H; -+const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0); -+exports.add5L = add5L; -+const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0; -+exports.add5H = add5H; -+// prettier-ignore -+const u64 = { -+ fromBig, split, toBig, -+ shrSH, shrSL, -+ rotrSH, rotrSL, rotrBH, rotrBL, -+ rotr32H, rotr32L, -+ rotlSH, rotlSL, rotlBH, rotlBL, -+ add, add3L, add3H, add4L, add4H, add5H, add5L, -+}; -+exports.default = u64; -+//# sourceMappingURL=_u64.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.js.map -new file mode 100644 -index 0000000..3543a9c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/_u64.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_u64.js","sourceRoot":"","sources":["src/_u64.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.d.ts -new file mode 100644 -index 0000000..9d4139c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.d.ts -@@ -0,0 +1,17 @@ -+import { Input } from './utils.js'; -+export type ArgonOpts = { -+ t: number; -+ m: number; -+ p: number; -+ version?: number; -+ key?: Input; -+ personalization?: Input; -+ dkLen?: number; -+ asyncTick?: number; -+ maxmem?: number; -+ onProgress?: (progress: number) => void; -+}; -+export declare const argon2d: (password: Input, salt: Input, opts: ArgonOpts) => Uint8Array; -+export declare const argon2i: (password: Input, salt: Input, opts: ArgonOpts) => Uint8Array; -+export declare const argon2id: (password: Input, salt: Input, opts: ArgonOpts) => Uint8Array; -+//# sourceMappingURL=argon2.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.d.ts.map -new file mode 100644 -index 0000000..001375d ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"argon2.d.ts","sourceRoot":"","sources":["src/argon2.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAoB,MAAM,YAAY,CAAC;AAkKrD,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,eAAe,CAAC,EAAE,KAAK,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAkMF,eAAO,MAAM,OAAO,aAAc,KAAK,QAAQ,KAAK,QAAQ,SAAS,eACvB,CAAC;AAC/C,eAAO,MAAM,OAAO,aAAc,KAAK,QAAQ,KAAK,QAAQ,SAAS,eACxB,CAAC;AAC9C,eAAO,MAAM,QAAQ,aAAc,KAAK,QAAQ,KAAK,QAAQ,SAAS,eACxB,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.js -new file mode 100644 -index 0000000..945f4b8 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.js -@@ -0,0 +1,303 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.argon2id = exports.argon2i = exports.argon2d = void 0; -+const _assert_js_1 = require("./_assert.js"); -+const utils_js_1 = require("./utils.js"); -+const blake2b_js_1 = require("./blake2b.js"); -+const _u64_js_1 = require("./_u64.js"); -+const ARGON2_SYNC_POINTS = 4; -+const toBytesOptional = (buf) => (buf !== undefined ? (0, utils_js_1.toBytes)(buf) : new Uint8Array([])); -+function mul(a, b) { -+ const aL = a & 0xffff; -+ const aH = a >>> 16; -+ const bL = b & 0xffff; -+ const bH = b >>> 16; -+ const ll = Math.imul(aL, bL); -+ const hl = Math.imul(aH, bL); -+ const lh = Math.imul(aL, bH); -+ const hh = Math.imul(aH, bH); -+ const BUF = ((ll >>> 16) + (hl & 0xffff) + lh) | 0; -+ const h = ((hl >>> 16) + (BUF >>> 16) + hh) | 0; -+ return { h, l: (BUF << 16) | (ll & 0xffff) }; -+} -+function relPos(areaSize, relativePos) { -+ // areaSize - 1 - ((areaSize * ((relativePos ** 2) >>> 32)) >>> 32) -+ return areaSize - 1 - mul(areaSize, mul(relativePos, relativePos).h).h; -+} -+function mul2(a, b) { -+ // 2 * a * b (via shifts) -+ const { h, l } = mul(a, b); -+ return { h: ((h << 1) | (l >>> 31)) & 4294967295, l: (l << 1) & 4294967295 }; -+} -+function blamka(Ah, Al, Bh, Bl) { -+ const { h: Ch, l: Cl } = mul2(Al, Bl); -+ // A + B + (2 * A * B) -+ const Rll = (0, _u64_js_1.add3L)(Al, Bl, Cl); -+ return { h: (0, _u64_js_1.add3H)(Rll, Ah, Bh, Ch), l: Rll | 0 }; -+} -+// Temporary block buffer -+const A2_BUF = new Uint32Array(256); -+function G(a, b, c, d) { -+ let Al = A2_BUF[2 * a], Ah = A2_BUF[2 * a + 1]; // prettier-ignore -+ let Bl = A2_BUF[2 * b], Bh = A2_BUF[2 * b + 1]; // prettier-ignore -+ let Cl = A2_BUF[2 * c], Ch = A2_BUF[2 * c + 1]; // prettier-ignore -+ let Dl = A2_BUF[2 * d], Dh = A2_BUF[2 * d + 1]; // prettier-ignore -+ ({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl)); -+ ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); -+ ({ Dh, Dl } = { Dh: (0, _u64_js_1.rotr32H)(Dh, Dl), Dl: (0, _u64_js_1.rotr32L)(Dh, Dl) }); -+ ({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl)); -+ ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); -+ ({ Bh, Bl } = { Bh: (0, _u64_js_1.rotrSH)(Bh, Bl, 24), Bl: (0, _u64_js_1.rotrSL)(Bh, Bl, 24) }); -+ ({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl)); -+ ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); -+ ({ Dh, Dl } = { Dh: (0, _u64_js_1.rotrSH)(Dh, Dl, 16), Dl: (0, _u64_js_1.rotrSL)(Dh, Dl, 16) }); -+ ({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl)); -+ ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); -+ ({ Bh, Bl } = { Bh: (0, _u64_js_1.rotrBH)(Bh, Bl, 63), Bl: (0, _u64_js_1.rotrBL)(Bh, Bl, 63) }); -+ (A2_BUF[2 * a] = Al), (A2_BUF[2 * a + 1] = Ah); -+ (A2_BUF[2 * b] = Bl), (A2_BUF[2 * b + 1] = Bh); -+ (A2_BUF[2 * c] = Cl), (A2_BUF[2 * c + 1] = Ch); -+ (A2_BUF[2 * d] = Dl), (A2_BUF[2 * d + 1] = Dh); -+} -+// prettier-ignore -+function P(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14, v15) { -+ G(v00, v04, v08, v12); -+ G(v01, v05, v09, v13); -+ G(v02, v06, v10, v14); -+ G(v03, v07, v11, v15); -+ G(v00, v05, v10, v15); -+ G(v01, v06, v11, v12); -+ G(v02, v07, v08, v13); -+ G(v03, v04, v09, v14); -+} -+function block(x, xPos, yPos, outPos, needXor) { -+ for (let i = 0; i < 256; i++) -+ A2_BUF[i] = x[xPos + i] ^ x[yPos + i]; -+ // columns -+ for (let i = 0; i < 128; i += 16) { -+ // prettier-ignore -+ P(i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, i + 8, i + 9, i + 10, i + 11, i + 12, i + 13, i + 14, i + 15); -+ } -+ // rows -+ for (let i = 0; i < 16; i += 2) { -+ // prettier-ignore -+ P(i, i + 1, i + 16, i + 17, i + 32, i + 33, i + 48, i + 49, i + 64, i + 65, i + 80, i + 81, i + 96, i + 97, i + 112, i + 113); -+ } -+ if (needXor) -+ for (let i = 0; i < 256; i++) -+ x[outPos + i] ^= A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i]; -+ else -+ for (let i = 0; i < 256; i++) -+ x[outPos + i] = A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i]; -+} -+// Variable-Length Hash Function H' -+function Hp(A, dkLen) { -+ const A8 = (0, utils_js_1.u8)(A); -+ const T = new Uint32Array(1); -+ const T8 = (0, utils_js_1.u8)(T); -+ T[0] = dkLen; -+ // Fast path -+ if (dkLen <= 64) -+ return blake2b_js_1.blake2b.create({ dkLen }).update(T8).update(A8).digest(); -+ const out = new Uint8Array(dkLen); -+ let V = blake2b_js_1.blake2b.create({}).update(T8).update(A8).digest(); -+ let pos = 0; -+ // First block -+ out.set(V.subarray(0, 32)); -+ pos += 32; -+ // Rest blocks -+ for (; dkLen - pos > 64; pos += 32) -+ out.set((V = (0, blake2b_js_1.blake2b)(V)).subarray(0, 32), pos); -+ // Last block -+ out.set((0, blake2b_js_1.blake2b)(V, { dkLen: dkLen - pos }), pos); -+ return (0, utils_js_1.u32)(out); -+} -+function indexAlpha(r, s, laneLen, segmentLen, index, randL, sameLane = false) { -+ let area; -+ if (0 == r) { -+ if (0 == s) -+ area = index - 1; -+ else if (sameLane) -+ area = s * segmentLen + index - 1; -+ else -+ area = s * segmentLen + (index == 0 ? -1 : 0); -+ } -+ else if (sameLane) -+ area = laneLen - segmentLen + index - 1; -+ else -+ area = laneLen - segmentLen + (index == 0 ? -1 : 0); -+ const startPos = r !== 0 && s !== ARGON2_SYNC_POINTS - 1 ? (s + 1) * segmentLen : 0; -+ const rel = relPos(area, randL); -+ // NOTE: check about overflows here -+ // absPos = (startPos + relPos) % laneLength; -+ return (startPos + rel) % laneLen; -+} -+function argon2Init(type, password, salt, opts) { -+ password = (0, utils_js_1.toBytes)(password); -+ salt = (0, utils_js_1.toBytes)(salt); -+ let { p, dkLen, m, t, version, key, personalization, maxmem, onProgress } = { -+ ...opts, -+ version: opts.version || 0x13, -+ dkLen: opts.dkLen || 32, -+ maxmem: 2 ** 32, -+ }; -+ // Validation -+ (0, _assert_js_1.number)(p); -+ (0, _assert_js_1.number)(dkLen); -+ (0, _assert_js_1.number)(m); -+ (0, _assert_js_1.number)(t); -+ (0, _assert_js_1.number)(version); -+ if (dkLen < 4 || dkLen >= 2 ** 32) -+ throw new Error('Argon2: dkLen should be at least 4 bytes'); -+ if (p < 1 || p >= 2 ** 32) -+ throw new Error('Argon2: p (parallelism) should be at least 1'); -+ if (t < 1 || t >= 2 ** 32) -+ throw new Error('Argon2: t (iterations) should be at least 1'); -+ if (m < 8 * p) -+ throw new Error(`Argon2: memory should be at least 8*p bytes`); -+ if (version !== 16 && version !== 19) -+ throw new Error(`Argon2: unknown version=${version}`); -+ password = (0, utils_js_1.toBytes)(password); -+ if (password.length < 0 || password.length >= 2 ** 32) -+ throw new Error('Argon2: password should be less than 4 GB'); -+ salt = (0, utils_js_1.toBytes)(salt); -+ if (salt.length < 8) -+ throw new Error('Argon2: salt should be at least 8 bytes'); -+ key = toBytesOptional(key); -+ personalization = toBytesOptional(personalization); -+ if (onProgress !== undefined && typeof onProgress !== 'function') -+ throw new Error('progressCb should be function'); -+ // Params -+ const lanes = p; -+ // m' = 4 * p * floor (m / 4p) -+ const mP = 4 * p * Math.floor(m / (ARGON2_SYNC_POINTS * p)); -+ //q = m' / p columns -+ const laneLen = Math.floor(mP / p); -+ const segmentLen = Math.floor(laneLen / ARGON2_SYNC_POINTS); -+ // H0 -+ const h = blake2b_js_1.blake2b.create({}); -+ const BUF = new Uint32Array(1); -+ const BUF8 = (0, utils_js_1.u8)(BUF); -+ for (const i of [p, dkLen, m, t, version, type]) { -+ if (i < 0 || i >= 2 ** 32) -+ throw new Error(`Argon2: wrong parameter=${i}, expected uint32`); -+ BUF[0] = i; -+ h.update(BUF8); -+ } -+ for (let i of [password, salt, key, personalization]) { -+ BUF[0] = i.length; -+ h.update(BUF8).update(i); -+ } -+ const H0 = new Uint32Array(18); -+ const H0_8 = (0, utils_js_1.u8)(H0); -+ h.digestInto(H0_8); -+ // 256 u32 = 1024 (BLOCK_SIZE) -+ const memUsed = mP * 256; -+ if (memUsed < 0 || memUsed >= 2 ** 32 || memUsed > maxmem) { -+ throw new Error(`Argon2: wrong params (memUsed=${memUsed} maxmem=${maxmem}), should be less than 2**32`); -+ } -+ const B = new Uint32Array(memUsed); -+ // Fill first blocks -+ for (let l = 0; l < p; l++) { -+ const i = 256 * laneLen * l; -+ // B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) -+ H0[17] = l; -+ H0[16] = 0; -+ B.set(Hp(H0, 1024), i); -+ // B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) -+ H0[16] = 1; -+ B.set(Hp(H0, 1024), i + 256); -+ } -+ let perBlock = () => { }; -+ if (onProgress) { -+ const totalBlock = t * ARGON2_SYNC_POINTS * p * segmentLen; -+ // Invoke callback if progress changes from 10.01 to 10.02 -+ // Allows to draw smooth progress bar on up to 8K screen -+ const callbackPer = Math.max(Math.floor(totalBlock / 10000), 1); -+ let blockCnt = 0; -+ perBlock = () => { -+ blockCnt++; -+ if (onProgress && (!(blockCnt % callbackPer) || blockCnt === totalBlock)) -+ onProgress(blockCnt / totalBlock); -+ }; -+ } -+ return { type, mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock }; -+} -+function argon2Output(B, p, laneLen, dkLen) { -+ const B_final = new Uint32Array(256); -+ for (let l = 0; l < p; l++) -+ for (let j = 0; j < 256; j++) -+ B_final[j] ^= B[256 * (laneLen * l + laneLen - 1) + j]; -+ return (0, utils_js_1.u8)(Hp(B_final, dkLen)); -+} -+function processBlock(B, address, l, r, s, index, laneLen, segmentLen, lanes, offset, prev, dataIndependent, needXor) { -+ if (offset % laneLen) -+ prev = offset - 1; -+ let randL, randH; -+ if (dataIndependent) { -+ if (index % 128 === 0) { -+ address[256 + 12]++; -+ block(address, 256, 2 * 256, 0, false); -+ block(address, 0, 2 * 256, 0, false); -+ } -+ randL = address[2 * (index % 128)]; -+ randH = address[2 * (index % 128) + 1]; -+ } -+ else { -+ const T = 256 * prev; -+ randL = B[T]; -+ randH = B[T + 1]; -+ } -+ // address block -+ const refLane = r === 0 && s === 0 ? l : randH % lanes; -+ const refPos = indexAlpha(r, s, laneLen, segmentLen, index, randL, refLane == l); -+ const refBlock = laneLen * refLane + refPos; -+ // B[i][j] = G(B[i][j-1], B[l][z]) -+ block(B, 256 * prev, 256 * refBlock, offset * 256, needXor); -+} -+function argon2(type, password, salt, opts) { -+ const { mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock } = argon2Init(type, password, salt, opts); -+ // Pre-loop setup -+ // [address, input, zero_block] format so we can pass single U32 to block function -+ const address = new Uint32Array(3 * 256); -+ address[256 + 6] = mP; -+ address[256 + 8] = t; -+ address[256 + 10] = type; -+ for (let r = 0; r < t; r++) { -+ const needXor = r !== 0 && version === 0x13; -+ address[256 + 0] = r; -+ for (let s = 0; s < ARGON2_SYNC_POINTS; s++) { -+ address[256 + 4] = s; -+ const dataIndependent = type == 1 /* Types.Argon2i */ || (type == 2 /* Types.Argon2id */ && r === 0 && s < 2); -+ for (let l = 0; l < p; l++) { -+ address[256 + 2] = l; -+ address[256 + 12] = 0; -+ let startPos = 0; -+ if (r === 0 && s === 0) { -+ startPos = 2; -+ if (dataIndependent) { -+ address[256 + 12]++; -+ block(address, 256, 2 * 256, 0, false); -+ block(address, 0, 2 * 256, 0, false); -+ } -+ } -+ // current block postion -+ let offset = l * laneLen + s * segmentLen + startPos; -+ // previous block position -+ let prev = offset % laneLen ? offset - 1 : offset + laneLen - 1; -+ for (let index = startPos; index < segmentLen; index++, offset++, prev++) { -+ perBlock(); -+ processBlock(B, address, l, r, s, index, laneLen, segmentLen, lanes, offset, prev, dataIndependent, needXor); -+ } -+ } -+ } -+ } -+ return argon2Output(B, p, laneLen, dkLen); -+} -+const argon2d = (password, salt, opts) => argon2(0 /* Types.Argond2d */, password, salt, opts); -+exports.argon2d = argon2d; -+const argon2i = (password, salt, opts) => argon2(1 /* Types.Argon2i */, password, salt, opts); -+exports.argon2i = argon2i; -+const argon2id = (password, salt, opts) => argon2(2 /* Types.Argon2id */, password, salt, opts); -+exports.argon2id = argon2id; -+//# sourceMappingURL=argon2.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.js.map -new file mode 100644 -index 0000000..4991e74 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/argon2.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"argon2.js","sourceRoot":"","sources":["src/argon2.ts"],"names":[],"mappings":";;;AAAA,6CAAsD;AACtD,yCAAqD;AACrD,6CAAuC;AACvC,uCAA2F;AAS3F,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,MAAM,eAAe,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AAEjG,SAAS,GAAG,CAAC,CAAS,EAAE,CAAS;IAC/B,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;IACtB,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;IACtB,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;IACpB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IAChD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,MAAM,CAAC,QAAgB,EAAE,WAAmB;IACnD,mEAAmE;IACnE,OAAO,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,IAAI,CAAC,CAAS,EAAE,CAAS;IAChC,yBAAyB;IACzB,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,UAAW,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,UAAW,EAAE,CAAC;AACjF,CAAC;AAED,SAAS,MAAM,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU;IAC5D,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACtC,sBAAsB;IACtB,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9B,OAAO,EAAE,CAAC,EAAE,IAAA,eAAK,EAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,yBAAyB;AACzB,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;AAEpC,SAAS,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS;IACnD,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAC9D,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAC9D,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAC9D,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAE9D,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAA,iBAAO,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAA,iBAAO,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAE5D,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAA,gBAAM,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAA,gBAAM,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAElE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAA,gBAAM,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAA,gBAAM,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAElE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAA,gBAAM,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAA,gBAAM,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAElE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,kBAAkB;AAClB,SAAS,CAAC,CACR,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EACtG,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW;IAEtG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,KAAK,CAAC,CAAc,EAAE,IAAY,EAAE,IAAY,EAAE,MAAc,EAAE,OAAgB;IACzF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;QAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAEpE,UAAU;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,kBAAkB;QAClB,CAAC,CACC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAClD,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAC7D,CAAC;IACJ,CAAC;IACD,OAAO;IACP,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,kBAAkB;QAClB,CAAC,CACC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EACxD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CACjE,CAAC;IACJ,CAAC;IAED,IAAI,OAAO;QAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;YAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;;QAC7F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;YAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,mCAAmC;AACnC,SAAS,EAAE,CAAC,CAAc,EAAE,KAAa;IACvC,MAAM,EAAE,GAAG,IAAA,aAAE,EAAC,CAAC,CAAC,CAAC;IACjB,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAA,aAAE,EAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACb,YAAY;IACZ,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,oBAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACjF,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG,oBAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAC1D,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,cAAc;IACd,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3B,GAAG,IAAI,EAAE,CAAC;IACV,cAAc;IACd,OAAO,KAAK,GAAG,GAAG,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE;QAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAA,oBAAO,EAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;IACnF,aAAa;IACb,GAAG,CAAC,GAAG,CAAC,IAAA,oBAAO,EAAC,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,IAAA,cAAG,EAAC,GAAG,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,UAAU,CACjB,CAAS,EACT,CAAS,EACT,OAAe,EACf,UAAkB,EAClB,KAAa,EACb,KAAa,EACb,WAAoB,KAAK;IAEzB,IAAI,IAAI,CAAC;IACT,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,IAAI,CAAC;YAAE,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;aACxB,IAAI,QAAQ;YAAE,IAAI,GAAG,CAAC,GAAG,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC;;YAChD,IAAI,GAAG,CAAC,GAAG,UAAU,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,QAAQ;QAAE,IAAI,GAAG,OAAO,GAAG,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC;;QACxD,IAAI,GAAG,OAAO,GAAG,UAAU,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAChC,mCAAmC;IACnC,iDAAiD;IACjD,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC;AACpC,CAAC;AAgBD,SAAS,UAAU,CAAC,IAAW,EAAE,QAAe,EAAE,IAAW,EAAE,IAAe;IAC5E,QAAQ,GAAG,IAAA,kBAAO,EAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,GAAG,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG;QAC1E,GAAG,IAAI;QACP,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;QAC7B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;QACvB,MAAM,EAAE,CAAC,IAAI,EAAE;KAChB,CAAC;IACF,aAAa;IACb,IAAA,mBAAY,EAAC,CAAC,CAAC,CAAC;IAChB,IAAA,mBAAY,EAAC,KAAK,CAAC,CAAC;IACpB,IAAA,mBAAY,EAAC,CAAC,CAAC,CAAC;IAChB,IAAA,mBAAY,EAAC,CAAC,CAAC,CAAC;IAChB,IAAA,mBAAY,EAAC,OAAO,CAAC,CAAC;IACtB,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC/F,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAC3F,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC1F,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC9E,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;IAC5F,QAAQ,GAAG,IAAA,kBAAO,EAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE;QACnD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,IAAI,GAAG,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;IACrB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAChF,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3B,eAAe,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;IACnD,IAAI,UAAU,KAAK,SAAS,IAAI,OAAO,UAAU,KAAK,UAAU;QAC9D,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,SAAS;IACT,MAAM,KAAK,GAAG,CAAC,CAAC;IAChB,8BAA8B;IAC9B,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5D,oBAAoB;IACpB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,kBAAkB,CAAC,CAAC;IAC5D,KAAK;IACL,MAAM,CAAC,GAAG,oBAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAA,aAAE,EAAC,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,mBAAmB,CAAC,CAAC;QAC5F,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACX,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,eAAe,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAClB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAA,aAAE,EAAC,EAAE,CAAC,CAAC;IACpB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAEnB,8BAA8B;IAC9B,MAAM,OAAO,GAAG,EAAE,GAAG,GAAG,CAAC;IACzB,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,iCAAiC,OAAO,WAAW,MAAM,8BAA8B,CACxF,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,oBAAoB;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,GAAG,GAAG,OAAO,GAAG,CAAC,CAAC;QAC5B,iDAAiD;QACjD,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;QACX,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;QACX,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACvB,iDAAiD;QACjD,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;QACX,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,QAAQ,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IACxB,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,CAAC,GAAG,kBAAkB,GAAG,CAAC,GAAG,UAAU,CAAC;QAC3D,0DAA0D;QAC1D,wDAAwD;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAChE,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,QAAQ,GAAG,GAAG,EAAE;YACd,QAAQ,EAAE,CAAC;YACX,IAAI,UAAU,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,WAAW,CAAC,IAAI,QAAQ,KAAK,UAAU,CAAC;gBACtE,UAAU,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC;QACtC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACrF,CAAC;AAED,SAAS,YAAY,CAAC,CAAc,EAAE,CAAS,EAAE,OAAe,EAAE,KAAa;IAC7E,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvF,OAAO,IAAA,aAAE,EAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,YAAY,CACnB,CAAc,EACd,OAAoB,EACpB,CAAS,EACT,CAAS,EACT,CAAS,EACT,KAAa,EACb,OAAe,EACf,UAAkB,EAClB,KAAa,EACb,MAAc,EACd,IAAY,EACZ,eAAwB,EACxB,OAAgB;IAEhB,IAAI,MAAM,GAAG,OAAO;QAAE,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC;IACxC,IAAI,KAAK,EAAE,KAAK,CAAC;IACjB,IAAI,eAAe,EAAE,CAAC;QACpB,IAAI,KAAK,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC;YACpB,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACvC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;QACnC,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACb,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnB,CAAC;IACD,gBAAgB;IAChB,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC;IACvD,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IAC5C,kCAAkC;IAClC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG,QAAQ,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,MAAM,CAAC,IAAW,EAAE,QAAe,EAAE,IAAW,EAAE,IAAe;IACxE,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,UAAU,CACtF,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,IAAI,CACL,CAAC;IACF,iBAAiB;IACjB,kFAAkF;IAClF,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACtB,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,IAAI,CAAC;QAC5C,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACrB,MAAM,eAAe,GAAG,IAAI,yBAAiB,IAAI,CAAC,IAAI,0BAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBACrB,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;gBACtB,IAAI,QAAQ,GAAG,CAAC,CAAC;gBACjB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBACvB,QAAQ,GAAG,CAAC,CAAC;oBACb,IAAI,eAAe,EAAE,CAAC;wBACpB,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC;wBACpB,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;wBACvC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;oBACvC,CAAC;gBACH,CAAC;gBACD,wBAAwB;gBACxB,IAAI,MAAM,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,GAAG,UAAU,GAAG,QAAQ,CAAC;gBACrD,0BAA0B;gBAC1B,IAAI,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC;gBAChE,KAAK,IAAI,KAAK,GAAG,QAAQ,EAAE,KAAK,GAAG,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC;oBACzE,QAAQ,EAAE,CAAC;oBACX,YAAY,CACV,CAAC,EACD,OAAO,EACP,CAAC,EACD,CAAC,EACD,CAAC,EACD,KAAK,EACL,OAAO,EACP,UAAU,EACV,KAAK,EACL,MAAM,EACN,IAAI,EACJ,eAAe,EACf,OAAO,CACR,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAEM,MAAM,OAAO,GAAG,CAAC,QAAe,EAAE,IAAW,EAAE,IAAe,EAAE,EAAE,CACvE,MAAM,yBAAiB,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AADlC,QAAA,OAAO,WAC2B;AACxC,MAAM,OAAO,GAAG,CAAC,QAAe,EAAE,IAAW,EAAE,IAAe,EAAE,EAAE,CACvE,MAAM,wBAAgB,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AADjC,QAAA,OAAO,WAC0B;AACvC,MAAM,QAAQ,GAAG,CAAC,QAAe,EAAE,IAAW,EAAE,IAAe,EAAE,EAAE,CACxE,MAAM,yBAAiB,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AADlC,QAAA,QAAQ,YAC0B"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.d.ts -new file mode 100644 -index 0000000..fa5b7f9 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.d.ts -@@ -0,0 +1,53 @@ -+import { BLAKE, BlakeOpts } from './_blake.js'; -+export declare class BLAKE2b extends BLAKE { -+ private v0l; -+ private v0h; -+ private v1l; -+ private v1h; -+ private v2l; -+ private v2h; -+ private v3l; -+ private v3h; -+ private v4l; -+ private v4h; -+ private v5l; -+ private v5h; -+ private v6l; -+ private v6h; -+ private v7l; -+ private v7h; -+ constructor(opts?: BlakeOpts); -+ protected get(): [ -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number -+ ]; -+ protected set(v0l: number, v0h: number, v1l: number, v1h: number, v2l: number, v2h: number, v3l: number, v3h: number, v4l: number, v4h: number, v5l: number, v5h: number, v6l: number, v6h: number, v7l: number, v7h: number): void; -+ protected compress(msg: Uint32Array, offset: number, isLast: boolean): void; -+ destroy(): void; -+} -+/** -+ * BLAKE2b - optimized for 64-bit platforms. JS doesn't have uint64, so it's slower than BLAKE2s. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, salt, personalization -+ */ -+export declare const blake2b: { -+ (msg: import("./utils.js").Input, opts?: BlakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: BlakeOpts): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=blake2b.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.d.ts.map -new file mode 100644 -index 0000000..fa909ed ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake2b.d.ts","sourceRoot":"","sources":["src/blake2b.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAS,MAAM,aAAa,CAAC;AAgEtD,qBAAa,OAAQ,SAAQ,KAAK,CAAC,OAAO,CAAC;IAEzC,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;gBAEjB,IAAI,GAAE,SAAc;IA0BhC,SAAS,CAAC,GAAG,IAAI;QACf,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAC9D,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;KAC/D;IAKD,SAAS,CAAC,GAAG,CACX,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAmBpD,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAkDpE,OAAO;CAKR;AAED;;;;GAIG;AACH,eAAO,MAAM,OAAO;;;;;CAEnB,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.js -new file mode 100644 -index 0000000..269e97c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.js -@@ -0,0 +1,193 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.blake2b = exports.BLAKE2b = void 0; -+const _blake_js_1 = require("./_blake.js"); -+const _u64_js_1 = require("./_u64.js"); -+const utils_js_1 = require("./utils.js"); -+// Same as SHA-512 but LE -+// prettier-ignore -+const B2B_IV = /* @__PURE__ */ new Uint32Array([ -+ 0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a, -+ 0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19 -+]); -+// Temporary buffer -+const BBUF = /* @__PURE__ */ new Uint32Array(32); -+// Mixing function G splitted in two halfs -+function G1b(a, b, c, d, msg, x) { -+ // NOTE: V is LE here -+ const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore -+ let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore -+ let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore -+ let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore -+ let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore -+ // v[a] = (v[a] + v[b] + x) | 0; -+ let ll = _u64_js_1.default.add3L(Al, Bl, Xl); -+ Ah = _u64_js_1.default.add3H(ll, Ah, Bh, Xh); -+ Al = ll | 0; -+ // v[d] = rotr(v[d] ^ v[a], 32) -+ ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); -+ ({ Dh, Dl } = { Dh: _u64_js_1.default.rotr32H(Dh, Dl), Dl: _u64_js_1.default.rotr32L(Dh, Dl) }); -+ // v[c] = (v[c] + v[d]) | 0; -+ ({ h: Ch, l: Cl } = _u64_js_1.default.add(Ch, Cl, Dh, Dl)); -+ // v[b] = rotr(v[b] ^ v[c], 24) -+ ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); -+ ({ Bh, Bl } = { Bh: _u64_js_1.default.rotrSH(Bh, Bl, 24), Bl: _u64_js_1.default.rotrSL(Bh, Bl, 24) }); -+ (BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah); -+ (BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh); -+ (BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch); -+ (BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh); -+} -+function G2b(a, b, c, d, msg, x) { -+ // NOTE: V is LE here -+ const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore -+ let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore -+ let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore -+ let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore -+ let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore -+ // v[a] = (v[a] + v[b] + x) | 0; -+ let ll = _u64_js_1.default.add3L(Al, Bl, Xl); -+ Ah = _u64_js_1.default.add3H(ll, Ah, Bh, Xh); -+ Al = ll | 0; -+ // v[d] = rotr(v[d] ^ v[a], 16) -+ ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); -+ ({ Dh, Dl } = { Dh: _u64_js_1.default.rotrSH(Dh, Dl, 16), Dl: _u64_js_1.default.rotrSL(Dh, Dl, 16) }); -+ // v[c] = (v[c] + v[d]) | 0; -+ ({ h: Ch, l: Cl } = _u64_js_1.default.add(Ch, Cl, Dh, Dl)); -+ // v[b] = rotr(v[b] ^ v[c], 63) -+ ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); -+ ({ Bh, Bl } = { Bh: _u64_js_1.default.rotrBH(Bh, Bl, 63), Bl: _u64_js_1.default.rotrBL(Bh, Bl, 63) }); -+ (BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah); -+ (BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh); -+ (BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch); -+ (BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh); -+} -+class BLAKE2b extends _blake_js_1.BLAKE { -+ constructor(opts = {}) { -+ super(128, opts.dkLen === undefined ? 64 : opts.dkLen, opts, 64, 16, 16); -+ // Same as SHA-512, but LE -+ this.v0l = B2B_IV[0] | 0; -+ this.v0h = B2B_IV[1] | 0; -+ this.v1l = B2B_IV[2] | 0; -+ this.v1h = B2B_IV[3] | 0; -+ this.v2l = B2B_IV[4] | 0; -+ this.v2h = B2B_IV[5] | 0; -+ this.v3l = B2B_IV[6] | 0; -+ this.v3h = B2B_IV[7] | 0; -+ this.v4l = B2B_IV[8] | 0; -+ this.v4h = B2B_IV[9] | 0; -+ this.v5l = B2B_IV[10] | 0; -+ this.v5h = B2B_IV[11] | 0; -+ this.v6l = B2B_IV[12] | 0; -+ this.v6h = B2B_IV[13] | 0; -+ this.v7l = B2B_IV[14] | 0; -+ this.v7h = B2B_IV[15] | 0; -+ const keyLength = opts.key ? opts.key.length : 0; -+ this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); -+ if (opts.salt) { -+ const salt = (0, utils_js_1.u32)((0, utils_js_1.toBytes)(opts.salt)); -+ this.v4l ^= (0, utils_js_1.byteSwapIfBE)(salt[0]); -+ this.v4h ^= (0, utils_js_1.byteSwapIfBE)(salt[1]); -+ this.v5l ^= (0, utils_js_1.byteSwapIfBE)(salt[2]); -+ this.v5h ^= (0, utils_js_1.byteSwapIfBE)(salt[3]); -+ } -+ if (opts.personalization) { -+ const pers = (0, utils_js_1.u32)((0, utils_js_1.toBytes)(opts.personalization)); -+ this.v6l ^= (0, utils_js_1.byteSwapIfBE)(pers[0]); -+ this.v6h ^= (0, utils_js_1.byteSwapIfBE)(pers[1]); -+ this.v7l ^= (0, utils_js_1.byteSwapIfBE)(pers[2]); -+ this.v7h ^= (0, utils_js_1.byteSwapIfBE)(pers[3]); -+ } -+ if (opts.key) { -+ // Pad to blockLen and update -+ const tmp = new Uint8Array(this.blockLen); -+ tmp.set((0, utils_js_1.toBytes)(opts.key)); -+ this.update(tmp); -+ } -+ } -+ // prettier-ignore -+ get() { -+ let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this; -+ return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h]; -+ } -+ // prettier-ignore -+ set(v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h) { -+ this.v0l = v0l | 0; -+ this.v0h = v0h | 0; -+ this.v1l = v1l | 0; -+ this.v1h = v1h | 0; -+ this.v2l = v2l | 0; -+ this.v2h = v2h | 0; -+ this.v3l = v3l | 0; -+ this.v3h = v3h | 0; -+ this.v4l = v4l | 0; -+ this.v4h = v4h | 0; -+ this.v5l = v5l | 0; -+ this.v5h = v5h | 0; -+ this.v6l = v6l | 0; -+ this.v6h = v6h | 0; -+ this.v7l = v7l | 0; -+ this.v7h = v7h | 0; -+ } -+ compress(msg, offset, isLast) { -+ this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state. -+ BBUF.set(B2B_IV, 16); // Second half from IV. -+ let { h, l } = _u64_js_1.default.fromBig(BigInt(this.length)); -+ BBUF[24] = B2B_IV[8] ^ l; // Low word of the offset. -+ BBUF[25] = B2B_IV[9] ^ h; // High word. -+ // Invert all bits for last block -+ if (isLast) { -+ BBUF[28] = ~BBUF[28]; -+ BBUF[29] = ~BBUF[29]; -+ } -+ let j = 0; -+ const s = _blake_js_1.SIGMA; -+ for (let i = 0; i < 12; i++) { -+ G1b(0, 4, 8, 12, msg, offset + 2 * s[j++]); -+ G2b(0, 4, 8, 12, msg, offset + 2 * s[j++]); -+ G1b(1, 5, 9, 13, msg, offset + 2 * s[j++]); -+ G2b(1, 5, 9, 13, msg, offset + 2 * s[j++]); -+ G1b(2, 6, 10, 14, msg, offset + 2 * s[j++]); -+ G2b(2, 6, 10, 14, msg, offset + 2 * s[j++]); -+ G1b(3, 7, 11, 15, msg, offset + 2 * s[j++]); -+ G2b(3, 7, 11, 15, msg, offset + 2 * s[j++]); -+ G1b(0, 5, 10, 15, msg, offset + 2 * s[j++]); -+ G2b(0, 5, 10, 15, msg, offset + 2 * s[j++]); -+ G1b(1, 6, 11, 12, msg, offset + 2 * s[j++]); -+ G2b(1, 6, 11, 12, msg, offset + 2 * s[j++]); -+ G1b(2, 7, 8, 13, msg, offset + 2 * s[j++]); -+ G2b(2, 7, 8, 13, msg, offset + 2 * s[j++]); -+ G1b(3, 4, 9, 14, msg, offset + 2 * s[j++]); -+ G2b(3, 4, 9, 14, msg, offset + 2 * s[j++]); -+ } -+ this.v0l ^= BBUF[0] ^ BBUF[16]; -+ this.v0h ^= BBUF[1] ^ BBUF[17]; -+ this.v1l ^= BBUF[2] ^ BBUF[18]; -+ this.v1h ^= BBUF[3] ^ BBUF[19]; -+ this.v2l ^= BBUF[4] ^ BBUF[20]; -+ this.v2h ^= BBUF[5] ^ BBUF[21]; -+ this.v3l ^= BBUF[6] ^ BBUF[22]; -+ this.v3h ^= BBUF[7] ^ BBUF[23]; -+ this.v4l ^= BBUF[8] ^ BBUF[24]; -+ this.v4h ^= BBUF[9] ^ BBUF[25]; -+ this.v5l ^= BBUF[10] ^ BBUF[26]; -+ this.v5h ^= BBUF[11] ^ BBUF[27]; -+ this.v6l ^= BBUF[12] ^ BBUF[28]; -+ this.v6h ^= BBUF[13] ^ BBUF[29]; -+ this.v7l ^= BBUF[14] ^ BBUF[30]; -+ this.v7h ^= BBUF[15] ^ BBUF[31]; -+ BBUF.fill(0); -+ } -+ destroy() { -+ this.destroyed = true; -+ this.buffer32.fill(0); -+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -+ } -+} -+exports.BLAKE2b = BLAKE2b; -+/** -+ * BLAKE2b - optimized for 64-bit platforms. JS doesn't have uint64, so it's slower than BLAKE2s. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, salt, personalization -+ */ -+exports.blake2b = (0, utils_js_1.wrapConstructorWithOpts)((opts) => new BLAKE2b(opts)); -+//# sourceMappingURL=blake2b.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.js.map -new file mode 100644 -index 0000000..9b618d9 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2b.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake2b.js","sourceRoot":"","sources":["src/blake2b.ts"],"names":[],"mappings":"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CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAE5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.d.ts -new file mode 100644 -index 0000000..29d4b2f ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.d.ts -@@ -0,0 +1,47 @@ -+import { BLAKE, BlakeOpts } from './_blake.js'; -+export declare const B2S_IV: Uint32Array; -+export declare function compress(s: Uint8Array, offset: number, msg: Uint32Array, rounds: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number): { -+ v0: number; -+ v1: number; -+ v2: number; -+ v3: number; -+ v4: number; -+ v5: number; -+ v6: number; -+ v7: number; -+ v8: number; -+ v9: number; -+ v10: number; -+ v11: number; -+ v12: number; -+ v13: number; -+ v14: number; -+ v15: number; -+}; -+export declare class BLAKE2s extends BLAKE { -+ private v0; -+ private v1; -+ private v2; -+ private v3; -+ private v4; -+ private v5; -+ private v6; -+ private v7; -+ constructor(opts?: BlakeOpts); -+ protected get(): [number, number, number, number, number, number, number, number]; -+ protected set(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number): void; -+ protected compress(msg: Uint32Array, offset: number, isLast: boolean): void; -+ destroy(): void; -+} -+/** -+ * BLAKE2s - optimized for 32-bit platforms. JS doesn't have uint64, so it's faster than BLAKE2b. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, salt, personalization -+ */ -+export declare const blake2s: { -+ (msg: import("./utils.js").Input, opts?: BlakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: BlakeOpts): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=blake2s.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.d.ts.map -new file mode 100644 -index 0000000..01296a1 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake2s.d.ts","sourceRoot":"","sources":["src/blake2s.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAS,MAAM,aAAa,CAAC;AAOtD,eAAO,MAAM,MAAM,aAEjB,CAAC;AAoBH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EACtF,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAC9F,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;;;;;;;;;;;;;;;;;EAuBrG;AAED,qBAAa,OAAQ,SAAQ,KAAK,CAAC,OAAO,CAAC;IAEzC,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;gBAEf,IAAI,GAAE,SAAc;IAqBhC,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAKjF,SAAS,CAAC,GAAG,CACX,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAWhG,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAkBpE,OAAO;CAKR;AAED;;;;GAIG;AACH,eAAO,MAAM,OAAO;;;;;CAEnB,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.js -new file mode 100644 -index 0000000..789b070 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.js -@@ -0,0 +1,124 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.blake2s = exports.BLAKE2s = exports.B2S_IV = void 0; -+exports.compress = compress; -+const _blake_js_1 = require("./_blake.js"); -+const _u64_js_1 = require("./_u64.js"); -+const utils_js_1 = require("./utils.js"); -+// Initial state: same as SHA256 -+// first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19 -+// prettier-ignore -+exports.B2S_IV = new Uint32Array([ -+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -+]); -+// Mixing function G splitted in two halfs -+function G1s(a, b, c, d, x) { -+ a = (a + b + x) | 0; -+ d = (0, utils_js_1.rotr)(d ^ a, 16); -+ c = (c + d) | 0; -+ b = (0, utils_js_1.rotr)(b ^ c, 12); -+ return { a, b, c, d }; -+} -+function G2s(a, b, c, d, x) { -+ a = (a + b + x) | 0; -+ d = (0, utils_js_1.rotr)(d ^ a, 8); -+ c = (c + d) | 0; -+ b = (0, utils_js_1.rotr)(b ^ c, 7); -+ return { a, b, c, d }; -+} -+// prettier-ignore -+function compress(s, offset, msg, rounds, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) { -+ let j = 0; -+ for (let i = 0; i < rounds; i++) { -+ ({ a: v0, b: v4, c: v8, d: v12 } = G1s(v0, v4, v8, v12, msg[offset + s[j++]])); -+ ({ a: v0, b: v4, c: v8, d: v12 } = G2s(v0, v4, v8, v12, msg[offset + s[j++]])); -+ ({ a: v1, b: v5, c: v9, d: v13 } = G1s(v1, v5, v9, v13, msg[offset + s[j++]])); -+ ({ a: v1, b: v5, c: v9, d: v13 } = G2s(v1, v5, v9, v13, msg[offset + s[j++]])); -+ ({ a: v2, b: v6, c: v10, d: v14 } = G1s(v2, v6, v10, v14, msg[offset + s[j++]])); -+ ({ a: v2, b: v6, c: v10, d: v14 } = G2s(v2, v6, v10, v14, msg[offset + s[j++]])); -+ ({ a: v3, b: v7, c: v11, d: v15 } = G1s(v3, v7, v11, v15, msg[offset + s[j++]])); -+ ({ a: v3, b: v7, c: v11, d: v15 } = G2s(v3, v7, v11, v15, msg[offset + s[j++]])); -+ ({ a: v0, b: v5, c: v10, d: v15 } = G1s(v0, v5, v10, v15, msg[offset + s[j++]])); -+ ({ a: v0, b: v5, c: v10, d: v15 } = G2s(v0, v5, v10, v15, msg[offset + s[j++]])); -+ ({ a: v1, b: v6, c: v11, d: v12 } = G1s(v1, v6, v11, v12, msg[offset + s[j++]])); -+ ({ a: v1, b: v6, c: v11, d: v12 } = G2s(v1, v6, v11, v12, msg[offset + s[j++]])); -+ ({ a: v2, b: v7, c: v8, d: v13 } = G1s(v2, v7, v8, v13, msg[offset + s[j++]])); -+ ({ a: v2, b: v7, c: v8, d: v13 } = G2s(v2, v7, v8, v13, msg[offset + s[j++]])); -+ ({ a: v3, b: v4, c: v9, d: v14 } = G1s(v3, v4, v9, v14, msg[offset + s[j++]])); -+ ({ a: v3, b: v4, c: v9, d: v14 } = G2s(v3, v4, v9, v14, msg[offset + s[j++]])); -+ } -+ return { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 }; -+} -+class BLAKE2s extends _blake_js_1.BLAKE { -+ constructor(opts = {}) { -+ super(64, opts.dkLen === undefined ? 32 : opts.dkLen, opts, 32, 8, 8); -+ // Internal state, same as SHA-256 -+ this.v0 = exports.B2S_IV[0] | 0; -+ this.v1 = exports.B2S_IV[1] | 0; -+ this.v2 = exports.B2S_IV[2] | 0; -+ this.v3 = exports.B2S_IV[3] | 0; -+ this.v4 = exports.B2S_IV[4] | 0; -+ this.v5 = exports.B2S_IV[5] | 0; -+ this.v6 = exports.B2S_IV[6] | 0; -+ this.v7 = exports.B2S_IV[7] | 0; -+ const keyLength = opts.key ? opts.key.length : 0; -+ this.v0 ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); -+ if (opts.salt) { -+ const salt = (0, utils_js_1.u32)((0, utils_js_1.toBytes)(opts.salt)); -+ this.v4 ^= (0, utils_js_1.byteSwapIfBE)(salt[0]); -+ this.v5 ^= (0, utils_js_1.byteSwapIfBE)(salt[1]); -+ } -+ if (opts.personalization) { -+ const pers = (0, utils_js_1.u32)((0, utils_js_1.toBytes)(opts.personalization)); -+ this.v6 ^= (0, utils_js_1.byteSwapIfBE)(pers[0]); -+ this.v7 ^= (0, utils_js_1.byteSwapIfBE)(pers[1]); -+ } -+ if (opts.key) { -+ // Pad to blockLen and update -+ const tmp = new Uint8Array(this.blockLen); -+ tmp.set((0, utils_js_1.toBytes)(opts.key)); -+ this.update(tmp); -+ } -+ } -+ get() { -+ const { v0, v1, v2, v3, v4, v5, v6, v7 } = this; -+ return [v0, v1, v2, v3, v4, v5, v6, v7]; -+ } -+ // prettier-ignore -+ set(v0, v1, v2, v3, v4, v5, v6, v7) { -+ this.v0 = v0 | 0; -+ this.v1 = v1 | 0; -+ this.v2 = v2 | 0; -+ this.v3 = v3 | 0; -+ this.v4 = v4 | 0; -+ this.v5 = v5 | 0; -+ this.v6 = v6 | 0; -+ this.v7 = v7 | 0; -+ } -+ compress(msg, offset, isLast) { -+ const { h, l } = (0, _u64_js_1.fromBig)(BigInt(this.length)); -+ // prettier-ignore -+ const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(_blake_js_1.SIGMA, offset, msg, 10, this.v0, this.v1, this.v2, this.v3, this.v4, this.v5, this.v6, this.v7, exports.B2S_IV[0], exports.B2S_IV[1], exports.B2S_IV[2], exports.B2S_IV[3], l ^ exports.B2S_IV[4], h ^ exports.B2S_IV[5], isLast ? ~exports.B2S_IV[6] : exports.B2S_IV[6], exports.B2S_IV[7]); -+ this.v0 ^= v0 ^ v8; -+ this.v1 ^= v1 ^ v9; -+ this.v2 ^= v2 ^ v10; -+ this.v3 ^= v3 ^ v11; -+ this.v4 ^= v4 ^ v12; -+ this.v5 ^= v5 ^ v13; -+ this.v6 ^= v6 ^ v14; -+ this.v7 ^= v7 ^ v15; -+ } -+ destroy() { -+ this.destroyed = true; -+ this.buffer32.fill(0); -+ this.set(0, 0, 0, 0, 0, 0, 0, 0); -+ } -+} -+exports.BLAKE2s = BLAKE2s; -+/** -+ * BLAKE2s - optimized for 32-bit platforms. JS doesn't have uint64, so it's faster than BLAKE2b. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, salt, personalization -+ */ -+exports.blake2s = (0, utils_js_1.wrapConstructorWithOpts)((opts) => new BLAKE2s(opts)); -+//# sourceMappingURL=blake2s.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.js.map -new file mode 100644 -index 0000000..9d81df0 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake2s.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake2s.js","sourceRoot":"","sources":["src/blake2s.ts"],"names":[],"mappings":"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CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.d.ts -new file mode 100644 -index 0000000..701b389 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.d.ts -@@ -0,0 +1,46 @@ -+import { BLAKE } from './_blake.js'; -+import { Input, HashXOF } from './utils.js'; -+export type Blake3Opts = { -+ dkLen?: number; -+ key?: Input; -+ context?: Input; -+}; -+export declare class BLAKE3 extends BLAKE implements HashXOF { -+ private IV; -+ private flags; -+ private state; -+ private chunkPos; -+ private chunksDone; -+ private stack; -+ private posOut; -+ private bufferOut32; -+ private bufferOut; -+ private chunkOut; -+ private enableXOF; -+ constructor(opts?: Blake3Opts, flags?: number); -+ protected get(): never[]; -+ protected set(): void; -+ private b2Compress; -+ protected compress(buf: Uint32Array, bufPos?: number, isLast?: boolean): void; -+ _cloneInto(to?: BLAKE3): BLAKE3; -+ destroy(): void; -+ private b2CompressOut; -+ protected finish(): void; -+ private writeInto; -+ xofInto(out: Uint8Array): Uint8Array; -+ xof(bytes: number): Uint8Array; -+ digestInto(out: Uint8Array): Uint8Array; -+ digest(): Uint8Array; -+} -+/** -+ * BLAKE3 hash function. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, context -+ */ -+export declare const blake3: { -+ (msg: Input, opts?: Blake3Opts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: Blake3Opts): HashXOF; -+}; -+//# sourceMappingURL=blake3.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.d.ts.map -new file mode 100644 -index 0000000..e6ff86a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake3.d.ts","sourceRoot":"","sources":["src/blake3.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,EACL,KAAK,EAIL,OAAO,EAIR,MAAM,YAAY,CAAC;AA4BpB,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAU1E,qBAAa,MAAO,SAAQ,KAAK,CAAC,MAAM,CAAE,YAAW,OAAO,CAAC,MAAM,CAAC;IAClE,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAQ;gBAEb,IAAI,GAAE,UAAe,EAAE,KAAK,SAAI;IA2B5C,SAAS,CAAC,GAAG;IAGb,SAAS,CAAC,GAAG;IACb,OAAO,CAAC,UAAU;IAmBlB,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,GAAE,MAAU,EAAE,MAAM,GAAE,OAAe;IAiChF,UAAU,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAe/B,OAAO;IASP,OAAO,CAAC,aAAa;IAiCrB,SAAS,CAAC,MAAM;IAoBhB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU;IAIpC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;IAI9B,UAAU,CAAC,GAAG,EAAE,UAAU;IAQ1B,MAAM;CAGP;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM;;;;;CAElB,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.js -new file mode 100644 -index 0000000..607d7f0 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.js -@@ -0,0 +1,244 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.blake3 = exports.BLAKE3 = void 0; -+const _assert_js_1 = require("./_assert.js"); -+const _u64_js_1 = require("./_u64.js"); -+const _blake_js_1 = require("./_blake.js"); -+const blake2s_js_1 = require("./blake2s.js"); -+const utils_js_1 = require("./utils.js"); -+const SIGMA = /* @__PURE__ */ (() => { -+ const Id = Array.from({ length: 16 }, (_, i) => i); -+ const permute = (arr) => [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8].map((i) => arr[i]); -+ const res = []; -+ for (let i = 0, v = Id; i < 7; i++, v = permute(v)) -+ res.push(...v); -+ return Uint8Array.from(res); -+})(); -+// Why is this so slow? It should be 6x faster than blake2b. -+// - There is only 30% reduction in number of rounds from blake2s -+// - This function uses tree mode to achive parallelisation via SIMD and threading, -+// however in JS we don't have threads and SIMD, so we get only overhead from tree structure -+// - It is possible to speed it up via Web Workers, hovewer it will make code singnificantly more -+// complicated, which we are trying to avoid, since this library is intended to be used -+// for cryptographic purposes. Also, parallelization happens only on chunk level (1024 bytes), -+// which won't really benefit small inputs. -+class BLAKE3 extends _blake_js_1.BLAKE { -+ constructor(opts = {}, flags = 0) { -+ super(64, opts.dkLen === undefined ? 32 : opts.dkLen, {}, Number.MAX_SAFE_INTEGER, 0, 0); -+ this.flags = 0 | 0; -+ this.chunkPos = 0; // Position of current block in chunk -+ this.chunksDone = 0; // How many chunks we already have -+ this.stack = []; -+ // Output -+ this.posOut = 0; -+ this.bufferOut32 = new Uint32Array(16); -+ this.chunkOut = 0; // index of output chunk -+ this.enableXOF = true; -+ this.outputLen = opts.dkLen === undefined ? 32 : opts.dkLen; -+ (0, _assert_js_1.number)(this.outputLen); -+ if (opts.key !== undefined && opts.context !== undefined) -+ throw new Error('Blake3: only key or context can be specified at same time'); -+ else if (opts.key !== undefined) { -+ const key = (0, utils_js_1.toBytes)(opts.key).slice(); -+ if (key.length !== 32) -+ throw new Error('Blake3: key should be 32 byte'); -+ this.IV = (0, utils_js_1.u32)(key); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(this.IV); -+ this.flags = flags | 16 /* B3_Flags.KEYED_HASH */; -+ } -+ else if (opts.context !== undefined) { -+ const context_key = new BLAKE3({ dkLen: 32 }, 32 /* B3_Flags.DERIVE_KEY_CONTEXT */) -+ .update(opts.context) -+ .digest(); -+ this.IV = (0, utils_js_1.u32)(context_key); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(this.IV); -+ this.flags = flags | 64 /* B3_Flags.DERIVE_KEY_MATERIAL */; -+ } -+ else { -+ this.IV = blake2s_js_1.B2S_IV.slice(); -+ this.flags = flags; -+ } -+ this.state = this.IV.slice(); -+ this.bufferOut = (0, utils_js_1.u8)(this.bufferOut32); -+ } -+ // Unused -+ get() { -+ return []; -+ } -+ set() { } -+ b2Compress(counter, flags, buf, bufPos = 0) { -+ const { state: s, pos } = this; -+ const { h, l } = (0, _u64_js_1.fromBig)(BigInt(counter), true); -+ // prettier-ignore -+ const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = (0, blake2s_js_1.compress)(SIGMA, bufPos, buf, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], blake2s_js_1.B2S_IV[0], blake2s_js_1.B2S_IV[1], blake2s_js_1.B2S_IV[2], blake2s_js_1.B2S_IV[3], h, l, pos, flags); -+ s[0] = v0 ^ v8; -+ s[1] = v1 ^ v9; -+ s[2] = v2 ^ v10; -+ s[3] = v3 ^ v11; -+ s[4] = v4 ^ v12; -+ s[5] = v5 ^ v13; -+ s[6] = v6 ^ v14; -+ s[7] = v7 ^ v15; -+ } -+ compress(buf, bufPos = 0, isLast = false) { -+ // Compress last block -+ let flags = this.flags; -+ if (!this.chunkPos) -+ flags |= 1 /* B3_Flags.CHUNK_START */; -+ if (this.chunkPos === 15 || isLast) -+ flags |= 2 /* B3_Flags.CHUNK_END */; -+ if (!isLast) -+ this.pos = this.blockLen; -+ this.b2Compress(this.chunksDone, flags, buf, bufPos); -+ this.chunkPos += 1; -+ // If current block is last in chunk (16 blocks), then compress chunks -+ if (this.chunkPos === 16 || isLast) { -+ let chunk = this.state; -+ this.state = this.IV.slice(); -+ // If not the last one, compress only when there are trailing zeros in chunk counter -+ // chunks used as binary tree where current stack is path. Zero means current leaf is finished and can be compressed. -+ // 1 (001) - leaf not finished (just push current chunk to stack) -+ // 2 (010) - leaf finished at depth=1 (merge with last elm on stack and push back) -+ // 3 (011) - last leaf not finished -+ // 4 (100) - leafs finished at depth=1 and depth=2 -+ for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) { -+ if (!(last = this.stack.pop())) -+ break; -+ this.buffer32.set(last, 0); -+ this.buffer32.set(chunk, 8); -+ this.pos = this.blockLen; -+ this.b2Compress(0, this.flags | 4 /* B3_Flags.PARENT */, this.buffer32, 0); -+ chunk = this.state; -+ this.state = this.IV.slice(); -+ } -+ this.chunksDone++; -+ this.chunkPos = 0; -+ this.stack.push(chunk); -+ } -+ this.pos = 0; -+ } -+ _cloneInto(to) { -+ to = super._cloneInto(to); -+ const { IV, flags, state, chunkPos, posOut, chunkOut, stack, chunksDone } = this; -+ to.state.set(state.slice()); -+ to.stack = stack.map((i) => Uint32Array.from(i)); -+ to.IV.set(IV); -+ to.flags = flags; -+ to.chunkPos = chunkPos; -+ to.chunksDone = chunksDone; -+ to.posOut = posOut; -+ to.chunkOut = chunkOut; -+ to.enableXOF = this.enableXOF; -+ to.bufferOut32.set(this.bufferOut32); -+ return to; -+ } -+ destroy() { -+ this.destroyed = true; -+ this.state.fill(0); -+ this.buffer32.fill(0); -+ this.IV.fill(0); -+ this.bufferOut32.fill(0); -+ for (let i of this.stack) -+ i.fill(0); -+ } -+ // Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8) -+ b2CompressOut() { -+ const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this; -+ const { h, l } = (0, _u64_js_1.fromBig)(BigInt(this.chunkOut++)); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(buffer32); -+ // prettier-ignore -+ const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = (0, blake2s_js_1.compress)(SIGMA, 0, buffer32, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], blake2s_js_1.B2S_IV[0], blake2s_js_1.B2S_IV[1], blake2s_js_1.B2S_IV[2], blake2s_js_1.B2S_IV[3], l, h, pos, flags); -+ out32[0] = v0 ^ v8; -+ out32[1] = v1 ^ v9; -+ out32[2] = v2 ^ v10; -+ out32[3] = v3 ^ v11; -+ out32[4] = v4 ^ v12; -+ out32[5] = v5 ^ v13; -+ out32[6] = v6 ^ v14; -+ out32[7] = v7 ^ v15; -+ out32[8] = s[0] ^ v8; -+ out32[9] = s[1] ^ v9; -+ out32[10] = s[2] ^ v10; -+ out32[11] = s[3] ^ v11; -+ out32[12] = s[4] ^ v12; -+ out32[13] = s[5] ^ v13; -+ out32[14] = s[6] ^ v14; -+ out32[15] = s[7] ^ v15; -+ if (!utils_js_1.isLE) { -+ (0, utils_js_1.byteSwap32)(buffer32); -+ (0, utils_js_1.byteSwap32)(out32); -+ } -+ this.posOut = 0; -+ } -+ finish() { -+ if (this.finished) -+ return; -+ this.finished = true; -+ // Padding -+ this.buffer.fill(0, this.pos); -+ // Process last chunk -+ let flags = this.flags | 8 /* B3_Flags.ROOT */; -+ if (this.stack.length) { -+ flags |= 4 /* B3_Flags.PARENT */; -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(this.buffer32); -+ this.compress(this.buffer32, 0, true); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(this.buffer32); -+ this.chunksDone = 0; -+ this.pos = this.blockLen; -+ } -+ else { -+ flags |= (!this.chunkPos ? 1 /* B3_Flags.CHUNK_START */ : 0) | 2 /* B3_Flags.CHUNK_END */; -+ } -+ this.flags = flags; -+ this.b2CompressOut(); -+ } -+ writeInto(out) { -+ (0, _assert_js_1.exists)(this, false); -+ (0, _assert_js_1.bytes)(out); -+ this.finish(); -+ const { blockLen, bufferOut } = this; -+ for (let pos = 0, len = out.length; pos < len;) { -+ if (this.posOut >= blockLen) -+ this.b2CompressOut(); -+ const take = Math.min(blockLen - this.posOut, len - pos); -+ out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); -+ this.posOut += take; -+ pos += take; -+ } -+ return out; -+ } -+ xofInto(out) { -+ if (!this.enableXOF) -+ throw new Error('XOF is not possible after digest call'); -+ return this.writeInto(out); -+ } -+ xof(bytes) { -+ (0, _assert_js_1.number)(bytes); -+ return this.xofInto(new Uint8Array(bytes)); -+ } -+ digestInto(out) { -+ (0, _assert_js_1.output)(out, this); -+ if (this.finished) -+ throw new Error('digest() was already called'); -+ this.enableXOF = false; -+ this.writeInto(out); -+ this.destroy(); -+ return out; -+ } -+ digest() { -+ return this.digestInto(new Uint8Array(this.outputLen)); -+ } -+} -+exports.BLAKE3 = BLAKE3; -+/** -+ * BLAKE3 hash function. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, context -+ */ -+exports.blake3 = (0, utils_js_1.wrapXOFConstructorWithOpts)((opts) => new BLAKE3(opts)); -+//# sourceMappingURL=blake3.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.js.map -new file mode 100644 -index 0000000..abe1edb ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/blake3.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake3.js","sourceRoot":"","sources":["src/blake3.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.d.ts -new file mode 100644 -index 0000000..ac181a0 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.d.ts -@@ -0,0 +1,2 @@ -+export declare const crypto: any; -+//# sourceMappingURL=crypto.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.d.ts.map -new file mode 100644 -index 0000000..a9ad2b4 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["src/crypto.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,KACuE,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.js -new file mode 100644 -index 0000000..8226391 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.js -@@ -0,0 +1,5 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.crypto = void 0; -+exports.crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined; -+//# sourceMappingURL=crypto.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.js.map -new file mode 100644 -index 0000000..9f794e2 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/crypto.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"crypto.js","sourceRoot":"","sources":["src/crypto.ts"],"names":[],"mappings":";;;AAGa,QAAA,MAAM,GACjB,OAAO,UAAU,KAAK,QAAQ,IAAI,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.d.ts -new file mode 100644 -index 0000000..98bda7b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.d.ts -@@ -0,0 +1,2 @@ -+export declare const crypto: any; -+//# sourceMappingURL=cryptoNode.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.d.ts.map -new file mode 100644 -index 0000000..5f3c48d ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"cryptoNode.d.ts","sourceRoot":"","sources":["src/cryptoNode.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,MAAM,KACoE,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.js -new file mode 100644 -index 0000000..a88676d ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.js -@@ -0,0 +1,10 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.crypto = void 0; -+// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. -+// See utils.ts for details. -+// The file will throw on node.js 14 and earlier. -+// @ts-ignore -+const nc = require("node:crypto"); -+exports.crypto = nc && typeof nc === 'object' && 'webcrypto' in nc ? nc.webcrypto : undefined; -+//# sourceMappingURL=cryptoNode.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.js.map -new file mode 100644 -index 0000000..9287d27 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/cryptoNode.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"cryptoNode.js","sourceRoot":"","sources":["src/cryptoNode.ts"],"names":[],"mappings":";;;AAAA,oFAAoF;AACpF,4BAA4B;AAC5B,iDAAiD;AACjD,aAAa;AACb,kCAAkC;AACrB,QAAA,MAAM,GACjB,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,WAAW,IAAI,EAAE,CAAC,CAAC,CAAE,EAAE,CAAC,SAAiB,CAAC,CAAC,CAAC,SAAS,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.d.ts -new file mode 100644 -index 0000000..66721eb ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.d.ts -@@ -0,0 +1,47 @@ -+export declare function scrypt(password: string, salt: string): Uint8Array; -+export declare function pbkdf2(password: string, salt: string): Uint8Array; -+/** -+ * Derives main seed. Takes a lot of time. Prefer `eskdf` method instead. -+ */ -+export declare function deriveMainSeed(username: string, password: string): Uint8Array; -+type AccountID = number | string; -+type OptsLength = { -+ keyLength: number; -+}; -+type OptsMod = { -+ modulus: bigint; -+}; -+type KeyOpts = undefined | OptsLength | OptsMod; -+export interface ESKDF { -+ /** -+ * Derives a child key. Child key will not be associated with any -+ * other child key because of properties of underlying KDF. -+ * -+ * @param protocol - 3-15 character protocol name -+ * @param accountId - numeric identifier of account -+ * @param options - `keyLength: 64` or `modulus: 41920438n` -+ * @example deriveChildKey('aes', 0) -+ */ -+ deriveChildKey: (protocol: string, accountId: AccountID, options?: KeyOpts) => Uint8Array; -+ /** -+ * Deletes the main seed from eskdf instance -+ */ -+ expire: () => void; -+ /** -+ * Account fingerprint -+ */ -+ fingerprint: string; -+} -+/** -+ * ESKDF -+ * @param username - username, email, or identifier, min: 8 characters, should have enough entropy -+ * @param password - password, min: 8 characters, should have enough entropy -+ * @example -+ * const kdf = await eskdf('example-university', 'beginning-new-example'); -+ * const key = kdf.deriveChildKey('aes', 0); -+ * console.log(kdf.fingerprint); -+ * kdf.expire(); -+ */ -+export declare function eskdf(username: string, password: string): Promise; -+export {}; -+//# sourceMappingURL=eskdf.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.d.ts.map -new file mode 100644 -index 0000000..a10e762 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"eskdf.d.ts","sourceRoot":"","sources":["src/eskdf.ts"],"names":[],"mappings":"AAeA,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAEjE;AAGD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAEjE;AAiBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAS7E;AAED,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AA+BjC,KAAK,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AACxC,KAAK,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACnC,KAAK,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAwChD,MAAM,WAAW,KAAK;IACpB;;;;;;;;OAQG;IACH,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,UAAU,CAAC;IAC1F;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAuB9E"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.js -new file mode 100644 -index 0000000..6a7671a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.js -@@ -0,0 +1,161 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.scrypt = scrypt; -+exports.pbkdf2 = pbkdf2; -+exports.deriveMainSeed = deriveMainSeed; -+exports.eskdf = eskdf; -+const _assert_js_1 = require("./_assert.js"); -+const hkdf_js_1 = require("./hkdf.js"); -+const sha256_js_1 = require("./sha256.js"); -+const pbkdf2_js_1 = require("./pbkdf2.js"); -+const scrypt_js_1 = require("./scrypt.js"); -+const utils_js_1 = require("./utils.js"); -+// A tiny KDF for various applications like AES key-gen. -+// Uses HKDF in a non-standard way, so it's not "KDF-secure", only "PRF-secure". -+// Which is good enough: assume sha2-256 retained preimage resistance. -+const SCRYPT_FACTOR = 2 ** 19; -+const PBKDF2_FACTOR = 2 ** 17; -+// Scrypt KDF -+function scrypt(password, salt) { -+ return (0, scrypt_js_1.scrypt)(password, salt, { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 }); -+} -+// PBKDF2-HMAC-SHA256 -+function pbkdf2(password, salt) { -+ return (0, pbkdf2_js_1.pbkdf2)(sha256_js_1.sha256, password, salt, { c: PBKDF2_FACTOR, dkLen: 32 }); -+} -+// Combines two 32-byte byte arrays -+function xor32(a, b) { -+ (0, _assert_js_1.bytes)(a, 32); -+ (0, _assert_js_1.bytes)(b, 32); -+ const arr = new Uint8Array(32); -+ for (let i = 0; i < 32; i++) { -+ arr[i] = a[i] ^ b[i]; -+ } -+ return arr; -+} -+function strHasLength(str, min, max) { -+ return typeof str === 'string' && str.length >= min && str.length <= max; -+} -+/** -+ * Derives main seed. Takes a lot of time. Prefer `eskdf` method instead. -+ */ -+function deriveMainSeed(username, password) { -+ if (!strHasLength(username, 8, 255)) -+ throw new Error('invalid username'); -+ if (!strHasLength(password, 8, 255)) -+ throw new Error('invalid password'); -+ const scr = scrypt(password + '\u{1}', username + '\u{1}'); -+ const pbk = pbkdf2(password + '\u{2}', username + '\u{2}'); -+ const res = xor32(scr, pbk); -+ scr.fill(0); -+ pbk.fill(0); -+ return res; -+} -+/** -+ * Converts protocol & accountId pair to HKDF salt & info params. -+ */ -+function getSaltInfo(protocol, accountId = 0) { -+ // Note that length here also repeats two lines below -+ // We do an additional length check here to reduce the scope of DoS attacks -+ if (!(strHasLength(protocol, 3, 15) && /^[a-z0-9]{3,15}$/.test(protocol))) { -+ throw new Error('invalid protocol'); -+ } -+ // Allow string account ids for some protocols -+ const allowsStr = /^password\d{0,3}|ssh|tor|file$/.test(protocol); -+ let salt; // Extract salt. Default is undefined. -+ if (typeof accountId === 'string') { -+ if (!allowsStr) -+ throw new Error('accountId must be a number'); -+ if (!strHasLength(accountId, 1, 255)) -+ throw new Error('accountId must be valid string'); -+ salt = (0, utils_js_1.toBytes)(accountId); -+ } -+ else if (Number.isSafeInteger(accountId)) { -+ if (accountId < 0 || accountId > 2 ** 32 - 1) -+ throw new Error('invalid accountId'); -+ // Convert to Big Endian Uint32 -+ salt = new Uint8Array(4); -+ (0, utils_js_1.createView)(salt).setUint32(0, accountId, false); -+ } -+ else { -+ throw new Error(`accountId must be a number${allowsStr ? ' or string' : ''}`); -+ } -+ const info = (0, utils_js_1.toBytes)(protocol); -+ return { salt, info }; -+} -+function countBytes(num) { -+ if (typeof num !== 'bigint' || num <= BigInt(128)) -+ throw new Error('invalid number'); -+ return Math.ceil(num.toString(2).length / 8); -+} -+/** -+ * Parses keyLength and modulus options to extract length of result key. -+ * If modulus is used, adds 64 bits to it as per FIPS 186 B.4.1 to combat modulo bias. -+ */ -+function getKeyLength(options) { -+ if (!options || typeof options !== 'object') -+ return 32; -+ const hasLen = 'keyLength' in options; -+ const hasMod = 'modulus' in options; -+ if (hasLen && hasMod) -+ throw new Error('cannot combine keyLength and modulus options'); -+ if (!hasLen && !hasMod) -+ throw new Error('must have either keyLength or modulus option'); -+ // FIPS 186 B.4.1 requires at least 64 more bits -+ const l = hasMod ? countBytes(options.modulus) + 8 : options.keyLength; -+ if (!(typeof l === 'number' && l >= 16 && l <= 8192)) -+ throw new Error('invalid keyLength'); -+ return l; -+} -+/** -+ * Converts key to bigint and divides it by modulus. Big Endian. -+ * Implements FIPS 186 B.4.1, which removes 0 and modulo bias from output. -+ */ -+function modReduceKey(key, modulus) { -+ const _1 = BigInt(1); -+ const num = BigInt('0x' + (0, utils_js_1.bytesToHex)(key)); // check for ui8a, then bytesToNumber() -+ const res = (num % (modulus - _1)) + _1; // Remove 0 from output -+ if (res < _1) -+ throw new Error('expected positive number'); // Guard against bad values -+ const len = key.length - 8; // FIPS requires 64 more bits = 8 bytes -+ const hex = res.toString(16).padStart(len * 2, '0'); // numberToHex() -+ const bytes = (0, utils_js_1.hexToBytes)(hex); -+ if (bytes.length !== len) -+ throw new Error('invalid length of result key'); -+ return bytes; -+} -+/** -+ * ESKDF -+ * @param username - username, email, or identifier, min: 8 characters, should have enough entropy -+ * @param password - password, min: 8 characters, should have enough entropy -+ * @example -+ * const kdf = await eskdf('example-university', 'beginning-new-example'); -+ * const key = kdf.deriveChildKey('aes', 0); -+ * console.log(kdf.fingerprint); -+ * kdf.expire(); -+ */ -+async function eskdf(username, password) { -+ // We are using closure + object instead of class because -+ // we want to make `seed` non-accessible for any external function. -+ let seed = deriveMainSeed(username, password); -+ function deriveCK(protocol, accountId = 0, options) { -+ (0, _assert_js_1.bytes)(seed, 32); -+ const { salt, info } = getSaltInfo(protocol, accountId); // validate protocol & accountId -+ const keyLength = getKeyLength(options); // validate options -+ const key = (0, hkdf_js_1.hkdf)(sha256_js_1.sha256, seed, salt, info, keyLength); -+ // Modulus has already been validated -+ return options && 'modulus' in options ? modReduceKey(key, options.modulus) : key; -+ } -+ function expire() { -+ if (seed) -+ seed.fill(1); -+ seed = undefined; -+ } -+ // prettier-ignore -+ const fingerprint = Array.from(deriveCK('fingerprint', 0)) -+ .slice(0, 6) -+ .map((char) => char.toString(16).padStart(2, '0').toUpperCase()) -+ .join(':'); -+ return Object.freeze({ deriveChildKey: deriveCK, expire, fingerprint }); -+} -+//# sourceMappingURL=eskdf.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.js.map -new file mode 100644 -index 0000000..43a4ede ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/eskdf.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"eskdf.js","sourceRoot":"","sources":["src/eskdf.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.d.ts -new file mode 100644 -index 0000000..f66656f ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.d.ts -@@ -0,0 +1,24 @@ -+declare function number(n: number): void; -+declare function bool(b: boolean): void; -+export declare function isBytes(a: unknown): a is Uint8Array; -+declare function bytes(b: Uint8Array | undefined, ...lengths: number[]): void; -+type Hash = { -+ (data: Uint8Array): Uint8Array; -+ blockLen: number; -+ outputLen: number; -+ create: any; -+}; -+declare function hash(h: Hash): void; -+declare function exists(instance: any, checkFinished?: boolean): void; -+declare function output(out: any, instance: any): void; -+export { number, bool, bytes, hash, exists, output }; -+declare const assert: { -+ number: typeof number; -+ bool: typeof bool; -+ bytes: typeof bytes; -+ hash: typeof hash; -+ exists: typeof exists; -+ output: typeof output; -+}; -+export default assert; -+//# sourceMappingURL=_assert.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.d.ts.map -new file mode 100644 -index 0000000..19f6194 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_assert.d.ts","sourceRoot":"","sources":["../src/_assert.ts"],"names":[],"mappings":"AAAA,iBAAS,MAAM,CAAC,CAAC,EAAE,MAAM,QAExB;AAED,iBAAS,IAAI,CAAC,CAAC,EAAE,OAAO,QAEvB;AAGD,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,UAAU,CAKnD;AAED,iBAAS,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,QAI7D;AAED,KAAK,IAAI,GAAG;IACV,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;CACb,CAAC;AACF,iBAAS,IAAI,CAAC,CAAC,EAAE,IAAI,QAKpB;AAED,iBAAS,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,UAAO,QAGlD;AACD,iBAAS,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,QAMtC;AAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAErD,QAAA,MAAM,MAAM;;;;;;;CAAgD,CAAC;AAC7D,eAAe,MAAM,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.js -new file mode 100644 -index 0000000..b6006b2 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.js -@@ -0,0 +1,42 @@ -+function number(n) { -+ if (!Number.isSafeInteger(n) || n < 0) -+ throw new Error(`positive integer expected, not ${n}`); -+} -+function bool(b) { -+ if (typeof b !== 'boolean') -+ throw new Error(`boolean expected, not ${b}`); -+} -+// copied from utils -+export function isBytes(a) { -+ return (a instanceof Uint8Array || -+ (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array')); -+} -+function bytes(b, ...lengths) { -+ if (!isBytes(b)) -+ throw new Error('Uint8Array expected'); -+ if (lengths.length > 0 && !lengths.includes(b.length)) -+ throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`); -+} -+function hash(h) { -+ if (typeof h !== 'function' || typeof h.create !== 'function') -+ throw new Error('Hash should be wrapped by utils.wrapConstructor'); -+ number(h.outputLen); -+ number(h.blockLen); -+} -+function exists(instance, checkFinished = true) { -+ if (instance.destroyed) -+ throw new Error('Hash instance has been destroyed'); -+ if (checkFinished && instance.finished) -+ throw new Error('Hash#digest() has already been called'); -+} -+function output(out, instance) { -+ bytes(out); -+ const min = instance.outputLen; -+ if (out.length < min) { -+ throw new Error(`digestInto() expects output buffer of length at least ${min}`); -+ } -+} -+export { number, bool, bytes, hash, exists, output }; -+const assert = { number, bool, bytes, hash, exists, output }; -+export default assert; -+//# sourceMappingURL=_assert.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.js.map -new file mode 100644 -index 0000000..3596c9e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_assert.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_assert.js","sourceRoot":"","sources":["../src/_assert.ts"],"names":[],"mappings":"AAAA,SAAS,MAAM,CAAC,CAAS;IACvB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,EAAE,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,IAAI,CAAC,CAAU;IACtB,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,oBAAoB;AACpB,MAAM,UAAU,OAAO,CAAC,CAAU;IAChC,OAAO,CACL,CAAC,YAAY,UAAU;QACvB,CAAC,CAAC,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,YAAY,CAAC,CAC5E,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,CAAyB,EAAE,GAAG,OAAiB;IAC5D,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,mBAAmB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAC3F,CAAC;AAQD,SAAS,IAAI,CAAC,CAAO;IACnB,IAAI,OAAO,CAAC,KAAK,UAAU,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU;QAC3D,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACpB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,MAAM,CAAC,QAAa,EAAE,aAAa,GAAG,IAAI;IACjD,IAAI,QAAQ,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC5E,IAAI,aAAa,IAAI,QAAQ,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;AACnG,CAAC;AACD,SAAS,MAAM,CAAC,GAAQ,EAAE,QAAa;IACrC,KAAK,CAAC,GAAG,CAAC,CAAC;IACX,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC;IAC/B,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yDAAyD,GAAG,EAAE,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAErD,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC7D,eAAe,MAAM,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.d.ts -new file mode 100644 -index 0000000..ddb3f3a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.d.ts -@@ -0,0 +1,28 @@ -+import { Hash, Input } from './utils.js'; -+export declare const SIGMA: Uint8Array; -+export type BlakeOpts = { -+ dkLen?: number; -+ key?: Input; -+ salt?: Input; -+ personalization?: Input; -+}; -+export declare abstract class BLAKE> extends Hash { -+ readonly blockLen: number; -+ outputLen: number; -+ protected abstract compress(msg: Uint32Array, offset: number, isLast: boolean): void; -+ protected abstract get(): number[]; -+ protected abstract set(...args: number[]): void; -+ abstract destroy(): void; -+ protected buffer: Uint8Array; -+ protected buffer32: Uint32Array; -+ protected length: number; -+ protected pos: number; -+ protected finished: boolean; -+ protected destroyed: boolean; -+ constructor(blockLen: number, outputLen: number, opts: BlakeOpts | undefined, keyLen: number, saltLen: number, persLen: number); -+ update(data: Input): this; -+ digestInto(out: Uint8Array): void; -+ digest(): Uint8Array; -+ _cloneInto(to?: T): T; -+} -+//# sourceMappingURL=_blake.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.d.ts.map -new file mode 100644 -index 0000000..ef482c7 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_blake.d.ts","sourceRoot":"","sources":["../src/_blake.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAgD,MAAM,YAAY,CAAC;AAMvF,eAAO,MAAM,KAAK,YAahB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,eAAe,CAAC,EAAE,KAAK,CAAC;CACzB,CAAC;AAEF,8BAAsB,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,CAAC,CAAC;IAa3D,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IAb1B,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IACpF,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,MAAM,EAAE;IAClC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAC/C,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC;IAChC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAK;IAC7B,SAAS,CAAC,GAAG,EAAE,MAAM,CAAK;IAC1B,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,SAAS,UAAS;gBAGjB,QAAQ,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACxB,IAAI,EAAE,SAAS,YAAK,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM;IAejB,MAAM,CAAC,IAAI,EAAE,KAAK;IAuClB,UAAU,CAAC,GAAG,EAAE,UAAU;IAa1B,MAAM;IAON,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;CAYtB"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.js -new file mode 100644 -index 0000000..e3da803 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.js -@@ -0,0 +1,120 @@ -+import { number, exists, output } from './_assert.js'; -+import { Hash, toBytes, u32, isLE, byteSwap32, byteSwapIfBE } from './utils.js'; -+// Blake is based on ChaCha permutation. -+// For BLAKE2b, the two extra permutations for rounds 10 and 11 are SIGMA[10..11] = SIGMA[0..1]. -+// prettier-ignore -+export const SIGMA = /* @__PURE__ */ new Uint8Array([ -+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -+ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, -+ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, -+ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, -+ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, -+ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, -+ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, -+ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, -+ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, -+ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, -+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -+ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, -+]); -+export class BLAKE extends Hash { -+ constructor(blockLen, outputLen, opts = {}, keyLen, saltLen, persLen) { -+ super(); -+ this.blockLen = blockLen; -+ this.outputLen = outputLen; -+ this.length = 0; -+ this.pos = 0; -+ this.finished = false; -+ this.destroyed = false; -+ number(blockLen); -+ number(outputLen); -+ number(keyLen); -+ if (outputLen < 0 || outputLen > keyLen) -+ throw new Error('outputLen bigger than keyLen'); -+ if (opts.key !== undefined && (opts.key.length < 1 || opts.key.length > keyLen)) -+ throw new Error(`key must be up 1..${keyLen} byte long or undefined`); -+ if (opts.salt !== undefined && opts.salt.length !== saltLen) -+ throw new Error(`salt must be ${saltLen} byte long or undefined`); -+ if (opts.personalization !== undefined && opts.personalization.length !== persLen) -+ throw new Error(`personalization must be ${persLen} byte long or undefined`); -+ this.buffer32 = u32((this.buffer = new Uint8Array(blockLen))); -+ } -+ update(data) { -+ exists(this); -+ // Main difference with other hashes: there is flag for last block, -+ // so we cannot process current block before we know that there -+ // is the next one. This significantly complicates logic and reduces ability -+ // to do zero-copy processing -+ const { blockLen, buffer, buffer32 } = this; -+ data = toBytes(data); -+ const len = data.length; -+ const offset = data.byteOffset; -+ const buf = data.buffer; -+ for (let pos = 0; pos < len;) { -+ // If buffer is full and we still have input (don't process last block, same as blake2s) -+ if (this.pos === blockLen) { -+ if (!isLE) -+ byteSwap32(buffer32); -+ this.compress(buffer32, 0, false); -+ if (!isLE) -+ byteSwap32(buffer32); -+ this.pos = 0; -+ } -+ const take = Math.min(blockLen - this.pos, len - pos); -+ const dataOffset = offset + pos; -+ // full block && aligned to 4 bytes && not last in input -+ if (take === blockLen && !(dataOffset % 4) && pos + take < len) { -+ const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4)); -+ if (!isLE) -+ byteSwap32(data32); -+ for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) { -+ this.length += blockLen; -+ this.compress(data32, pos32, false); -+ } -+ if (!isLE) -+ byteSwap32(data32); -+ continue; -+ } -+ buffer.set(data.subarray(pos, pos + take), this.pos); -+ this.pos += take; -+ this.length += take; -+ pos += take; -+ } -+ return this; -+ } -+ digestInto(out) { -+ exists(this); -+ output(out, this); -+ const { pos, buffer32 } = this; -+ this.finished = true; -+ // Padding -+ this.buffer.subarray(pos).fill(0); -+ if (!isLE) -+ byteSwap32(buffer32); -+ this.compress(buffer32, 0, true); -+ if (!isLE) -+ byteSwap32(buffer32); -+ const out32 = u32(out); -+ this.get().forEach((v, i) => (out32[i] = byteSwapIfBE(v))); -+ } -+ digest() { -+ const { buffer, outputLen } = this; -+ this.digestInto(buffer); -+ const res = buffer.slice(0, outputLen); -+ this.destroy(); -+ return res; -+ } -+ _cloneInto(to) { -+ const { buffer, length, finished, destroyed, outputLen, pos } = this; -+ to || (to = new this.constructor({ dkLen: outputLen })); -+ to.set(...this.get()); -+ to.length = length; -+ to.finished = finished; -+ to.destroyed = destroyed; -+ to.outputLen = outputLen; -+ to.buffer.set(buffer); -+ to.pos = pos; -+ return to; -+ } -+} -+//# sourceMappingURL=_blake.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.js.map -new file mode 100644 -index 0000000..73c73dc ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_blake.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_blake.js","sourceRoot":"","sources":["../src/_blake.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.d.ts -new file mode 100644 -index 0000000..1c34636 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.d.ts -@@ -0,0 +1,36 @@ -+import { Hash, Input } from './utils.js'; -+/** -+ * Choice: a ? b : c -+ */ -+export declare const Chi: (a: number, b: number, c: number) => number; -+/** -+ * Majority function, true if any two inputs is true -+ */ -+export declare const Maj: (a: number, b: number, c: number) => number; -+/** -+ * Merkle-Damgard hash construction base class. -+ * Could be used to create MD5, RIPEMD, SHA1, SHA2. -+ */ -+export declare abstract class HashMD> extends Hash { -+ readonly blockLen: number; -+ outputLen: number; -+ readonly padOffset: number; -+ readonly isLE: boolean; -+ protected abstract process(buf: DataView, offset: number): void; -+ protected abstract get(): number[]; -+ protected abstract set(...args: number[]): void; -+ abstract destroy(): void; -+ protected abstract roundClean(): void; -+ protected buffer: Uint8Array; -+ protected view: DataView; -+ protected finished: boolean; -+ protected length: number; -+ protected pos: number; -+ protected destroyed: boolean; -+ constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean); -+ update(data: Input): this; -+ digestInto(out: Uint8Array): void; -+ digest(): Uint8Array; -+ _cloneInto(to?: T): T; -+} -+//# sourceMappingURL=_md.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.d.ts.map -new file mode 100644 -index 0000000..2422450 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_md.d.ts","sourceRoot":"","sources":["../src/_md.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAc,KAAK,EAAW,MAAM,YAAY,CAAC;AAiB9D;;GAEG;AACH,eAAO,MAAM,GAAG,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAuB,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,GAAG,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAgC,CAAC;AAEpF;;;GAGG;AACH,8BAAsB,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,CAAC,CAAC;IAe7D,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO;IAjBxB,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAC/D,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,MAAM,EAAE;IAClC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAC/C,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,SAAS,CAAC,QAAQ,CAAC,UAAU,IAAI,IAAI;IAErC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;IACzB,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,MAAM,SAAK;IACrB,SAAS,CAAC,GAAG,SAAK;IAClB,SAAS,CAAC,SAAS,UAAS;gBAGjB,QAAQ,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO;IAMxB,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI;IAyBzB,UAAU,CAAC,GAAG,EAAE,UAAU;IAkC1B,MAAM;IAON,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;CAWtB"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.js -new file mode 100644 -index 0000000..691d84b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.js -@@ -0,0 +1,128 @@ -+import { exists, output } from './_assert.js'; -+import { Hash, createView, toBytes } from './utils.js'; -+/** -+ * Polyfill for Safari 14 -+ */ -+function setBigUint64(view, byteOffset, value, isLE) { -+ if (typeof view.setBigUint64 === 'function') -+ return view.setBigUint64(byteOffset, value, isLE); -+ const _32n = BigInt(32); -+ const _u32_max = BigInt(0xffffffff); -+ const wh = Number((value >> _32n) & _u32_max); -+ const wl = Number(value & _u32_max); -+ const h = isLE ? 4 : 0; -+ const l = isLE ? 0 : 4; -+ view.setUint32(byteOffset + h, wh, isLE); -+ view.setUint32(byteOffset + l, wl, isLE); -+} -+/** -+ * Choice: a ? b : c -+ */ -+export const Chi = (a, b, c) => (a & b) ^ (~a & c); -+/** -+ * Majority function, true if any two inputs is true -+ */ -+export const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c); -+/** -+ * Merkle-Damgard hash construction base class. -+ * Could be used to create MD5, RIPEMD, SHA1, SHA2. -+ */ -+export class HashMD extends Hash { -+ constructor(blockLen, outputLen, padOffset, isLE) { -+ super(); -+ this.blockLen = blockLen; -+ this.outputLen = outputLen; -+ this.padOffset = padOffset; -+ this.isLE = isLE; -+ this.finished = false; -+ this.length = 0; -+ this.pos = 0; -+ this.destroyed = false; -+ this.buffer = new Uint8Array(blockLen); -+ this.view = createView(this.buffer); -+ } -+ update(data) { -+ exists(this); -+ const { view, buffer, blockLen } = this; -+ data = toBytes(data); -+ const len = data.length; -+ for (let pos = 0; pos < len;) { -+ const take = Math.min(blockLen - this.pos, len - pos); -+ // Fast path: we have at least one block in input, cast it to view and process -+ if (take === blockLen) { -+ const dataView = createView(data); -+ for (; blockLen <= len - pos; pos += blockLen) -+ this.process(dataView, pos); -+ continue; -+ } -+ buffer.set(data.subarray(pos, pos + take), this.pos); -+ this.pos += take; -+ pos += take; -+ if (this.pos === blockLen) { -+ this.process(view, 0); -+ this.pos = 0; -+ } -+ } -+ this.length += data.length; -+ this.roundClean(); -+ return this; -+ } -+ digestInto(out) { -+ exists(this); -+ output(out, this); -+ this.finished = true; -+ // Padding -+ // We can avoid allocation of buffer for padding completely if it -+ // was previously not allocated here. But it won't change performance. -+ const { buffer, view, blockLen, isLE } = this; -+ let { pos } = this; -+ // append the bit '1' to the message -+ buffer[pos++] = 0b10000000; -+ this.buffer.subarray(pos).fill(0); -+ // we have less than padOffset left in buffer, so we cannot put length in -+ // current block, need process it and pad again -+ if (this.padOffset > blockLen - pos) { -+ this.process(view, 0); -+ pos = 0; -+ } -+ // Pad until full block byte with zeros -+ for (let i = pos; i < blockLen; i++) -+ buffer[i] = 0; -+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that -+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen. -+ // So we just write lowest 64 bits of that value. -+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE); -+ this.process(view, 0); -+ const oview = createView(out); -+ const len = this.outputLen; -+ // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT -+ if (len % 4) -+ throw new Error('_sha2: outputLen should be aligned to 32bit'); -+ const outLen = len / 4; -+ const state = this.get(); -+ if (outLen > state.length) -+ throw new Error('_sha2: outputLen bigger than state'); -+ for (let i = 0; i < outLen; i++) -+ oview.setUint32(4 * i, state[i], isLE); -+ } -+ digest() { -+ const { buffer, outputLen } = this; -+ this.digestInto(buffer); -+ const res = buffer.slice(0, outputLen); -+ this.destroy(); -+ return res; -+ } -+ _cloneInto(to) { -+ to || (to = new this.constructor()); -+ to.set(...this.get()); -+ const { blockLen, buffer, length, finished, destroyed, pos } = this; -+ to.length = length; -+ to.pos = pos; -+ to.finished = finished; -+ to.destroyed = destroyed; -+ if (length % blockLen) -+ to.buffer.set(buffer); -+ return to; -+ } -+} -+//# sourceMappingURL=_md.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.js.map -new file mode 100644 -index 0000000..912b473 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_md.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_md.js","sourceRoot":"","sources":["../src/_md.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.d.ts -new file mode 100644 -index 0000000..6b8c273 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.d.ts -@@ -0,0 +1,55 @@ -+declare function fromBig(n: bigint, le?: boolean): { -+ h: number; -+ l: number; -+}; -+declare function split(lst: bigint[], le?: boolean): Uint32Array[]; -+declare const toBig: (h: number, l: number) => bigint; -+declare const shrSH: (h: number, _l: number, s: number) => number; -+declare const shrSL: (h: number, l: number, s: number) => number; -+declare const rotrSH: (h: number, l: number, s: number) => number; -+declare const rotrSL: (h: number, l: number, s: number) => number; -+declare const rotrBH: (h: number, l: number, s: number) => number; -+declare const rotrBL: (h: number, l: number, s: number) => number; -+declare const rotr32H: (_h: number, l: number) => number; -+declare const rotr32L: (h: number, _l: number) => number; -+declare const rotlSH: (h: number, l: number, s: number) => number; -+declare const rotlSL: (h: number, l: number, s: number) => number; -+declare const rotlBH: (h: number, l: number, s: number) => number; -+declare const rotlBL: (h: number, l: number, s: number) => number; -+declare function add(Ah: number, Al: number, Bh: number, Bl: number): { -+ h: number; -+ l: number; -+}; -+declare const add3L: (Al: number, Bl: number, Cl: number) => number; -+declare const add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; -+declare const add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; -+declare const add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; -+declare const add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; -+declare const add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; -+export { fromBig, split, toBig, shrSH, shrSL, rotrSH, rotrSL, rotrBH, rotrBL, rotr32H, rotr32L, rotlSH, rotlSL, rotlBH, rotlBL, add, add3L, add3H, add4L, add4H, add5H, add5L, }; -+declare const u64: { -+ fromBig: typeof fromBig; -+ split: typeof split; -+ toBig: (h: number, l: number) => bigint; -+ shrSH: (h: number, _l: number, s: number) => number; -+ shrSL: (h: number, l: number, s: number) => number; -+ rotrSH: (h: number, l: number, s: number) => number; -+ rotrSL: (h: number, l: number, s: number) => number; -+ rotrBH: (h: number, l: number, s: number) => number; -+ rotrBL: (h: number, l: number, s: number) => number; -+ rotr32H: (_h: number, l: number) => number; -+ rotr32L: (h: number, _l: number) => number; -+ rotlSH: (h: number, l: number, s: number) => number; -+ rotlSL: (h: number, l: number, s: number) => number; -+ rotlBH: (h: number, l: number, s: number) => number; -+ rotlBL: (h: number, l: number, s: number) => number; -+ add: typeof add; -+ add3L: (Al: number, Bl: number, Cl: number) => number; -+ add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; -+ add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; -+ add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; -+ add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; -+ add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; -+}; -+export default u64; -+//# sourceMappingURL=_u64.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.d.ts.map -new file mode 100644 -index 0000000..7580fea ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_u64.d.ts","sourceRoot":"","sources":["../src/_u64.ts"],"names":[],"mappings":"AAIA,iBAAS,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,UAAQ;;;EAGrC;AAED,iBAAS,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,UAAQ,iBAQvC;AAED,QAAA,MAAM,KAAK,MAAO,MAAM,KAAK,MAAM,WAAgD,CAAC;AAEpF,QAAA,MAAM,KAAK,MAAO,MAAM,MAAM,MAAM,KAAK,MAAM,WAAY,CAAC;AAC5D,QAAA,MAAM,KAAK,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAgC,CAAC;AAE/E,QAAA,MAAM,MAAM,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAgC,CAAC;AAChF,QAAA,MAAM,MAAM,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAgC,CAAC;AAEhF,QAAA,MAAM,MAAM,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAuC,CAAC;AACvF,QAAA,MAAM,MAAM,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAuC,CAAC;AAEvF,QAAA,MAAM,OAAO,OAAQ,MAAM,KAAK,MAAM,WAAM,CAAC;AAC7C,QAAA,MAAM,OAAO,MAAO,MAAM,MAAM,MAAM,WAAM,CAAC;AAE7C,QAAA,MAAM,MAAM,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAgC,CAAC;AAChF,QAAA,MAAM,MAAM,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAgC,CAAC;AAEhF,QAAA,MAAM,MAAM,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAuC,CAAC;AACvF,QAAA,MAAM,MAAM,MAAO,MAAM,KAAK,MAAM,KAAK,MAAM,WAAuC,CAAC;AAIvF,iBAAS,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;EAG1D;AAED,QAAA,MAAM,KAAK,OAAQ,MAAM,MAAM,MAAM,MAAM,MAAM,WAAyC,CAAC;AAC3F,QAAA,MAAM,KAAK,QAAS,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,WAClB,CAAC;AAC7C,QAAA,MAAM,KAAK,OAAQ,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,WACV,CAAC;AACpD,QAAA,MAAM,KAAK,QAAS,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,WACzB,CAAC;AAClD,QAAA,MAAM,KAAK,OAAQ,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,WACT,CAAC;AACjE,QAAA,MAAM,KAAK,QAAS,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,WAChC,CAAC;AAGvD,OAAO,EACL,OAAO,EAAE,KAAK,EAAE,KAAK,EACrB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC9B,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAC9C,CAAC;AAEF,QAAA,MAAM,GAAG;;;eAjDS,MAAM,KAAK,MAAM;eAEjB,MAAM,MAAM,MAAM,KAAK,MAAM;eAC7B,MAAM,KAAK,MAAM,KAAK,MAAM;gBAE3B,MAAM,KAAK,MAAM,KAAK,MAAM;gBAC5B,MAAM,KAAK,MAAM,KAAK,MAAM;gBAE5B,MAAM,KAAK,MAAM,KAAK,MAAM;gBAC5B,MAAM,KAAK,MAAM,KAAK,MAAM;kBAE1B,MAAM,KAAK,MAAM;iBAClB,MAAM,MAAM,MAAM;gBAEnB,MAAM,KAAK,MAAM,KAAK,MAAM;gBAC5B,MAAM,KAAK,MAAM,KAAK,MAAM;gBAE5B,MAAM,KAAK,MAAM,KAAK,MAAM;gBAC5B,MAAM,KAAK,MAAM,KAAK,MAAM;;gBAS5B,MAAM,MAAM,MAAM,MAAM,MAAM;iBAC7B,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM;gBAE3C,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM;iBAEzC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM;iBAItD,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM;gBAFnE,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM;CAsBxE,CAAC;AACF,eAAe,GAAG,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.js -new file mode 100644 -index 0000000..66cce47 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.js -@@ -0,0 +1,62 @@ -+const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1); -+const _32n = /* @__PURE__ */ BigInt(32); -+// We are not using BigUint64Array, because they are extremely slow as per 2022 -+function fromBig(n, le = false) { -+ if (le) -+ return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) }; -+ return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 }; -+} -+function split(lst, le = false) { -+ let Ah = new Uint32Array(lst.length); -+ let Al = new Uint32Array(lst.length); -+ for (let i = 0; i < lst.length; i++) { -+ const { h, l } = fromBig(lst[i], le); -+ [Ah[i], Al[i]] = [h, l]; -+ } -+ return [Ah, Al]; -+} -+const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0); -+// for Shift in [0, 32) -+const shrSH = (h, _l, s) => h >>> s; -+const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s); -+// Right rotate for Shift in [1, 32) -+const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s)); -+const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s); -+// Right rotate for Shift in (32, 64), NOTE: 32 is special case. -+const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32)); -+const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s)); -+// Right rotate for shift===32 (just swaps l&h) -+const rotr32H = (_h, l) => l; -+const rotr32L = (h, _l) => h; -+// Left rotate for Shift in [1, 32) -+const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s)); -+const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s)); -+// Left rotate for Shift in (32, 64), NOTE: 32 is special case. -+const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s)); -+const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s)); -+// JS uses 32-bit signed integers for bitwise operations which means we cannot -+// simple take carry out of low bit sum by shift, we need to use division. -+function add(Ah, Al, Bh, Bl) { -+ const l = (Al >>> 0) + (Bl >>> 0); -+ return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 }; -+} -+// Addition with more than 2 elements -+const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0); -+const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0; -+const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0); -+const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0; -+const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0); -+const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0; -+// prettier-ignore -+export { fromBig, split, toBig, shrSH, shrSL, rotrSH, rotrSL, rotrBH, rotrBL, rotr32H, rotr32L, rotlSH, rotlSL, rotlBH, rotlBL, add, add3L, add3H, add4L, add4H, add5H, add5L, }; -+// prettier-ignore -+const u64 = { -+ fromBig, split, toBig, -+ shrSH, shrSL, -+ rotrSH, rotrSL, rotrBH, rotrBL, -+ rotr32H, rotr32L, -+ rotlSH, rotlSL, rotlBH, rotlBL, -+ add, add3L, add3H, add4L, add4H, add5H, add5L, -+}; -+export default u64; -+//# sourceMappingURL=_u64.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.js.map -new file mode 100644 -index 0000000..ecba77f ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/_u64.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"_u64.js","sourceRoot":"","sources":["../src/_u64.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.d.ts -new file mode 100644 -index 0000000..9d4139c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.d.ts -@@ -0,0 +1,17 @@ -+import { Input } from './utils.js'; -+export type ArgonOpts = { -+ t: number; -+ m: number; -+ p: number; -+ version?: number; -+ key?: Input; -+ personalization?: Input; -+ dkLen?: number; -+ asyncTick?: number; -+ maxmem?: number; -+ onProgress?: (progress: number) => void; -+}; -+export declare const argon2d: (password: Input, salt: Input, opts: ArgonOpts) => Uint8Array; -+export declare const argon2i: (password: Input, salt: Input, opts: ArgonOpts) => Uint8Array; -+export declare const argon2id: (password: Input, salt: Input, opts: ArgonOpts) => Uint8Array; -+//# sourceMappingURL=argon2.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.d.ts.map -new file mode 100644 -index 0000000..8035207 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"argon2.d.ts","sourceRoot":"","sources":["../src/argon2.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAoB,MAAM,YAAY,CAAC;AAkKrD,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,eAAe,CAAC,EAAE,KAAK,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAkMF,eAAO,MAAM,OAAO,aAAc,KAAK,QAAQ,KAAK,QAAQ,SAAS,eACvB,CAAC;AAC/C,eAAO,MAAM,OAAO,aAAc,KAAK,QAAQ,KAAK,QAAQ,SAAS,eACxB,CAAC;AAC9C,eAAO,MAAM,QAAQ,aAAc,KAAK,QAAQ,KAAK,QAAQ,SAAS,eACxB,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.js -new file mode 100644 -index 0000000..682eb34 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.js -@@ -0,0 +1,297 @@ -+import { number as assertNumber } from './_assert.js'; -+import { toBytes, u8, u32 } from './utils.js'; -+import { blake2b } from './blake2b.js'; -+import { add3H, add3L, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL } from './_u64.js'; -+const ARGON2_SYNC_POINTS = 4; -+const toBytesOptional = (buf) => (buf !== undefined ? toBytes(buf) : new Uint8Array([])); -+function mul(a, b) { -+ const aL = a & 0xffff; -+ const aH = a >>> 16; -+ const bL = b & 0xffff; -+ const bH = b >>> 16; -+ const ll = Math.imul(aL, bL); -+ const hl = Math.imul(aH, bL); -+ const lh = Math.imul(aL, bH); -+ const hh = Math.imul(aH, bH); -+ const BUF = ((ll >>> 16) + (hl & 0xffff) + lh) | 0; -+ const h = ((hl >>> 16) + (BUF >>> 16) + hh) | 0; -+ return { h, l: (BUF << 16) | (ll & 0xffff) }; -+} -+function relPos(areaSize, relativePos) { -+ // areaSize - 1 - ((areaSize * ((relativePos ** 2) >>> 32)) >>> 32) -+ return areaSize - 1 - mul(areaSize, mul(relativePos, relativePos).h).h; -+} -+function mul2(a, b) { -+ // 2 * a * b (via shifts) -+ const { h, l } = mul(a, b); -+ return { h: ((h << 1) | (l >>> 31)) & 4294967295, l: (l << 1) & 4294967295 }; -+} -+function blamka(Ah, Al, Bh, Bl) { -+ const { h: Ch, l: Cl } = mul2(Al, Bl); -+ // A + B + (2 * A * B) -+ const Rll = add3L(Al, Bl, Cl); -+ return { h: add3H(Rll, Ah, Bh, Ch), l: Rll | 0 }; -+} -+// Temporary block buffer -+const A2_BUF = new Uint32Array(256); -+function G(a, b, c, d) { -+ let Al = A2_BUF[2 * a], Ah = A2_BUF[2 * a + 1]; // prettier-ignore -+ let Bl = A2_BUF[2 * b], Bh = A2_BUF[2 * b + 1]; // prettier-ignore -+ let Cl = A2_BUF[2 * c], Ch = A2_BUF[2 * c + 1]; // prettier-ignore -+ let Dl = A2_BUF[2 * d], Dh = A2_BUF[2 * d + 1]; // prettier-ignore -+ ({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl)); -+ ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); -+ ({ Dh, Dl } = { Dh: rotr32H(Dh, Dl), Dl: rotr32L(Dh, Dl) }); -+ ({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl)); -+ ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); -+ ({ Bh, Bl } = { Bh: rotrSH(Bh, Bl, 24), Bl: rotrSL(Bh, Bl, 24) }); -+ ({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl)); -+ ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); -+ ({ Dh, Dl } = { Dh: rotrSH(Dh, Dl, 16), Dl: rotrSL(Dh, Dl, 16) }); -+ ({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl)); -+ ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); -+ ({ Bh, Bl } = { Bh: rotrBH(Bh, Bl, 63), Bl: rotrBL(Bh, Bl, 63) }); -+ (A2_BUF[2 * a] = Al), (A2_BUF[2 * a + 1] = Ah); -+ (A2_BUF[2 * b] = Bl), (A2_BUF[2 * b + 1] = Bh); -+ (A2_BUF[2 * c] = Cl), (A2_BUF[2 * c + 1] = Ch); -+ (A2_BUF[2 * d] = Dl), (A2_BUF[2 * d + 1] = Dh); -+} -+// prettier-ignore -+function P(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14, v15) { -+ G(v00, v04, v08, v12); -+ G(v01, v05, v09, v13); -+ G(v02, v06, v10, v14); -+ G(v03, v07, v11, v15); -+ G(v00, v05, v10, v15); -+ G(v01, v06, v11, v12); -+ G(v02, v07, v08, v13); -+ G(v03, v04, v09, v14); -+} -+function block(x, xPos, yPos, outPos, needXor) { -+ for (let i = 0; i < 256; i++) -+ A2_BUF[i] = x[xPos + i] ^ x[yPos + i]; -+ // columns -+ for (let i = 0; i < 128; i += 16) { -+ // prettier-ignore -+ P(i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, i + 8, i + 9, i + 10, i + 11, i + 12, i + 13, i + 14, i + 15); -+ } -+ // rows -+ for (let i = 0; i < 16; i += 2) { -+ // prettier-ignore -+ P(i, i + 1, i + 16, i + 17, i + 32, i + 33, i + 48, i + 49, i + 64, i + 65, i + 80, i + 81, i + 96, i + 97, i + 112, i + 113); -+ } -+ if (needXor) -+ for (let i = 0; i < 256; i++) -+ x[outPos + i] ^= A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i]; -+ else -+ for (let i = 0; i < 256; i++) -+ x[outPos + i] = A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i]; -+} -+// Variable-Length Hash Function H' -+function Hp(A, dkLen) { -+ const A8 = u8(A); -+ const T = new Uint32Array(1); -+ const T8 = u8(T); -+ T[0] = dkLen; -+ // Fast path -+ if (dkLen <= 64) -+ return blake2b.create({ dkLen }).update(T8).update(A8).digest(); -+ const out = new Uint8Array(dkLen); -+ let V = blake2b.create({}).update(T8).update(A8).digest(); -+ let pos = 0; -+ // First block -+ out.set(V.subarray(0, 32)); -+ pos += 32; -+ // Rest blocks -+ for (; dkLen - pos > 64; pos += 32) -+ out.set((V = blake2b(V)).subarray(0, 32), pos); -+ // Last block -+ out.set(blake2b(V, { dkLen: dkLen - pos }), pos); -+ return u32(out); -+} -+function indexAlpha(r, s, laneLen, segmentLen, index, randL, sameLane = false) { -+ let area; -+ if (0 == r) { -+ if (0 == s) -+ area = index - 1; -+ else if (sameLane) -+ area = s * segmentLen + index - 1; -+ else -+ area = s * segmentLen + (index == 0 ? -1 : 0); -+ } -+ else if (sameLane) -+ area = laneLen - segmentLen + index - 1; -+ else -+ area = laneLen - segmentLen + (index == 0 ? -1 : 0); -+ const startPos = r !== 0 && s !== ARGON2_SYNC_POINTS - 1 ? (s + 1) * segmentLen : 0; -+ const rel = relPos(area, randL); -+ // NOTE: check about overflows here -+ // absPos = (startPos + relPos) % laneLength; -+ return (startPos + rel) % laneLen; -+} -+function argon2Init(type, password, salt, opts) { -+ password = toBytes(password); -+ salt = toBytes(salt); -+ let { p, dkLen, m, t, version, key, personalization, maxmem, onProgress } = { -+ ...opts, -+ version: opts.version || 0x13, -+ dkLen: opts.dkLen || 32, -+ maxmem: 2 ** 32, -+ }; -+ // Validation -+ assertNumber(p); -+ assertNumber(dkLen); -+ assertNumber(m); -+ assertNumber(t); -+ assertNumber(version); -+ if (dkLen < 4 || dkLen >= 2 ** 32) -+ throw new Error('Argon2: dkLen should be at least 4 bytes'); -+ if (p < 1 || p >= 2 ** 32) -+ throw new Error('Argon2: p (parallelism) should be at least 1'); -+ if (t < 1 || t >= 2 ** 32) -+ throw new Error('Argon2: t (iterations) should be at least 1'); -+ if (m < 8 * p) -+ throw new Error(`Argon2: memory should be at least 8*p bytes`); -+ if (version !== 16 && version !== 19) -+ throw new Error(`Argon2: unknown version=${version}`); -+ password = toBytes(password); -+ if (password.length < 0 || password.length >= 2 ** 32) -+ throw new Error('Argon2: password should be less than 4 GB'); -+ salt = toBytes(salt); -+ if (salt.length < 8) -+ throw new Error('Argon2: salt should be at least 8 bytes'); -+ key = toBytesOptional(key); -+ personalization = toBytesOptional(personalization); -+ if (onProgress !== undefined && typeof onProgress !== 'function') -+ throw new Error('progressCb should be function'); -+ // Params -+ const lanes = p; -+ // m' = 4 * p * floor (m / 4p) -+ const mP = 4 * p * Math.floor(m / (ARGON2_SYNC_POINTS * p)); -+ //q = m' / p columns -+ const laneLen = Math.floor(mP / p); -+ const segmentLen = Math.floor(laneLen / ARGON2_SYNC_POINTS); -+ // H0 -+ const h = blake2b.create({}); -+ const BUF = new Uint32Array(1); -+ const BUF8 = u8(BUF); -+ for (const i of [p, dkLen, m, t, version, type]) { -+ if (i < 0 || i >= 2 ** 32) -+ throw new Error(`Argon2: wrong parameter=${i}, expected uint32`); -+ BUF[0] = i; -+ h.update(BUF8); -+ } -+ for (let i of [password, salt, key, personalization]) { -+ BUF[0] = i.length; -+ h.update(BUF8).update(i); -+ } -+ const H0 = new Uint32Array(18); -+ const H0_8 = u8(H0); -+ h.digestInto(H0_8); -+ // 256 u32 = 1024 (BLOCK_SIZE) -+ const memUsed = mP * 256; -+ if (memUsed < 0 || memUsed >= 2 ** 32 || memUsed > maxmem) { -+ throw new Error(`Argon2: wrong params (memUsed=${memUsed} maxmem=${maxmem}), should be less than 2**32`); -+ } -+ const B = new Uint32Array(memUsed); -+ // Fill first blocks -+ for (let l = 0; l < p; l++) { -+ const i = 256 * laneLen * l; -+ // B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) -+ H0[17] = l; -+ H0[16] = 0; -+ B.set(Hp(H0, 1024), i); -+ // B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) -+ H0[16] = 1; -+ B.set(Hp(H0, 1024), i + 256); -+ } -+ let perBlock = () => { }; -+ if (onProgress) { -+ const totalBlock = t * ARGON2_SYNC_POINTS * p * segmentLen; -+ // Invoke callback if progress changes from 10.01 to 10.02 -+ // Allows to draw smooth progress bar on up to 8K screen -+ const callbackPer = Math.max(Math.floor(totalBlock / 10000), 1); -+ let blockCnt = 0; -+ perBlock = () => { -+ blockCnt++; -+ if (onProgress && (!(blockCnt % callbackPer) || blockCnt === totalBlock)) -+ onProgress(blockCnt / totalBlock); -+ }; -+ } -+ return { type, mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock }; -+} -+function argon2Output(B, p, laneLen, dkLen) { -+ const B_final = new Uint32Array(256); -+ for (let l = 0; l < p; l++) -+ for (let j = 0; j < 256; j++) -+ B_final[j] ^= B[256 * (laneLen * l + laneLen - 1) + j]; -+ return u8(Hp(B_final, dkLen)); -+} -+function processBlock(B, address, l, r, s, index, laneLen, segmentLen, lanes, offset, prev, dataIndependent, needXor) { -+ if (offset % laneLen) -+ prev = offset - 1; -+ let randL, randH; -+ if (dataIndependent) { -+ if (index % 128 === 0) { -+ address[256 + 12]++; -+ block(address, 256, 2 * 256, 0, false); -+ block(address, 0, 2 * 256, 0, false); -+ } -+ randL = address[2 * (index % 128)]; -+ randH = address[2 * (index % 128) + 1]; -+ } -+ else { -+ const T = 256 * prev; -+ randL = B[T]; -+ randH = B[T + 1]; -+ } -+ // address block -+ const refLane = r === 0 && s === 0 ? l : randH % lanes; -+ const refPos = indexAlpha(r, s, laneLen, segmentLen, index, randL, refLane == l); -+ const refBlock = laneLen * refLane + refPos; -+ // B[i][j] = G(B[i][j-1], B[l][z]) -+ block(B, 256 * prev, 256 * refBlock, offset * 256, needXor); -+} -+function argon2(type, password, salt, opts) { -+ const { mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock } = argon2Init(type, password, salt, opts); -+ // Pre-loop setup -+ // [address, input, zero_block] format so we can pass single U32 to block function -+ const address = new Uint32Array(3 * 256); -+ address[256 + 6] = mP; -+ address[256 + 8] = t; -+ address[256 + 10] = type; -+ for (let r = 0; r < t; r++) { -+ const needXor = r !== 0 && version === 0x13; -+ address[256 + 0] = r; -+ for (let s = 0; s < ARGON2_SYNC_POINTS; s++) { -+ address[256 + 4] = s; -+ const dataIndependent = type == 1 /* Types.Argon2i */ || (type == 2 /* Types.Argon2id */ && r === 0 && s < 2); -+ for (let l = 0; l < p; l++) { -+ address[256 + 2] = l; -+ address[256 + 12] = 0; -+ let startPos = 0; -+ if (r === 0 && s === 0) { -+ startPos = 2; -+ if (dataIndependent) { -+ address[256 + 12]++; -+ block(address, 256, 2 * 256, 0, false); -+ block(address, 0, 2 * 256, 0, false); -+ } -+ } -+ // current block postion -+ let offset = l * laneLen + s * segmentLen + startPos; -+ // previous block position -+ let prev = offset % laneLen ? offset - 1 : offset + laneLen - 1; -+ for (let index = startPos; index < segmentLen; index++, offset++, prev++) { -+ perBlock(); -+ processBlock(B, address, l, r, s, index, laneLen, segmentLen, lanes, offset, prev, dataIndependent, needXor); -+ } -+ } -+ } -+ } -+ return argon2Output(B, p, laneLen, dkLen); -+} -+export const argon2d = (password, salt, opts) => argon2(0 /* Types.Argond2d */, password, salt, opts); -+export const argon2i = (password, salt, opts) => argon2(1 /* Types.Argon2i */, password, salt, opts); -+export const argon2id = (password, salt, opts) => argon2(2 /* Types.Argon2id */, password, salt, opts); -+//# sourceMappingURL=argon2.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.js.map -new file mode 100644 -index 0000000..4a51e8a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/argon2.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"argon2.js","sourceRoot":"","sources":["../src/argon2.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.d.ts -new file mode 100644 -index 0000000..fa5b7f9 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.d.ts -@@ -0,0 +1,53 @@ -+import { BLAKE, BlakeOpts } from './_blake.js'; -+export declare class BLAKE2b extends BLAKE { -+ private v0l; -+ private v0h; -+ private v1l; -+ private v1h; -+ private v2l; -+ private v2h; -+ private v3l; -+ private v3h; -+ private v4l; -+ private v4h; -+ private v5l; -+ private v5h; -+ private v6l; -+ private v6h; -+ private v7l; -+ private v7h; -+ constructor(opts?: BlakeOpts); -+ protected get(): [ -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number -+ ]; -+ protected set(v0l: number, v0h: number, v1l: number, v1h: number, v2l: number, v2h: number, v3l: number, v3h: number, v4l: number, v4h: number, v5l: number, v5h: number, v6l: number, v6h: number, v7l: number, v7h: number): void; -+ protected compress(msg: Uint32Array, offset: number, isLast: boolean): void; -+ destroy(): void; -+} -+/** -+ * BLAKE2b - optimized for 64-bit platforms. JS doesn't have uint64, so it's slower than BLAKE2s. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, salt, personalization -+ */ -+export declare const blake2b: { -+ (msg: import("./utils.js").Input, opts?: BlakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: BlakeOpts): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=blake2b.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.d.ts.map -new file mode 100644 -index 0000000..046c3e0 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake2b.d.ts","sourceRoot":"","sources":["../src/blake2b.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAS,MAAM,aAAa,CAAC;AAgEtD,qBAAa,OAAQ,SAAQ,KAAK,CAAC,OAAO,CAAC;IAEzC,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;gBAEjB,IAAI,GAAE,SAAc;IA0BhC,SAAS,CAAC,GAAG,IAAI;QACf,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAC9D,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;KAC/D;IAKD,SAAS,CAAC,GAAG,CACX,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAmBpD,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAkDpE,OAAO;CAKR;AAED;;;;GAIG;AACH,eAAO,MAAM,OAAO;;;;;CAEnB,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.js -new file mode 100644 -index 0000000..207b222 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.js -@@ -0,0 +1,189 @@ -+import { BLAKE, SIGMA } from './_blake.js'; -+import u64 from './_u64.js'; -+import { toBytes, u32, wrapConstructorWithOpts, byteSwapIfBE } from './utils.js'; -+// Same as SHA-512 but LE -+// prettier-ignore -+const B2B_IV = /* @__PURE__ */ new Uint32Array([ -+ 0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a, -+ 0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19 -+]); -+// Temporary buffer -+const BBUF = /* @__PURE__ */ new Uint32Array(32); -+// Mixing function G splitted in two halfs -+function G1b(a, b, c, d, msg, x) { -+ // NOTE: V is LE here -+ const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore -+ let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore -+ let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore -+ let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore -+ let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore -+ // v[a] = (v[a] + v[b] + x) | 0; -+ let ll = u64.add3L(Al, Bl, Xl); -+ Ah = u64.add3H(ll, Ah, Bh, Xh); -+ Al = ll | 0; -+ // v[d] = rotr(v[d] ^ v[a], 32) -+ ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); -+ ({ Dh, Dl } = { Dh: u64.rotr32H(Dh, Dl), Dl: u64.rotr32L(Dh, Dl) }); -+ // v[c] = (v[c] + v[d]) | 0; -+ ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); -+ // v[b] = rotr(v[b] ^ v[c], 24) -+ ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); -+ ({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 24), Bl: u64.rotrSL(Bh, Bl, 24) }); -+ (BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah); -+ (BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh); -+ (BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch); -+ (BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh); -+} -+function G2b(a, b, c, d, msg, x) { -+ // NOTE: V is LE here -+ const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore -+ let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore -+ let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore -+ let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore -+ let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore -+ // v[a] = (v[a] + v[b] + x) | 0; -+ let ll = u64.add3L(Al, Bl, Xl); -+ Ah = u64.add3H(ll, Ah, Bh, Xh); -+ Al = ll | 0; -+ // v[d] = rotr(v[d] ^ v[a], 16) -+ ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); -+ ({ Dh, Dl } = { Dh: u64.rotrSH(Dh, Dl, 16), Dl: u64.rotrSL(Dh, Dl, 16) }); -+ // v[c] = (v[c] + v[d]) | 0; -+ ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); -+ // v[b] = rotr(v[b] ^ v[c], 63) -+ ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); -+ ({ Bh, Bl } = { Bh: u64.rotrBH(Bh, Bl, 63), Bl: u64.rotrBL(Bh, Bl, 63) }); -+ (BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah); -+ (BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh); -+ (BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch); -+ (BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh); -+} -+export class BLAKE2b extends BLAKE { -+ constructor(opts = {}) { -+ super(128, opts.dkLen === undefined ? 64 : opts.dkLen, opts, 64, 16, 16); -+ // Same as SHA-512, but LE -+ this.v0l = B2B_IV[0] | 0; -+ this.v0h = B2B_IV[1] | 0; -+ this.v1l = B2B_IV[2] | 0; -+ this.v1h = B2B_IV[3] | 0; -+ this.v2l = B2B_IV[4] | 0; -+ this.v2h = B2B_IV[5] | 0; -+ this.v3l = B2B_IV[6] | 0; -+ this.v3h = B2B_IV[7] | 0; -+ this.v4l = B2B_IV[8] | 0; -+ this.v4h = B2B_IV[9] | 0; -+ this.v5l = B2B_IV[10] | 0; -+ this.v5h = B2B_IV[11] | 0; -+ this.v6l = B2B_IV[12] | 0; -+ this.v6h = B2B_IV[13] | 0; -+ this.v7l = B2B_IV[14] | 0; -+ this.v7h = B2B_IV[15] | 0; -+ const keyLength = opts.key ? opts.key.length : 0; -+ this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); -+ if (opts.salt) { -+ const salt = u32(toBytes(opts.salt)); -+ this.v4l ^= byteSwapIfBE(salt[0]); -+ this.v4h ^= byteSwapIfBE(salt[1]); -+ this.v5l ^= byteSwapIfBE(salt[2]); -+ this.v5h ^= byteSwapIfBE(salt[3]); -+ } -+ if (opts.personalization) { -+ const pers = u32(toBytes(opts.personalization)); -+ this.v6l ^= byteSwapIfBE(pers[0]); -+ this.v6h ^= byteSwapIfBE(pers[1]); -+ this.v7l ^= byteSwapIfBE(pers[2]); -+ this.v7h ^= byteSwapIfBE(pers[3]); -+ } -+ if (opts.key) { -+ // Pad to blockLen and update -+ const tmp = new Uint8Array(this.blockLen); -+ tmp.set(toBytes(opts.key)); -+ this.update(tmp); -+ } -+ } -+ // prettier-ignore -+ get() { -+ let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this; -+ return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h]; -+ } -+ // prettier-ignore -+ set(v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h) { -+ this.v0l = v0l | 0; -+ this.v0h = v0h | 0; -+ this.v1l = v1l | 0; -+ this.v1h = v1h | 0; -+ this.v2l = v2l | 0; -+ this.v2h = v2h | 0; -+ this.v3l = v3l | 0; -+ this.v3h = v3h | 0; -+ this.v4l = v4l | 0; -+ this.v4h = v4h | 0; -+ this.v5l = v5l | 0; -+ this.v5h = v5h | 0; -+ this.v6l = v6l | 0; -+ this.v6h = v6h | 0; -+ this.v7l = v7l | 0; -+ this.v7h = v7h | 0; -+ } -+ compress(msg, offset, isLast) { -+ this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state. -+ BBUF.set(B2B_IV, 16); // Second half from IV. -+ let { h, l } = u64.fromBig(BigInt(this.length)); -+ BBUF[24] = B2B_IV[8] ^ l; // Low word of the offset. -+ BBUF[25] = B2B_IV[9] ^ h; // High word. -+ // Invert all bits for last block -+ if (isLast) { -+ BBUF[28] = ~BBUF[28]; -+ BBUF[29] = ~BBUF[29]; -+ } -+ let j = 0; -+ const s = SIGMA; -+ for (let i = 0; i < 12; i++) { -+ G1b(0, 4, 8, 12, msg, offset + 2 * s[j++]); -+ G2b(0, 4, 8, 12, msg, offset + 2 * s[j++]); -+ G1b(1, 5, 9, 13, msg, offset + 2 * s[j++]); -+ G2b(1, 5, 9, 13, msg, offset + 2 * s[j++]); -+ G1b(2, 6, 10, 14, msg, offset + 2 * s[j++]); -+ G2b(2, 6, 10, 14, msg, offset + 2 * s[j++]); -+ G1b(3, 7, 11, 15, msg, offset + 2 * s[j++]); -+ G2b(3, 7, 11, 15, msg, offset + 2 * s[j++]); -+ G1b(0, 5, 10, 15, msg, offset + 2 * s[j++]); -+ G2b(0, 5, 10, 15, msg, offset + 2 * s[j++]); -+ G1b(1, 6, 11, 12, msg, offset + 2 * s[j++]); -+ G2b(1, 6, 11, 12, msg, offset + 2 * s[j++]); -+ G1b(2, 7, 8, 13, msg, offset + 2 * s[j++]); -+ G2b(2, 7, 8, 13, msg, offset + 2 * s[j++]); -+ G1b(3, 4, 9, 14, msg, offset + 2 * s[j++]); -+ G2b(3, 4, 9, 14, msg, offset + 2 * s[j++]); -+ } -+ this.v0l ^= BBUF[0] ^ BBUF[16]; -+ this.v0h ^= BBUF[1] ^ BBUF[17]; -+ this.v1l ^= BBUF[2] ^ BBUF[18]; -+ this.v1h ^= BBUF[3] ^ BBUF[19]; -+ this.v2l ^= BBUF[4] ^ BBUF[20]; -+ this.v2h ^= BBUF[5] ^ BBUF[21]; -+ this.v3l ^= BBUF[6] ^ BBUF[22]; -+ this.v3h ^= BBUF[7] ^ BBUF[23]; -+ this.v4l ^= BBUF[8] ^ BBUF[24]; -+ this.v4h ^= BBUF[9] ^ BBUF[25]; -+ this.v5l ^= BBUF[10] ^ BBUF[26]; -+ this.v5h ^= BBUF[11] ^ BBUF[27]; -+ this.v6l ^= BBUF[12] ^ BBUF[28]; -+ this.v6h ^= BBUF[13] ^ BBUF[29]; -+ this.v7l ^= BBUF[14] ^ BBUF[30]; -+ this.v7h ^= BBUF[15] ^ BBUF[31]; -+ BBUF.fill(0); -+ } -+ destroy() { -+ this.destroyed = true; -+ this.buffer32.fill(0); -+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -+ } -+} -+/** -+ * BLAKE2b - optimized for 64-bit platforms. JS doesn't have uint64, so it's slower than BLAKE2s. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, salt, personalization -+ */ -+export const blake2b = /* @__PURE__ */ wrapConstructorWithOpts((opts) => new BLAKE2b(opts)); -+//# sourceMappingURL=blake2b.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.js.map -new file mode 100644 -index 0000000..8b51057 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2b.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake2b.js","sourceRoot":"","sources":["../src/blake2b.ts"],"names":[],"mappings":"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AC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAE5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACf,CAAC;IACD,OAAO;QACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC,uBAAuB,CAC5D,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAC5B,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.d.ts -new file mode 100644 -index 0000000..29d4b2f ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.d.ts -@@ -0,0 +1,47 @@ -+import { BLAKE, BlakeOpts } from './_blake.js'; -+export declare const B2S_IV: Uint32Array; -+export declare function compress(s: Uint8Array, offset: number, msg: Uint32Array, rounds: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number): { -+ v0: number; -+ v1: number; -+ v2: number; -+ v3: number; -+ v4: number; -+ v5: number; -+ v6: number; -+ v7: number; -+ v8: number; -+ v9: number; -+ v10: number; -+ v11: number; -+ v12: number; -+ v13: number; -+ v14: number; -+ v15: number; -+}; -+export declare class BLAKE2s extends BLAKE { -+ private v0; -+ private v1; -+ private v2; -+ private v3; -+ private v4; -+ private v5; -+ private v6; -+ private v7; -+ constructor(opts?: BlakeOpts); -+ protected get(): [number, number, number, number, number, number, number, number]; -+ protected set(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number): void; -+ protected compress(msg: Uint32Array, offset: number, isLast: boolean): void; -+ destroy(): void; -+} -+/** -+ * BLAKE2s - optimized for 32-bit platforms. JS doesn't have uint64, so it's faster than BLAKE2b. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, salt, personalization -+ */ -+export declare const blake2s: { -+ (msg: import("./utils.js").Input, opts?: BlakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: BlakeOpts): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=blake2s.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.d.ts.map -new file mode 100644 -index 0000000..c092a23 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake2s.d.ts","sourceRoot":"","sources":["../src/blake2s.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAS,MAAM,aAAa,CAAC;AAOtD,eAAO,MAAM,MAAM,aAEjB,CAAC;AAoBH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EACtF,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAC9F,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;;;;;;;;;;;;;;;;;EAuBrG;AAED,qBAAa,OAAQ,SAAQ,KAAK,CAAC,OAAO,CAAC;IAEzC,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;gBAEf,IAAI,GAAE,SAAc;IAqBhC,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAKjF,SAAS,CAAC,GAAG,CACX,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAWhG,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAkBpE,OAAO;CAKR;AAED;;;;GAIG;AACH,eAAO,MAAM,OAAO;;;;;CAEnB,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.js -new file mode 100644 -index 0000000..d601eeb ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.js -@@ -0,0 +1,119 @@ -+import { BLAKE, SIGMA } from './_blake.js'; -+import { fromBig } from './_u64.js'; -+import { rotr, toBytes, wrapConstructorWithOpts, u32, byteSwapIfBE } from './utils.js'; -+// Initial state: same as SHA256 -+// first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19 -+// prettier-ignore -+export const B2S_IV = /* @__PURE__ */ new Uint32Array([ -+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -+]); -+// Mixing function G splitted in two halfs -+function G1s(a, b, c, d, x) { -+ a = (a + b + x) | 0; -+ d = rotr(d ^ a, 16); -+ c = (c + d) | 0; -+ b = rotr(b ^ c, 12); -+ return { a, b, c, d }; -+} -+function G2s(a, b, c, d, x) { -+ a = (a + b + x) | 0; -+ d = rotr(d ^ a, 8); -+ c = (c + d) | 0; -+ b = rotr(b ^ c, 7); -+ return { a, b, c, d }; -+} -+// prettier-ignore -+export function compress(s, offset, msg, rounds, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) { -+ let j = 0; -+ for (let i = 0; i < rounds; i++) { -+ ({ a: v0, b: v4, c: v8, d: v12 } = G1s(v0, v4, v8, v12, msg[offset + s[j++]])); -+ ({ a: v0, b: v4, c: v8, d: v12 } = G2s(v0, v4, v8, v12, msg[offset + s[j++]])); -+ ({ a: v1, b: v5, c: v9, d: v13 } = G1s(v1, v5, v9, v13, msg[offset + s[j++]])); -+ ({ a: v1, b: v5, c: v9, d: v13 } = G2s(v1, v5, v9, v13, msg[offset + s[j++]])); -+ ({ a: v2, b: v6, c: v10, d: v14 } = G1s(v2, v6, v10, v14, msg[offset + s[j++]])); -+ ({ a: v2, b: v6, c: v10, d: v14 } = G2s(v2, v6, v10, v14, msg[offset + s[j++]])); -+ ({ a: v3, b: v7, c: v11, d: v15 } = G1s(v3, v7, v11, v15, msg[offset + s[j++]])); -+ ({ a: v3, b: v7, c: v11, d: v15 } = G2s(v3, v7, v11, v15, msg[offset + s[j++]])); -+ ({ a: v0, b: v5, c: v10, d: v15 } = G1s(v0, v5, v10, v15, msg[offset + s[j++]])); -+ ({ a: v0, b: v5, c: v10, d: v15 } = G2s(v0, v5, v10, v15, msg[offset + s[j++]])); -+ ({ a: v1, b: v6, c: v11, d: v12 } = G1s(v1, v6, v11, v12, msg[offset + s[j++]])); -+ ({ a: v1, b: v6, c: v11, d: v12 } = G2s(v1, v6, v11, v12, msg[offset + s[j++]])); -+ ({ a: v2, b: v7, c: v8, d: v13 } = G1s(v2, v7, v8, v13, msg[offset + s[j++]])); -+ ({ a: v2, b: v7, c: v8, d: v13 } = G2s(v2, v7, v8, v13, msg[offset + s[j++]])); -+ ({ a: v3, b: v4, c: v9, d: v14 } = G1s(v3, v4, v9, v14, msg[offset + s[j++]])); -+ ({ a: v3, b: v4, c: v9, d: v14 } = G2s(v3, v4, v9, v14, msg[offset + s[j++]])); -+ } -+ return { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 }; -+} -+export class BLAKE2s extends BLAKE { -+ constructor(opts = {}) { -+ super(64, opts.dkLen === undefined ? 32 : opts.dkLen, opts, 32, 8, 8); -+ // Internal state, same as SHA-256 -+ this.v0 = B2S_IV[0] | 0; -+ this.v1 = B2S_IV[1] | 0; -+ this.v2 = B2S_IV[2] | 0; -+ this.v3 = B2S_IV[3] | 0; -+ this.v4 = B2S_IV[4] | 0; -+ this.v5 = B2S_IV[5] | 0; -+ this.v6 = B2S_IV[6] | 0; -+ this.v7 = B2S_IV[7] | 0; -+ const keyLength = opts.key ? opts.key.length : 0; -+ this.v0 ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); -+ if (opts.salt) { -+ const salt = u32(toBytes(opts.salt)); -+ this.v4 ^= byteSwapIfBE(salt[0]); -+ this.v5 ^= byteSwapIfBE(salt[1]); -+ } -+ if (opts.personalization) { -+ const pers = u32(toBytes(opts.personalization)); -+ this.v6 ^= byteSwapIfBE(pers[0]); -+ this.v7 ^= byteSwapIfBE(pers[1]); -+ } -+ if (opts.key) { -+ // Pad to blockLen and update -+ const tmp = new Uint8Array(this.blockLen); -+ tmp.set(toBytes(opts.key)); -+ this.update(tmp); -+ } -+ } -+ get() { -+ const { v0, v1, v2, v3, v4, v5, v6, v7 } = this; -+ return [v0, v1, v2, v3, v4, v5, v6, v7]; -+ } -+ // prettier-ignore -+ set(v0, v1, v2, v3, v4, v5, v6, v7) { -+ this.v0 = v0 | 0; -+ this.v1 = v1 | 0; -+ this.v2 = v2 | 0; -+ this.v3 = v3 | 0; -+ this.v4 = v4 | 0; -+ this.v5 = v5 | 0; -+ this.v6 = v6 | 0; -+ this.v7 = v7 | 0; -+ } -+ compress(msg, offset, isLast) { -+ const { h, l } = fromBig(BigInt(this.length)); -+ // prettier-ignore -+ const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(SIGMA, offset, msg, 10, this.v0, this.v1, this.v2, this.v3, this.v4, this.v5, this.v6, this.v7, B2S_IV[0], B2S_IV[1], B2S_IV[2], B2S_IV[3], l ^ B2S_IV[4], h ^ B2S_IV[5], isLast ? ~B2S_IV[6] : B2S_IV[6], B2S_IV[7]); -+ this.v0 ^= v0 ^ v8; -+ this.v1 ^= v1 ^ v9; -+ this.v2 ^= v2 ^ v10; -+ this.v3 ^= v3 ^ v11; -+ this.v4 ^= v4 ^ v12; -+ this.v5 ^= v5 ^ v13; -+ this.v6 ^= v6 ^ v14; -+ this.v7 ^= v7 ^ v15; -+ } -+ destroy() { -+ this.destroyed = true; -+ this.buffer32.fill(0); -+ this.set(0, 0, 0, 0, 0, 0, 0, 0); -+ } -+} -+/** -+ * BLAKE2s - optimized for 32-bit platforms. JS doesn't have uint64, so it's faster than BLAKE2b. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, salt, personalization -+ */ -+export const blake2s = /* @__PURE__ */ wrapConstructorWithOpts((opts) => new BLAKE2s(opts)); -+//# sourceMappingURL=blake2s.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.js.map -new file mode 100644 -index 0000000..ddd4acd ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake2s.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake2s.js","sourceRoot":"","sources":["../src/blake2s.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAa,KAAK,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,uBAAuB,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEvF,gCAAgC;AAChC,wFAAwF;AACxF,kBAAkB;AAClB,MAAM,CAAC,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,WAAW,CAAC;IACpD,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;CAC/F,CAAC,CAAC;AAEH,0CAA0C;AAC1C,SAAS,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS;IAChE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS;IAChE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACxB,CAAC;AAED,kBAAkB;AAClB,MAAM,UAAU,QAAQ,CAAC,CAAa,EAAE,MAAc,EAAE,GAAgB,EAAE,MAAc,EACtF,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAC9F,EAAU,EAAE,EAAU,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW,EAAE,GAAW;IAEpG,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,C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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.d.ts -new file mode 100644 -index 0000000..701b389 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.d.ts -@@ -0,0 +1,46 @@ -+import { BLAKE } from './_blake.js'; -+import { Input, HashXOF } from './utils.js'; -+export type Blake3Opts = { -+ dkLen?: number; -+ key?: Input; -+ context?: Input; -+}; -+export declare class BLAKE3 extends BLAKE implements HashXOF { -+ private IV; -+ private flags; -+ private state; -+ private chunkPos; -+ private chunksDone; -+ private stack; -+ private posOut; -+ private bufferOut32; -+ private bufferOut; -+ private chunkOut; -+ private enableXOF; -+ constructor(opts?: Blake3Opts, flags?: number); -+ protected get(): never[]; -+ protected set(): void; -+ private b2Compress; -+ protected compress(buf: Uint32Array, bufPos?: number, isLast?: boolean): void; -+ _cloneInto(to?: BLAKE3): BLAKE3; -+ destroy(): void; -+ private b2CompressOut; -+ protected finish(): void; -+ private writeInto; -+ xofInto(out: Uint8Array): Uint8Array; -+ xof(bytes: number): Uint8Array; -+ digestInto(out: Uint8Array): Uint8Array; -+ digest(): Uint8Array; -+} -+/** -+ * BLAKE3 hash function. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, context -+ */ -+export declare const blake3: { -+ (msg: Input, opts?: Blake3Opts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: Blake3Opts): HashXOF; -+}; -+//# sourceMappingURL=blake3.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.d.ts.map -new file mode 100644 -index 0000000..8eced0b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake3.d.ts","sourceRoot":"","sources":["../src/blake3.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,EACL,KAAK,EAIL,OAAO,EAIR,MAAM,YAAY,CAAC;AA4BpB,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAU1E,qBAAa,MAAO,SAAQ,KAAK,CAAC,MAAM,CAAE,YAAW,OAAO,CAAC,MAAM,CAAC;IAClE,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAQ;gBAEb,IAAI,GAAE,UAAe,EAAE,KAAK,SAAI;IA2B5C,SAAS,CAAC,GAAG;IAGb,SAAS,CAAC,GAAG;IACb,OAAO,CAAC,UAAU;IAmBlB,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,GAAE,MAAU,EAAE,MAAM,GAAE,OAAe;IAiChF,UAAU,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAe/B,OAAO;IASP,OAAO,CAAC,aAAa;IAiCrB,SAAS,CAAC,MAAM;IAoBhB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU;IAIpC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;IAI9B,UAAU,CAAC,GAAG,EAAE,UAAU;IAQ1B,MAAM;CAGP;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM;;;;;CAElB,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.js -new file mode 100644 -index 0000000..3577963 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.js -@@ -0,0 +1,240 @@ -+import { bytes, exists, number, output } from './_assert.js'; -+import { fromBig } from './_u64.js'; -+import { BLAKE } from './_blake.js'; -+import { compress, B2S_IV } from './blake2s.js'; -+import { u8, u32, toBytes, wrapXOFConstructorWithOpts, isLE, byteSwap32, } from './utils.js'; -+const SIGMA = /* @__PURE__ */ (() => { -+ const Id = Array.from({ length: 16 }, (_, i) => i); -+ const permute = (arr) => [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8].map((i) => arr[i]); -+ const res = []; -+ for (let i = 0, v = Id; i < 7; i++, v = permute(v)) -+ res.push(...v); -+ return Uint8Array.from(res); -+})(); -+// Why is this so slow? It should be 6x faster than blake2b. -+// - There is only 30% reduction in number of rounds from blake2s -+// - This function uses tree mode to achive parallelisation via SIMD and threading, -+// however in JS we don't have threads and SIMD, so we get only overhead from tree structure -+// - It is possible to speed it up via Web Workers, hovewer it will make code singnificantly more -+// complicated, which we are trying to avoid, since this library is intended to be used -+// for cryptographic purposes. Also, parallelization happens only on chunk level (1024 bytes), -+// which won't really benefit small inputs. -+export class BLAKE3 extends BLAKE { -+ constructor(opts = {}, flags = 0) { -+ super(64, opts.dkLen === undefined ? 32 : opts.dkLen, {}, Number.MAX_SAFE_INTEGER, 0, 0); -+ this.flags = 0 | 0; -+ this.chunkPos = 0; // Position of current block in chunk -+ this.chunksDone = 0; // How many chunks we already have -+ this.stack = []; -+ // Output -+ this.posOut = 0; -+ this.bufferOut32 = new Uint32Array(16); -+ this.chunkOut = 0; // index of output chunk -+ this.enableXOF = true; -+ this.outputLen = opts.dkLen === undefined ? 32 : opts.dkLen; -+ number(this.outputLen); -+ if (opts.key !== undefined && opts.context !== undefined) -+ throw new Error('Blake3: only key or context can be specified at same time'); -+ else if (opts.key !== undefined) { -+ const key = toBytes(opts.key).slice(); -+ if (key.length !== 32) -+ throw new Error('Blake3: key should be 32 byte'); -+ this.IV = u32(key); -+ if (!isLE) -+ byteSwap32(this.IV); -+ this.flags = flags | 16 /* B3_Flags.KEYED_HASH */; -+ } -+ else if (opts.context !== undefined) { -+ const context_key = new BLAKE3({ dkLen: 32 }, 32 /* B3_Flags.DERIVE_KEY_CONTEXT */) -+ .update(opts.context) -+ .digest(); -+ this.IV = u32(context_key); -+ if (!isLE) -+ byteSwap32(this.IV); -+ this.flags = flags | 64 /* B3_Flags.DERIVE_KEY_MATERIAL */; -+ } -+ else { -+ this.IV = B2S_IV.slice(); -+ this.flags = flags; -+ } -+ this.state = this.IV.slice(); -+ this.bufferOut = u8(this.bufferOut32); -+ } -+ // Unused -+ get() { -+ return []; -+ } -+ set() { } -+ b2Compress(counter, flags, buf, bufPos = 0) { -+ const { state: s, pos } = this; -+ const { h, l } = fromBig(BigInt(counter), true); -+ // prettier-ignore -+ const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(SIGMA, bufPos, buf, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B2S_IV[0], B2S_IV[1], B2S_IV[2], B2S_IV[3], h, l, pos, flags); -+ s[0] = v0 ^ v8; -+ s[1] = v1 ^ v9; -+ s[2] = v2 ^ v10; -+ s[3] = v3 ^ v11; -+ s[4] = v4 ^ v12; -+ s[5] = v5 ^ v13; -+ s[6] = v6 ^ v14; -+ s[7] = v7 ^ v15; -+ } -+ compress(buf, bufPos = 0, isLast = false) { -+ // Compress last block -+ let flags = this.flags; -+ if (!this.chunkPos) -+ flags |= 1 /* B3_Flags.CHUNK_START */; -+ if (this.chunkPos === 15 || isLast) -+ flags |= 2 /* B3_Flags.CHUNK_END */; -+ if (!isLast) -+ this.pos = this.blockLen; -+ this.b2Compress(this.chunksDone, flags, buf, bufPos); -+ this.chunkPos += 1; -+ // If current block is last in chunk (16 blocks), then compress chunks -+ if (this.chunkPos === 16 || isLast) { -+ let chunk = this.state; -+ this.state = this.IV.slice(); -+ // If not the last one, compress only when there are trailing zeros in chunk counter -+ // chunks used as binary tree where current stack is path. Zero means current leaf is finished and can be compressed. -+ // 1 (001) - leaf not finished (just push current chunk to stack) -+ // 2 (010) - leaf finished at depth=1 (merge with last elm on stack and push back) -+ // 3 (011) - last leaf not finished -+ // 4 (100) - leafs finished at depth=1 and depth=2 -+ for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) { -+ if (!(last = this.stack.pop())) -+ break; -+ this.buffer32.set(last, 0); -+ this.buffer32.set(chunk, 8); -+ this.pos = this.blockLen; -+ this.b2Compress(0, this.flags | 4 /* B3_Flags.PARENT */, this.buffer32, 0); -+ chunk = this.state; -+ this.state = this.IV.slice(); -+ } -+ this.chunksDone++; -+ this.chunkPos = 0; -+ this.stack.push(chunk); -+ } -+ this.pos = 0; -+ } -+ _cloneInto(to) { -+ to = super._cloneInto(to); -+ const { IV, flags, state, chunkPos, posOut, chunkOut, stack, chunksDone } = this; -+ to.state.set(state.slice()); -+ to.stack = stack.map((i) => Uint32Array.from(i)); -+ to.IV.set(IV); -+ to.flags = flags; -+ to.chunkPos = chunkPos; -+ to.chunksDone = chunksDone; -+ to.posOut = posOut; -+ to.chunkOut = chunkOut; -+ to.enableXOF = this.enableXOF; -+ to.bufferOut32.set(this.bufferOut32); -+ return to; -+ } -+ destroy() { -+ this.destroyed = true; -+ this.state.fill(0); -+ this.buffer32.fill(0); -+ this.IV.fill(0); -+ this.bufferOut32.fill(0); -+ for (let i of this.stack) -+ i.fill(0); -+ } -+ // Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8) -+ b2CompressOut() { -+ const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this; -+ const { h, l } = fromBig(BigInt(this.chunkOut++)); -+ if (!isLE) -+ byteSwap32(buffer32); -+ // prettier-ignore -+ const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(SIGMA, 0, buffer32, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B2S_IV[0], B2S_IV[1], B2S_IV[2], B2S_IV[3], l, h, pos, flags); -+ out32[0] = v0 ^ v8; -+ out32[1] = v1 ^ v9; -+ out32[2] = v2 ^ v10; -+ out32[3] = v3 ^ v11; -+ out32[4] = v4 ^ v12; -+ out32[5] = v5 ^ v13; -+ out32[6] = v6 ^ v14; -+ out32[7] = v7 ^ v15; -+ out32[8] = s[0] ^ v8; -+ out32[9] = s[1] ^ v9; -+ out32[10] = s[2] ^ v10; -+ out32[11] = s[3] ^ v11; -+ out32[12] = s[4] ^ v12; -+ out32[13] = s[5] ^ v13; -+ out32[14] = s[6] ^ v14; -+ out32[15] = s[7] ^ v15; -+ if (!isLE) { -+ byteSwap32(buffer32); -+ byteSwap32(out32); -+ } -+ this.posOut = 0; -+ } -+ finish() { -+ if (this.finished) -+ return; -+ this.finished = true; -+ // Padding -+ this.buffer.fill(0, this.pos); -+ // Process last chunk -+ let flags = this.flags | 8 /* B3_Flags.ROOT */; -+ if (this.stack.length) { -+ flags |= 4 /* B3_Flags.PARENT */; -+ if (!isLE) -+ byteSwap32(this.buffer32); -+ this.compress(this.buffer32, 0, true); -+ if (!isLE) -+ byteSwap32(this.buffer32); -+ this.chunksDone = 0; -+ this.pos = this.blockLen; -+ } -+ else { -+ flags |= (!this.chunkPos ? 1 /* B3_Flags.CHUNK_START */ : 0) | 2 /* B3_Flags.CHUNK_END */; -+ } -+ this.flags = flags; -+ this.b2CompressOut(); -+ } -+ writeInto(out) { -+ exists(this, false); -+ bytes(out); -+ this.finish(); -+ const { blockLen, bufferOut } = this; -+ for (let pos = 0, len = out.length; pos < len;) { -+ if (this.posOut >= blockLen) -+ this.b2CompressOut(); -+ const take = Math.min(blockLen - this.posOut, len - pos); -+ out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); -+ this.posOut += take; -+ pos += take; -+ } -+ return out; -+ } -+ xofInto(out) { -+ if (!this.enableXOF) -+ throw new Error('XOF is not possible after digest call'); -+ return this.writeInto(out); -+ } -+ xof(bytes) { -+ number(bytes); -+ return this.xofInto(new Uint8Array(bytes)); -+ } -+ digestInto(out) { -+ output(out, this); -+ if (this.finished) -+ throw new Error('digest() was already called'); -+ this.enableXOF = false; -+ this.writeInto(out); -+ this.destroy(); -+ return out; -+ } -+ digest() { -+ return this.digestInto(new Uint8Array(this.outputLen)); -+ } -+} -+/** -+ * BLAKE3 hash function. -+ * @param msg - message that would be hashed -+ * @param opts - dkLen, key, context -+ */ -+export const blake3 = /* @__PURE__ */ wrapXOFConstructorWithOpts((opts) => new BLAKE3(opts)); -+//# sourceMappingURL=blake3.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.js.map -new file mode 100644 -index 0000000..c82019a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/blake3.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"blake3.js","sourceRoot":"","sources":["../src/blake3.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.d.ts -new file mode 100644 -index 0000000..ac181a0 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.d.ts -@@ -0,0 +1,2 @@ -+export declare const crypto: any; -+//# sourceMappingURL=crypto.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.d.ts.map -new file mode 100644 -index 0000000..d31325e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,KACuE,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.js -new file mode 100644 -index 0000000..8d499a0 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.js -@@ -0,0 +1,2 @@ -+export const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined; -+//# sourceMappingURL=crypto.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.js.map -new file mode 100644 -index 0000000..4b4fd3d ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/crypto.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,MAAM,GACjB,OAAO,UAAU,KAAK,QAAQ,IAAI,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.d.ts -new file mode 100644 -index 0000000..98bda7b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.d.ts -@@ -0,0 +1,2 @@ -+export declare const crypto: any; -+//# sourceMappingURL=cryptoNode.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map -new file mode 100644 -index 0000000..75df3e3 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"cryptoNode.d.ts","sourceRoot":"","sources":["../src/cryptoNode.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,MAAM,KACoE,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.js -new file mode 100644 -index 0000000..241f1da ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.js -@@ -0,0 +1,7 @@ -+// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. -+// See utils.ts for details. -+// The file will throw on node.js 14 and earlier. -+// @ts-ignore -+import * as nc from 'node:crypto'; -+export const crypto = nc && typeof nc === 'object' && 'webcrypto' in nc ? nc.webcrypto : undefined; -+//# sourceMappingURL=cryptoNode.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.js.map -new file mode 100644 -index 0000000..f7ab75e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/cryptoNode.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"cryptoNode.js","sourceRoot":"","sources":["../src/cryptoNode.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,4BAA4B;AAC5B,iDAAiD;AACjD,aAAa;AACb,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,MAAM,CAAC,MAAM,MAAM,GACjB,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,WAAW,IAAI,EAAE,CAAC,CAAC,CAAE,EAAE,CAAC,SAAiB,CAAC,CAAC,CAAC,SAAS,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.d.ts -new file mode 100644 -index 0000000..66721eb ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.d.ts -@@ -0,0 +1,47 @@ -+export declare function scrypt(password: string, salt: string): Uint8Array; -+export declare function pbkdf2(password: string, salt: string): Uint8Array; -+/** -+ * Derives main seed. Takes a lot of time. Prefer `eskdf` method instead. -+ */ -+export declare function deriveMainSeed(username: string, password: string): Uint8Array; -+type AccountID = number | string; -+type OptsLength = { -+ keyLength: number; -+}; -+type OptsMod = { -+ modulus: bigint; -+}; -+type KeyOpts = undefined | OptsLength | OptsMod; -+export interface ESKDF { -+ /** -+ * Derives a child key. Child key will not be associated with any -+ * other child key because of properties of underlying KDF. -+ * -+ * @param protocol - 3-15 character protocol name -+ * @param accountId - numeric identifier of account -+ * @param options - `keyLength: 64` or `modulus: 41920438n` -+ * @example deriveChildKey('aes', 0) -+ */ -+ deriveChildKey: (protocol: string, accountId: AccountID, options?: KeyOpts) => Uint8Array; -+ /** -+ * Deletes the main seed from eskdf instance -+ */ -+ expire: () => void; -+ /** -+ * Account fingerprint -+ */ -+ fingerprint: string; -+} -+/** -+ * ESKDF -+ * @param username - username, email, or identifier, min: 8 characters, should have enough entropy -+ * @param password - password, min: 8 characters, should have enough entropy -+ * @example -+ * const kdf = await eskdf('example-university', 'beginning-new-example'); -+ * const key = kdf.deriveChildKey('aes', 0); -+ * console.log(kdf.fingerprint); -+ * kdf.expire(); -+ */ -+export declare function eskdf(username: string, password: string): Promise; -+export {}; -+//# sourceMappingURL=eskdf.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.d.ts.map -new file mode 100644 -index 0000000..9236618 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"eskdf.d.ts","sourceRoot":"","sources":["../src/eskdf.ts"],"names":[],"mappings":"AAeA,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAEjE;AAGD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAEjE;AAiBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAS7E;AAED,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AA+BjC,KAAK,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AACxC,KAAK,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACnC,KAAK,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAwChD,MAAM,WAAW,KAAK;IACpB;;;;;;;;OAQG;IACH,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,UAAU,CAAC;IAC1F;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAuB9E"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.js -new file mode 100644 -index 0000000..13253eb ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.js -@@ -0,0 +1,155 @@ -+import { bytes as assertBytes } from './_assert.js'; -+import { hkdf } from './hkdf.js'; -+import { sha256 } from './sha256.js'; -+import { pbkdf2 as _pbkdf2 } from './pbkdf2.js'; -+import { scrypt as _scrypt } from './scrypt.js'; -+import { bytesToHex, createView, hexToBytes, toBytes } from './utils.js'; -+// A tiny KDF for various applications like AES key-gen. -+// Uses HKDF in a non-standard way, so it's not "KDF-secure", only "PRF-secure". -+// Which is good enough: assume sha2-256 retained preimage resistance. -+const SCRYPT_FACTOR = 2 ** 19; -+const PBKDF2_FACTOR = 2 ** 17; -+// Scrypt KDF -+export function scrypt(password, salt) { -+ return _scrypt(password, salt, { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 }); -+} -+// PBKDF2-HMAC-SHA256 -+export function pbkdf2(password, salt) { -+ return _pbkdf2(sha256, password, salt, { c: PBKDF2_FACTOR, dkLen: 32 }); -+} -+// Combines two 32-byte byte arrays -+function xor32(a, b) { -+ assertBytes(a, 32); -+ assertBytes(b, 32); -+ const arr = new Uint8Array(32); -+ for (let i = 0; i < 32; i++) { -+ arr[i] = a[i] ^ b[i]; -+ } -+ return arr; -+} -+function strHasLength(str, min, max) { -+ return typeof str === 'string' && str.length >= min && str.length <= max; -+} -+/** -+ * Derives main seed. Takes a lot of time. Prefer `eskdf` method instead. -+ */ -+export function deriveMainSeed(username, password) { -+ if (!strHasLength(username, 8, 255)) -+ throw new Error('invalid username'); -+ if (!strHasLength(password, 8, 255)) -+ throw new Error('invalid password'); -+ const scr = scrypt(password + '\u{1}', username + '\u{1}'); -+ const pbk = pbkdf2(password + '\u{2}', username + '\u{2}'); -+ const res = xor32(scr, pbk); -+ scr.fill(0); -+ pbk.fill(0); -+ return res; -+} -+/** -+ * Converts protocol & accountId pair to HKDF salt & info params. -+ */ -+function getSaltInfo(protocol, accountId = 0) { -+ // Note that length here also repeats two lines below -+ // We do an additional length check here to reduce the scope of DoS attacks -+ if (!(strHasLength(protocol, 3, 15) && /^[a-z0-9]{3,15}$/.test(protocol))) { -+ throw new Error('invalid protocol'); -+ } -+ // Allow string account ids for some protocols -+ const allowsStr = /^password\d{0,3}|ssh|tor|file$/.test(protocol); -+ let salt; // Extract salt. Default is undefined. -+ if (typeof accountId === 'string') { -+ if (!allowsStr) -+ throw new Error('accountId must be a number'); -+ if (!strHasLength(accountId, 1, 255)) -+ throw new Error('accountId must be valid string'); -+ salt = toBytes(accountId); -+ } -+ else if (Number.isSafeInteger(accountId)) { -+ if (accountId < 0 || accountId > 2 ** 32 - 1) -+ throw new Error('invalid accountId'); -+ // Convert to Big Endian Uint32 -+ salt = new Uint8Array(4); -+ createView(salt).setUint32(0, accountId, false); -+ } -+ else { -+ throw new Error(`accountId must be a number${allowsStr ? ' or string' : ''}`); -+ } -+ const info = toBytes(protocol); -+ return { salt, info }; -+} -+function countBytes(num) { -+ if (typeof num !== 'bigint' || num <= BigInt(128)) -+ throw new Error('invalid number'); -+ return Math.ceil(num.toString(2).length / 8); -+} -+/** -+ * Parses keyLength and modulus options to extract length of result key. -+ * If modulus is used, adds 64 bits to it as per FIPS 186 B.4.1 to combat modulo bias. -+ */ -+function getKeyLength(options) { -+ if (!options || typeof options !== 'object') -+ return 32; -+ const hasLen = 'keyLength' in options; -+ const hasMod = 'modulus' in options; -+ if (hasLen && hasMod) -+ throw new Error('cannot combine keyLength and modulus options'); -+ if (!hasLen && !hasMod) -+ throw new Error('must have either keyLength or modulus option'); -+ // FIPS 186 B.4.1 requires at least 64 more bits -+ const l = hasMod ? countBytes(options.modulus) + 8 : options.keyLength; -+ if (!(typeof l === 'number' && l >= 16 && l <= 8192)) -+ throw new Error('invalid keyLength'); -+ return l; -+} -+/** -+ * Converts key to bigint and divides it by modulus. Big Endian. -+ * Implements FIPS 186 B.4.1, which removes 0 and modulo bias from output. -+ */ -+function modReduceKey(key, modulus) { -+ const _1 = BigInt(1); -+ const num = BigInt('0x' + bytesToHex(key)); // check for ui8a, then bytesToNumber() -+ const res = (num % (modulus - _1)) + _1; // Remove 0 from output -+ if (res < _1) -+ throw new Error('expected positive number'); // Guard against bad values -+ const len = key.length - 8; // FIPS requires 64 more bits = 8 bytes -+ const hex = res.toString(16).padStart(len * 2, '0'); // numberToHex() -+ const bytes = hexToBytes(hex); -+ if (bytes.length !== len) -+ throw new Error('invalid length of result key'); -+ return bytes; -+} -+/** -+ * ESKDF -+ * @param username - username, email, or identifier, min: 8 characters, should have enough entropy -+ * @param password - password, min: 8 characters, should have enough entropy -+ * @example -+ * const kdf = await eskdf('example-university', 'beginning-new-example'); -+ * const key = kdf.deriveChildKey('aes', 0); -+ * console.log(kdf.fingerprint); -+ * kdf.expire(); -+ */ -+export async function eskdf(username, password) { -+ // We are using closure + object instead of class because -+ // we want to make `seed` non-accessible for any external function. -+ let seed = deriveMainSeed(username, password); -+ function deriveCK(protocol, accountId = 0, options) { -+ assertBytes(seed, 32); -+ const { salt, info } = getSaltInfo(protocol, accountId); // validate protocol & accountId -+ const keyLength = getKeyLength(options); // validate options -+ const key = hkdf(sha256, seed, salt, info, keyLength); -+ // Modulus has already been validated -+ return options && 'modulus' in options ? modReduceKey(key, options.modulus) : key; -+ } -+ function expire() { -+ if (seed) -+ seed.fill(1); -+ seed = undefined; -+ } -+ // prettier-ignore -+ const fingerprint = Array.from(deriveCK('fingerprint', 0)) -+ .slice(0, 6) -+ .map((char) => char.toString(16).padStart(2, '0').toUpperCase()) -+ .join(':'); -+ return Object.freeze({ deriveChildKey: deriveCK, expire, fingerprint }); -+} -+//# sourceMappingURL=eskdf.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.js.map -new file mode 100644 -index 0000000..1a7c815 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/eskdf.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"eskdf.js","sourceRoot":"","sources":["../src/eskdf.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.d.ts -new file mode 100644 -index 0000000..f2ff770 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.d.ts -@@ -0,0 +1,27 @@ -+import { CHash, Input } from './utils.js'; -+/** -+ * HKDF-Extract(IKM, salt) -> PRK -+ * Arguments position differs from spec (IKM is first one, since it is not optional) -+ * @param hash -+ * @param ikm -+ * @param salt -+ * @returns -+ */ -+export declare function extract(hash: CHash, ikm: Input, salt?: Input): Uint8Array; -+/** -+ * HKDF-expand from the spec. -+ * @param prk - a pseudorandom key of at least HashLen octets (usually, the output from the extract step) -+ * @param info - optional context and application specific information (can be a zero-length string) -+ * @param length - length of output keying material in octets -+ */ -+export declare function expand(hash: CHash, prk: Input, info?: Input, length?: number): Uint8Array; -+/** -+ * HKDF (RFC 5869): extract + expand in one step. -+ * @param hash - hash function that would be used (e.g. sha256) -+ * @param ikm - input keying material, the initial key -+ * @param salt - optional salt value (a non-secret random value) -+ * @param info - optional context and application specific information -+ * @param length - length of output keying material in octets -+ */ -+export declare const hkdf: (hash: CHash, ikm: Input, salt: Input | undefined, info: Input | undefined, length: number) => Uint8Array; -+//# sourceMappingURL=hkdf.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.d.ts.map -new file mode 100644 -index 0000000..e5b6be0 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"hkdf.d.ts","sourceRoot":"","sources":["../src/hkdf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAW,MAAM,YAAY,CAAC;AAMnD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,cAO5D;AAMD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,GAAE,MAAW,cA4BhF;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,SACT,KAAK,OACN,KAAK,QACJ,KAAK,GAAG,SAAS,QACjB,KAAK,GAAG,SAAS,UACf,MAAM,eACyC,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.js -new file mode 100644 -index 0000000..8fbdac8 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.js -@@ -0,0 +1,72 @@ -+import { hash as assertHash, number as assertNumber } from './_assert.js'; -+import { toBytes } from './utils.js'; -+import { hmac } from './hmac.js'; -+// HKDF (RFC 5869) -+// https://soatok.blog/2021/11/17/understanding-hkdf/ -+/** -+ * HKDF-Extract(IKM, salt) -> PRK -+ * Arguments position differs from spec (IKM is first one, since it is not optional) -+ * @param hash -+ * @param ikm -+ * @param salt -+ * @returns -+ */ -+export function extract(hash, ikm, salt) { -+ assertHash(hash); -+ // NOTE: some libraries treat zero-length array as 'not provided'; -+ // we don't, since we have undefined as 'not provided' -+ // https://github.com/RustCrypto/KDFs/issues/15 -+ if (salt === undefined) -+ salt = new Uint8Array(hash.outputLen); // if not provided, it is set to a string of HashLen zeros -+ return hmac(hash, toBytes(salt), toBytes(ikm)); -+} -+// HKDF-Expand(PRK, info, L) -> OKM -+const HKDF_COUNTER = /* @__PURE__ */ new Uint8Array([0]); -+const EMPTY_BUFFER = /* @__PURE__ */ new Uint8Array(); -+/** -+ * HKDF-expand from the spec. -+ * @param prk - a pseudorandom key of at least HashLen octets (usually, the output from the extract step) -+ * @param info - optional context and application specific information (can be a zero-length string) -+ * @param length - length of output keying material in octets -+ */ -+export function expand(hash, prk, info, length = 32) { -+ assertHash(hash); -+ assertNumber(length); -+ if (length > 255 * hash.outputLen) -+ throw new Error('Length should be <= 255*HashLen'); -+ const blocks = Math.ceil(length / hash.outputLen); -+ if (info === undefined) -+ info = EMPTY_BUFFER; -+ // first L(ength) octets of T -+ const okm = new Uint8Array(blocks * hash.outputLen); -+ // Re-use HMAC instance between blocks -+ const HMAC = hmac.create(hash, prk); -+ const HMACTmp = HMAC._cloneInto(); -+ const T = new Uint8Array(HMAC.outputLen); -+ for (let counter = 0; counter < blocks; counter++) { -+ HKDF_COUNTER[0] = counter + 1; -+ // T(0) = empty string (zero length) -+ // T(N) = HMAC-Hash(PRK, T(N-1) | info | N) -+ HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T) -+ .update(info) -+ .update(HKDF_COUNTER) -+ .digestInto(T); -+ okm.set(T, hash.outputLen * counter); -+ HMAC._cloneInto(HMACTmp); -+ } -+ HMAC.destroy(); -+ HMACTmp.destroy(); -+ T.fill(0); -+ HKDF_COUNTER.fill(0); -+ return okm.slice(0, length); -+} -+/** -+ * HKDF (RFC 5869): extract + expand in one step. -+ * @param hash - hash function that would be used (e.g. sha256) -+ * @param ikm - input keying material, the initial key -+ * @param salt - optional salt value (a non-secret random value) -+ * @param info - optional context and application specific information -+ * @param length - length of output keying material in octets -+ */ -+export const hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length); -+//# sourceMappingURL=hkdf.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.js.map -new file mode 100644 -index 0000000..f8fd588 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hkdf.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"hkdf.js","sourceRoot":"","sources":["../src/hkdf.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.d.ts -new file mode 100644 -index 0000000..5a9f896 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.d.ts -@@ -0,0 +1,30 @@ -+import { Hash, CHash, Input } from './utils.js'; -+export declare class HMAC> extends Hash> { -+ oHash: T; -+ iHash: T; -+ blockLen: number; -+ outputLen: number; -+ private finished; -+ private destroyed; -+ constructor(hash: CHash, _key: Input); -+ update(buf: Input): this; -+ digestInto(out: Uint8Array): void; -+ digest(): Uint8Array; -+ _cloneInto(to?: HMAC): HMAC; -+ destroy(): void; -+} -+/** -+ * HMAC: RFC2104 message authentication code. -+ * @param hash - function that would be used e.g. sha256 -+ * @param key - message key -+ * @param message - message data -+ * @example -+ * import { hmac } from '@noble/hashes/hmac'; -+ * import { sha256 } from '@noble/hashes/sha2'; -+ * const mac1 = hmac(sha256, 'key', 'message'); -+ */ -+export declare const hmac: { -+ (hash: CHash, key: Input, message: Input): Uint8Array; -+ create(hash: CHash, key: Input): HMAC; -+}; -+//# sourceMappingURL=hmac.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.d.ts.map -new file mode 100644 -index 0000000..f6b4aa6 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../src/hmac.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAW,MAAM,YAAY,CAAC;AAEzD,qBAAa,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK;IAsBpC,MAAM,CAAC,GAAG,EAAE,KAAK;IAKjB,UAAU,CAAC,GAAG,EAAE,UAAU;IAS1B,MAAM;IAKN,UAAU,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAajC,OAAO;CAKR;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI;WAAU,KAAK,OAAO,KAAK,WAAW,KAAK,GAAG,UAAU;iBAEpD,KAAK,OAAO,KAAK;CADa,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.js -new file mode 100644 -index 0000000..02f6975 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.js -@@ -0,0 +1,81 @@ -+import { hash as assertHash, bytes as assertBytes, exists as assertExists } from './_assert.js'; -+import { Hash, toBytes } from './utils.js'; -+// HMAC (RFC 2104) -+export class HMAC extends Hash { -+ constructor(hash, _key) { -+ super(); -+ this.finished = false; -+ this.destroyed = false; -+ assertHash(hash); -+ const key = toBytes(_key); -+ this.iHash = hash.create(); -+ if (typeof this.iHash.update !== 'function') -+ throw new Error('Expected instance of class which extends utils.Hash'); -+ this.blockLen = this.iHash.blockLen; -+ this.outputLen = this.iHash.outputLen; -+ const blockLen = this.blockLen; -+ const pad = new Uint8Array(blockLen); -+ // blockLen can be bigger than outputLen -+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key); -+ for (let i = 0; i < pad.length; i++) -+ pad[i] ^= 0x36; -+ this.iHash.update(pad); -+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone -+ this.oHash = hash.create(); -+ // Undo internal XOR && apply outer XOR -+ for (let i = 0; i < pad.length; i++) -+ pad[i] ^= 0x36 ^ 0x5c; -+ this.oHash.update(pad); -+ pad.fill(0); -+ } -+ update(buf) { -+ assertExists(this); -+ this.iHash.update(buf); -+ return this; -+ } -+ digestInto(out) { -+ assertExists(this); -+ assertBytes(out, this.outputLen); -+ this.finished = true; -+ this.iHash.digestInto(out); -+ this.oHash.update(out); -+ this.oHash.digestInto(out); -+ this.destroy(); -+ } -+ digest() { -+ const out = new Uint8Array(this.oHash.outputLen); -+ this.digestInto(out); -+ return out; -+ } -+ _cloneInto(to) { -+ // Create new instance without calling constructor since key already in state and we don't know it. -+ to || (to = Object.create(Object.getPrototypeOf(this), {})); -+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this; -+ to = to; -+ to.finished = finished; -+ to.destroyed = destroyed; -+ to.blockLen = blockLen; -+ to.outputLen = outputLen; -+ to.oHash = oHash._cloneInto(to.oHash); -+ to.iHash = iHash._cloneInto(to.iHash); -+ return to; -+ } -+ destroy() { -+ this.destroyed = true; -+ this.oHash.destroy(); -+ this.iHash.destroy(); -+ } -+} -+/** -+ * HMAC: RFC2104 message authentication code. -+ * @param hash - function that would be used e.g. sha256 -+ * @param key - message key -+ * @param message - message data -+ * @example -+ * import { hmac } from '@noble/hashes/hmac'; -+ * import { sha256 } from '@noble/hashes/sha2'; -+ * const mac1 = hmac(sha256, 'key', 'message'); -+ */ -+export const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest(); -+hmac.create = (hash, key) => new HMAC(hash, key); -+//# sourceMappingURL=hmac.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.js.map -new file mode 100644 -index 0000000..6a8bb0b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/hmac.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"hmac.js","sourceRoot":"","sources":["../src/hmac.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.d.ts -new file mode 100644 -index 0000000..e26a57a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.d.ts -@@ -0,0 +1,2 @@ -+export {}; -+//# sourceMappingURL=index.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.d.ts.map -new file mode 100644 -index 0000000..535b86d ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.js -new file mode 100644 -index 0000000..d02dc7a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.js -@@ -0,0 +1,3 @@ -+throw new Error('root module cannot be imported: import submodules instead. Check out README'); -+export {}; -+//# sourceMappingURL=index.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.js.map -new file mode 100644 -index 0000000..d17f53a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/index.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.d.ts -new file mode 100644 -index 0000000..1fb1b27 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.d.ts -@@ -0,0 +1,16 @@ -+import { CHash, Input } from './utils.js'; -+export type Pbkdf2Opt = { -+ c: number; -+ dkLen?: number; -+ asyncTick?: number; -+}; -+/** -+ * PBKDF2-HMAC: RFC 2898 key derivation function -+ * @param hash - hash function that would be used e.g. sha256 -+ * @param password - password from which a derived key is generated -+ * @param salt - cryptographic salt -+ * @param opts - {c, dkLen} where c is work factor and dkLen is output message size -+ */ -+export declare function pbkdf2(hash: CHash, password: Input, salt: Input, opts: Pbkdf2Opt): Uint8Array; -+export declare function pbkdf2Async(hash: CHash, password: Input, salt: Input, opts: Pbkdf2Opt): Promise; -+//# sourceMappingURL=pbkdf2.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map -new file mode 100644 -index 0000000..2556fc4 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"pbkdf2.d.ts","sourceRoot":"","sources":["../src/pbkdf2.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,KAAK,EAAE,KAAK,EAA6C,MAAM,YAAY,CAAC;AAG3F,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAkCF;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,cAsBhF;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,uBAsB3F"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.js -new file mode 100644 -index 0000000..3f0c11f ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.js -@@ -0,0 +1,86 @@ -+import { hash as assertHash, number as assertNumber } from './_assert.js'; -+import { hmac } from './hmac.js'; -+import { createView, toBytes, checkOpts, asyncLoop } from './utils.js'; -+// Common prologue and epilogue for sync/async functions -+function pbkdf2Init(hash, _password, _salt, _opts) { -+ assertHash(hash); -+ const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts); -+ const { c, dkLen, asyncTick } = opts; -+ assertNumber(c); -+ assertNumber(dkLen); -+ assertNumber(asyncTick); -+ if (c < 1) -+ throw new Error('PBKDF2: iterations (c) should be >= 1'); -+ const password = toBytes(_password); -+ const salt = toBytes(_salt); -+ // DK = PBKDF2(PRF, Password, Salt, c, dkLen); -+ const DK = new Uint8Array(dkLen); -+ // U1 = PRF(Password, Salt + INT_32_BE(i)) -+ const PRF = hmac.create(hash, password); -+ const PRFSalt = PRF._cloneInto().update(salt); -+ return { c, dkLen, asyncTick, DK, PRF, PRFSalt }; -+} -+function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) { -+ PRF.destroy(); -+ PRFSalt.destroy(); -+ if (prfW) -+ prfW.destroy(); -+ u.fill(0); -+ return DK; -+} -+/** -+ * PBKDF2-HMAC: RFC 2898 key derivation function -+ * @param hash - hash function that would be used e.g. sha256 -+ * @param password - password from which a derived key is generated -+ * @param salt - cryptographic salt -+ * @param opts - {c, dkLen} where c is work factor and dkLen is output message size -+ */ -+export function pbkdf2(hash, password, salt, opts) { -+ const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); -+ let prfW; // Working copy -+ const arr = new Uint8Array(4); -+ const view = createView(arr); -+ const u = new Uint8Array(PRF.outputLen); -+ // DK = T1 + T2 + ⋯ + Tdklen/hlen -+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { -+ // Ti = F(Password, Salt, c, i) -+ const Ti = DK.subarray(pos, pos + PRF.outputLen); -+ view.setInt32(0, ti, false); -+ // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc -+ // U1 = PRF(Password, Salt + INT_32_BE(i)) -+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); -+ Ti.set(u.subarray(0, Ti.length)); -+ for (let ui = 1; ui < c; ui++) { -+ // Uc = PRF(Password, Uc−1) -+ PRF._cloneInto(prfW).update(u).digestInto(u); -+ for (let i = 0; i < Ti.length; i++) -+ Ti[i] ^= u[i]; -+ } -+ } -+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); -+} -+export async function pbkdf2Async(hash, password, salt, opts) { -+ const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); -+ let prfW; // Working copy -+ const arr = new Uint8Array(4); -+ const view = createView(arr); -+ const u = new Uint8Array(PRF.outputLen); -+ // DK = T1 + T2 + ⋯ + Tdklen/hlen -+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { -+ // Ti = F(Password, Salt, c, i) -+ const Ti = DK.subarray(pos, pos + PRF.outputLen); -+ view.setInt32(0, ti, false); -+ // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc -+ // U1 = PRF(Password, Salt + INT_32_BE(i)) -+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); -+ Ti.set(u.subarray(0, Ti.length)); -+ await asyncLoop(c - 1, asyncTick, () => { -+ // Uc = PRF(Password, Uc−1) -+ PRF._cloneInto(prfW).update(u).digestInto(u); -+ for (let i = 0; i < Ti.length; i++) -+ Ti[i] ^= u[i]; -+ }); -+ } -+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); -+} -+//# sourceMappingURL=pbkdf2.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.js.map -new file mode 100644 -index 0000000..989dcbb ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/pbkdf2.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"pbkdf2.js","sourceRoot":"","sources":["../src/pbkdf2.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.d.ts -new file mode 100644 -index 0000000..1320a14 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.d.ts -@@ -0,0 +1,25 @@ -+import { HashMD } from './_md.js'; -+export declare class RIPEMD160 extends HashMD { -+ private h0; -+ private h1; -+ private h2; -+ private h3; -+ private h4; -+ constructor(); -+ protected get(): [number, number, number, number, number]; -+ protected set(h0: number, h1: number, h2: number, h3: number, h4: number): void; -+ protected process(view: DataView, offset: number): void; -+ protected roundClean(): void; -+ destroy(): void; -+} -+/** -+ * RIPEMD-160 - a hash function from 1990s. -+ * @param message - msg that would be hashed -+ */ -+export declare const ripemd160: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=ripemd160.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.d.ts.map -new file mode 100644 -index 0000000..bf78e18 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ripemd160.d.ts","sourceRoot":"","sources":["../src/ripemd160.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAqClC,qBAAa,SAAU,SAAQ,MAAM,CAAC,SAAS,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;;IAK5B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIzD,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAOxE,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAmCvD,SAAS,CAAC,UAAU;IAGpB,OAAO;CAKR;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;CAAyD,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.js -new file mode 100644 -index 0000000..c8e7100 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.js -@@ -0,0 +1,102 @@ -+import { HashMD } from './_md.js'; -+import { rotl, wrapConstructor } from './utils.js'; -+// https://homes.esat.kuleuven.be/~bosselae/ripemd160.html -+// https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf -+const Rho = /* @__PURE__ */ new Uint8Array([7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8]); -+const Id = /* @__PURE__ */ new Uint8Array(new Array(16).fill(0).map((_, i) => i)); -+const Pi = /* @__PURE__ */ Id.map((i) => (9 * i + 5) % 16); -+let idxL = [Id]; -+let idxR = [Pi]; -+for (let i = 0; i < 4; i++) -+ for (let j of [idxL, idxR]) -+ j.push(j[i].map((k) => Rho[k])); -+const shifts = /* @__PURE__ */ [ -+ [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8], -+ [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7], -+ [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9], -+ [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6], -+ [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5], -+].map((i) => new Uint8Array(i)); -+const shiftsL = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts[i][j])); -+const shiftsR = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts[i][j])); -+const Kl = /* @__PURE__ */ new Uint32Array([ -+ 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e, -+]); -+const Kr = /* @__PURE__ */ new Uint32Array([ -+ 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000, -+]); -+// It's called f() in spec. -+function f(group, x, y, z) { -+ if (group === 0) -+ return x ^ y ^ z; -+ else if (group === 1) -+ return (x & y) | (~x & z); -+ else if (group === 2) -+ return (x | ~y) ^ z; -+ else if (group === 3) -+ return (x & z) | (y & ~z); -+ else -+ return x ^ (y | ~z); -+} -+// Temporary buffer, not used to store anything between runs -+const R_BUF = /* @__PURE__ */ new Uint32Array(16); -+export class RIPEMD160 extends HashMD { -+ constructor() { -+ super(64, 20, 8, true); -+ this.h0 = 0x67452301 | 0; -+ this.h1 = 0xefcdab89 | 0; -+ this.h2 = 0x98badcfe | 0; -+ this.h3 = 0x10325476 | 0; -+ this.h4 = 0xc3d2e1f0 | 0; -+ } -+ get() { -+ const { h0, h1, h2, h3, h4 } = this; -+ return [h0, h1, h2, h3, h4]; -+ } -+ set(h0, h1, h2, h3, h4) { -+ this.h0 = h0 | 0; -+ this.h1 = h1 | 0; -+ this.h2 = h2 | 0; -+ this.h3 = h3 | 0; -+ this.h4 = h4 | 0; -+ } -+ process(view, offset) { -+ for (let i = 0; i < 16; i++, offset += 4) -+ R_BUF[i] = view.getUint32(offset, true); -+ // prettier-ignore -+ let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el; -+ // Instead of iterating 0 to 80, we split it into 5 groups -+ // And use the groups in constants, functions, etc. Much simpler -+ for (let group = 0; group < 5; group++) { -+ const rGroup = 4 - group; -+ const hbl = Kl[group], hbr = Kr[group]; // prettier-ignore -+ const rl = idxL[group], rr = idxR[group]; // prettier-ignore -+ const sl = shiftsL[group], sr = shiftsR[group]; // prettier-ignore -+ for (let i = 0; i < 16; i++) { -+ const tl = (rotl(al + f(group, bl, cl, dl) + R_BUF[rl[i]] + hbl, sl[i]) + el) | 0; -+ al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore -+ } -+ // 2 loops are 10% faster -+ for (let i = 0; i < 16; i++) { -+ const tr = (rotl(ar + f(rGroup, br, cr, dr) + R_BUF[rr[i]] + hbr, sr[i]) + er) | 0; -+ ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore -+ } -+ } -+ // Add the compressed chunk to the current hash value -+ this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0); -+ } -+ roundClean() { -+ R_BUF.fill(0); -+ } -+ destroy() { -+ this.destroyed = true; -+ this.buffer.fill(0); -+ this.set(0, 0, 0, 0, 0); -+ } -+} -+/** -+ * RIPEMD-160 - a hash function from 1990s. -+ * @param message - msg that would be hashed -+ */ -+export const ripemd160 = /* @__PURE__ */ wrapConstructor(() => new RIPEMD160()); -+//# sourceMappingURL=ripemd160.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.js.map -new file mode 100644 -index 0000000..343c7c0 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/ripemd160.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ripemd160.js","sourceRoot":"","sources":["../src/ripemd160.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.d.ts -new file mode 100644 -index 0000000..68368e6 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.d.ts -@@ -0,0 +1,30 @@ -+import { Input } from './utils.js'; -+export type ScryptOpts = { -+ N: number; -+ r: number; -+ p: number; -+ dkLen?: number; -+ asyncTick?: number; -+ maxmem?: number; -+ onProgress?: (progress: number) => void; -+}; -+/** -+ * Scrypt KDF from RFC 7914. -+ * @param password - pass -+ * @param salt - salt -+ * @param opts - parameters -+ * - `N` is cpu/mem work factor (power of 2 e.g. 2**18) -+ * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance -+ * - `p` is parallelization factor (1 is common) -+ * - `dkLen` is output key length in bytes e.g. 32. -+ * - `asyncTick` - (default: 10) max time in ms for which async function can block execution -+ * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt -+ * - `onProgress` - callback function that would be executed for progress report -+ * @returns Derived key -+ */ -+export declare function scrypt(password: Input, salt: Input, opts: ScryptOpts): Uint8Array; -+/** -+ * Scrypt KDF from RFC 7914. -+ */ -+export declare function scryptAsync(password: Input, salt: Input, opts: ScryptOpts): Promise; -+//# sourceMappingURL=scrypt.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.d.ts.map -new file mode 100644 -index 0000000..a16a176 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"scrypt.d.ts","sourceRoot":"","sources":["../src/scrypt.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,EAAyB,MAAM,YAAY,CAAC;AAyEtF,MAAM,MAAM,UAAU,GAAG;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAoFF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,cA0BpE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,uBA2B/E"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.js -new file mode 100644 -index 0000000..d24decf ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.js -@@ -0,0 +1,224 @@ -+import { number as assertNumber } from './_assert.js'; -+import { sha256 } from './sha256.js'; -+import { pbkdf2 } from './pbkdf2.js'; -+import { rotl, asyncLoop, checkOpts, u32, isLE, byteSwap32 } from './utils.js'; -+// RFC 7914 Scrypt KDF -+// The main Scrypt loop: uses Salsa extensively. -+// Six versions of the function were tried, this is the fastest one. -+// prettier-ignore -+function XorAndSalsa(prev, pi, input, ii, out, oi) { -+ // Based on https://cr.yp.to/salsa20.html -+ // Xor blocks -+ let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++]; -+ let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++]; -+ let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++]; -+ let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++]; -+ let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++]; -+ let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++]; -+ let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++]; -+ let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++]; -+ // Save state to temporary variables (salsa) -+ let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15; -+ // Main loop (salsa) -+ for (let i = 0; i < 8; i += 2) { -+ x04 ^= rotl(x00 + x12 | 0, 7); -+ x08 ^= rotl(x04 + x00 | 0, 9); -+ x12 ^= rotl(x08 + x04 | 0, 13); -+ x00 ^= rotl(x12 + x08 | 0, 18); -+ x09 ^= rotl(x05 + x01 | 0, 7); -+ x13 ^= rotl(x09 + x05 | 0, 9); -+ x01 ^= rotl(x13 + x09 | 0, 13); -+ x05 ^= rotl(x01 + x13 | 0, 18); -+ x14 ^= rotl(x10 + x06 | 0, 7); -+ x02 ^= rotl(x14 + x10 | 0, 9); -+ x06 ^= rotl(x02 + x14 | 0, 13); -+ x10 ^= rotl(x06 + x02 | 0, 18); -+ x03 ^= rotl(x15 + x11 | 0, 7); -+ x07 ^= rotl(x03 + x15 | 0, 9); -+ x11 ^= rotl(x07 + x03 | 0, 13); -+ x15 ^= rotl(x11 + x07 | 0, 18); -+ x01 ^= rotl(x00 + x03 | 0, 7); -+ x02 ^= rotl(x01 + x00 | 0, 9); -+ x03 ^= rotl(x02 + x01 | 0, 13); -+ x00 ^= rotl(x03 + x02 | 0, 18); -+ x06 ^= rotl(x05 + x04 | 0, 7); -+ x07 ^= rotl(x06 + x05 | 0, 9); -+ x04 ^= rotl(x07 + x06 | 0, 13); -+ x05 ^= rotl(x04 + x07 | 0, 18); -+ x11 ^= rotl(x10 + x09 | 0, 7); -+ x08 ^= rotl(x11 + x10 | 0, 9); -+ x09 ^= rotl(x08 + x11 | 0, 13); -+ x10 ^= rotl(x09 + x08 | 0, 18); -+ x12 ^= rotl(x15 + x14 | 0, 7); -+ x13 ^= rotl(x12 + x15 | 0, 9); -+ x14 ^= rotl(x13 + x12 | 0, 13); -+ x15 ^= rotl(x14 + x13 | 0, 18); -+ } -+ // Write output (salsa) -+ out[oi++] = (y00 + x00) | 0; -+ out[oi++] = (y01 + x01) | 0; -+ out[oi++] = (y02 + x02) | 0; -+ out[oi++] = (y03 + x03) | 0; -+ out[oi++] = (y04 + x04) | 0; -+ out[oi++] = (y05 + x05) | 0; -+ out[oi++] = (y06 + x06) | 0; -+ out[oi++] = (y07 + x07) | 0; -+ out[oi++] = (y08 + x08) | 0; -+ out[oi++] = (y09 + x09) | 0; -+ out[oi++] = (y10 + x10) | 0; -+ out[oi++] = (y11 + x11) | 0; -+ out[oi++] = (y12 + x12) | 0; -+ out[oi++] = (y13 + x13) | 0; -+ out[oi++] = (y14 + x14) | 0; -+ out[oi++] = (y15 + x15) | 0; -+} -+function BlockMix(input, ii, out, oi, r) { -+ // The block B is r 128-byte chunks (which is equivalent of 2r 64-byte chunks) -+ let head = oi + 0; -+ let tail = oi + 16 * r; -+ for (let i = 0; i < 16; i++) -+ out[tail + i] = input[ii + (2 * r - 1) * 16 + i]; // X ← B[2r−1] -+ for (let i = 0; i < r; i++, head += 16, ii += 16) { -+ // We write odd & even Yi at same time. Even: 0bXXXXX0 Odd: 0bXXXXX1 -+ XorAndSalsa(out, tail, input, ii, out, head); // head[i] = Salsa(blockIn[2*i] ^ tail[i-1]) -+ if (i > 0) -+ tail += 16; // First iteration overwrites tmp value in tail -+ XorAndSalsa(out, head, input, (ii += 16), out, tail); // tail[i] = Salsa(blockIn[2*i+1] ^ head[i]) -+ } -+} -+// Common prologue and epilogue for sync/async functions -+function scryptInit(password, salt, _opts) { -+ // Maxmem - 1GB+1KB by default -+ const opts = checkOpts({ -+ dkLen: 32, -+ asyncTick: 10, -+ maxmem: 1024 ** 3 + 1024, -+ }, _opts); -+ const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts; -+ assertNumber(N); -+ assertNumber(r); -+ assertNumber(p); -+ assertNumber(dkLen); -+ assertNumber(asyncTick); -+ assertNumber(maxmem); -+ if (onProgress !== undefined && typeof onProgress !== 'function') -+ throw new Error('progressCb should be function'); -+ const blockSize = 128 * r; -+ const blockSize32 = blockSize / 4; -+ if (N <= 1 || (N & (N - 1)) !== 0 || N >= 2 ** (blockSize / 8) || N > 2 ** 32) { -+ // NOTE: we limit N to be less than 2**32 because of 32 bit variant of Integrify function -+ // There is no JS engines that allows alocate more than 4GB per single Uint8Array for now, but can change in future. -+ throw new Error('Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32'); -+ } -+ if (p < 0 || p > ((2 ** 32 - 1) * 32) / blockSize) { -+ throw new Error('Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)'); -+ } -+ if (dkLen < 0 || dkLen > (2 ** 32 - 1) * 32) { -+ throw new Error('Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32'); -+ } -+ const memUsed = blockSize * (N + p); -+ if (memUsed > maxmem) { -+ throw new Error(`Scrypt: parameters too large, ${memUsed} (128 * r * (N + p)) > ${maxmem} (maxmem)`); -+ } -+ // [B0...Bp−1] ← PBKDF2HMAC-SHA256(Passphrase, Salt, 1, blockSize*ParallelizationFactor) -+ // Since it has only one iteration there is no reason to use async variant -+ const B = pbkdf2(sha256, password, salt, { c: 1, dkLen: blockSize * p }); -+ const B32 = u32(B); -+ // Re-used between parallel iterations. Array(iterations) of B -+ const V = u32(new Uint8Array(blockSize * N)); -+ const tmp = u32(new Uint8Array(blockSize)); -+ let blockMixCb = () => { }; -+ if (onProgress) { -+ const totalBlockMix = 2 * N * p; -+ // Invoke callback if progress changes from 10.01 to 10.02 -+ // Allows to draw smooth progress bar on up to 8K screen -+ const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1); -+ let blockMixCnt = 0; -+ blockMixCb = () => { -+ blockMixCnt++; -+ if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix)) -+ onProgress(blockMixCnt / totalBlockMix); -+ }; -+ } -+ return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick }; -+} -+function scryptOutput(password, dkLen, B, V, tmp) { -+ const res = pbkdf2(sha256, password, B, { c: 1, dkLen }); -+ B.fill(0); -+ V.fill(0); -+ tmp.fill(0); -+ return res; -+} -+/** -+ * Scrypt KDF from RFC 7914. -+ * @param password - pass -+ * @param salt - salt -+ * @param opts - parameters -+ * - `N` is cpu/mem work factor (power of 2 e.g. 2**18) -+ * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance -+ * - `p` is parallelization factor (1 is common) -+ * - `dkLen` is output key length in bytes e.g. 32. -+ * - `asyncTick` - (default: 10) max time in ms for which async function can block execution -+ * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt -+ * - `onProgress` - callback function that would be executed for progress report -+ * @returns Derived key -+ */ -+export function scrypt(password, salt, opts) { -+ const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit(password, salt, opts); -+ if (!isLE) -+ byteSwap32(B32); -+ for (let pi = 0; pi < p; pi++) { -+ const Pi = blockSize32 * pi; -+ for (let i = 0; i < blockSize32; i++) -+ V[i] = B32[Pi + i]; // V[0] = B[i] -+ for (let i = 0, pos = 0; i < N - 1; i++) { -+ BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]); -+ blockMixCb(); -+ } -+ BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element -+ blockMixCb(); -+ for (let i = 0; i < N; i++) { -+ // First u32 of the last 64-byte block (u32 is LE) -+ const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations -+ for (let k = 0; k < blockSize32; k++) -+ tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j] -+ BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j]) -+ blockMixCb(); -+ } -+ } -+ if (!isLE) -+ byteSwap32(B32); -+ return scryptOutput(password, dkLen, B, V, tmp); -+} -+/** -+ * Scrypt KDF from RFC 7914. -+ */ -+export async function scryptAsync(password, salt, opts) { -+ const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick } = scryptInit(password, salt, opts); -+ if (!isLE) -+ byteSwap32(B32); -+ for (let pi = 0; pi < p; pi++) { -+ const Pi = blockSize32 * pi; -+ for (let i = 0; i < blockSize32; i++) -+ V[i] = B32[Pi + i]; // V[0] = B[i] -+ let pos = 0; -+ await asyncLoop(N - 1, asyncTick, () => { -+ BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]); -+ blockMixCb(); -+ }); -+ BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element -+ blockMixCb(); -+ await asyncLoop(N, asyncTick, () => { -+ // First u32 of the last 64-byte block (u32 is LE) -+ const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations -+ for (let k = 0; k < blockSize32; k++) -+ tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j] -+ BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j]) -+ blockMixCb(); -+ }); -+ } -+ if (!isLE) -+ byteSwap32(B32); -+ return scryptOutput(password, dkLen, B, V, tmp); -+} -+//# sourceMappingURL=scrypt.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.js.map -new file mode 100644 -index 0000000..ce40ca7 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/scrypt.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"scrypt.js","sourceRoot":"","sources":["../src/scrypt.ts"],"names":[],"mappings":"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I,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.d.ts -new file mode 100644 -index 0000000..f210c5c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.d.ts -@@ -0,0 +1,26 @@ -+import { HashMD } from './_md.js'; -+export declare class SHA1 extends HashMD { -+ private A; -+ private B; -+ private C; -+ private D; -+ private E; -+ constructor(); -+ protected get(): [number, number, number, number, number]; -+ protected set(A: number, B: number, C: number, D: number, E: number): void; -+ protected process(view: DataView, offset: number): void; -+ protected roundClean(): void; -+ destroy(): void; -+} -+/** -+ * SHA1 (RFC 3174) hash function. -+ * It was cryptographically broken: prefer newer algorithms. -+ * @param message - data that would be hashed -+ */ -+export declare const sha1: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=sha1.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.d.ts.map -new file mode 100644 -index 0000000..a2bcda2 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha1.d.ts","sourceRoot":"","sources":["../src/sha1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,UAAU,CAAC;AAa5C,qBAAa,IAAK,SAAQ,MAAM,CAAC,IAAI,CAAC;IACpC,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;;IAK3B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIzD,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAOnE,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoCvD,SAAS,CAAC,UAAU;IAGpB,OAAO;CAIR;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI;;;;;CAAoD,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.js -new file mode 100644 -index 0000000..8975407 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.js -@@ -0,0 +1,85 @@ -+import { HashMD, Chi, Maj } from './_md.js'; -+import { rotl, wrapConstructor } from './utils.js'; -+// SHA1 (RFC 3174). It was cryptographically broken: prefer newer algorithms. -+// Initial state -+const SHA1_IV = /* @__PURE__ */ new Uint32Array([ -+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0, -+]); -+// Temporary buffer, not used to store anything between runs -+// Named this way because it matches specification. -+const SHA1_W = /* @__PURE__ */ new Uint32Array(80); -+export class SHA1 extends HashMD { -+ constructor() { -+ super(64, 20, 8, false); -+ this.A = SHA1_IV[0] | 0; -+ this.B = SHA1_IV[1] | 0; -+ this.C = SHA1_IV[2] | 0; -+ this.D = SHA1_IV[3] | 0; -+ this.E = SHA1_IV[4] | 0; -+ } -+ get() { -+ const { A, B, C, D, E } = this; -+ return [A, B, C, D, E]; -+ } -+ set(A, B, C, D, E) { -+ this.A = A | 0; -+ this.B = B | 0; -+ this.C = C | 0; -+ this.D = D | 0; -+ this.E = E | 0; -+ } -+ process(view, offset) { -+ for (let i = 0; i < 16; i++, offset += 4) -+ SHA1_W[i] = view.getUint32(offset, false); -+ for (let i = 16; i < 80; i++) -+ SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1); -+ // Compression function main loop, 80 rounds -+ let { A, B, C, D, E } = this; -+ for (let i = 0; i < 80; i++) { -+ let F, K; -+ if (i < 20) { -+ F = Chi(B, C, D); -+ K = 0x5a827999; -+ } -+ else if (i < 40) { -+ F = B ^ C ^ D; -+ K = 0x6ed9eba1; -+ } -+ else if (i < 60) { -+ F = Maj(B, C, D); -+ K = 0x8f1bbcdc; -+ } -+ else { -+ F = B ^ C ^ D; -+ K = 0xca62c1d6; -+ } -+ const T = (rotl(A, 5) + F + E + K + SHA1_W[i]) | 0; -+ E = D; -+ D = C; -+ C = rotl(B, 30); -+ B = A; -+ A = T; -+ } -+ // Add the compressed chunk to the current hash value -+ A = (A + this.A) | 0; -+ B = (B + this.B) | 0; -+ C = (C + this.C) | 0; -+ D = (D + this.D) | 0; -+ E = (E + this.E) | 0; -+ this.set(A, B, C, D, E); -+ } -+ roundClean() { -+ SHA1_W.fill(0); -+ } -+ destroy() { -+ this.set(0, 0, 0, 0, 0); -+ this.buffer.fill(0); -+ } -+} -+/** -+ * SHA1 (RFC 3174) hash function. -+ * It was cryptographically broken: prefer newer algorithms. -+ * @param message - data that would be hashed -+ */ -+export const sha1 = /* @__PURE__ */ wrapConstructor(() => new SHA1()); -+//# sourceMappingURL=sha1.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.js.map -new file mode 100644 -index 0000000..4ca21c2 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha1.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha1.js","sourceRoot":"","sources":["../src/sha1.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.d.ts -new file mode 100644 -index 0000000..6052a2a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.d.ts -@@ -0,0 +1,3 @@ -+export { sha256, sha224 } from './sha256.js'; -+export { sha512, sha512_224, sha512_256, sha384 } from './sha512.js'; -+//# sourceMappingURL=sha2.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.d.ts.map -new file mode 100644 -index 0000000..dc32e7a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha2.d.ts","sourceRoot":"","sources":["../src/sha2.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.js -new file mode 100644 -index 0000000..780eb18 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.js -@@ -0,0 +1,4 @@ -+// Usually you either use sha256, or sha512. We re-export them as sha2 for naming consistency. -+export { sha256, sha224 } from './sha256.js'; -+export { sha512, sha512_224, sha512_256, sha384 } from './sha512.js'; -+//# sourceMappingURL=sha2.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.js.map -new file mode 100644 -index 0000000..b77fde8 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha2.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha2.js","sourceRoot":"","sources":["../src/sha2.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.d.ts -new file mode 100644 -index 0000000..b31a842 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.d.ts -@@ -0,0 +1,37 @@ -+import { HashMD } from './_md.js'; -+export declare class SHA256 extends HashMD { -+ A: number; -+ B: number; -+ C: number; -+ D: number; -+ E: number; -+ F: number; -+ G: number; -+ H: number; -+ constructor(); -+ protected get(): [number, number, number, number, number, number, number, number]; -+ protected set(A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number): void; -+ protected process(view: DataView, offset: number): void; -+ protected roundClean(): void; -+ destroy(): void; -+} -+/** -+ * SHA2-256 hash function -+ * @param message - data that would be hashed -+ */ -+export declare const sha256: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+/** -+ * SHA2-224 hash function -+ */ -+export declare const sha224: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=sha256.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.d.ts.map -new file mode 100644 -index 0000000..2969d86 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha256.d.ts","sourceRoot":"","sources":["../src/sha256.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,UAAU,CAAC;AA8B5C,qBAAa,MAAO,SAAQ,MAAM,CAAC,MAAM,CAAC;IAGxC,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;;IAKrB,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAKjF,SAAS,CAAC,GAAG,CACX,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAWxF,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAqCvD,SAAS,CAAC,UAAU;IAGpB,OAAO;CAIR;AAiBD;;;GAGG;AACH,eAAO,MAAM,MAAM;;;;;CAAsD,CAAC;AAC1E;;GAEG;AACH,eAAO,MAAM,MAAM;;;;;CAAsD,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.js -new file mode 100644 -index 0000000..91dbe12 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.js -@@ -0,0 +1,126 @@ -+import { HashMD, Chi, Maj } from './_md.js'; -+import { rotr, wrapConstructor } from './utils.js'; -+// SHA2-256 need to try 2^128 hashes to execute birthday attack. -+// BTC network is doing 2^67 hashes/sec as per early 2023. -+// Round constants: -+// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311) -+// prettier-ignore -+const SHA256_K = /* @__PURE__ */ new Uint32Array([ -+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, -+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, -+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, -+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, -+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, -+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, -+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, -+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -+]); -+// Initial state: -+// first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19 -+// prettier-ignore -+const SHA256_IV = /* @__PURE__ */ new Uint32Array([ -+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -+]); -+// Temporary buffer, not used to store anything between runs -+// Named this way because it matches specification. -+const SHA256_W = /* @__PURE__ */ new Uint32Array(64); -+export class SHA256 extends HashMD { -+ constructor() { -+ super(64, 32, 8, false); -+ // We cannot use array here since array allows indexing by variable -+ // which means optimizer/compiler cannot use registers. -+ this.A = SHA256_IV[0] | 0; -+ this.B = SHA256_IV[1] | 0; -+ this.C = SHA256_IV[2] | 0; -+ this.D = SHA256_IV[3] | 0; -+ this.E = SHA256_IV[4] | 0; -+ this.F = SHA256_IV[5] | 0; -+ this.G = SHA256_IV[6] | 0; -+ this.H = SHA256_IV[7] | 0; -+ } -+ get() { -+ const { A, B, C, D, E, F, G, H } = this; -+ return [A, B, C, D, E, F, G, H]; -+ } -+ // prettier-ignore -+ set(A, B, C, D, E, F, G, H) { -+ this.A = A | 0; -+ this.B = B | 0; -+ this.C = C | 0; -+ this.D = D | 0; -+ this.E = E | 0; -+ this.F = F | 0; -+ this.G = G | 0; -+ this.H = H | 0; -+ } -+ process(view, offset) { -+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array -+ for (let i = 0; i < 16; i++, offset += 4) -+ SHA256_W[i] = view.getUint32(offset, false); -+ for (let i = 16; i < 64; i++) { -+ const W15 = SHA256_W[i - 15]; -+ const W2 = SHA256_W[i - 2]; -+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3); -+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10); -+ SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0; -+ } -+ // Compression function main loop, 64 rounds -+ let { A, B, C, D, E, F, G, H } = this; -+ for (let i = 0; i < 64; i++) { -+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25); -+ const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; -+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22); -+ const T2 = (sigma0 + Maj(A, B, C)) | 0; -+ H = G; -+ G = F; -+ F = E; -+ E = (D + T1) | 0; -+ D = C; -+ C = B; -+ B = A; -+ A = (T1 + T2) | 0; -+ } -+ // Add the compressed chunk to the current hash value -+ A = (A + this.A) | 0; -+ B = (B + this.B) | 0; -+ C = (C + this.C) | 0; -+ D = (D + this.D) | 0; -+ E = (E + this.E) | 0; -+ F = (F + this.F) | 0; -+ G = (G + this.G) | 0; -+ H = (H + this.H) | 0; -+ this.set(A, B, C, D, E, F, G, H); -+ } -+ roundClean() { -+ SHA256_W.fill(0); -+ } -+ destroy() { -+ this.set(0, 0, 0, 0, 0, 0, 0, 0); -+ this.buffer.fill(0); -+ } -+} -+// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf -+class SHA224 extends SHA256 { -+ constructor() { -+ super(); -+ this.A = 0xc1059ed8 | 0; -+ this.B = 0x367cd507 | 0; -+ this.C = 0x3070dd17 | 0; -+ this.D = 0xf70e5939 | 0; -+ this.E = 0xffc00b31 | 0; -+ this.F = 0x68581511 | 0; -+ this.G = 0x64f98fa7 | 0; -+ this.H = 0xbefa4fa4 | 0; -+ this.outputLen = 28; -+ } -+} -+/** -+ * SHA2-256 hash function -+ * @param message - data that would be hashed -+ */ -+export const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256()); -+/** -+ * SHA2-224 hash function -+ */ -+export const sha224 = /* @__PURE__ */ wrapConstructor(() => new SHA224()); -+//# sourceMappingURL=sha256.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.js.map -new file mode 100644 -index 0000000..d785c23 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha256.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha256.js","sourceRoot":"","sources":["../src/sha256.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.d.ts -new file mode 100644 -index 0000000..151cdf2 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.d.ts -@@ -0,0 +1,154 @@ -+import { Input, Hash, HashXOF } from './utils.js'; -+import { Keccak, ShakeOpts } from './sha3.js'; -+export type cShakeOpts = ShakeOpts & { -+ personalization?: Input; -+ NISTfn?: Input; -+}; -+export declare const cshake128: { -+ (msg: Input, opts?: cShakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: cShakeOpts): HashXOF; -+}; -+export declare const cshake256: { -+ (msg: Input, opts?: cShakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: cShakeOpts): HashXOF; -+}; -+export declare class KMAC extends Keccak implements HashXOF { -+ constructor(blockLen: number, outputLen: number, enableXOF: boolean, key: Input, opts?: cShakeOpts); -+ protected finish(): void; -+ _cloneInto(to?: KMAC): KMAC; -+ clone(): KMAC; -+} -+export declare const kmac128: { -+ (key: Input, message: Input, opts?: cShakeOpts): Uint8Array; -+ create(key: Input, opts?: cShakeOpts): KMAC; -+}; -+export declare const kmac256: { -+ (key: Input, message: Input, opts?: cShakeOpts): Uint8Array; -+ create(key: Input, opts?: cShakeOpts): KMAC; -+}; -+export declare const kmac128xof: { -+ (key: Input, message: Input, opts?: cShakeOpts): Uint8Array; -+ create(key: Input, opts?: cShakeOpts): KMAC; -+}; -+export declare const kmac256xof: { -+ (key: Input, message: Input, opts?: cShakeOpts): Uint8Array; -+ create(key: Input, opts?: cShakeOpts): KMAC; -+}; -+export declare class TupleHash extends Keccak implements HashXOF { -+ constructor(blockLen: number, outputLen: number, enableXOF: boolean, opts?: cShakeOpts); -+ protected finish(): void; -+ _cloneInto(to?: TupleHash): TupleHash; -+ clone(): TupleHash; -+} -+export declare const tuplehash128: { -+ (messages: Input[], opts?: cShakeOpts): Uint8Array; -+ create(opts?: cShakeOpts): TupleHash; -+}; -+export declare const tuplehash256: { -+ (messages: Input[], opts?: cShakeOpts): Uint8Array; -+ create(opts?: cShakeOpts): TupleHash; -+}; -+export declare const tuplehash128xof: { -+ (messages: Input[], opts?: cShakeOpts): Uint8Array; -+ create(opts?: cShakeOpts): TupleHash; -+}; -+export declare const tuplehash256xof: { -+ (messages: Input[], opts?: cShakeOpts): Uint8Array; -+ create(opts?: cShakeOpts): TupleHash; -+}; -+type ParallelOpts = cShakeOpts & { -+ blockLen?: number; -+}; -+export declare class ParallelHash extends Keccak implements HashXOF { -+ protected leafCons: () => Hash; -+ private leafHash?; -+ private chunkPos; -+ private chunksDone; -+ private chunkLen; -+ constructor(blockLen: number, outputLen: number, leafCons: () => Hash, enableXOF: boolean, opts?: ParallelOpts); -+ protected finish(): void; -+ _cloneInto(to?: ParallelHash): ParallelHash; -+ destroy(): void; -+ clone(): ParallelHash; -+} -+export declare const parallelhash128: { -+ (message: Input, opts?: ParallelOpts): Uint8Array; -+ create(opts?: ParallelOpts): ParallelHash; -+}; -+export declare const parallelhash256: { -+ (message: Input, opts?: ParallelOpts): Uint8Array; -+ create(opts?: ParallelOpts): ParallelHash; -+}; -+export declare const parallelhash128xof: { -+ (message: Input, opts?: ParallelOpts): Uint8Array; -+ create(opts?: ParallelOpts): ParallelHash; -+}; -+export declare const parallelhash256xof: { -+ (message: Input, opts?: ParallelOpts): Uint8Array; -+ create(opts?: ParallelOpts): ParallelHash; -+}; -+export type TurboshakeOpts = ShakeOpts & { -+ D?: number; -+}; -+export declare const turboshake128: { -+ (msg: Input, opts?: TurboshakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: TurboshakeOpts): HashXOF>; -+}; -+export declare const turboshake256: { -+ (msg: Input, opts?: TurboshakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: TurboshakeOpts): HashXOF>; -+}; -+export type KangarooOpts = { -+ dkLen?: number; -+ personalization?: Input; -+}; -+export declare class KangarooTwelve extends Keccak implements HashXOF { -+ protected leafLen: number; -+ readonly chunkLen = 8192; -+ private leafHash?; -+ private personalization; -+ private chunkPos; -+ private chunksDone; -+ constructor(blockLen: number, leafLen: number, outputLen: number, rounds: number, opts: KangarooOpts); -+ update(data: Input): this; -+ protected finish(): void; -+ destroy(): void; -+ _cloneInto(to?: KangarooTwelve): KangarooTwelve; -+ clone(): KangarooTwelve; -+} -+export declare const k12: { -+ (msg: Input, opts?: KangarooOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: KangarooOpts): Hash; -+}; -+export declare const m14: { -+ (msg: Input, opts?: KangarooOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: KangarooOpts): Hash; -+}; -+export declare class KeccakPRG extends Keccak { -+ protected rate: number; -+ constructor(capacity: number); -+ keccak(): void; -+ update(data: Input): this; -+ feed(data: Input): this; -+ protected finish(): void; -+ digestInto(_out: Uint8Array): Uint8Array; -+ fetch(bytes: number): Uint8Array; -+ forget(): void; -+ _cloneInto(to?: KeccakPRG): KeccakPRG; -+ clone(): KeccakPRG; -+} -+export declare const keccakprg: (capacity?: number) => KeccakPRG; -+export {}; -+//# sourceMappingURL=sha3-addons.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map -new file mode 100644 -index 0000000..ace68ec ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha3-addons.d.ts","sourceRoot":"","sources":["../src/sha3-addons.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.js -new file mode 100644 -index 0000000..533cfaf ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.js -@@ -0,0 +1,356 @@ -+import { number as assertNumber } from './_assert.js'; -+import { toBytes, wrapConstructorWithOpts, u32, wrapXOFConstructorWithOpts, } from './utils.js'; -+import { Keccak } from './sha3.js'; -+// cSHAKE && KMAC (NIST SP800-185) -+function leftEncode(n) { -+ const res = [n & 0xff]; -+ n >>= 8; -+ for (; n > 0; n >>= 8) -+ res.unshift(n & 0xff); -+ res.unshift(res.length); -+ return new Uint8Array(res); -+} -+function rightEncode(n) { -+ const res = [n & 0xff]; -+ n >>= 8; -+ for (; n > 0; n >>= 8) -+ res.unshift(n & 0xff); -+ res.push(res.length); -+ return new Uint8Array(res); -+} -+function chooseLen(opts, outputLen) { -+ return opts.dkLen === undefined ? outputLen : opts.dkLen; -+} -+const toBytesOptional = (buf) => (buf !== undefined ? toBytes(buf) : new Uint8Array([])); -+// NOTE: second modulo is necessary since we don't need to add padding if current element takes whole block -+const getPadding = (len, block) => new Uint8Array((block - (len % block)) % block); -+// Personalization -+function cshakePers(hash, opts = {}) { -+ if (!opts || (!opts.personalization && !opts.NISTfn)) -+ return hash; -+ // Encode and pad inplace to avoid unneccesary memory copies/slices (so we don't need to zero them later) -+ // bytepad(encode_string(N) || encode_string(S), 168) -+ const blockLenBytes = leftEncode(hash.blockLen); -+ const fn = toBytesOptional(opts.NISTfn); -+ const fnLen = leftEncode(8 * fn.length); // length in bits -+ const pers = toBytesOptional(opts.personalization); -+ const persLen = leftEncode(8 * pers.length); // length in bits -+ if (!fn.length && !pers.length) -+ return hash; -+ hash.suffix = 0x04; -+ hash.update(blockLenBytes).update(fnLen).update(fn).update(persLen).update(pers); -+ let totalLen = blockLenBytes.length + fnLen.length + fn.length + persLen.length + pers.length; -+ hash.update(getPadding(totalLen, hash.blockLen)); -+ return hash; -+} -+const gencShake = (suffix, blockLen, outputLen) => wrapXOFConstructorWithOpts((opts = {}) => cshakePers(new Keccak(blockLen, suffix, chooseLen(opts, outputLen), true), opts)); -+export const cshake128 = /* @__PURE__ */ (() => gencShake(0x1f, 168, 128 / 8))(); -+export const cshake256 = /* @__PURE__ */ (() => gencShake(0x1f, 136, 256 / 8))(); -+export class KMAC extends Keccak { -+ constructor(blockLen, outputLen, enableXOF, key, opts = {}) { -+ super(blockLen, 0x1f, outputLen, enableXOF); -+ cshakePers(this, { NISTfn: 'KMAC', personalization: opts.personalization }); -+ key = toBytes(key); -+ // 1. newX = bytepad(encode_string(K), 168) || X || right_encode(L). -+ const blockLenBytes = leftEncode(this.blockLen); -+ const keyLen = leftEncode(8 * key.length); -+ this.update(blockLenBytes).update(keyLen).update(key); -+ const totalLen = blockLenBytes.length + keyLen.length + key.length; -+ this.update(getPadding(totalLen, this.blockLen)); -+ } -+ finish() { -+ if (!this.finished) -+ this.update(rightEncode(this.enableXOF ? 0 : this.outputLen * 8)); // outputLen in bits -+ super.finish(); -+ } -+ _cloneInto(to) { -+ // Create new instance without calling constructor since key already in state and we don't know it. -+ // Force "to" to be instance of KMAC instead of Sha3. -+ if (!to) { -+ to = Object.create(Object.getPrototypeOf(this), {}); -+ to.state = this.state.slice(); -+ to.blockLen = this.blockLen; -+ to.state32 = u32(to.state); -+ } -+ return super._cloneInto(to); -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+function genKmac(blockLen, outputLen, xof = false) { -+ const kmac = (key, message, opts) => kmac.create(key, opts).update(message).digest(); -+ kmac.create = (key, opts = {}) => new KMAC(blockLen, chooseLen(opts, outputLen), xof, key, opts); -+ return kmac; -+} -+export const kmac128 = /* @__PURE__ */ (() => genKmac(168, 128 / 8))(); -+export const kmac256 = /* @__PURE__ */ (() => genKmac(136, 256 / 8))(); -+export const kmac128xof = /* @__PURE__ */ (() => genKmac(168, 128 / 8, true))(); -+export const kmac256xof = /* @__PURE__ */ (() => genKmac(136, 256 / 8, true))(); -+// TupleHash -+// Usage: tuple(['ab', 'cd']) != tuple(['a', 'bcd']) -+export class TupleHash extends Keccak { -+ constructor(blockLen, outputLen, enableXOF, opts = {}) { -+ super(blockLen, 0x1f, outputLen, enableXOF); -+ cshakePers(this, { NISTfn: 'TupleHash', personalization: opts.personalization }); -+ // Change update after cshake processed -+ this.update = (data) => { -+ data = toBytes(data); -+ super.update(leftEncode(data.length * 8)); -+ super.update(data); -+ return this; -+ }; -+ } -+ finish() { -+ if (!this.finished) -+ super.update(rightEncode(this.enableXOF ? 0 : this.outputLen * 8)); // outputLen in bits -+ super.finish(); -+ } -+ _cloneInto(to) { -+ to || (to = new TupleHash(this.blockLen, this.outputLen, this.enableXOF)); -+ return super._cloneInto(to); -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+function genTuple(blockLen, outputLen, xof = false) { -+ const tuple = (messages, opts) => { -+ const h = tuple.create(opts); -+ for (const msg of messages) -+ h.update(msg); -+ return h.digest(); -+ }; -+ tuple.create = (opts = {}) => new TupleHash(blockLen, chooseLen(opts, outputLen), xof, opts); -+ return tuple; -+} -+export const tuplehash128 = /* @__PURE__ */ (() => genTuple(168, 128 / 8))(); -+export const tuplehash256 = /* @__PURE__ */ (() => genTuple(136, 256 / 8))(); -+export const tuplehash128xof = /* @__PURE__ */ (() => genTuple(168, 128 / 8, true))(); -+export const tuplehash256xof = /* @__PURE__ */ (() => genTuple(136, 256 / 8, true))(); -+export class ParallelHash extends Keccak { -+ constructor(blockLen, outputLen, leafCons, enableXOF, opts = {}) { -+ super(blockLen, 0x1f, outputLen, enableXOF); -+ this.leafCons = leafCons; -+ this.chunkPos = 0; // Position of current block in chunk -+ this.chunksDone = 0; // How many chunks we already have -+ cshakePers(this, { NISTfn: 'ParallelHash', personalization: opts.personalization }); -+ let { blockLen: B } = opts; -+ B || (B = 8); -+ assertNumber(B); -+ this.chunkLen = B; -+ super.update(leftEncode(B)); -+ // Change update after cshake processed -+ this.update = (data) => { -+ data = toBytes(data); -+ const { chunkLen, leafCons } = this; -+ for (let pos = 0, len = data.length; pos < len;) { -+ if (this.chunkPos == chunkLen || !this.leafHash) { -+ if (this.leafHash) { -+ super.update(this.leafHash.digest()); -+ this.chunksDone++; -+ } -+ this.leafHash = leafCons(); -+ this.chunkPos = 0; -+ } -+ const take = Math.min(chunkLen - this.chunkPos, len - pos); -+ this.leafHash.update(data.subarray(pos, pos + take)); -+ this.chunkPos += take; -+ pos += take; -+ } -+ return this; -+ }; -+ } -+ finish() { -+ if (this.finished) -+ return; -+ if (this.leafHash) { -+ super.update(this.leafHash.digest()); -+ this.chunksDone++; -+ } -+ super.update(rightEncode(this.chunksDone)); -+ super.update(rightEncode(this.enableXOF ? 0 : this.outputLen * 8)); // outputLen in bits -+ super.finish(); -+ } -+ _cloneInto(to) { -+ to || (to = new ParallelHash(this.blockLen, this.outputLen, this.leafCons, this.enableXOF)); -+ if (this.leafHash) -+ to.leafHash = this.leafHash._cloneInto(to.leafHash); -+ to.chunkPos = this.chunkPos; -+ to.chunkLen = this.chunkLen; -+ to.chunksDone = this.chunksDone; -+ return super._cloneInto(to); -+ } -+ destroy() { -+ super.destroy.call(this); -+ if (this.leafHash) -+ this.leafHash.destroy(); -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+function genPrl(blockLen, outputLen, leaf, xof = false) { -+ const parallel = (message, opts) => parallel.create(opts).update(message).digest(); -+ parallel.create = (opts = {}) => new ParallelHash(blockLen, chooseLen(opts, outputLen), () => leaf.create({ dkLen: 2 * outputLen }), xof, opts); -+ return parallel; -+} -+export const parallelhash128 = /* @__PURE__ */ (() => genPrl(168, 128 / 8, cshake128))(); -+export const parallelhash256 = /* @__PURE__ */ (() => genPrl(136, 256 / 8, cshake256))(); -+export const parallelhash128xof = /* @__PURE__ */ (() => genPrl(168, 128 / 8, cshake128, true))(); -+export const parallelhash256xof = /* @__PURE__ */ (() => genPrl(136, 256 / 8, cshake256, true))(); -+const genTurboshake = (blockLen, outputLen) => wrapXOFConstructorWithOpts((opts = {}) => { -+ const D = opts.D === undefined ? 0x1f : opts.D; -+ // Section 2.1 of https://datatracker.ietf.org/doc/draft-irtf-cfrg-kangarootwelve/ -+ if (!Number.isSafeInteger(D) || D < 0x01 || D > 0x7f) -+ throw new Error(`turboshake: wrong domain separation byte: ${D}, should be 0x01..0x7f`); -+ return new Keccak(blockLen, D, opts.dkLen === undefined ? outputLen : opts.dkLen, true, 12); -+}); -+export const turboshake128 = /* @__PURE__ */ genTurboshake(168, 256 / 8); -+export const turboshake256 = /* @__PURE__ */ genTurboshake(136, 512 / 8); -+// Kangaroo -+// Same as NIST rightEncode, but returns [0] for zero string -+function rightEncodeK12(n) { -+ const res = []; -+ for (; n > 0; n >>= 8) -+ res.unshift(n & 0xff); -+ res.push(res.length); -+ return new Uint8Array(res); -+} -+const EMPTY = new Uint8Array([]); -+export class KangarooTwelve extends Keccak { -+ constructor(blockLen, leafLen, outputLen, rounds, opts) { -+ super(blockLen, 0x07, outputLen, true, rounds); -+ this.leafLen = leafLen; -+ this.chunkLen = 8192; -+ this.chunkPos = 0; // Position of current block in chunk -+ this.chunksDone = 0; // How many chunks we already have -+ const { personalization } = opts; -+ this.personalization = toBytesOptional(personalization); -+ } -+ update(data) { -+ data = toBytes(data); -+ const { chunkLen, blockLen, leafLen, rounds } = this; -+ for (let pos = 0, len = data.length; pos < len;) { -+ if (this.chunkPos == chunkLen) { -+ if (this.leafHash) -+ super.update(this.leafHash.digest()); -+ else { -+ this.suffix = 0x06; // Its safe to change suffix here since its used only in digest() -+ super.update(new Uint8Array([3, 0, 0, 0, 0, 0, 0, 0])); -+ } -+ this.leafHash = new Keccak(blockLen, 0x0b, leafLen, false, rounds); -+ this.chunksDone++; -+ this.chunkPos = 0; -+ } -+ const take = Math.min(chunkLen - this.chunkPos, len - pos); -+ const chunk = data.subarray(pos, pos + take); -+ if (this.leafHash) -+ this.leafHash.update(chunk); -+ else -+ super.update(chunk); -+ this.chunkPos += take; -+ pos += take; -+ } -+ return this; -+ } -+ finish() { -+ if (this.finished) -+ return; -+ const { personalization } = this; -+ this.update(personalization).update(rightEncodeK12(personalization.length)); -+ // Leaf hash -+ if (this.leafHash) { -+ super.update(this.leafHash.digest()); -+ super.update(rightEncodeK12(this.chunksDone)); -+ super.update(new Uint8Array([0xff, 0xff])); -+ } -+ super.finish.call(this); -+ } -+ destroy() { -+ super.destroy.call(this); -+ if (this.leafHash) -+ this.leafHash.destroy(); -+ // We cannot zero personalization buffer since it is user provided and we don't want to mutate user input -+ this.personalization = EMPTY; -+ } -+ _cloneInto(to) { -+ const { blockLen, leafLen, leafHash, outputLen, rounds } = this; -+ to || (to = new KangarooTwelve(blockLen, leafLen, outputLen, rounds, {})); -+ super._cloneInto(to); -+ if (leafHash) -+ to.leafHash = leafHash._cloneInto(to.leafHash); -+ to.personalization.set(this.personalization); -+ to.leafLen = this.leafLen; -+ to.chunkPos = this.chunkPos; -+ to.chunksDone = this.chunksDone; -+ return to; -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+// Default to 32 bytes, so it can be used without opts -+export const k12 = /* @__PURE__ */ (() => wrapConstructorWithOpts((opts = {}) => new KangarooTwelve(168, 32, chooseLen(opts, 32), 12, opts)))(); -+// MarsupilamiFourteen -+export const m14 = /* @__PURE__ */ (() => wrapConstructorWithOpts((opts = {}) => new KangarooTwelve(136, 64, chooseLen(opts, 64), 14, opts)))(); -+// https://keccak.team/files/CSF-0.1.pdf -+// + https://github.com/XKCP/XKCP/tree/master/lib/high/Keccak/PRG -+export class KeccakPRG extends Keccak { -+ constructor(capacity) { -+ assertNumber(capacity); -+ // Rho should be full bytes -+ if (capacity < 0 || capacity > 1600 - 10 || (1600 - capacity - 2) % 8) -+ throw new Error('KeccakPRG: Invalid capacity'); -+ // blockLen = rho in bytes -+ super((1600 - capacity - 2) / 8, 0, 0, true); -+ this.rate = 1600 - capacity; -+ this.posOut = Math.floor((this.rate + 7) / 8); -+ } -+ keccak() { -+ // Duplex padding -+ this.state[this.pos] ^= 0x01; -+ this.state[this.blockLen] ^= 0x02; // Rho is full bytes -+ super.keccak(); -+ this.pos = 0; -+ this.posOut = 0; -+ } -+ update(data) { -+ super.update(data); -+ this.posOut = this.blockLen; -+ return this; -+ } -+ feed(data) { -+ return this.update(data); -+ } -+ finish() { } -+ digestInto(_out) { -+ throw new Error('KeccakPRG: digest is not allowed, please use .fetch instead.'); -+ } -+ fetch(bytes) { -+ return this.xof(bytes); -+ } -+ // Ensure irreversibility (even if state leaked previous outputs cannot be computed) -+ forget() { -+ if (this.rate < 1600 / 2 + 1) -+ throw new Error('KeccakPRG: rate too low to use forget'); -+ this.keccak(); -+ for (let i = 0; i < this.blockLen; i++) -+ this.state[i] = 0; -+ this.pos = this.blockLen; -+ this.keccak(); -+ this.posOut = this.blockLen; -+ } -+ _cloneInto(to) { -+ const { rate } = this; -+ to || (to = new KeccakPRG(1600 - rate)); -+ super._cloneInto(to); -+ to.rate = rate; -+ return to; -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+export const keccakprg = (capacity = 254) => new KeccakPRG(capacity); -+//# sourceMappingURL=sha3-addons.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.js.map -new file mode 100644 -index 0000000..257310e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3-addons.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha3-addons.js","sourceRoot":"","sources":["../src/sha3-addons.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.d.ts -new file mode 100644 -index 0000000..82b88a8 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.d.ts -@@ -0,0 +1,98 @@ -+import { Hash, Input, HashXOF } from './utils.js'; -+export declare function keccakP(s: Uint32Array, rounds?: number): void; -+export declare class Keccak extends Hash implements HashXOF { -+ blockLen: number; -+ suffix: number; -+ outputLen: number; -+ protected enableXOF: boolean; -+ protected rounds: number; -+ protected state: Uint8Array; -+ protected pos: number; -+ protected posOut: number; -+ protected finished: boolean; -+ protected state32: Uint32Array; -+ protected destroyed: boolean; -+ constructor(blockLen: number, suffix: number, outputLen: number, enableXOF?: boolean, rounds?: number); -+ protected keccak(): void; -+ update(data: Input): this; -+ protected finish(): void; -+ protected writeInto(out: Uint8Array): Uint8Array; -+ xofInto(out: Uint8Array): Uint8Array; -+ xof(bytes: number): Uint8Array; -+ digestInto(out: Uint8Array): Uint8Array; -+ digest(): Uint8Array; -+ destroy(): void; -+ _cloneInto(to?: Keccak): Keccak; -+} -+export declare const sha3_224: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+/** -+ * SHA3-256 hash function -+ * @param message - that would be hashed -+ */ -+export declare const sha3_256: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const sha3_384: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const sha3_512: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const keccak_224: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+/** -+ * keccak-256 hash function. Different from SHA3-256. -+ * @param message - that would be hashed -+ */ -+export declare const keccak_256: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const keccak_384: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const keccak_512: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export type ShakeOpts = { -+ dkLen?: number; -+}; -+export declare const shake128: { -+ (msg: Input, opts?: ShakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: ShakeOpts): HashXOF>; -+}; -+export declare const shake256: { -+ (msg: Input, opts?: ShakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: ShakeOpts): HashXOF>; -+}; -+//# sourceMappingURL=sha3.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.d.ts.map -new file mode 100644 -index 0000000..18faedf ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha3.d.ts","sourceRoot":"","sources":["../src/sha3.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,IAAI,EAEJ,KAAK,EAIL,OAAO,EAGR,MAAM,YAAY,CAAC;AAoCpB,wBAAgB,OAAO,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,GAAE,MAAW,QAyC1D;AAED,qBAAa,MAAO,SAAQ,IAAI,CAAC,MAAM,CAAE,YAAW,OAAO,CAAC,MAAM,CAAC;IASxD,QAAQ,EAAE,MAAM;IAChB,MAAM,EAAE,MAAM;IACd,SAAS,EAAE,MAAM;IACxB,SAAS,CAAC,SAAS;IACnB,SAAS,CAAC,MAAM,EAAE,MAAM;IAZ1B,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC;IAC5B,SAAS,CAAC,GAAG,SAAK;IAClB,SAAS,CAAC,MAAM,SAAK;IACrB,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC;IAC/B,SAAS,CAAC,SAAS,UAAS;gBAGnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACd,SAAS,UAAQ,EACjB,MAAM,GAAE,MAAW;IAW/B,SAAS,CAAC,MAAM;IAOhB,MAAM,CAAC,IAAI,EAAE,KAAK;IAYlB,SAAS,CAAC,MAAM;IAUhB,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU;IAehD,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU;IAKpC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;IAI9B,UAAU,CAAC,GAAG,EAAE,UAAU;IAO1B,MAAM;IAGN,OAAO;IAIP,UAAU,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;CAehC;AAKD,eAAO,MAAM,QAAQ;;;;;CAA0C,CAAC;AAChE;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;CAA0C,CAAC;AAChE,eAAO,MAAM,QAAQ;;;;;CAA0C,CAAC;AAChE,eAAO,MAAM,QAAQ;;;;;CAAyC,CAAC;AAC/D,eAAO,MAAM,UAAU;;;;;CAA0C,CAAC;AAClE;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;CAA0C,CAAC;AAClE,eAAO,MAAM,UAAU;;;;;CAA0C,CAAC;AAClE,eAAO,MAAM,UAAU;;;;;CAAyC,CAAC;AAEjE,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAQ3C,eAAO,MAAM,QAAQ;;;;;CAA+C,CAAC;AACrE,eAAO,MAAM,QAAQ;;;;;CAA+C,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.js -new file mode 100644 -index 0000000..4809ba7 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.js -@@ -0,0 +1,214 @@ -+import { bytes, exists, number, output } from './_assert.js'; -+import { rotlBH, rotlBL, rotlSH, rotlSL, split } from './_u64.js'; -+import { Hash, u32, toBytes, wrapConstructor, wrapXOFConstructorWithOpts, isLE, byteSwap32, } from './utils.js'; -+// SHA3 (keccak) is based on a new design: basically, the internal state is bigger than output size. -+// It's called a sponge function. -+// Various per round constants calculations -+const SHA3_PI = []; -+const SHA3_ROTL = []; -+const _SHA3_IOTA = []; -+const _0n = /* @__PURE__ */ BigInt(0); -+const _1n = /* @__PURE__ */ BigInt(1); -+const _2n = /* @__PURE__ */ BigInt(2); -+const _7n = /* @__PURE__ */ BigInt(7); -+const _256n = /* @__PURE__ */ BigInt(256); -+const _0x71n = /* @__PURE__ */ BigInt(0x71); -+for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) { -+ // Pi -+ [x, y] = [y, (2 * x + 3 * y) % 5]; -+ SHA3_PI.push(2 * (5 * y + x)); -+ // Rotational -+ SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64); -+ // Iota -+ let t = _0n; -+ for (let j = 0; j < 7; j++) { -+ R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n; -+ if (R & _2n) -+ t ^= _1n << ((_1n << /* @__PURE__ */ BigInt(j)) - _1n); -+ } -+ _SHA3_IOTA.push(t); -+} -+const [SHA3_IOTA_H, SHA3_IOTA_L] = /* @__PURE__ */ split(_SHA3_IOTA, true); -+// Left rotation (without 0, 32, 64) -+const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s)); -+const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s)); -+// Same as keccakf1600, but allows to skip some rounds -+export function keccakP(s, rounds = 24) { -+ const B = new Uint32Array(5 * 2); -+ // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js) -+ for (let round = 24 - rounds; round < 24; round++) { -+ // Theta θ -+ for (let x = 0; x < 10; x++) -+ B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40]; -+ for (let x = 0; x < 10; x += 2) { -+ const idx1 = (x + 8) % 10; -+ const idx0 = (x + 2) % 10; -+ const B0 = B[idx0]; -+ const B1 = B[idx0 + 1]; -+ const Th = rotlH(B0, B1, 1) ^ B[idx1]; -+ const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1]; -+ for (let y = 0; y < 50; y += 10) { -+ s[x + y] ^= Th; -+ s[x + y + 1] ^= Tl; -+ } -+ } -+ // Rho (ρ) and Pi (π) -+ let curH = s[2]; -+ let curL = s[3]; -+ for (let t = 0; t < 24; t++) { -+ const shift = SHA3_ROTL[t]; -+ const Th = rotlH(curH, curL, shift); -+ const Tl = rotlL(curH, curL, shift); -+ const PI = SHA3_PI[t]; -+ curH = s[PI]; -+ curL = s[PI + 1]; -+ s[PI] = Th; -+ s[PI + 1] = Tl; -+ } -+ // Chi (χ) -+ for (let y = 0; y < 50; y += 10) { -+ for (let x = 0; x < 10; x++) -+ B[x] = s[y + x]; -+ for (let x = 0; x < 10; x++) -+ s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10]; -+ } -+ // Iota (ι) -+ s[0] ^= SHA3_IOTA_H[round]; -+ s[1] ^= SHA3_IOTA_L[round]; -+ } -+ B.fill(0); -+} -+export class Keccak extends Hash { -+ // NOTE: we accept arguments in bytes instead of bits here. -+ constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) { -+ super(); -+ this.blockLen = blockLen; -+ this.suffix = suffix; -+ this.outputLen = outputLen; -+ this.enableXOF = enableXOF; -+ this.rounds = rounds; -+ this.pos = 0; -+ this.posOut = 0; -+ this.finished = false; -+ this.destroyed = false; -+ // Can be passed from user as dkLen -+ number(outputLen); -+ // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes -+ if (0 >= this.blockLen || this.blockLen >= 200) -+ throw new Error('Sha3 supports only keccak-f1600 function'); -+ this.state = new Uint8Array(200); -+ this.state32 = u32(this.state); -+ } -+ keccak() { -+ if (!isLE) -+ byteSwap32(this.state32); -+ keccakP(this.state32, this.rounds); -+ if (!isLE) -+ byteSwap32(this.state32); -+ this.posOut = 0; -+ this.pos = 0; -+ } -+ update(data) { -+ exists(this); -+ const { blockLen, state } = this; -+ data = toBytes(data); -+ const len = data.length; -+ for (let pos = 0; pos < len;) { -+ const take = Math.min(blockLen - this.pos, len - pos); -+ for (let i = 0; i < take; i++) -+ state[this.pos++] ^= data[pos++]; -+ if (this.pos === blockLen) -+ this.keccak(); -+ } -+ return this; -+ } -+ finish() { -+ if (this.finished) -+ return; -+ this.finished = true; -+ const { state, suffix, pos, blockLen } = this; -+ // Do the padding -+ state[pos] ^= suffix; -+ if ((suffix & 0x80) !== 0 && pos === blockLen - 1) -+ this.keccak(); -+ state[blockLen - 1] ^= 0x80; -+ this.keccak(); -+ } -+ writeInto(out) { -+ exists(this, false); -+ bytes(out); -+ this.finish(); -+ const bufferOut = this.state; -+ const { blockLen } = this; -+ for (let pos = 0, len = out.length; pos < len;) { -+ if (this.posOut >= blockLen) -+ this.keccak(); -+ const take = Math.min(blockLen - this.posOut, len - pos); -+ out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); -+ this.posOut += take; -+ pos += take; -+ } -+ return out; -+ } -+ xofInto(out) { -+ // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF -+ if (!this.enableXOF) -+ throw new Error('XOF is not possible for this instance'); -+ return this.writeInto(out); -+ } -+ xof(bytes) { -+ number(bytes); -+ return this.xofInto(new Uint8Array(bytes)); -+ } -+ digestInto(out) { -+ output(out, this); -+ if (this.finished) -+ throw new Error('digest() was already called'); -+ this.writeInto(out); -+ this.destroy(); -+ return out; -+ } -+ digest() { -+ return this.digestInto(new Uint8Array(this.outputLen)); -+ } -+ destroy() { -+ this.destroyed = true; -+ this.state.fill(0); -+ } -+ _cloneInto(to) { -+ const { blockLen, suffix, outputLen, rounds, enableXOF } = this; -+ to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds)); -+ to.state32.set(this.state32); -+ to.pos = this.pos; -+ to.posOut = this.posOut; -+ to.finished = this.finished; -+ to.rounds = rounds; -+ // Suffix can change in cSHAKE -+ to.suffix = suffix; -+ to.outputLen = outputLen; -+ to.enableXOF = enableXOF; -+ to.destroyed = this.destroyed; -+ return to; -+ } -+} -+const gen = (suffix, blockLen, outputLen) => wrapConstructor(() => new Keccak(blockLen, suffix, outputLen)); -+export const sha3_224 = /* @__PURE__ */ gen(0x06, 144, 224 / 8); -+/** -+ * SHA3-256 hash function -+ * @param message - that would be hashed -+ */ -+export const sha3_256 = /* @__PURE__ */ gen(0x06, 136, 256 / 8); -+export const sha3_384 = /* @__PURE__ */ gen(0x06, 104, 384 / 8); -+export const sha3_512 = /* @__PURE__ */ gen(0x06, 72, 512 / 8); -+export const keccak_224 = /* @__PURE__ */ gen(0x01, 144, 224 / 8); -+/** -+ * keccak-256 hash function. Different from SHA3-256. -+ * @param message - that would be hashed -+ */ -+export const keccak_256 = /* @__PURE__ */ gen(0x01, 136, 256 / 8); -+export const keccak_384 = /* @__PURE__ */ gen(0x01, 104, 384 / 8); -+export const keccak_512 = /* @__PURE__ */ gen(0x01, 72, 512 / 8); -+const genShake = (suffix, blockLen, outputLen) => wrapXOFConstructorWithOpts((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true)); -+export const shake128 = /* @__PURE__ */ genShake(0x1f, 168, 128 / 8); -+export const shake256 = /* @__PURE__ */ genShake(0x1f, 136, 256 / 8); -+//# sourceMappingURL=sha3.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.js.map -new file mode 100644 -index 0000000..e73a11c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha3.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha3.js","sourceRoot":"","sources":["../src/sha3.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.d.ts -new file mode 100644 -index 0000000..2282d2b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.d.ts -@@ -0,0 +1,124 @@ -+import { HashMD } from './_md.js'; -+export declare class SHA512 extends HashMD { -+ Ah: number; -+ Al: number; -+ Bh: number; -+ Bl: number; -+ Ch: number; -+ Cl: number; -+ Dh: number; -+ Dl: number; -+ Eh: number; -+ El: number; -+ Fh: number; -+ Fl: number; -+ Gh: number; -+ Gl: number; -+ Hh: number; -+ Hl: number; -+ constructor(); -+ protected get(): [ -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number -+ ]; -+ protected set(Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number, Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number): void; -+ protected process(view: DataView, offset: number): void; -+ protected roundClean(): void; -+ destroy(): void; -+} -+export declare class SHA512_224 extends SHA512 { -+ Ah: number; -+ Al: number; -+ Bh: number; -+ Bl: number; -+ Ch: number; -+ Cl: number; -+ Dh: number; -+ Dl: number; -+ Eh: number; -+ El: number; -+ Fh: number; -+ Fl: number; -+ Gh: number; -+ Gl: number; -+ Hh: number; -+ Hl: number; -+ constructor(); -+} -+export declare class SHA512_256 extends SHA512 { -+ Ah: number; -+ Al: number; -+ Bh: number; -+ Bl: number; -+ Ch: number; -+ Cl: number; -+ Dh: number; -+ Dl: number; -+ Eh: number; -+ El: number; -+ Fh: number; -+ Fl: number; -+ Gh: number; -+ Gl: number; -+ Hh: number; -+ Hl: number; -+ constructor(); -+} -+export declare class SHA384 extends SHA512 { -+ Ah: number; -+ Al: number; -+ Bh: number; -+ Bl: number; -+ Ch: number; -+ Cl: number; -+ Dh: number; -+ Dl: number; -+ Eh: number; -+ El: number; -+ Fh: number; -+ Fl: number; -+ Gh: number; -+ Gl: number; -+ Hh: number; -+ Hl: number; -+ constructor(); -+} -+export declare const sha512: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+export declare const sha512_224: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+export declare const sha512_256: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+export declare const sha384: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=sha512.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.d.ts.map -new file mode 100644 -index 0000000..0a0b9fd ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha512.d.ts","sourceRoot":"","sources":["../src/sha512.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.js -new file mode 100644 -index 0000000..6ea9be1 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.js -@@ -0,0 +1,231 @@ -+import { HashMD } from './_md.js'; -+import u64 from './_u64.js'; -+import { wrapConstructor } from './utils.js'; -+// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409): -+// prettier-ignore -+const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([ -+ '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc', -+ '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118', -+ '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2', -+ '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694', -+ '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65', -+ '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5', -+ '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4', -+ '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70', -+ '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df', -+ '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b', -+ '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30', -+ '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8', -+ '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8', -+ '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3', -+ '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec', -+ '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b', -+ '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178', -+ '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b', -+ '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c', -+ '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817' -+].map(n => BigInt(n))))(); -+// Temporary buffer, not used to store anything between runs -+const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80); -+const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80); -+export class SHA512 extends HashMD { -+ constructor() { -+ super(128, 64, 16, false); -+ // We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers. -+ // Also looks cleaner and easier to verify with spec. -+ // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19): -+ // h -- high 32 bits, l -- low 32 bits -+ this.Ah = 0x6a09e667 | 0; -+ this.Al = 0xf3bcc908 | 0; -+ this.Bh = 0xbb67ae85 | 0; -+ this.Bl = 0x84caa73b | 0; -+ this.Ch = 0x3c6ef372 | 0; -+ this.Cl = 0xfe94f82b | 0; -+ this.Dh = 0xa54ff53a | 0; -+ this.Dl = 0x5f1d36f1 | 0; -+ this.Eh = 0x510e527f | 0; -+ this.El = 0xade682d1 | 0; -+ this.Fh = 0x9b05688c | 0; -+ this.Fl = 0x2b3e6c1f | 0; -+ this.Gh = 0x1f83d9ab | 0; -+ this.Gl = 0xfb41bd6b | 0; -+ this.Hh = 0x5be0cd19 | 0; -+ this.Hl = 0x137e2179 | 0; -+ } -+ // prettier-ignore -+ get() { -+ const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; -+ return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl]; -+ } -+ // prettier-ignore -+ set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) { -+ this.Ah = Ah | 0; -+ this.Al = Al | 0; -+ this.Bh = Bh | 0; -+ this.Bl = Bl | 0; -+ this.Ch = Ch | 0; -+ this.Cl = Cl | 0; -+ this.Dh = Dh | 0; -+ this.Dl = Dl | 0; -+ this.Eh = Eh | 0; -+ this.El = El | 0; -+ this.Fh = Fh | 0; -+ this.Fl = Fl | 0; -+ this.Gh = Gh | 0; -+ this.Gl = Gl | 0; -+ this.Hh = Hh | 0; -+ this.Hl = Hl | 0; -+ } -+ process(view, offset) { -+ // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array -+ for (let i = 0; i < 16; i++, offset += 4) { -+ SHA512_W_H[i] = view.getUint32(offset); -+ SHA512_W_L[i] = view.getUint32((offset += 4)); -+ } -+ for (let i = 16; i < 80; i++) { -+ // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7) -+ const W15h = SHA512_W_H[i - 15] | 0; -+ const W15l = SHA512_W_L[i - 15] | 0; -+ const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7); -+ const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7); -+ // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6) -+ const W2h = SHA512_W_H[i - 2] | 0; -+ const W2l = SHA512_W_L[i - 2] | 0; -+ const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6); -+ const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6); -+ // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16]; -+ const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]); -+ const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]); -+ SHA512_W_H[i] = SUMh | 0; -+ SHA512_W_L[i] = SUMl | 0; -+ } -+ let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; -+ // Compression function main loop, 80 rounds -+ for (let i = 0; i < 80; i++) { -+ // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41) -+ const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41); -+ const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41); -+ //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; -+ const CHIh = (Eh & Fh) ^ (~Eh & Gh); -+ const CHIl = (El & Fl) ^ (~El & Gl); -+ // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i] -+ // prettier-ignore -+ const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]); -+ const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]); -+ const T1l = T1ll | 0; -+ // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39) -+ const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39); -+ const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39); -+ const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch); -+ const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl); -+ Hh = Gh | 0; -+ Hl = Gl | 0; -+ Gh = Fh | 0; -+ Gl = Fl | 0; -+ Fh = Eh | 0; -+ Fl = El | 0; -+ ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0)); -+ Dh = Ch | 0; -+ Dl = Cl | 0; -+ Ch = Bh | 0; -+ Cl = Bl | 0; -+ Bh = Ah | 0; -+ Bl = Al | 0; -+ const All = u64.add3L(T1l, sigma0l, MAJl); -+ Ah = u64.add3H(All, T1h, sigma0h, MAJh); -+ Al = All | 0; -+ } -+ // Add the compressed chunk to the current hash value -+ ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0)); -+ ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0)); -+ ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0)); -+ ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0)); -+ ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0)); -+ ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0)); -+ ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0)); -+ ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0)); -+ this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl); -+ } -+ roundClean() { -+ SHA512_W_H.fill(0); -+ SHA512_W_L.fill(0); -+ } -+ destroy() { -+ this.buffer.fill(0); -+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -+ } -+} -+export class SHA512_224 extends SHA512 { -+ constructor() { -+ super(); -+ // h -- high 32 bits, l -- low 32 bits -+ this.Ah = 0x8c3d37c8 | 0; -+ this.Al = 0x19544da2 | 0; -+ this.Bh = 0x73e19966 | 0; -+ this.Bl = 0x89dcd4d6 | 0; -+ this.Ch = 0x1dfab7ae | 0; -+ this.Cl = 0x32ff9c82 | 0; -+ this.Dh = 0x679dd514 | 0; -+ this.Dl = 0x582f9fcf | 0; -+ this.Eh = 0x0f6d2b69 | 0; -+ this.El = 0x7bd44da8 | 0; -+ this.Fh = 0x77e36f73 | 0; -+ this.Fl = 0x04c48942 | 0; -+ this.Gh = 0x3f9d85a8 | 0; -+ this.Gl = 0x6a1d36c8 | 0; -+ this.Hh = 0x1112e6ad | 0; -+ this.Hl = 0x91d692a1 | 0; -+ this.outputLen = 28; -+ } -+} -+export class SHA512_256 extends SHA512 { -+ constructor() { -+ super(); -+ // h -- high 32 bits, l -- low 32 bits -+ this.Ah = 0x22312194 | 0; -+ this.Al = 0xfc2bf72c | 0; -+ this.Bh = 0x9f555fa3 | 0; -+ this.Bl = 0xc84c64c2 | 0; -+ this.Ch = 0x2393b86b | 0; -+ this.Cl = 0x6f53b151 | 0; -+ this.Dh = 0x96387719 | 0; -+ this.Dl = 0x5940eabd | 0; -+ this.Eh = 0x96283ee2 | 0; -+ this.El = 0xa88effe3 | 0; -+ this.Fh = 0xbe5e1e25 | 0; -+ this.Fl = 0x53863992 | 0; -+ this.Gh = 0x2b0199fc | 0; -+ this.Gl = 0x2c85b8aa | 0; -+ this.Hh = 0x0eb72ddc | 0; -+ this.Hl = 0x81c52ca2 | 0; -+ this.outputLen = 32; -+ } -+} -+export class SHA384 extends SHA512 { -+ constructor() { -+ super(); -+ // h -- high 32 bits, l -- low 32 bits -+ this.Ah = 0xcbbb9d5d | 0; -+ this.Al = 0xc1059ed8 | 0; -+ this.Bh = 0x629a292a | 0; -+ this.Bl = 0x367cd507 | 0; -+ this.Ch = 0x9159015a | 0; -+ this.Cl = 0x3070dd17 | 0; -+ this.Dh = 0x152fecd8 | 0; -+ this.Dl = 0xf70e5939 | 0; -+ this.Eh = 0x67332667 | 0; -+ this.El = 0xffc00b31 | 0; -+ this.Fh = 0x8eb44a87 | 0; -+ this.Fl = 0x68581511 | 0; -+ this.Gh = 0xdb0c2e0d | 0; -+ this.Gl = 0x64f98fa7 | 0; -+ this.Hh = 0x47b5481d | 0; -+ this.Hl = 0xbefa4fa4 | 0; -+ this.outputLen = 48; -+ } -+} -+export const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512()); -+export const sha512_224 = /* @__PURE__ */ wrapConstructor(() => new SHA512_224()); -+export const sha512_256 = /* @__PURE__ */ wrapConstructor(() => new SHA512_256()); -+export const sha384 = /* @__PURE__ */ wrapConstructor(() => new SHA384()); -+//# sourceMappingURL=sha512.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.js.map -new file mode 100644 -index 0000000..7bc2e75 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/sha512.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha512.js","sourceRoot":"","sources":["../src/sha512.ts"],"names":[],"mappings":"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EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.d.ts -new file mode 100644 -index 0000000..21254c4 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.d.ts -@@ -0,0 +1,96 @@ -+/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ -+export declare function isBytes(a: unknown): a is Uint8Array; -+export type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array | Uint16Array | Int16Array | Uint32Array | Int32Array; -+export declare const u8: (arr: TypedArray) => Uint8Array; -+export declare const u32: (arr: TypedArray) => Uint32Array; -+export declare const createView: (arr: TypedArray) => DataView; -+export declare const rotr: (word: number, shift: number) => number; -+export declare const rotl: (word: number, shift: number) => number; -+export declare const isLE: boolean; -+export declare const byteSwap: (word: number) => number; -+export declare const byteSwapIfBE: (n: number) => number; -+export declare function byteSwap32(arr: Uint32Array): void; -+/** -+ * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123' -+ */ -+export declare function bytesToHex(bytes: Uint8Array): string; -+/** -+ * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) -+ */ -+export declare function hexToBytes(hex: string): Uint8Array; -+export declare const nextTick: () => Promise; -+export declare function asyncLoop(iters: number, tick: number, cb: (i: number) => void): Promise; -+/** -+ * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99]) -+ */ -+export declare function utf8ToBytes(str: string): Uint8Array; -+export type Input = Uint8Array | string; -+/** -+ * Normalizes (non-hex) string or Uint8Array to Uint8Array. -+ * Warning: when Uint8Array is passed, it would NOT get copied. -+ * Keep in mind for future mutable operations. -+ */ -+export declare function toBytes(data: Input): Uint8Array; -+/** -+ * Copies several Uint8Arrays into one. -+ */ -+export declare function concatBytes(...arrays: Uint8Array[]): Uint8Array; -+export declare abstract class Hash> { -+ abstract blockLen: number; -+ abstract outputLen: number; -+ abstract update(buf: Input): this; -+ abstract digestInto(buf: Uint8Array): void; -+ abstract digest(): Uint8Array; -+ /** -+ * Resets internal state. Makes Hash instance unusable. -+ * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed -+ * by user, they will need to manually call `destroy()` when zeroing is necessary. -+ */ -+ abstract destroy(): void; -+ /** -+ * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()` -+ * when no options are passed. -+ * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal -+ * buffers are overwritten => causes buffer overwrite which is used for digest in some cases. -+ * There are no guarantees for clean-up because it's impossible in JS. -+ */ -+ abstract _cloneInto(to?: T): T; -+ clone(): T; -+} -+/** -+ * XOF: streaming API to read digest in chunks. -+ * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name. -+ * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot -+ * destroy state, next call can require more bytes. -+ */ -+export type HashXOF> = Hash & { -+ xof(bytes: number): Uint8Array; -+ xofInto(buf: Uint8Array): Uint8Array; -+}; -+type EmptyObj = {}; -+export declare function checkOpts(defaults: T1, opts?: T2): T1 & T2; -+export type CHash = ReturnType; -+export declare function wrapConstructor>(hashCons: () => Hash): { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare function wrapConstructorWithOpts, T extends Object>(hashCons: (opts?: T) => Hash): { -+ (msg: Input, opts?: T): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: T): Hash; -+}; -+export declare function wrapXOFConstructorWithOpts, T extends Object>(hashCons: (opts?: T) => HashXOF): { -+ (msg: Input, opts?: T): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: T): HashXOF; -+}; -+/** -+ * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS. -+ */ -+export declare function randomBytes(bytesLength?: number): Uint8Array; -+export {}; -+//# sourceMappingURL=utils.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.d.ts.map -new file mode 100644 -index 0000000..0e0456b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.js -new file mode 100644 -index 0000000..da75f64 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.js -@@ -0,0 +1,187 @@ -+/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ -+// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. -+// node.js versions earlier than v19 don't declare it in global scope. -+// For node.js, package.json#exports field mapping rewrites import -+// from `crypto` to `cryptoNode`, which imports native module. -+// Makes the utils un-importable in browsers without a bundler. -+// Once node.js 18 is deprecated (2025-04-30), we can just drop the import. -+import { crypto } from '@noble/hashes/crypto'; -+import { bytes as abytes } from './_assert.js'; -+// export { isBytes } from './_assert.js'; -+// We can't reuse isBytes from _assert, because somehow this causes huge perf issues -+export function isBytes(a) { -+ return (a instanceof Uint8Array || -+ (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array')); -+} -+// Cast array to different type -+export const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength); -+export const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4)); -+// Cast array to view -+export const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength); -+// The rotate right (circular right shift) operation for uint32 -+export const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift); -+// The rotate left (circular left shift) operation for uint32 -+export const rotl = (word, shift) => (word << shift) | ((word >>> (32 - shift)) >>> 0); -+export const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44; -+// The byte swap operation for uint32 -+export const byteSwap = (word) => ((word << 24) & 0xff000000) | -+ ((word << 8) & 0xff0000) | -+ ((word >>> 8) & 0xff00) | -+ ((word >>> 24) & 0xff); -+// Conditionally byte swap if on a big-endian platform -+export const byteSwapIfBE = isLE ? (n) => n : (n) => byteSwap(n); -+// In place byte swap for Uint32Array -+export function byteSwap32(arr) { -+ for (let i = 0; i < arr.length; i++) { -+ arr[i] = byteSwap(arr[i]); -+ } -+} -+// Array where index 0xf0 (240) is mapped to string 'f0' -+const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0')); -+/** -+ * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123' -+ */ -+export function bytesToHex(bytes) { -+ abytes(bytes); -+ // pre-caching improves the speed 6x -+ let hex = ''; -+ for (let i = 0; i < bytes.length; i++) { -+ hex += hexes[bytes[i]]; -+ } -+ return hex; -+} -+// We use optimized technique to convert hex string to byte array -+const asciis = { _0: 48, _9: 57, _A: 65, _F: 70, _a: 97, _f: 102 }; -+function asciiToBase16(char) { -+ if (char >= asciis._0 && char <= asciis._9) -+ return char - asciis._0; -+ if (char >= asciis._A && char <= asciis._F) -+ return char - (asciis._A - 10); -+ if (char >= asciis._a && char <= asciis._f) -+ return char - (asciis._a - 10); -+ return; -+} -+/** -+ * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) -+ */ -+export function hexToBytes(hex) { -+ if (typeof hex !== 'string') -+ throw new Error('hex string expected, got ' + typeof hex); -+ const hl = hex.length; -+ const al = hl / 2; -+ if (hl % 2) -+ throw new Error('padded hex string expected, got unpadded hex of length ' + hl); -+ const array = new Uint8Array(al); -+ for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) { -+ const n1 = asciiToBase16(hex.charCodeAt(hi)); -+ const n2 = asciiToBase16(hex.charCodeAt(hi + 1)); -+ if (n1 === undefined || n2 === undefined) { -+ const char = hex[hi] + hex[hi + 1]; -+ throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi); -+ } -+ array[ai] = n1 * 16 + n2; -+ } -+ return array; -+} -+// There is no setImmediate in browser and setTimeout is slow. -+// call of async fn will return Promise, which will be fullfiled only on -+// next scheduler queue processing step and this is exactly what we need. -+export const nextTick = async () => { }; -+// Returns control to thread each 'tick' ms to avoid blocking -+export async function asyncLoop(iters, tick, cb) { -+ let ts = Date.now(); -+ for (let i = 0; i < iters; i++) { -+ cb(i); -+ // Date.now() is not monotonic, so in case if clock goes backwards we return return control too -+ const diff = Date.now() - ts; -+ if (diff >= 0 && diff < tick) -+ continue; -+ await nextTick(); -+ ts += diff; -+ } -+} -+/** -+ * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99]) -+ */ -+export function utf8ToBytes(str) { -+ if (typeof str !== 'string') -+ throw new Error(`utf8ToBytes expected string, got ${typeof str}`); -+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809 -+} -+/** -+ * Normalizes (non-hex) string or Uint8Array to Uint8Array. -+ * Warning: when Uint8Array is passed, it would NOT get copied. -+ * Keep in mind for future mutable operations. -+ */ -+export function toBytes(data) { -+ if (typeof data === 'string') -+ data = utf8ToBytes(data); -+ abytes(data); -+ return data; -+} -+/** -+ * Copies several Uint8Arrays into one. -+ */ -+export function concatBytes(...arrays) { -+ let sum = 0; -+ for (let i = 0; i < arrays.length; i++) { -+ const a = arrays[i]; -+ abytes(a); -+ sum += a.length; -+ } -+ const res = new Uint8Array(sum); -+ for (let i = 0, pad = 0; i < arrays.length; i++) { -+ const a = arrays[i]; -+ res.set(a, pad); -+ pad += a.length; -+ } -+ return res; -+} -+// For runtime check if class implements interface -+export class Hash { -+ // Safe version that clones internal state -+ clone() { -+ return this._cloneInto(); -+ } -+} -+const toStr = {}.toString; -+export function checkOpts(defaults, opts) { -+ if (opts !== undefined && toStr.call(opts) !== '[object Object]') -+ throw new Error('Options should be object or undefined'); -+ const merged = Object.assign(defaults, opts); -+ return merged; -+} -+export function wrapConstructor(hashCons) { -+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest(); -+ const tmp = hashCons(); -+ hashC.outputLen = tmp.outputLen; -+ hashC.blockLen = tmp.blockLen; -+ hashC.create = () => hashCons(); -+ return hashC; -+} -+export function wrapConstructorWithOpts(hashCons) { -+ const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest(); -+ const tmp = hashCons({}); -+ hashC.outputLen = tmp.outputLen; -+ hashC.blockLen = tmp.blockLen; -+ hashC.create = (opts) => hashCons(opts); -+ return hashC; -+} -+export function wrapXOFConstructorWithOpts(hashCons) { -+ const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest(); -+ const tmp = hashCons({}); -+ hashC.outputLen = tmp.outputLen; -+ hashC.blockLen = tmp.blockLen; -+ hashC.create = (opts) => hashCons(opts); -+ return hashC; -+} -+/** -+ * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS. -+ */ -+export function randomBytes(bytesLength = 32) { -+ if (crypto && typeof crypto.getRandomValues === 'function') { -+ return crypto.getRandomValues(new Uint8Array(bytesLength)); -+ } -+ throw new Error('crypto.getRandomValues must be defined'); -+} -+//# sourceMappingURL=utils.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.js.map -new file mode 100644 -index 0000000..742bafa ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/esm/utils.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.d.ts -new file mode 100644 -index 0000000..f2ff770 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.d.ts -@@ -0,0 +1,27 @@ -+import { CHash, Input } from './utils.js'; -+/** -+ * HKDF-Extract(IKM, salt) -> PRK -+ * Arguments position differs from spec (IKM is first one, since it is not optional) -+ * @param hash -+ * @param ikm -+ * @param salt -+ * @returns -+ */ -+export declare function extract(hash: CHash, ikm: Input, salt?: Input): Uint8Array; -+/** -+ * HKDF-expand from the spec. -+ * @param prk - a pseudorandom key of at least HashLen octets (usually, the output from the extract step) -+ * @param info - optional context and application specific information (can be a zero-length string) -+ * @param length - length of output keying material in octets -+ */ -+export declare function expand(hash: CHash, prk: Input, info?: Input, length?: number): Uint8Array; -+/** -+ * HKDF (RFC 5869): extract + expand in one step. -+ * @param hash - hash function that would be used (e.g. sha256) -+ * @param ikm - input keying material, the initial key -+ * @param salt - optional salt value (a non-secret random value) -+ * @param info - optional context and application specific information -+ * @param length - length of output keying material in octets -+ */ -+export declare const hkdf: (hash: CHash, ikm: Input, salt: Input | undefined, info: Input | undefined, length: number) => Uint8Array; -+//# sourceMappingURL=hkdf.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.d.ts.map -new file mode 100644 -index 0000000..d27f938 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"hkdf.d.ts","sourceRoot":"","sources":["src/hkdf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAW,MAAM,YAAY,CAAC;AAMnD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,cAO5D;AAMD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,GAAE,MAAW,cA4BhF;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,SACT,KAAK,OACN,KAAK,QACJ,KAAK,GAAG,SAAS,QACjB,KAAK,GAAG,SAAS,UACf,MAAM,eACyC,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.js -new file mode 100644 -index 0000000..1a3a82b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.js -@@ -0,0 +1,78 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.hkdf = void 0; -+exports.extract = extract; -+exports.expand = expand; -+const _assert_js_1 = require("./_assert.js"); -+const utils_js_1 = require("./utils.js"); -+const hmac_js_1 = require("./hmac.js"); -+// HKDF (RFC 5869) -+// https://soatok.blog/2021/11/17/understanding-hkdf/ -+/** -+ * HKDF-Extract(IKM, salt) -> PRK -+ * Arguments position differs from spec (IKM is first one, since it is not optional) -+ * @param hash -+ * @param ikm -+ * @param salt -+ * @returns -+ */ -+function extract(hash, ikm, salt) { -+ (0, _assert_js_1.hash)(hash); -+ // NOTE: some libraries treat zero-length array as 'not provided'; -+ // we don't, since we have undefined as 'not provided' -+ // https://github.com/RustCrypto/KDFs/issues/15 -+ if (salt === undefined) -+ salt = new Uint8Array(hash.outputLen); // if not provided, it is set to a string of HashLen zeros -+ return (0, hmac_js_1.hmac)(hash, (0, utils_js_1.toBytes)(salt), (0, utils_js_1.toBytes)(ikm)); -+} -+// HKDF-Expand(PRK, info, L) -> OKM -+const HKDF_COUNTER = /* @__PURE__ */ new Uint8Array([0]); -+const EMPTY_BUFFER = /* @__PURE__ */ new Uint8Array(); -+/** -+ * HKDF-expand from the spec. -+ * @param prk - a pseudorandom key of at least HashLen octets (usually, the output from the extract step) -+ * @param info - optional context and application specific information (can be a zero-length string) -+ * @param length - length of output keying material in octets -+ */ -+function expand(hash, prk, info, length = 32) { -+ (0, _assert_js_1.hash)(hash); -+ (0, _assert_js_1.number)(length); -+ if (length > 255 * hash.outputLen) -+ throw new Error('Length should be <= 255*HashLen'); -+ const blocks = Math.ceil(length / hash.outputLen); -+ if (info === undefined) -+ info = EMPTY_BUFFER; -+ // first L(ength) octets of T -+ const okm = new Uint8Array(blocks * hash.outputLen); -+ // Re-use HMAC instance between blocks -+ const HMAC = hmac_js_1.hmac.create(hash, prk); -+ const HMACTmp = HMAC._cloneInto(); -+ const T = new Uint8Array(HMAC.outputLen); -+ for (let counter = 0; counter < blocks; counter++) { -+ HKDF_COUNTER[0] = counter + 1; -+ // T(0) = empty string (zero length) -+ // T(N) = HMAC-Hash(PRK, T(N-1) | info | N) -+ HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T) -+ .update(info) -+ .update(HKDF_COUNTER) -+ .digestInto(T); -+ okm.set(T, hash.outputLen * counter); -+ HMAC._cloneInto(HMACTmp); -+ } -+ HMAC.destroy(); -+ HMACTmp.destroy(); -+ T.fill(0); -+ HKDF_COUNTER.fill(0); -+ return okm.slice(0, length); -+} -+/** -+ * HKDF (RFC 5869): extract + expand in one step. -+ * @param hash - hash function that would be used (e.g. sha256) -+ * @param ikm - input keying material, the initial key -+ * @param salt - optional salt value (a non-secret random value) -+ * @param info - optional context and application specific information -+ * @param length - length of output keying material in octets -+ */ -+const hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length); -+exports.hkdf = hkdf; -+//# sourceMappingURL=hkdf.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.js.map -new file mode 100644 -index 0000000..58b39d2 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hkdf.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"hkdf.js","sourceRoot":"","sources":["src/hkdf.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.d.ts -new file mode 100644 -index 0000000..5a9f896 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.d.ts -@@ -0,0 +1,30 @@ -+import { Hash, CHash, Input } from './utils.js'; -+export declare class HMAC> extends Hash> { -+ oHash: T; -+ iHash: T; -+ blockLen: number; -+ outputLen: number; -+ private finished; -+ private destroyed; -+ constructor(hash: CHash, _key: Input); -+ update(buf: Input): this; -+ digestInto(out: Uint8Array): void; -+ digest(): Uint8Array; -+ _cloneInto(to?: HMAC): HMAC; -+ destroy(): void; -+} -+/** -+ * HMAC: RFC2104 message authentication code. -+ * @param hash - function that would be used e.g. sha256 -+ * @param key - message key -+ * @param message - message data -+ * @example -+ * import { hmac } from '@noble/hashes/hmac'; -+ * import { sha256 } from '@noble/hashes/sha2'; -+ * const mac1 = hmac(sha256, 'key', 'message'); -+ */ -+export declare const hmac: { -+ (hash: CHash, key: Input, message: Input): Uint8Array; -+ create(hash: CHash, key: Input): HMAC; -+}; -+//# sourceMappingURL=hmac.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.d.ts.map -new file mode 100644 -index 0000000..797ea17 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["src/hmac.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAW,MAAM,YAAY,CAAC;AAEzD,qBAAa,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK;IAsBpC,MAAM,CAAC,GAAG,EAAE,KAAK;IAKjB,UAAU,CAAC,GAAG,EAAE,UAAU;IAS1B,MAAM;IAKN,UAAU,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAajC,OAAO;CAKR;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI;WAAU,KAAK,OAAO,KAAK,WAAW,KAAK,GAAG,UAAU;iBAEpD,KAAK,OAAO,KAAK;CADa,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.js -new file mode 100644 -index 0000000..74f1f48 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.js -@@ -0,0 +1,86 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.hmac = exports.HMAC = void 0; -+const _assert_js_1 = require("./_assert.js"); -+const utils_js_1 = require("./utils.js"); -+// HMAC (RFC 2104) -+class HMAC extends utils_js_1.Hash { -+ constructor(hash, _key) { -+ super(); -+ this.finished = false; -+ this.destroyed = false; -+ (0, _assert_js_1.hash)(hash); -+ const key = (0, utils_js_1.toBytes)(_key); -+ this.iHash = hash.create(); -+ if (typeof this.iHash.update !== 'function') -+ throw new Error('Expected instance of class which extends utils.Hash'); -+ this.blockLen = this.iHash.blockLen; -+ this.outputLen = this.iHash.outputLen; -+ const blockLen = this.blockLen; -+ const pad = new Uint8Array(blockLen); -+ // blockLen can be bigger than outputLen -+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key); -+ for (let i = 0; i < pad.length; i++) -+ pad[i] ^= 0x36; -+ this.iHash.update(pad); -+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone -+ this.oHash = hash.create(); -+ // Undo internal XOR && apply outer XOR -+ for (let i = 0; i < pad.length; i++) -+ pad[i] ^= 0x36 ^ 0x5c; -+ this.oHash.update(pad); -+ pad.fill(0); -+ } -+ update(buf) { -+ (0, _assert_js_1.exists)(this); -+ this.iHash.update(buf); -+ return this; -+ } -+ digestInto(out) { -+ (0, _assert_js_1.exists)(this); -+ (0, _assert_js_1.bytes)(out, this.outputLen); -+ this.finished = true; -+ this.iHash.digestInto(out); -+ this.oHash.update(out); -+ this.oHash.digestInto(out); -+ this.destroy(); -+ } -+ digest() { -+ const out = new Uint8Array(this.oHash.outputLen); -+ this.digestInto(out); -+ return out; -+ } -+ _cloneInto(to) { -+ // Create new instance without calling constructor since key already in state and we don't know it. -+ to || (to = Object.create(Object.getPrototypeOf(this), {})); -+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this; -+ to = to; -+ to.finished = finished; -+ to.destroyed = destroyed; -+ to.blockLen = blockLen; -+ to.outputLen = outputLen; -+ to.oHash = oHash._cloneInto(to.oHash); -+ to.iHash = iHash._cloneInto(to.iHash); -+ return to; -+ } -+ destroy() { -+ this.destroyed = true; -+ this.oHash.destroy(); -+ this.iHash.destroy(); -+ } -+} -+exports.HMAC = HMAC; -+/** -+ * HMAC: RFC2104 message authentication code. -+ * @param hash - function that would be used e.g. sha256 -+ * @param key - message key -+ * @param message - message data -+ * @example -+ * import { hmac } from '@noble/hashes/hmac'; -+ * import { sha256 } from '@noble/hashes/sha2'; -+ * const mac1 = hmac(sha256, 'key', 'message'); -+ */ -+const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest(); -+exports.hmac = hmac; -+exports.hmac.create = (hash, key) => new HMAC(hash, key); -+//# sourceMappingURL=hmac.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.js.map -new file mode 100644 -index 0000000..3612e23 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/hmac.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"hmac.js","sourceRoot":"","sources":["src/hmac.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.d.ts -new file mode 100644 -index 0000000..f36479a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.d.ts -@@ -0,0 +1 @@ -+//# sourceMappingURL=index.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.d.ts.map -new file mode 100644 -index 0000000..4e8c581 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":""} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.js -new file mode 100644 -index 0000000..da92182 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.js -@@ -0,0 +1,3 @@ -+"use strict"; -+throw new Error('root module cannot be imported: import submodules instead. Check out README'); -+//# sourceMappingURL=index.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.js.map -new file mode 100644 -index 0000000..b6e5db7 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/index.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":";AAAA,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.d.ts -new file mode 100644 -index 0000000..1fb1b27 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.d.ts -@@ -0,0 +1,16 @@ -+import { CHash, Input } from './utils.js'; -+export type Pbkdf2Opt = { -+ c: number; -+ dkLen?: number; -+ asyncTick?: number; -+}; -+/** -+ * PBKDF2-HMAC: RFC 2898 key derivation function -+ * @param hash - hash function that would be used e.g. sha256 -+ * @param password - password from which a derived key is generated -+ * @param salt - cryptographic salt -+ * @param opts - {c, dkLen} where c is work factor and dkLen is output message size -+ */ -+export declare function pbkdf2(hash: CHash, password: Input, salt: Input, opts: Pbkdf2Opt): Uint8Array; -+export declare function pbkdf2Async(hash: CHash, password: Input, salt: Input, opts: Pbkdf2Opt): Promise; -+//# sourceMappingURL=pbkdf2.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.d.ts.map -new file mode 100644 -index 0000000..830ceeb ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"pbkdf2.d.ts","sourceRoot":"","sources":["src/pbkdf2.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,KAAK,EAAE,KAAK,EAA6C,MAAM,YAAY,CAAC;AAG3F,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAkCF;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,cAsBhF;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,uBAsB3F"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.js -new file mode 100644 -index 0000000..40b919a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.js -@@ -0,0 +1,90 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.pbkdf2 = pbkdf2; -+exports.pbkdf2Async = pbkdf2Async; -+const _assert_js_1 = require("./_assert.js"); -+const hmac_js_1 = require("./hmac.js"); -+const utils_js_1 = require("./utils.js"); -+// Common prologue and epilogue for sync/async functions -+function pbkdf2Init(hash, _password, _salt, _opts) { -+ (0, _assert_js_1.hash)(hash); -+ const opts = (0, utils_js_1.checkOpts)({ dkLen: 32, asyncTick: 10 }, _opts); -+ const { c, dkLen, asyncTick } = opts; -+ (0, _assert_js_1.number)(c); -+ (0, _assert_js_1.number)(dkLen); -+ (0, _assert_js_1.number)(asyncTick); -+ if (c < 1) -+ throw new Error('PBKDF2: iterations (c) should be >= 1'); -+ const password = (0, utils_js_1.toBytes)(_password); -+ const salt = (0, utils_js_1.toBytes)(_salt); -+ // DK = PBKDF2(PRF, Password, Salt, c, dkLen); -+ const DK = new Uint8Array(dkLen); -+ // U1 = PRF(Password, Salt + INT_32_BE(i)) -+ const PRF = hmac_js_1.hmac.create(hash, password); -+ const PRFSalt = PRF._cloneInto().update(salt); -+ return { c, dkLen, asyncTick, DK, PRF, PRFSalt }; -+} -+function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) { -+ PRF.destroy(); -+ PRFSalt.destroy(); -+ if (prfW) -+ prfW.destroy(); -+ u.fill(0); -+ return DK; -+} -+/** -+ * PBKDF2-HMAC: RFC 2898 key derivation function -+ * @param hash - hash function that would be used e.g. sha256 -+ * @param password - password from which a derived key is generated -+ * @param salt - cryptographic salt -+ * @param opts - {c, dkLen} where c is work factor and dkLen is output message size -+ */ -+function pbkdf2(hash, password, salt, opts) { -+ const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); -+ let prfW; // Working copy -+ const arr = new Uint8Array(4); -+ const view = (0, utils_js_1.createView)(arr); -+ const u = new Uint8Array(PRF.outputLen); -+ // DK = T1 + T2 + ⋯ + Tdklen/hlen -+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { -+ // Ti = F(Password, Salt, c, i) -+ const Ti = DK.subarray(pos, pos + PRF.outputLen); -+ view.setInt32(0, ti, false); -+ // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc -+ // U1 = PRF(Password, Salt + INT_32_BE(i)) -+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); -+ Ti.set(u.subarray(0, Ti.length)); -+ for (let ui = 1; ui < c; ui++) { -+ // Uc = PRF(Password, Uc−1) -+ PRF._cloneInto(prfW).update(u).digestInto(u); -+ for (let i = 0; i < Ti.length; i++) -+ Ti[i] ^= u[i]; -+ } -+ } -+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); -+} -+async function pbkdf2Async(hash, password, salt, opts) { -+ const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); -+ let prfW; // Working copy -+ const arr = new Uint8Array(4); -+ const view = (0, utils_js_1.createView)(arr); -+ const u = new Uint8Array(PRF.outputLen); -+ // DK = T1 + T2 + ⋯ + Tdklen/hlen -+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { -+ // Ti = F(Password, Salt, c, i) -+ const Ti = DK.subarray(pos, pos + PRF.outputLen); -+ view.setInt32(0, ti, false); -+ // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc -+ // U1 = PRF(Password, Salt + INT_32_BE(i)) -+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); -+ Ti.set(u.subarray(0, Ti.length)); -+ await (0, utils_js_1.asyncLoop)(c - 1, asyncTick, () => { -+ // Uc = PRF(Password, Uc−1) -+ PRF._cloneInto(prfW).update(u).digestInto(u); -+ for (let i = 0; i < Ti.length; i++) -+ Ti[i] ^= u[i]; -+ }); -+ } -+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); -+} -+//# sourceMappingURL=pbkdf2.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.js.map -new file mode 100644 -index 0000000..c2da67a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/pbkdf2.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"pbkdf2.js","sourceRoot":"","sources":["src/pbkdf2.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.d.ts -new file mode 100644 -index 0000000..1320a14 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.d.ts -@@ -0,0 +1,25 @@ -+import { HashMD } from './_md.js'; -+export declare class RIPEMD160 extends HashMD { -+ private h0; -+ private h1; -+ private h2; -+ private h3; -+ private h4; -+ constructor(); -+ protected get(): [number, number, number, number, number]; -+ protected set(h0: number, h1: number, h2: number, h3: number, h4: number): void; -+ protected process(view: DataView, offset: number): void; -+ protected roundClean(): void; -+ destroy(): void; -+} -+/** -+ * RIPEMD-160 - a hash function from 1990s. -+ * @param message - msg that would be hashed -+ */ -+export declare const ripemd160: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=ripemd160.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.d.ts.map -new file mode 100644 -index 0000000..00a3aa2 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ripemd160.d.ts","sourceRoot":"","sources":["src/ripemd160.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAqClC,qBAAa,SAAU,SAAQ,MAAM,CAAC,SAAS,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;;IAK5B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIzD,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAOxE,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAmCvD,SAAS,CAAC,UAAU;IAGpB,OAAO;CAKR;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;CAAyD,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.js -new file mode 100644 -index 0000000..244744e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.js -@@ -0,0 +1,106 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.ripemd160 = exports.RIPEMD160 = void 0; -+const _md_js_1 = require("./_md.js"); -+const utils_js_1 = require("./utils.js"); -+// https://homes.esat.kuleuven.be/~bosselae/ripemd160.html -+// https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf -+const Rho = /* @__PURE__ */ new Uint8Array([7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8]); -+const Id = /* @__PURE__ */ new Uint8Array(new Array(16).fill(0).map((_, i) => i)); -+const Pi = /* @__PURE__ */ Id.map((i) => (9 * i + 5) % 16); -+let idxL = [Id]; -+let idxR = [Pi]; -+for (let i = 0; i < 4; i++) -+ for (let j of [idxL, idxR]) -+ j.push(j[i].map((k) => Rho[k])); -+const shifts = /* @__PURE__ */ [ -+ [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8], -+ [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7], -+ [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9], -+ [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6], -+ [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5], -+].map((i) => new Uint8Array(i)); -+const shiftsL = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts[i][j])); -+const shiftsR = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts[i][j])); -+const Kl = /* @__PURE__ */ new Uint32Array([ -+ 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e, -+]); -+const Kr = /* @__PURE__ */ new Uint32Array([ -+ 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000, -+]); -+// It's called f() in spec. -+function f(group, x, y, z) { -+ if (group === 0) -+ return x ^ y ^ z; -+ else if (group === 1) -+ return (x & y) | (~x & z); -+ else if (group === 2) -+ return (x | ~y) ^ z; -+ else if (group === 3) -+ return (x & z) | (y & ~z); -+ else -+ return x ^ (y | ~z); -+} -+// Temporary buffer, not used to store anything between runs -+const R_BUF = /* @__PURE__ */ new Uint32Array(16); -+class RIPEMD160 extends _md_js_1.HashMD { -+ constructor() { -+ super(64, 20, 8, true); -+ this.h0 = 0x67452301 | 0; -+ this.h1 = 0xefcdab89 | 0; -+ this.h2 = 0x98badcfe | 0; -+ this.h3 = 0x10325476 | 0; -+ this.h4 = 0xc3d2e1f0 | 0; -+ } -+ get() { -+ const { h0, h1, h2, h3, h4 } = this; -+ return [h0, h1, h2, h3, h4]; -+ } -+ set(h0, h1, h2, h3, h4) { -+ this.h0 = h0 | 0; -+ this.h1 = h1 | 0; -+ this.h2 = h2 | 0; -+ this.h3 = h3 | 0; -+ this.h4 = h4 | 0; -+ } -+ process(view, offset) { -+ for (let i = 0; i < 16; i++, offset += 4) -+ R_BUF[i] = view.getUint32(offset, true); -+ // prettier-ignore -+ let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el; -+ // Instead of iterating 0 to 80, we split it into 5 groups -+ // And use the groups in constants, functions, etc. Much simpler -+ for (let group = 0; group < 5; group++) { -+ const rGroup = 4 - group; -+ const hbl = Kl[group], hbr = Kr[group]; // prettier-ignore -+ const rl = idxL[group], rr = idxR[group]; // prettier-ignore -+ const sl = shiftsL[group], sr = shiftsR[group]; // prettier-ignore -+ for (let i = 0; i < 16; i++) { -+ const tl = ((0, utils_js_1.rotl)(al + f(group, bl, cl, dl) + R_BUF[rl[i]] + hbl, sl[i]) + el) | 0; -+ al = el, el = dl, dl = (0, utils_js_1.rotl)(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore -+ } -+ // 2 loops are 10% faster -+ for (let i = 0; i < 16; i++) { -+ const tr = ((0, utils_js_1.rotl)(ar + f(rGroup, br, cr, dr) + R_BUF[rr[i]] + hbr, sr[i]) + er) | 0; -+ ar = er, er = dr, dr = (0, utils_js_1.rotl)(cr, 10) | 0, cr = br, br = tr; // prettier-ignore -+ } -+ } -+ // Add the compressed chunk to the current hash value -+ this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0); -+ } -+ roundClean() { -+ R_BUF.fill(0); -+ } -+ destroy() { -+ this.destroyed = true; -+ this.buffer.fill(0); -+ this.set(0, 0, 0, 0, 0); -+ } -+} -+exports.RIPEMD160 = RIPEMD160; -+/** -+ * RIPEMD-160 - a hash function from 1990s. -+ * @param message - msg that would be hashed -+ */ -+exports.ripemd160 = (0, utils_js_1.wrapConstructor)(() => new RIPEMD160()); -+//# sourceMappingURL=ripemd160.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.js.map -new file mode 100644 -index 0000000..f8ee722 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/ripemd160.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ripemd160.js","sourceRoot":"","sources":["src/ripemd160.ts"],"names":[],"mappings":";;;AAAA,qCAAkC;AAClC,yCAAmD;AAEnD,0DAA0D;AAC1D,6EAA6E;AAC7E,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AACnG,MAAM,EAAE,GAAG,eAAe,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAClF,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AAC3D,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;AAChB,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;AAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;IAAE,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;QAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAExF,MAAM,MAAM,GAAG,eAAe,CAAC;IAC7B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;CACzD,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAChC,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnF,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnF,MAAM,EAAE,GAAG,eAAe,CAAC,IAAI,WAAW,CAAC;IACzC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;CAC3D,CAAC,CAAC;AACH,MAAM,EAAE,GAAG,eAAe,CAAC,IAAI,WAAW,CAAC;IACzC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;CAC3D,CAAC,CAAC;AACH,2BAA2B;AAC3B,SAAS,CAAC,CAAC,KAAa,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS;IACvD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SAC7B,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;SAC3C,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACrC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;;QAC3C,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AACD,4DAA4D;AAC5D,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;AAClD,MAAa,SAAU,SAAQ,eAAiB;IAO9C;QACE,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAPjB,OAAE,GAAG,UAAU,GAAG,CAAC,CAAC;QACpB,OAAE,GAAG,UAAU,GAAG,CAAC,CAAC;QACpB,OAAE,GAAG,UAAU,GAAG,CAAC,CAAC;QACpB,OAAE,GAAG,UAAU,GAAG,CAAC,CAAC;QACpB,OAAE,GAAG,UAAU,GAAG,CAAC,CAAC;IAI5B,CAAC;IACS,GAAG;QACX,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;QACpC,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC;IACS,GAAG,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU;QACtE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACnB,CAAC;IACS,OAAO,CAAC,IAAc,EAAE,MAAc;QAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,CAAC;YAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAClF,kBAAkB;QAClB,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EACzB,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EACzB,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EACzB,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EACzB,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC;QAE9B,0DAA0D;QAC1D,gEAAgE;QAChE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;YACzB,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB;YAC1D,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB;YAC5D,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB;YAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5B,MAAM,EAAE,GAAG,CAAC,IAAA,eAAI,EAAC,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;gBAClF,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,IAAA,eAAI,EAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,kBAAkB;YAC/E,CAAC;YACD,yBAAyB;YACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5B,MAAM,EAAE,GAAG,CAAC,IAAA,eAAI,EAAC,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;gBACnF,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,IAAA,eAAI,EAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,kBAAkB;YAC/E,CAAC;QACH,CAAC;QACD,qDAAqD;QACrD,IAAI,CAAC,GAAG,CACN,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EACvB,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EACvB,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EACvB,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EACvB,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CACxB,CAAC;IACJ,CAAC;IACS,UAAU;QAClB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;IACD,OAAO;QACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC;CACF;AAhED,8BAgEC;AAED;;;GAGG;AACU,QAAA,SAAS,GAAmB,IAAA,0BAAe,EAAC,GAAG,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.d.ts -new file mode 100644 -index 0000000..68368e6 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.d.ts -@@ -0,0 +1,30 @@ -+import { Input } from './utils.js'; -+export type ScryptOpts = { -+ N: number; -+ r: number; -+ p: number; -+ dkLen?: number; -+ asyncTick?: number; -+ maxmem?: number; -+ onProgress?: (progress: number) => void; -+}; -+/** -+ * Scrypt KDF from RFC 7914. -+ * @param password - pass -+ * @param salt - salt -+ * @param opts - parameters -+ * - `N` is cpu/mem work factor (power of 2 e.g. 2**18) -+ * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance -+ * - `p` is parallelization factor (1 is common) -+ * - `dkLen` is output key length in bytes e.g. 32. -+ * - `asyncTick` - (default: 10) max time in ms for which async function can block execution -+ * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt -+ * - `onProgress` - callback function that would be executed for progress report -+ * @returns Derived key -+ */ -+export declare function scrypt(password: Input, salt: Input, opts: ScryptOpts): Uint8Array; -+/** -+ * Scrypt KDF from RFC 7914. -+ */ -+export declare function scryptAsync(password: Input, salt: Input, opts: ScryptOpts): Promise; -+//# sourceMappingURL=scrypt.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.d.ts.map -new file mode 100644 -index 0000000..ab45209 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"scrypt.d.ts","sourceRoot":"","sources":["src/scrypt.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,EAAyB,MAAM,YAAY,CAAC;AAyEtF,MAAM,MAAM,UAAU,GAAG;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAoFF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,cA0BpE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,uBA2B/E"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.js -new file mode 100644 -index 0000000..30cfc0e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.js -@@ -0,0 +1,228 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.scrypt = scrypt; -+exports.scryptAsync = scryptAsync; -+const _assert_js_1 = require("./_assert.js"); -+const sha256_js_1 = require("./sha256.js"); -+const pbkdf2_js_1 = require("./pbkdf2.js"); -+const utils_js_1 = require("./utils.js"); -+// RFC 7914 Scrypt KDF -+// The main Scrypt loop: uses Salsa extensively. -+// Six versions of the function were tried, this is the fastest one. -+// prettier-ignore -+function XorAndSalsa(prev, pi, input, ii, out, oi) { -+ // Based on https://cr.yp.to/salsa20.html -+ // Xor blocks -+ let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++]; -+ let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++]; -+ let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++]; -+ let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++]; -+ let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++]; -+ let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++]; -+ let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++]; -+ let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++]; -+ // Save state to temporary variables (salsa) -+ let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15; -+ // Main loop (salsa) -+ for (let i = 0; i < 8; i += 2) { -+ x04 ^= (0, utils_js_1.rotl)(x00 + x12 | 0, 7); -+ x08 ^= (0, utils_js_1.rotl)(x04 + x00 | 0, 9); -+ x12 ^= (0, utils_js_1.rotl)(x08 + x04 | 0, 13); -+ x00 ^= (0, utils_js_1.rotl)(x12 + x08 | 0, 18); -+ x09 ^= (0, utils_js_1.rotl)(x05 + x01 | 0, 7); -+ x13 ^= (0, utils_js_1.rotl)(x09 + x05 | 0, 9); -+ x01 ^= (0, utils_js_1.rotl)(x13 + x09 | 0, 13); -+ x05 ^= (0, utils_js_1.rotl)(x01 + x13 | 0, 18); -+ x14 ^= (0, utils_js_1.rotl)(x10 + x06 | 0, 7); -+ x02 ^= (0, utils_js_1.rotl)(x14 + x10 | 0, 9); -+ x06 ^= (0, utils_js_1.rotl)(x02 + x14 | 0, 13); -+ x10 ^= (0, utils_js_1.rotl)(x06 + x02 | 0, 18); -+ x03 ^= (0, utils_js_1.rotl)(x15 + x11 | 0, 7); -+ x07 ^= (0, utils_js_1.rotl)(x03 + x15 | 0, 9); -+ x11 ^= (0, utils_js_1.rotl)(x07 + x03 | 0, 13); -+ x15 ^= (0, utils_js_1.rotl)(x11 + x07 | 0, 18); -+ x01 ^= (0, utils_js_1.rotl)(x00 + x03 | 0, 7); -+ x02 ^= (0, utils_js_1.rotl)(x01 + x00 | 0, 9); -+ x03 ^= (0, utils_js_1.rotl)(x02 + x01 | 0, 13); -+ x00 ^= (0, utils_js_1.rotl)(x03 + x02 | 0, 18); -+ x06 ^= (0, utils_js_1.rotl)(x05 + x04 | 0, 7); -+ x07 ^= (0, utils_js_1.rotl)(x06 + x05 | 0, 9); -+ x04 ^= (0, utils_js_1.rotl)(x07 + x06 | 0, 13); -+ x05 ^= (0, utils_js_1.rotl)(x04 + x07 | 0, 18); -+ x11 ^= (0, utils_js_1.rotl)(x10 + x09 | 0, 7); -+ x08 ^= (0, utils_js_1.rotl)(x11 + x10 | 0, 9); -+ x09 ^= (0, utils_js_1.rotl)(x08 + x11 | 0, 13); -+ x10 ^= (0, utils_js_1.rotl)(x09 + x08 | 0, 18); -+ x12 ^= (0, utils_js_1.rotl)(x15 + x14 | 0, 7); -+ x13 ^= (0, utils_js_1.rotl)(x12 + x15 | 0, 9); -+ x14 ^= (0, utils_js_1.rotl)(x13 + x12 | 0, 13); -+ x15 ^= (0, utils_js_1.rotl)(x14 + x13 | 0, 18); -+ } -+ // Write output (salsa) -+ out[oi++] = (y00 + x00) | 0; -+ out[oi++] = (y01 + x01) | 0; -+ out[oi++] = (y02 + x02) | 0; -+ out[oi++] = (y03 + x03) | 0; -+ out[oi++] = (y04 + x04) | 0; -+ out[oi++] = (y05 + x05) | 0; -+ out[oi++] = (y06 + x06) | 0; -+ out[oi++] = (y07 + x07) | 0; -+ out[oi++] = (y08 + x08) | 0; -+ out[oi++] = (y09 + x09) | 0; -+ out[oi++] = (y10 + x10) | 0; -+ out[oi++] = (y11 + x11) | 0; -+ out[oi++] = (y12 + x12) | 0; -+ out[oi++] = (y13 + x13) | 0; -+ out[oi++] = (y14 + x14) | 0; -+ out[oi++] = (y15 + x15) | 0; -+} -+function BlockMix(input, ii, out, oi, r) { -+ // The block B is r 128-byte chunks (which is equivalent of 2r 64-byte chunks) -+ let head = oi + 0; -+ let tail = oi + 16 * r; -+ for (let i = 0; i < 16; i++) -+ out[tail + i] = input[ii + (2 * r - 1) * 16 + i]; // X ← B[2r−1] -+ for (let i = 0; i < r; i++, head += 16, ii += 16) { -+ // We write odd & even Yi at same time. Even: 0bXXXXX0 Odd: 0bXXXXX1 -+ XorAndSalsa(out, tail, input, ii, out, head); // head[i] = Salsa(blockIn[2*i] ^ tail[i-1]) -+ if (i > 0) -+ tail += 16; // First iteration overwrites tmp value in tail -+ XorAndSalsa(out, head, input, (ii += 16), out, tail); // tail[i] = Salsa(blockIn[2*i+1] ^ head[i]) -+ } -+} -+// Common prologue and epilogue for sync/async functions -+function scryptInit(password, salt, _opts) { -+ // Maxmem - 1GB+1KB by default -+ const opts = (0, utils_js_1.checkOpts)({ -+ dkLen: 32, -+ asyncTick: 10, -+ maxmem: 1024 ** 3 + 1024, -+ }, _opts); -+ const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts; -+ (0, _assert_js_1.number)(N); -+ (0, _assert_js_1.number)(r); -+ (0, _assert_js_1.number)(p); -+ (0, _assert_js_1.number)(dkLen); -+ (0, _assert_js_1.number)(asyncTick); -+ (0, _assert_js_1.number)(maxmem); -+ if (onProgress !== undefined && typeof onProgress !== 'function') -+ throw new Error('progressCb should be function'); -+ const blockSize = 128 * r; -+ const blockSize32 = blockSize / 4; -+ if (N <= 1 || (N & (N - 1)) !== 0 || N >= 2 ** (blockSize / 8) || N > 2 ** 32) { -+ // NOTE: we limit N to be less than 2**32 because of 32 bit variant of Integrify function -+ // There is no JS engines that allows alocate more than 4GB per single Uint8Array for now, but can change in future. -+ throw new Error('Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32'); -+ } -+ if (p < 0 || p > ((2 ** 32 - 1) * 32) / blockSize) { -+ throw new Error('Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)'); -+ } -+ if (dkLen < 0 || dkLen > (2 ** 32 - 1) * 32) { -+ throw new Error('Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32'); -+ } -+ const memUsed = blockSize * (N + p); -+ if (memUsed > maxmem) { -+ throw new Error(`Scrypt: parameters too large, ${memUsed} (128 * r * (N + p)) > ${maxmem} (maxmem)`); -+ } -+ // [B0...Bp−1] ← PBKDF2HMAC-SHA256(Passphrase, Salt, 1, blockSize*ParallelizationFactor) -+ // Since it has only one iteration there is no reason to use async variant -+ const B = (0, pbkdf2_js_1.pbkdf2)(sha256_js_1.sha256, password, salt, { c: 1, dkLen: blockSize * p }); -+ const B32 = (0, utils_js_1.u32)(B); -+ // Re-used between parallel iterations. Array(iterations) of B -+ const V = (0, utils_js_1.u32)(new Uint8Array(blockSize * N)); -+ const tmp = (0, utils_js_1.u32)(new Uint8Array(blockSize)); -+ let blockMixCb = () => { }; -+ if (onProgress) { -+ const totalBlockMix = 2 * N * p; -+ // Invoke callback if progress changes from 10.01 to 10.02 -+ // Allows to draw smooth progress bar on up to 8K screen -+ const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1); -+ let blockMixCnt = 0; -+ blockMixCb = () => { -+ blockMixCnt++; -+ if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix)) -+ onProgress(blockMixCnt / totalBlockMix); -+ }; -+ } -+ return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick }; -+} -+function scryptOutput(password, dkLen, B, V, tmp) { -+ const res = (0, pbkdf2_js_1.pbkdf2)(sha256_js_1.sha256, password, B, { c: 1, dkLen }); -+ B.fill(0); -+ V.fill(0); -+ tmp.fill(0); -+ return res; -+} -+/** -+ * Scrypt KDF from RFC 7914. -+ * @param password - pass -+ * @param salt - salt -+ * @param opts - parameters -+ * - `N` is cpu/mem work factor (power of 2 e.g. 2**18) -+ * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance -+ * - `p` is parallelization factor (1 is common) -+ * - `dkLen` is output key length in bytes e.g. 32. -+ * - `asyncTick` - (default: 10) max time in ms for which async function can block execution -+ * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt -+ * - `onProgress` - callback function that would be executed for progress report -+ * @returns Derived key -+ */ -+function scrypt(password, salt, opts) { -+ const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit(password, salt, opts); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(B32); -+ for (let pi = 0; pi < p; pi++) { -+ const Pi = blockSize32 * pi; -+ for (let i = 0; i < blockSize32; i++) -+ V[i] = B32[Pi + i]; // V[0] = B[i] -+ for (let i = 0, pos = 0; i < N - 1; i++) { -+ BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]); -+ blockMixCb(); -+ } -+ BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element -+ blockMixCb(); -+ for (let i = 0; i < N; i++) { -+ // First u32 of the last 64-byte block (u32 is LE) -+ const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations -+ for (let k = 0; k < blockSize32; k++) -+ tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j] -+ BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j]) -+ blockMixCb(); -+ } -+ } -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(B32); -+ return scryptOutput(password, dkLen, B, V, tmp); -+} -+/** -+ * Scrypt KDF from RFC 7914. -+ */ -+async function scryptAsync(password, salt, opts) { -+ const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick } = scryptInit(password, salt, opts); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(B32); -+ for (let pi = 0; pi < p; pi++) { -+ const Pi = blockSize32 * pi; -+ for (let i = 0; i < blockSize32; i++) -+ V[i] = B32[Pi + i]; // V[0] = B[i] -+ let pos = 0; -+ await (0, utils_js_1.asyncLoop)(N - 1, asyncTick, () => { -+ BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]); -+ blockMixCb(); -+ }); -+ BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element -+ blockMixCb(); -+ await (0, utils_js_1.asyncLoop)(N, asyncTick, () => { -+ // First u32 of the last 64-byte block (u32 is LE) -+ const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations -+ for (let k = 0; k < blockSize32; k++) -+ tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j] -+ BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j]) -+ blockMixCb(); -+ }); -+ } -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(B32); -+ return scryptOutput(password, dkLen, B, V, tmp); -+} -+//# sourceMappingURL=scrypt.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.js.map -new file mode 100644 -index 0000000..060d6b6 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/scrypt.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"scrypt.js","sourceRoot":"","sources":["src/scrypt.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.d.ts -new file mode 100644 -index 0000000..f210c5c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.d.ts -@@ -0,0 +1,26 @@ -+import { HashMD } from './_md.js'; -+export declare class SHA1 extends HashMD { -+ private A; -+ private B; -+ private C; -+ private D; -+ private E; -+ constructor(); -+ protected get(): [number, number, number, number, number]; -+ protected set(A: number, B: number, C: number, D: number, E: number): void; -+ protected process(view: DataView, offset: number): void; -+ protected roundClean(): void; -+ destroy(): void; -+} -+/** -+ * SHA1 (RFC 3174) hash function. -+ * It was cryptographically broken: prefer newer algorithms. -+ * @param message - data that would be hashed -+ */ -+export declare const sha1: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=sha1.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.d.ts.map -new file mode 100644 -index 0000000..ea42f9e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha1.d.ts","sourceRoot":"","sources":["src/sha1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,UAAU,CAAC;AAa5C,qBAAa,IAAK,SAAQ,MAAM,CAAC,IAAI,CAAC;IACpC,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;;IAK3B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIzD,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAOnE,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoCvD,SAAS,CAAC,UAAU;IAGpB,OAAO;CAIR;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI;;;;;CAAoD,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.js -new file mode 100644 -index 0000000..a6dca1b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.js -@@ -0,0 +1,89 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.sha1 = exports.SHA1 = void 0; -+const _md_js_1 = require("./_md.js"); -+const utils_js_1 = require("./utils.js"); -+// SHA1 (RFC 3174). It was cryptographically broken: prefer newer algorithms. -+// Initial state -+const SHA1_IV = /* @__PURE__ */ new Uint32Array([ -+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0, -+]); -+// Temporary buffer, not used to store anything between runs -+// Named this way because it matches specification. -+const SHA1_W = /* @__PURE__ */ new Uint32Array(80); -+class SHA1 extends _md_js_1.HashMD { -+ constructor() { -+ super(64, 20, 8, false); -+ this.A = SHA1_IV[0] | 0; -+ this.B = SHA1_IV[1] | 0; -+ this.C = SHA1_IV[2] | 0; -+ this.D = SHA1_IV[3] | 0; -+ this.E = SHA1_IV[4] | 0; -+ } -+ get() { -+ const { A, B, C, D, E } = this; -+ return [A, B, C, D, E]; -+ } -+ set(A, B, C, D, E) { -+ this.A = A | 0; -+ this.B = B | 0; -+ this.C = C | 0; -+ this.D = D | 0; -+ this.E = E | 0; -+ } -+ process(view, offset) { -+ for (let i = 0; i < 16; i++, offset += 4) -+ SHA1_W[i] = view.getUint32(offset, false); -+ for (let i = 16; i < 80; i++) -+ SHA1_W[i] = (0, utils_js_1.rotl)(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1); -+ // Compression function main loop, 80 rounds -+ let { A, B, C, D, E } = this; -+ for (let i = 0; i < 80; i++) { -+ let F, K; -+ if (i < 20) { -+ F = (0, _md_js_1.Chi)(B, C, D); -+ K = 0x5a827999; -+ } -+ else if (i < 40) { -+ F = B ^ C ^ D; -+ K = 0x6ed9eba1; -+ } -+ else if (i < 60) { -+ F = (0, _md_js_1.Maj)(B, C, D); -+ K = 0x8f1bbcdc; -+ } -+ else { -+ F = B ^ C ^ D; -+ K = 0xca62c1d6; -+ } -+ const T = ((0, utils_js_1.rotl)(A, 5) + F + E + K + SHA1_W[i]) | 0; -+ E = D; -+ D = C; -+ C = (0, utils_js_1.rotl)(B, 30); -+ B = A; -+ A = T; -+ } -+ // Add the compressed chunk to the current hash value -+ A = (A + this.A) | 0; -+ B = (B + this.B) | 0; -+ C = (C + this.C) | 0; -+ D = (D + this.D) | 0; -+ E = (E + this.E) | 0; -+ this.set(A, B, C, D, E); -+ } -+ roundClean() { -+ SHA1_W.fill(0); -+ } -+ destroy() { -+ this.set(0, 0, 0, 0, 0); -+ this.buffer.fill(0); -+ } -+} -+exports.SHA1 = SHA1; -+/** -+ * SHA1 (RFC 3174) hash function. -+ * It was cryptographically broken: prefer newer algorithms. -+ * @param message - data that would be hashed -+ */ -+exports.sha1 = (0, utils_js_1.wrapConstructor)(() => new SHA1()); -+//# sourceMappingURL=sha1.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.js.map -new file mode 100644 -index 0000000..d0e4764 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha1.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha1.js","sourceRoot":"","sources":["src/sha1.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.d.ts -new file mode 100644 -index 0000000..6052a2a ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.d.ts -@@ -0,0 +1,3 @@ -+export { sha256, sha224 } from './sha256.js'; -+export { sha512, sha512_224, sha512_256, sha384 } from './sha512.js'; -+//# sourceMappingURL=sha2.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.d.ts.map -new file mode 100644 -index 0000000..588445d ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha2.d.ts","sourceRoot":"","sources":["src/sha2.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.js -new file mode 100644 -index 0000000..651b9e4 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.js -@@ -0,0 +1,13 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.sha384 = exports.sha512_256 = exports.sha512_224 = exports.sha512 = exports.sha224 = exports.sha256 = void 0; -+// Usually you either use sha256, or sha512. We re-export them as sha2 for naming consistency. -+var sha256_js_1 = require("./sha256.js"); -+Object.defineProperty(exports, "sha256", { enumerable: true, get: function () { return sha256_js_1.sha256; } }); -+Object.defineProperty(exports, "sha224", { enumerable: true, get: function () { return sha256_js_1.sha224; } }); -+var sha512_js_1 = require("./sha512.js"); -+Object.defineProperty(exports, "sha512", { enumerable: true, get: function () { return sha512_js_1.sha512; } }); -+Object.defineProperty(exports, "sha512_224", { enumerable: true, get: function () { return sha512_js_1.sha512_224; } }); -+Object.defineProperty(exports, "sha512_256", { enumerable: true, get: function () { return sha512_js_1.sha512_256; } }); -+Object.defineProperty(exports, "sha384", { enumerable: true, get: function () { return sha512_js_1.sha384; } }); -+//# sourceMappingURL=sha2.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.js.map -new file mode 100644 -index 0000000..a0c2748 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha2.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha2.js","sourceRoot":"","sources":["src/sha2.ts"],"names":[],"mappings":";;;AAAA,8FAA8F;AAC9F,yCAA6C;AAApC,mGAAA,MAAM,OAAA;AAAE,mGAAA,MAAM,OAAA;AACvB,yCAAqE;AAA5D,mGAAA,MAAM,OAAA;AAAE,uGAAA,UAAU,OAAA;AAAE,uGAAA,UAAU,OAAA;AAAE,mGAAA,MAAM,OAAA"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.d.ts -new file mode 100644 -index 0000000..b31a842 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.d.ts -@@ -0,0 +1,37 @@ -+import { HashMD } from './_md.js'; -+export declare class SHA256 extends HashMD { -+ A: number; -+ B: number; -+ C: number; -+ D: number; -+ E: number; -+ F: number; -+ G: number; -+ H: number; -+ constructor(); -+ protected get(): [number, number, number, number, number, number, number, number]; -+ protected set(A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number): void; -+ protected process(view: DataView, offset: number): void; -+ protected roundClean(): void; -+ destroy(): void; -+} -+/** -+ * SHA2-256 hash function -+ * @param message - data that would be hashed -+ */ -+export declare const sha256: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+/** -+ * SHA2-224 hash function -+ */ -+export declare const sha224: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=sha256.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.d.ts.map -new file mode 100644 -index 0000000..0c59b17 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha256.d.ts","sourceRoot":"","sources":["src/sha256.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,UAAU,CAAC;AA8B5C,qBAAa,MAAO,SAAQ,MAAM,CAAC,MAAM,CAAC;IAGxC,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;IACrB,CAAC,SAAoB;;IAKrB,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAKjF,SAAS,CAAC,GAAG,CACX,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAWxF,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAqCvD,SAAS,CAAC,UAAU;IAGpB,OAAO;CAIR;AAiBD;;;GAGG;AACH,eAAO,MAAM,MAAM;;;;;CAAsD,CAAC;AAC1E;;GAEG;AACH,eAAO,MAAM,MAAM;;;;;CAAsD,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.js -new file mode 100644 -index 0000000..3e21558 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.js -@@ -0,0 +1,130 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.sha224 = exports.sha256 = exports.SHA256 = void 0; -+const _md_js_1 = require("./_md.js"); -+const utils_js_1 = require("./utils.js"); -+// SHA2-256 need to try 2^128 hashes to execute birthday attack. -+// BTC network is doing 2^67 hashes/sec as per early 2023. -+// Round constants: -+// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311) -+// prettier-ignore -+const SHA256_K = /* @__PURE__ */ new Uint32Array([ -+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, -+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, -+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, -+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, -+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, -+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, -+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, -+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -+]); -+// Initial state: -+// first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19 -+// prettier-ignore -+const SHA256_IV = /* @__PURE__ */ new Uint32Array([ -+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -+]); -+// Temporary buffer, not used to store anything between runs -+// Named this way because it matches specification. -+const SHA256_W = /* @__PURE__ */ new Uint32Array(64); -+class SHA256 extends _md_js_1.HashMD { -+ constructor() { -+ super(64, 32, 8, false); -+ // We cannot use array here since array allows indexing by variable -+ // which means optimizer/compiler cannot use registers. -+ this.A = SHA256_IV[0] | 0; -+ this.B = SHA256_IV[1] | 0; -+ this.C = SHA256_IV[2] | 0; -+ this.D = SHA256_IV[3] | 0; -+ this.E = SHA256_IV[4] | 0; -+ this.F = SHA256_IV[5] | 0; -+ this.G = SHA256_IV[6] | 0; -+ this.H = SHA256_IV[7] | 0; -+ } -+ get() { -+ const { A, B, C, D, E, F, G, H } = this; -+ return [A, B, C, D, E, F, G, H]; -+ } -+ // prettier-ignore -+ set(A, B, C, D, E, F, G, H) { -+ this.A = A | 0; -+ this.B = B | 0; -+ this.C = C | 0; -+ this.D = D | 0; -+ this.E = E | 0; -+ this.F = F | 0; -+ this.G = G | 0; -+ this.H = H | 0; -+ } -+ process(view, offset) { -+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array -+ for (let i = 0; i < 16; i++, offset += 4) -+ SHA256_W[i] = view.getUint32(offset, false); -+ for (let i = 16; i < 64; i++) { -+ const W15 = SHA256_W[i - 15]; -+ const W2 = SHA256_W[i - 2]; -+ const s0 = (0, utils_js_1.rotr)(W15, 7) ^ (0, utils_js_1.rotr)(W15, 18) ^ (W15 >>> 3); -+ const s1 = (0, utils_js_1.rotr)(W2, 17) ^ (0, utils_js_1.rotr)(W2, 19) ^ (W2 >>> 10); -+ SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0; -+ } -+ // Compression function main loop, 64 rounds -+ let { A, B, C, D, E, F, G, H } = this; -+ for (let i = 0; i < 64; i++) { -+ const sigma1 = (0, utils_js_1.rotr)(E, 6) ^ (0, utils_js_1.rotr)(E, 11) ^ (0, utils_js_1.rotr)(E, 25); -+ const T1 = (H + sigma1 + (0, _md_js_1.Chi)(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; -+ const sigma0 = (0, utils_js_1.rotr)(A, 2) ^ (0, utils_js_1.rotr)(A, 13) ^ (0, utils_js_1.rotr)(A, 22); -+ const T2 = (sigma0 + (0, _md_js_1.Maj)(A, B, C)) | 0; -+ H = G; -+ G = F; -+ F = E; -+ E = (D + T1) | 0; -+ D = C; -+ C = B; -+ B = A; -+ A = (T1 + T2) | 0; -+ } -+ // Add the compressed chunk to the current hash value -+ A = (A + this.A) | 0; -+ B = (B + this.B) | 0; -+ C = (C + this.C) | 0; -+ D = (D + this.D) | 0; -+ E = (E + this.E) | 0; -+ F = (F + this.F) | 0; -+ G = (G + this.G) | 0; -+ H = (H + this.H) | 0; -+ this.set(A, B, C, D, E, F, G, H); -+ } -+ roundClean() { -+ SHA256_W.fill(0); -+ } -+ destroy() { -+ this.set(0, 0, 0, 0, 0, 0, 0, 0); -+ this.buffer.fill(0); -+ } -+} -+exports.SHA256 = SHA256; -+// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf -+class SHA224 extends SHA256 { -+ constructor() { -+ super(); -+ this.A = 0xc1059ed8 | 0; -+ this.B = 0x367cd507 | 0; -+ this.C = 0x3070dd17 | 0; -+ this.D = 0xf70e5939 | 0; -+ this.E = 0xffc00b31 | 0; -+ this.F = 0x68581511 | 0; -+ this.G = 0x64f98fa7 | 0; -+ this.H = 0xbefa4fa4 | 0; -+ this.outputLen = 28; -+ } -+} -+/** -+ * SHA2-256 hash function -+ * @param message - data that would be hashed -+ */ -+exports.sha256 = (0, utils_js_1.wrapConstructor)(() => new SHA256()); -+/** -+ * SHA2-224 hash function -+ */ -+exports.sha224 = (0, utils_js_1.wrapConstructor)(() => new SHA224()); -+//# sourceMappingURL=sha256.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.js.map -new file mode 100644 -index 0000000..2b14c2e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha256.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha256.js","sourceRoot":"","sources":["src/sha256.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.d.ts -new file mode 100644 -index 0000000..151cdf2 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.d.ts -@@ -0,0 +1,154 @@ -+import { Input, Hash, HashXOF } from './utils.js'; -+import { Keccak, ShakeOpts } from './sha3.js'; -+export type cShakeOpts = ShakeOpts & { -+ personalization?: Input; -+ NISTfn?: Input; -+}; -+export declare const cshake128: { -+ (msg: Input, opts?: cShakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: cShakeOpts): HashXOF; -+}; -+export declare const cshake256: { -+ (msg: Input, opts?: cShakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: cShakeOpts): HashXOF; -+}; -+export declare class KMAC extends Keccak implements HashXOF { -+ constructor(blockLen: number, outputLen: number, enableXOF: boolean, key: Input, opts?: cShakeOpts); -+ protected finish(): void; -+ _cloneInto(to?: KMAC): KMAC; -+ clone(): KMAC; -+} -+export declare const kmac128: { -+ (key: Input, message: Input, opts?: cShakeOpts): Uint8Array; -+ create(key: Input, opts?: cShakeOpts): KMAC; -+}; -+export declare const kmac256: { -+ (key: Input, message: Input, opts?: cShakeOpts): Uint8Array; -+ create(key: Input, opts?: cShakeOpts): KMAC; -+}; -+export declare const kmac128xof: { -+ (key: Input, message: Input, opts?: cShakeOpts): Uint8Array; -+ create(key: Input, opts?: cShakeOpts): KMAC; -+}; -+export declare const kmac256xof: { -+ (key: Input, message: Input, opts?: cShakeOpts): Uint8Array; -+ create(key: Input, opts?: cShakeOpts): KMAC; -+}; -+export declare class TupleHash extends Keccak implements HashXOF { -+ constructor(blockLen: number, outputLen: number, enableXOF: boolean, opts?: cShakeOpts); -+ protected finish(): void; -+ _cloneInto(to?: TupleHash): TupleHash; -+ clone(): TupleHash; -+} -+export declare const tuplehash128: { -+ (messages: Input[], opts?: cShakeOpts): Uint8Array; -+ create(opts?: cShakeOpts): TupleHash; -+}; -+export declare const tuplehash256: { -+ (messages: Input[], opts?: cShakeOpts): Uint8Array; -+ create(opts?: cShakeOpts): TupleHash; -+}; -+export declare const tuplehash128xof: { -+ (messages: Input[], opts?: cShakeOpts): Uint8Array; -+ create(opts?: cShakeOpts): TupleHash; -+}; -+export declare const tuplehash256xof: { -+ (messages: Input[], opts?: cShakeOpts): Uint8Array; -+ create(opts?: cShakeOpts): TupleHash; -+}; -+type ParallelOpts = cShakeOpts & { -+ blockLen?: number; -+}; -+export declare class ParallelHash extends Keccak implements HashXOF { -+ protected leafCons: () => Hash; -+ private leafHash?; -+ private chunkPos; -+ private chunksDone; -+ private chunkLen; -+ constructor(blockLen: number, outputLen: number, leafCons: () => Hash, enableXOF: boolean, opts?: ParallelOpts); -+ protected finish(): void; -+ _cloneInto(to?: ParallelHash): ParallelHash; -+ destroy(): void; -+ clone(): ParallelHash; -+} -+export declare const parallelhash128: { -+ (message: Input, opts?: ParallelOpts): Uint8Array; -+ create(opts?: ParallelOpts): ParallelHash; -+}; -+export declare const parallelhash256: { -+ (message: Input, opts?: ParallelOpts): Uint8Array; -+ create(opts?: ParallelOpts): ParallelHash; -+}; -+export declare const parallelhash128xof: { -+ (message: Input, opts?: ParallelOpts): Uint8Array; -+ create(opts?: ParallelOpts): ParallelHash; -+}; -+export declare const parallelhash256xof: { -+ (message: Input, opts?: ParallelOpts): Uint8Array; -+ create(opts?: ParallelOpts): ParallelHash; -+}; -+export type TurboshakeOpts = ShakeOpts & { -+ D?: number; -+}; -+export declare const turboshake128: { -+ (msg: Input, opts?: TurboshakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: TurboshakeOpts): HashXOF>; -+}; -+export declare const turboshake256: { -+ (msg: Input, opts?: TurboshakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: TurboshakeOpts): HashXOF>; -+}; -+export type KangarooOpts = { -+ dkLen?: number; -+ personalization?: Input; -+}; -+export declare class KangarooTwelve extends Keccak implements HashXOF { -+ protected leafLen: number; -+ readonly chunkLen = 8192; -+ private leafHash?; -+ private personalization; -+ private chunkPos; -+ private chunksDone; -+ constructor(blockLen: number, leafLen: number, outputLen: number, rounds: number, opts: KangarooOpts); -+ update(data: Input): this; -+ protected finish(): void; -+ destroy(): void; -+ _cloneInto(to?: KangarooTwelve): KangarooTwelve; -+ clone(): KangarooTwelve; -+} -+export declare const k12: { -+ (msg: Input, opts?: KangarooOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: KangarooOpts): Hash; -+}; -+export declare const m14: { -+ (msg: Input, opts?: KangarooOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: KangarooOpts): Hash; -+}; -+export declare class KeccakPRG extends Keccak { -+ protected rate: number; -+ constructor(capacity: number); -+ keccak(): void; -+ update(data: Input): this; -+ feed(data: Input): this; -+ protected finish(): void; -+ digestInto(_out: Uint8Array): Uint8Array; -+ fetch(bytes: number): Uint8Array; -+ forget(): void; -+ _cloneInto(to?: KeccakPRG): KeccakPRG; -+ clone(): KeccakPRG; -+} -+export declare const keccakprg: (capacity?: number) => KeccakPRG; -+export {}; -+//# sourceMappingURL=sha3-addons.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.d.ts.map -new file mode 100644 -index 0000000..c2def57 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha3-addons.d.ts","sourceRoot":"","sources":["src/sha3-addons.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.js -new file mode 100644 -index 0000000..5f2a4d4 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.js -@@ -0,0 +1,365 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.keccakprg = exports.KeccakPRG = exports.m14 = exports.k12 = exports.KangarooTwelve = exports.turboshake256 = exports.turboshake128 = exports.parallelhash256xof = exports.parallelhash128xof = exports.parallelhash256 = exports.parallelhash128 = exports.ParallelHash = exports.tuplehash256xof = exports.tuplehash128xof = exports.tuplehash256 = exports.tuplehash128 = exports.TupleHash = exports.kmac256xof = exports.kmac128xof = exports.kmac256 = exports.kmac128 = exports.KMAC = exports.cshake256 = exports.cshake128 = void 0; -+const _assert_js_1 = require("./_assert.js"); -+const utils_js_1 = require("./utils.js"); -+const sha3_js_1 = require("./sha3.js"); -+// cSHAKE && KMAC (NIST SP800-185) -+function leftEncode(n) { -+ const res = [n & 0xff]; -+ n >>= 8; -+ for (; n > 0; n >>= 8) -+ res.unshift(n & 0xff); -+ res.unshift(res.length); -+ return new Uint8Array(res); -+} -+function rightEncode(n) { -+ const res = [n & 0xff]; -+ n >>= 8; -+ for (; n > 0; n >>= 8) -+ res.unshift(n & 0xff); -+ res.push(res.length); -+ return new Uint8Array(res); -+} -+function chooseLen(opts, outputLen) { -+ return opts.dkLen === undefined ? outputLen : opts.dkLen; -+} -+const toBytesOptional = (buf) => (buf !== undefined ? (0, utils_js_1.toBytes)(buf) : new Uint8Array([])); -+// NOTE: second modulo is necessary since we don't need to add padding if current element takes whole block -+const getPadding = (len, block) => new Uint8Array((block - (len % block)) % block); -+// Personalization -+function cshakePers(hash, opts = {}) { -+ if (!opts || (!opts.personalization && !opts.NISTfn)) -+ return hash; -+ // Encode and pad inplace to avoid unneccesary memory copies/slices (so we don't need to zero them later) -+ // bytepad(encode_string(N) || encode_string(S), 168) -+ const blockLenBytes = leftEncode(hash.blockLen); -+ const fn = toBytesOptional(opts.NISTfn); -+ const fnLen = leftEncode(8 * fn.length); // length in bits -+ const pers = toBytesOptional(opts.personalization); -+ const persLen = leftEncode(8 * pers.length); // length in bits -+ if (!fn.length && !pers.length) -+ return hash; -+ hash.suffix = 0x04; -+ hash.update(blockLenBytes).update(fnLen).update(fn).update(persLen).update(pers); -+ let totalLen = blockLenBytes.length + fnLen.length + fn.length + persLen.length + pers.length; -+ hash.update(getPadding(totalLen, hash.blockLen)); -+ return hash; -+} -+const gencShake = (suffix, blockLen, outputLen) => (0, utils_js_1.wrapXOFConstructorWithOpts)((opts = {}) => cshakePers(new sha3_js_1.Keccak(blockLen, suffix, chooseLen(opts, outputLen), true), opts)); -+exports.cshake128 = (() => gencShake(0x1f, 168, 128 / 8))(); -+exports.cshake256 = (() => gencShake(0x1f, 136, 256 / 8))(); -+class KMAC extends sha3_js_1.Keccak { -+ constructor(blockLen, outputLen, enableXOF, key, opts = {}) { -+ super(blockLen, 0x1f, outputLen, enableXOF); -+ cshakePers(this, { NISTfn: 'KMAC', personalization: opts.personalization }); -+ key = (0, utils_js_1.toBytes)(key); -+ // 1. newX = bytepad(encode_string(K), 168) || X || right_encode(L). -+ const blockLenBytes = leftEncode(this.blockLen); -+ const keyLen = leftEncode(8 * key.length); -+ this.update(blockLenBytes).update(keyLen).update(key); -+ const totalLen = blockLenBytes.length + keyLen.length + key.length; -+ this.update(getPadding(totalLen, this.blockLen)); -+ } -+ finish() { -+ if (!this.finished) -+ this.update(rightEncode(this.enableXOF ? 0 : this.outputLen * 8)); // outputLen in bits -+ super.finish(); -+ } -+ _cloneInto(to) { -+ // Create new instance without calling constructor since key already in state and we don't know it. -+ // Force "to" to be instance of KMAC instead of Sha3. -+ if (!to) { -+ to = Object.create(Object.getPrototypeOf(this), {}); -+ to.state = this.state.slice(); -+ to.blockLen = this.blockLen; -+ to.state32 = (0, utils_js_1.u32)(to.state); -+ } -+ return super._cloneInto(to); -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+exports.KMAC = KMAC; -+function genKmac(blockLen, outputLen, xof = false) { -+ const kmac = (key, message, opts) => kmac.create(key, opts).update(message).digest(); -+ kmac.create = (key, opts = {}) => new KMAC(blockLen, chooseLen(opts, outputLen), xof, key, opts); -+ return kmac; -+} -+exports.kmac128 = (() => genKmac(168, 128 / 8))(); -+exports.kmac256 = (() => genKmac(136, 256 / 8))(); -+exports.kmac128xof = (() => genKmac(168, 128 / 8, true))(); -+exports.kmac256xof = (() => genKmac(136, 256 / 8, true))(); -+// TupleHash -+// Usage: tuple(['ab', 'cd']) != tuple(['a', 'bcd']) -+class TupleHash extends sha3_js_1.Keccak { -+ constructor(blockLen, outputLen, enableXOF, opts = {}) { -+ super(blockLen, 0x1f, outputLen, enableXOF); -+ cshakePers(this, { NISTfn: 'TupleHash', personalization: opts.personalization }); -+ // Change update after cshake processed -+ this.update = (data) => { -+ data = (0, utils_js_1.toBytes)(data); -+ super.update(leftEncode(data.length * 8)); -+ super.update(data); -+ return this; -+ }; -+ } -+ finish() { -+ if (!this.finished) -+ super.update(rightEncode(this.enableXOF ? 0 : this.outputLen * 8)); // outputLen in bits -+ super.finish(); -+ } -+ _cloneInto(to) { -+ to || (to = new TupleHash(this.blockLen, this.outputLen, this.enableXOF)); -+ return super._cloneInto(to); -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+exports.TupleHash = TupleHash; -+function genTuple(blockLen, outputLen, xof = false) { -+ const tuple = (messages, opts) => { -+ const h = tuple.create(opts); -+ for (const msg of messages) -+ h.update(msg); -+ return h.digest(); -+ }; -+ tuple.create = (opts = {}) => new TupleHash(blockLen, chooseLen(opts, outputLen), xof, opts); -+ return tuple; -+} -+exports.tuplehash128 = (() => genTuple(168, 128 / 8))(); -+exports.tuplehash256 = (() => genTuple(136, 256 / 8))(); -+exports.tuplehash128xof = (() => genTuple(168, 128 / 8, true))(); -+exports.tuplehash256xof = (() => genTuple(136, 256 / 8, true))(); -+class ParallelHash extends sha3_js_1.Keccak { -+ constructor(blockLen, outputLen, leafCons, enableXOF, opts = {}) { -+ super(blockLen, 0x1f, outputLen, enableXOF); -+ this.leafCons = leafCons; -+ this.chunkPos = 0; // Position of current block in chunk -+ this.chunksDone = 0; // How many chunks we already have -+ cshakePers(this, { NISTfn: 'ParallelHash', personalization: opts.personalization }); -+ let { blockLen: B } = opts; -+ B || (B = 8); -+ (0, _assert_js_1.number)(B); -+ this.chunkLen = B; -+ super.update(leftEncode(B)); -+ // Change update after cshake processed -+ this.update = (data) => { -+ data = (0, utils_js_1.toBytes)(data); -+ const { chunkLen, leafCons } = this; -+ for (let pos = 0, len = data.length; pos < len;) { -+ if (this.chunkPos == chunkLen || !this.leafHash) { -+ if (this.leafHash) { -+ super.update(this.leafHash.digest()); -+ this.chunksDone++; -+ } -+ this.leafHash = leafCons(); -+ this.chunkPos = 0; -+ } -+ const take = Math.min(chunkLen - this.chunkPos, len - pos); -+ this.leafHash.update(data.subarray(pos, pos + take)); -+ this.chunkPos += take; -+ pos += take; -+ } -+ return this; -+ }; -+ } -+ finish() { -+ if (this.finished) -+ return; -+ if (this.leafHash) { -+ super.update(this.leafHash.digest()); -+ this.chunksDone++; -+ } -+ super.update(rightEncode(this.chunksDone)); -+ super.update(rightEncode(this.enableXOF ? 0 : this.outputLen * 8)); // outputLen in bits -+ super.finish(); -+ } -+ _cloneInto(to) { -+ to || (to = new ParallelHash(this.blockLen, this.outputLen, this.leafCons, this.enableXOF)); -+ if (this.leafHash) -+ to.leafHash = this.leafHash._cloneInto(to.leafHash); -+ to.chunkPos = this.chunkPos; -+ to.chunkLen = this.chunkLen; -+ to.chunksDone = this.chunksDone; -+ return super._cloneInto(to); -+ } -+ destroy() { -+ super.destroy.call(this); -+ if (this.leafHash) -+ this.leafHash.destroy(); -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+exports.ParallelHash = ParallelHash; -+function genPrl(blockLen, outputLen, leaf, xof = false) { -+ const parallel = (message, opts) => parallel.create(opts).update(message).digest(); -+ parallel.create = (opts = {}) => new ParallelHash(blockLen, chooseLen(opts, outputLen), () => leaf.create({ dkLen: 2 * outputLen }), xof, opts); -+ return parallel; -+} -+exports.parallelhash128 = (() => genPrl(168, 128 / 8, exports.cshake128))(); -+exports.parallelhash256 = (() => genPrl(136, 256 / 8, exports.cshake256))(); -+exports.parallelhash128xof = (() => genPrl(168, 128 / 8, exports.cshake128, true))(); -+exports.parallelhash256xof = (() => genPrl(136, 256 / 8, exports.cshake256, true))(); -+const genTurboshake = (blockLen, outputLen) => (0, utils_js_1.wrapXOFConstructorWithOpts)((opts = {}) => { -+ const D = opts.D === undefined ? 0x1f : opts.D; -+ // Section 2.1 of https://datatracker.ietf.org/doc/draft-irtf-cfrg-kangarootwelve/ -+ if (!Number.isSafeInteger(D) || D < 0x01 || D > 0x7f) -+ throw new Error(`turboshake: wrong domain separation byte: ${D}, should be 0x01..0x7f`); -+ return new sha3_js_1.Keccak(blockLen, D, opts.dkLen === undefined ? outputLen : opts.dkLen, true, 12); -+}); -+exports.turboshake128 = genTurboshake(168, 256 / 8); -+exports.turboshake256 = genTurboshake(136, 512 / 8); -+// Kangaroo -+// Same as NIST rightEncode, but returns [0] for zero string -+function rightEncodeK12(n) { -+ const res = []; -+ for (; n > 0; n >>= 8) -+ res.unshift(n & 0xff); -+ res.push(res.length); -+ return new Uint8Array(res); -+} -+const EMPTY = new Uint8Array([]); -+class KangarooTwelve extends sha3_js_1.Keccak { -+ constructor(blockLen, leafLen, outputLen, rounds, opts) { -+ super(blockLen, 0x07, outputLen, true, rounds); -+ this.leafLen = leafLen; -+ this.chunkLen = 8192; -+ this.chunkPos = 0; // Position of current block in chunk -+ this.chunksDone = 0; // How many chunks we already have -+ const { personalization } = opts; -+ this.personalization = toBytesOptional(personalization); -+ } -+ update(data) { -+ data = (0, utils_js_1.toBytes)(data); -+ const { chunkLen, blockLen, leafLen, rounds } = this; -+ for (let pos = 0, len = data.length; pos < len;) { -+ if (this.chunkPos == chunkLen) { -+ if (this.leafHash) -+ super.update(this.leafHash.digest()); -+ else { -+ this.suffix = 0x06; // Its safe to change suffix here since its used only in digest() -+ super.update(new Uint8Array([3, 0, 0, 0, 0, 0, 0, 0])); -+ } -+ this.leafHash = new sha3_js_1.Keccak(blockLen, 0x0b, leafLen, false, rounds); -+ this.chunksDone++; -+ this.chunkPos = 0; -+ } -+ const take = Math.min(chunkLen - this.chunkPos, len - pos); -+ const chunk = data.subarray(pos, pos + take); -+ if (this.leafHash) -+ this.leafHash.update(chunk); -+ else -+ super.update(chunk); -+ this.chunkPos += take; -+ pos += take; -+ } -+ return this; -+ } -+ finish() { -+ if (this.finished) -+ return; -+ const { personalization } = this; -+ this.update(personalization).update(rightEncodeK12(personalization.length)); -+ // Leaf hash -+ if (this.leafHash) { -+ super.update(this.leafHash.digest()); -+ super.update(rightEncodeK12(this.chunksDone)); -+ super.update(new Uint8Array([0xff, 0xff])); -+ } -+ super.finish.call(this); -+ } -+ destroy() { -+ super.destroy.call(this); -+ if (this.leafHash) -+ this.leafHash.destroy(); -+ // We cannot zero personalization buffer since it is user provided and we don't want to mutate user input -+ this.personalization = EMPTY; -+ } -+ _cloneInto(to) { -+ const { blockLen, leafLen, leafHash, outputLen, rounds } = this; -+ to || (to = new KangarooTwelve(blockLen, leafLen, outputLen, rounds, {})); -+ super._cloneInto(to); -+ if (leafHash) -+ to.leafHash = leafHash._cloneInto(to.leafHash); -+ to.personalization.set(this.personalization); -+ to.leafLen = this.leafLen; -+ to.chunkPos = this.chunkPos; -+ to.chunksDone = this.chunksDone; -+ return to; -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+exports.KangarooTwelve = KangarooTwelve; -+// Default to 32 bytes, so it can be used without opts -+exports.k12 = (() => (0, utils_js_1.wrapConstructorWithOpts)((opts = {}) => new KangarooTwelve(168, 32, chooseLen(opts, 32), 12, opts)))(); -+// MarsupilamiFourteen -+exports.m14 = (() => (0, utils_js_1.wrapConstructorWithOpts)((opts = {}) => new KangarooTwelve(136, 64, chooseLen(opts, 64), 14, opts)))(); -+// https://keccak.team/files/CSF-0.1.pdf -+// + https://github.com/XKCP/XKCP/tree/master/lib/high/Keccak/PRG -+class KeccakPRG extends sha3_js_1.Keccak { -+ constructor(capacity) { -+ (0, _assert_js_1.number)(capacity); -+ // Rho should be full bytes -+ if (capacity < 0 || capacity > 1600 - 10 || (1600 - capacity - 2) % 8) -+ throw new Error('KeccakPRG: Invalid capacity'); -+ // blockLen = rho in bytes -+ super((1600 - capacity - 2) / 8, 0, 0, true); -+ this.rate = 1600 - capacity; -+ this.posOut = Math.floor((this.rate + 7) / 8); -+ } -+ keccak() { -+ // Duplex padding -+ this.state[this.pos] ^= 0x01; -+ this.state[this.blockLen] ^= 0x02; // Rho is full bytes -+ super.keccak(); -+ this.pos = 0; -+ this.posOut = 0; -+ } -+ update(data) { -+ super.update(data); -+ this.posOut = this.blockLen; -+ return this; -+ } -+ feed(data) { -+ return this.update(data); -+ } -+ finish() { } -+ digestInto(_out) { -+ throw new Error('KeccakPRG: digest is not allowed, please use .fetch instead.'); -+ } -+ fetch(bytes) { -+ return this.xof(bytes); -+ } -+ // Ensure irreversibility (even if state leaked previous outputs cannot be computed) -+ forget() { -+ if (this.rate < 1600 / 2 + 1) -+ throw new Error('KeccakPRG: rate too low to use forget'); -+ this.keccak(); -+ for (let i = 0; i < this.blockLen; i++) -+ this.state[i] = 0; -+ this.pos = this.blockLen; -+ this.keccak(); -+ this.posOut = this.blockLen; -+ } -+ _cloneInto(to) { -+ const { rate } = this; -+ to || (to = new KeccakPRG(1600 - rate)); -+ super._cloneInto(to); -+ to.rate = rate; -+ return to; -+ } -+ clone() { -+ return this._cloneInto(); -+ } -+} -+exports.KeccakPRG = KeccakPRG; -+const keccakprg = (capacity = 254) => new KeccakPRG(capacity); -+exports.keccakprg = keccakprg; -+//# sourceMappingURL=sha3-addons.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.js.map -new file mode 100644 -index 0000000..589e3e5 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3-addons.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha3-addons.js","sourceRoot":"","sources":["src/sha3-addons.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.d.ts -new file mode 100644 -index 0000000..82b88a8 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.d.ts -@@ -0,0 +1,98 @@ -+import { Hash, Input, HashXOF } from './utils.js'; -+export declare function keccakP(s: Uint32Array, rounds?: number): void; -+export declare class Keccak extends Hash implements HashXOF { -+ blockLen: number; -+ suffix: number; -+ outputLen: number; -+ protected enableXOF: boolean; -+ protected rounds: number; -+ protected state: Uint8Array; -+ protected pos: number; -+ protected posOut: number; -+ protected finished: boolean; -+ protected state32: Uint32Array; -+ protected destroyed: boolean; -+ constructor(blockLen: number, suffix: number, outputLen: number, enableXOF?: boolean, rounds?: number); -+ protected keccak(): void; -+ update(data: Input): this; -+ protected finish(): void; -+ protected writeInto(out: Uint8Array): Uint8Array; -+ xofInto(out: Uint8Array): Uint8Array; -+ xof(bytes: number): Uint8Array; -+ digestInto(out: Uint8Array): Uint8Array; -+ digest(): Uint8Array; -+ destroy(): void; -+ _cloneInto(to?: Keccak): Keccak; -+} -+export declare const sha3_224: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+/** -+ * SHA3-256 hash function -+ * @param message - that would be hashed -+ */ -+export declare const sha3_256: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const sha3_384: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const sha3_512: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const keccak_224: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+/** -+ * keccak-256 hash function. Different from SHA3-256. -+ * @param message - that would be hashed -+ */ -+export declare const keccak_256: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const keccak_384: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare const keccak_512: { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export type ShakeOpts = { -+ dkLen?: number; -+}; -+export declare const shake128: { -+ (msg: Input, opts?: ShakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: ShakeOpts): HashXOF>; -+}; -+export declare const shake256: { -+ (msg: Input, opts?: ShakeOpts | undefined): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: ShakeOpts): HashXOF>; -+}; -+//# sourceMappingURL=sha3.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.d.ts.map -new file mode 100644 -index 0000000..3644f6e ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha3.d.ts","sourceRoot":"","sources":["src/sha3.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,IAAI,EAEJ,KAAK,EAIL,OAAO,EAGR,MAAM,YAAY,CAAC;AAoCpB,wBAAgB,OAAO,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,GAAE,MAAW,QAyC1D;AAED,qBAAa,MAAO,SAAQ,IAAI,CAAC,MAAM,CAAE,YAAW,OAAO,CAAC,MAAM,CAAC;IASxD,QAAQ,EAAE,MAAM;IAChB,MAAM,EAAE,MAAM;IACd,SAAS,EAAE,MAAM;IACxB,SAAS,CAAC,SAAS;IACnB,SAAS,CAAC,MAAM,EAAE,MAAM;IAZ1B,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC;IAC5B,SAAS,CAAC,GAAG,SAAK;IAClB,SAAS,CAAC,MAAM,SAAK;IACrB,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC;IAC/B,SAAS,CAAC,SAAS,UAAS;gBAGnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACd,SAAS,UAAQ,EACjB,MAAM,GAAE,MAAW;IAW/B,SAAS,CAAC,MAAM;IAOhB,MAAM,CAAC,IAAI,EAAE,KAAK;IAYlB,SAAS,CAAC,MAAM;IAUhB,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU;IAehD,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU;IAKpC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;IAI9B,UAAU,CAAC,GAAG,EAAE,UAAU;IAO1B,MAAM;IAGN,OAAO;IAIP,UAAU,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;CAehC;AAKD,eAAO,MAAM,QAAQ;;;;;CAA0C,CAAC;AAChE;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;CAA0C,CAAC;AAChE,eAAO,MAAM,QAAQ;;;;;CAA0C,CAAC;AAChE,eAAO,MAAM,QAAQ;;;;;CAAyC,CAAC;AAC/D,eAAO,MAAM,UAAU;;;;;CAA0C,CAAC;AAClE;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;CAA0C,CAAC;AAClE,eAAO,MAAM,UAAU;;;;;CAA0C,CAAC;AAClE,eAAO,MAAM,UAAU;;;;;CAAyC,CAAC;AAEjE,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAQ3C,eAAO,MAAM,QAAQ;;;;;CAA+C,CAAC;AACrE,eAAO,MAAM,QAAQ;;;;;CAA+C,CAAC"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.js -new file mode 100644 -index 0000000..cb0b719 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.js -@@ -0,0 +1,219 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.shake256 = exports.shake128 = exports.keccak_512 = exports.keccak_384 = exports.keccak_256 = exports.keccak_224 = exports.sha3_512 = exports.sha3_384 = exports.sha3_256 = exports.sha3_224 = exports.Keccak = void 0; -+exports.keccakP = keccakP; -+const _assert_js_1 = require("./_assert.js"); -+const _u64_js_1 = require("./_u64.js"); -+const utils_js_1 = require("./utils.js"); -+// SHA3 (keccak) is based on a new design: basically, the internal state is bigger than output size. -+// It's called a sponge function. -+// Various per round constants calculations -+const SHA3_PI = []; -+const SHA3_ROTL = []; -+const _SHA3_IOTA = []; -+const _0n = /* @__PURE__ */ BigInt(0); -+const _1n = /* @__PURE__ */ BigInt(1); -+const _2n = /* @__PURE__ */ BigInt(2); -+const _7n = /* @__PURE__ */ BigInt(7); -+const _256n = /* @__PURE__ */ BigInt(256); -+const _0x71n = /* @__PURE__ */ BigInt(0x71); -+for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) { -+ // Pi -+ [x, y] = [y, (2 * x + 3 * y) % 5]; -+ SHA3_PI.push(2 * (5 * y + x)); -+ // Rotational -+ SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64); -+ // Iota -+ let t = _0n; -+ for (let j = 0; j < 7; j++) { -+ R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n; -+ if (R & _2n) -+ t ^= _1n << ((_1n << /* @__PURE__ */ BigInt(j)) - _1n); -+ } -+ _SHA3_IOTA.push(t); -+} -+const [SHA3_IOTA_H, SHA3_IOTA_L] = /* @__PURE__ */ (0, _u64_js_1.split)(_SHA3_IOTA, true); -+// Left rotation (without 0, 32, 64) -+const rotlH = (h, l, s) => (s > 32 ? (0, _u64_js_1.rotlBH)(h, l, s) : (0, _u64_js_1.rotlSH)(h, l, s)); -+const rotlL = (h, l, s) => (s > 32 ? (0, _u64_js_1.rotlBL)(h, l, s) : (0, _u64_js_1.rotlSL)(h, l, s)); -+// Same as keccakf1600, but allows to skip some rounds -+function keccakP(s, rounds = 24) { -+ const B = new Uint32Array(5 * 2); -+ // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js) -+ for (let round = 24 - rounds; round < 24; round++) { -+ // Theta θ -+ for (let x = 0; x < 10; x++) -+ B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40]; -+ for (let x = 0; x < 10; x += 2) { -+ const idx1 = (x + 8) % 10; -+ const idx0 = (x + 2) % 10; -+ const B0 = B[idx0]; -+ const B1 = B[idx0 + 1]; -+ const Th = rotlH(B0, B1, 1) ^ B[idx1]; -+ const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1]; -+ for (let y = 0; y < 50; y += 10) { -+ s[x + y] ^= Th; -+ s[x + y + 1] ^= Tl; -+ } -+ } -+ // Rho (ρ) and Pi (π) -+ let curH = s[2]; -+ let curL = s[3]; -+ for (let t = 0; t < 24; t++) { -+ const shift = SHA3_ROTL[t]; -+ const Th = rotlH(curH, curL, shift); -+ const Tl = rotlL(curH, curL, shift); -+ const PI = SHA3_PI[t]; -+ curH = s[PI]; -+ curL = s[PI + 1]; -+ s[PI] = Th; -+ s[PI + 1] = Tl; -+ } -+ // Chi (χ) -+ for (let y = 0; y < 50; y += 10) { -+ for (let x = 0; x < 10; x++) -+ B[x] = s[y + x]; -+ for (let x = 0; x < 10; x++) -+ s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10]; -+ } -+ // Iota (ι) -+ s[0] ^= SHA3_IOTA_H[round]; -+ s[1] ^= SHA3_IOTA_L[round]; -+ } -+ B.fill(0); -+} -+class Keccak extends utils_js_1.Hash { -+ // NOTE: we accept arguments in bytes instead of bits here. -+ constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) { -+ super(); -+ this.blockLen = blockLen; -+ this.suffix = suffix; -+ this.outputLen = outputLen; -+ this.enableXOF = enableXOF; -+ this.rounds = rounds; -+ this.pos = 0; -+ this.posOut = 0; -+ this.finished = false; -+ this.destroyed = false; -+ // Can be passed from user as dkLen -+ (0, _assert_js_1.number)(outputLen); -+ // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes -+ if (0 >= this.blockLen || this.blockLen >= 200) -+ throw new Error('Sha3 supports only keccak-f1600 function'); -+ this.state = new Uint8Array(200); -+ this.state32 = (0, utils_js_1.u32)(this.state); -+ } -+ keccak() { -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(this.state32); -+ keccakP(this.state32, this.rounds); -+ if (!utils_js_1.isLE) -+ (0, utils_js_1.byteSwap32)(this.state32); -+ this.posOut = 0; -+ this.pos = 0; -+ } -+ update(data) { -+ (0, _assert_js_1.exists)(this); -+ const { blockLen, state } = this; -+ data = (0, utils_js_1.toBytes)(data); -+ const len = data.length; -+ for (let pos = 0; pos < len;) { -+ const take = Math.min(blockLen - this.pos, len - pos); -+ for (let i = 0; i < take; i++) -+ state[this.pos++] ^= data[pos++]; -+ if (this.pos === blockLen) -+ this.keccak(); -+ } -+ return this; -+ } -+ finish() { -+ if (this.finished) -+ return; -+ this.finished = true; -+ const { state, suffix, pos, blockLen } = this; -+ // Do the padding -+ state[pos] ^= suffix; -+ if ((suffix & 0x80) !== 0 && pos === blockLen - 1) -+ this.keccak(); -+ state[blockLen - 1] ^= 0x80; -+ this.keccak(); -+ } -+ writeInto(out) { -+ (0, _assert_js_1.exists)(this, false); -+ (0, _assert_js_1.bytes)(out); -+ this.finish(); -+ const bufferOut = this.state; -+ const { blockLen } = this; -+ for (let pos = 0, len = out.length; pos < len;) { -+ if (this.posOut >= blockLen) -+ this.keccak(); -+ const take = Math.min(blockLen - this.posOut, len - pos); -+ out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); -+ this.posOut += take; -+ pos += take; -+ } -+ return out; -+ } -+ xofInto(out) { -+ // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF -+ if (!this.enableXOF) -+ throw new Error('XOF is not possible for this instance'); -+ return this.writeInto(out); -+ } -+ xof(bytes) { -+ (0, _assert_js_1.number)(bytes); -+ return this.xofInto(new Uint8Array(bytes)); -+ } -+ digestInto(out) { -+ (0, _assert_js_1.output)(out, this); -+ if (this.finished) -+ throw new Error('digest() was already called'); -+ this.writeInto(out); -+ this.destroy(); -+ return out; -+ } -+ digest() { -+ return this.digestInto(new Uint8Array(this.outputLen)); -+ } -+ destroy() { -+ this.destroyed = true; -+ this.state.fill(0); -+ } -+ _cloneInto(to) { -+ const { blockLen, suffix, outputLen, rounds, enableXOF } = this; -+ to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds)); -+ to.state32.set(this.state32); -+ to.pos = this.pos; -+ to.posOut = this.posOut; -+ to.finished = this.finished; -+ to.rounds = rounds; -+ // Suffix can change in cSHAKE -+ to.suffix = suffix; -+ to.outputLen = outputLen; -+ to.enableXOF = enableXOF; -+ to.destroyed = this.destroyed; -+ return to; -+ } -+} -+exports.Keccak = Keccak; -+const gen = (suffix, blockLen, outputLen) => (0, utils_js_1.wrapConstructor)(() => new Keccak(blockLen, suffix, outputLen)); -+exports.sha3_224 = gen(0x06, 144, 224 / 8); -+/** -+ * SHA3-256 hash function -+ * @param message - that would be hashed -+ */ -+exports.sha3_256 = gen(0x06, 136, 256 / 8); -+exports.sha3_384 = gen(0x06, 104, 384 / 8); -+exports.sha3_512 = gen(0x06, 72, 512 / 8); -+exports.keccak_224 = gen(0x01, 144, 224 / 8); -+/** -+ * keccak-256 hash function. Different from SHA3-256. -+ * @param message - that would be hashed -+ */ -+exports.keccak_256 = gen(0x01, 136, 256 / 8); -+exports.keccak_384 = gen(0x01, 104, 384 / 8); -+exports.keccak_512 = gen(0x01, 72, 512 / 8); -+const genShake = (suffix, blockLen, outputLen) => (0, utils_js_1.wrapXOFConstructorWithOpts)((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true)); -+exports.shake128 = genShake(0x1f, 168, 128 / 8); -+exports.shake256 = genShake(0x1f, 136, 256 / 8); -+//# sourceMappingURL=sha3.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.js.map -new file mode 100644 -index 0000000..1dc4d71 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha3.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha3.js","sourceRoot":"","sources":["src/sha3.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.d.ts -new file mode 100644 -index 0000000..2282d2b ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.d.ts -@@ -0,0 +1,124 @@ -+import { HashMD } from './_md.js'; -+export declare class SHA512 extends HashMD { -+ Ah: number; -+ Al: number; -+ Bh: number; -+ Bl: number; -+ Ch: number; -+ Cl: number; -+ Dh: number; -+ Dl: number; -+ Eh: number; -+ El: number; -+ Fh: number; -+ Fl: number; -+ Gh: number; -+ Gl: number; -+ Hh: number; -+ Hl: number; -+ constructor(); -+ protected get(): [ -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number, -+ number -+ ]; -+ protected set(Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number, Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number): void; -+ protected process(view: DataView, offset: number): void; -+ protected roundClean(): void; -+ destroy(): void; -+} -+export declare class SHA512_224 extends SHA512 { -+ Ah: number; -+ Al: number; -+ Bh: number; -+ Bl: number; -+ Ch: number; -+ Cl: number; -+ Dh: number; -+ Dl: number; -+ Eh: number; -+ El: number; -+ Fh: number; -+ Fl: number; -+ Gh: number; -+ Gl: number; -+ Hh: number; -+ Hl: number; -+ constructor(); -+} -+export declare class SHA512_256 extends SHA512 { -+ Ah: number; -+ Al: number; -+ Bh: number; -+ Bl: number; -+ Ch: number; -+ Cl: number; -+ Dh: number; -+ Dl: number; -+ Eh: number; -+ El: number; -+ Fh: number; -+ Fl: number; -+ Gh: number; -+ Gl: number; -+ Hh: number; -+ Hl: number; -+ constructor(); -+} -+export declare class SHA384 extends SHA512 { -+ Ah: number; -+ Al: number; -+ Bh: number; -+ Bl: number; -+ Ch: number; -+ Cl: number; -+ Dh: number; -+ Dl: number; -+ Eh: number; -+ El: number; -+ Fh: number; -+ Fl: number; -+ Gh: number; -+ Gl: number; -+ Hh: number; -+ Hl: number; -+ constructor(); -+} -+export declare const sha512: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+export declare const sha512_224: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+export declare const sha512_256: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+export declare const sha384: { -+ (msg: import("./utils.js").Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): import("./utils.js").Hash; -+}; -+//# sourceMappingURL=sha512.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.d.ts.map -new file mode 100644 -index 0000000..efa0211 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha512.d.ts","sourceRoot":"","sources":["src/sha512.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.js -new file mode 100644 -index 0000000..a793ba6 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.js -@@ -0,0 +1,238 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.sha384 = exports.sha512_256 = exports.sha512_224 = exports.sha512 = exports.SHA384 = exports.SHA512_256 = exports.SHA512_224 = exports.SHA512 = void 0; -+const _md_js_1 = require("./_md.js"); -+const _u64_js_1 = require("./_u64.js"); -+const utils_js_1 = require("./utils.js"); -+// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409): -+// prettier-ignore -+const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => _u64_js_1.default.split([ -+ '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc', -+ '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118', -+ '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2', -+ '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694', -+ '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65', -+ '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5', -+ '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4', -+ '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70', -+ '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df', -+ '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b', -+ '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30', -+ '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8', -+ '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8', -+ '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3', -+ '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec', -+ '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b', -+ '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178', -+ '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b', -+ '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c', -+ '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817' -+].map(n => BigInt(n))))(); -+// Temporary buffer, not used to store anything between runs -+const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80); -+const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80); -+class SHA512 extends _md_js_1.HashMD { -+ constructor() { -+ super(128, 64, 16, false); -+ // We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers. -+ // Also looks cleaner and easier to verify with spec. -+ // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19): -+ // h -- high 32 bits, l -- low 32 bits -+ this.Ah = 0x6a09e667 | 0; -+ this.Al = 0xf3bcc908 | 0; -+ this.Bh = 0xbb67ae85 | 0; -+ this.Bl = 0x84caa73b | 0; -+ this.Ch = 0x3c6ef372 | 0; -+ this.Cl = 0xfe94f82b | 0; -+ this.Dh = 0xa54ff53a | 0; -+ this.Dl = 0x5f1d36f1 | 0; -+ this.Eh = 0x510e527f | 0; -+ this.El = 0xade682d1 | 0; -+ this.Fh = 0x9b05688c | 0; -+ this.Fl = 0x2b3e6c1f | 0; -+ this.Gh = 0x1f83d9ab | 0; -+ this.Gl = 0xfb41bd6b | 0; -+ this.Hh = 0x5be0cd19 | 0; -+ this.Hl = 0x137e2179 | 0; -+ } -+ // prettier-ignore -+ get() { -+ const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; -+ return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl]; -+ } -+ // prettier-ignore -+ set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) { -+ this.Ah = Ah | 0; -+ this.Al = Al | 0; -+ this.Bh = Bh | 0; -+ this.Bl = Bl | 0; -+ this.Ch = Ch | 0; -+ this.Cl = Cl | 0; -+ this.Dh = Dh | 0; -+ this.Dl = Dl | 0; -+ this.Eh = Eh | 0; -+ this.El = El | 0; -+ this.Fh = Fh | 0; -+ this.Fl = Fl | 0; -+ this.Gh = Gh | 0; -+ this.Gl = Gl | 0; -+ this.Hh = Hh | 0; -+ this.Hl = Hl | 0; -+ } -+ process(view, offset) { -+ // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array -+ for (let i = 0; i < 16; i++, offset += 4) { -+ SHA512_W_H[i] = view.getUint32(offset); -+ SHA512_W_L[i] = view.getUint32((offset += 4)); -+ } -+ for (let i = 16; i < 80; i++) { -+ // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7) -+ const W15h = SHA512_W_H[i - 15] | 0; -+ const W15l = SHA512_W_L[i - 15] | 0; -+ const s0h = _u64_js_1.default.rotrSH(W15h, W15l, 1) ^ _u64_js_1.default.rotrSH(W15h, W15l, 8) ^ _u64_js_1.default.shrSH(W15h, W15l, 7); -+ const s0l = _u64_js_1.default.rotrSL(W15h, W15l, 1) ^ _u64_js_1.default.rotrSL(W15h, W15l, 8) ^ _u64_js_1.default.shrSL(W15h, W15l, 7); -+ // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6) -+ const W2h = SHA512_W_H[i - 2] | 0; -+ const W2l = SHA512_W_L[i - 2] | 0; -+ const s1h = _u64_js_1.default.rotrSH(W2h, W2l, 19) ^ _u64_js_1.default.rotrBH(W2h, W2l, 61) ^ _u64_js_1.default.shrSH(W2h, W2l, 6); -+ const s1l = _u64_js_1.default.rotrSL(W2h, W2l, 19) ^ _u64_js_1.default.rotrBL(W2h, W2l, 61) ^ _u64_js_1.default.shrSL(W2h, W2l, 6); -+ // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16]; -+ const SUMl = _u64_js_1.default.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]); -+ const SUMh = _u64_js_1.default.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]); -+ SHA512_W_H[i] = SUMh | 0; -+ SHA512_W_L[i] = SUMl | 0; -+ } -+ let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; -+ // Compression function main loop, 80 rounds -+ for (let i = 0; i < 80; i++) { -+ // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41) -+ const sigma1h = _u64_js_1.default.rotrSH(Eh, El, 14) ^ _u64_js_1.default.rotrSH(Eh, El, 18) ^ _u64_js_1.default.rotrBH(Eh, El, 41); -+ const sigma1l = _u64_js_1.default.rotrSL(Eh, El, 14) ^ _u64_js_1.default.rotrSL(Eh, El, 18) ^ _u64_js_1.default.rotrBL(Eh, El, 41); -+ //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; -+ const CHIh = (Eh & Fh) ^ (~Eh & Gh); -+ const CHIl = (El & Fl) ^ (~El & Gl); -+ // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i] -+ // prettier-ignore -+ const T1ll = _u64_js_1.default.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]); -+ const T1h = _u64_js_1.default.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]); -+ const T1l = T1ll | 0; -+ // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39) -+ const sigma0h = _u64_js_1.default.rotrSH(Ah, Al, 28) ^ _u64_js_1.default.rotrBH(Ah, Al, 34) ^ _u64_js_1.default.rotrBH(Ah, Al, 39); -+ const sigma0l = _u64_js_1.default.rotrSL(Ah, Al, 28) ^ _u64_js_1.default.rotrBL(Ah, Al, 34) ^ _u64_js_1.default.rotrBL(Ah, Al, 39); -+ const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch); -+ const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl); -+ Hh = Gh | 0; -+ Hl = Gl | 0; -+ Gh = Fh | 0; -+ Gl = Fl | 0; -+ Fh = Eh | 0; -+ Fl = El | 0; -+ ({ h: Eh, l: El } = _u64_js_1.default.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0)); -+ Dh = Ch | 0; -+ Dl = Cl | 0; -+ Ch = Bh | 0; -+ Cl = Bl | 0; -+ Bh = Ah | 0; -+ Bl = Al | 0; -+ const All = _u64_js_1.default.add3L(T1l, sigma0l, MAJl); -+ Ah = _u64_js_1.default.add3H(All, T1h, sigma0h, MAJh); -+ Al = All | 0; -+ } -+ // Add the compressed chunk to the current hash value -+ ({ h: Ah, l: Al } = _u64_js_1.default.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0)); -+ ({ h: Bh, l: Bl } = _u64_js_1.default.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0)); -+ ({ h: Ch, l: Cl } = _u64_js_1.default.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0)); -+ ({ h: Dh, l: Dl } = _u64_js_1.default.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0)); -+ ({ h: Eh, l: El } = _u64_js_1.default.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0)); -+ ({ h: Fh, l: Fl } = _u64_js_1.default.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0)); -+ ({ h: Gh, l: Gl } = _u64_js_1.default.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0)); -+ ({ h: Hh, l: Hl } = _u64_js_1.default.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0)); -+ this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl); -+ } -+ roundClean() { -+ SHA512_W_H.fill(0); -+ SHA512_W_L.fill(0); -+ } -+ destroy() { -+ this.buffer.fill(0); -+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -+ } -+} -+exports.SHA512 = SHA512; -+class SHA512_224 extends SHA512 { -+ constructor() { -+ super(); -+ // h -- high 32 bits, l -- low 32 bits -+ this.Ah = 0x8c3d37c8 | 0; -+ this.Al = 0x19544da2 | 0; -+ this.Bh = 0x73e19966 | 0; -+ this.Bl = 0x89dcd4d6 | 0; -+ this.Ch = 0x1dfab7ae | 0; -+ this.Cl = 0x32ff9c82 | 0; -+ this.Dh = 0x679dd514 | 0; -+ this.Dl = 0x582f9fcf | 0; -+ this.Eh = 0x0f6d2b69 | 0; -+ this.El = 0x7bd44da8 | 0; -+ this.Fh = 0x77e36f73 | 0; -+ this.Fl = 0x04c48942 | 0; -+ this.Gh = 0x3f9d85a8 | 0; -+ this.Gl = 0x6a1d36c8 | 0; -+ this.Hh = 0x1112e6ad | 0; -+ this.Hl = 0x91d692a1 | 0; -+ this.outputLen = 28; -+ } -+} -+exports.SHA512_224 = SHA512_224; -+class SHA512_256 extends SHA512 { -+ constructor() { -+ super(); -+ // h -- high 32 bits, l -- low 32 bits -+ this.Ah = 0x22312194 | 0; -+ this.Al = 0xfc2bf72c | 0; -+ this.Bh = 0x9f555fa3 | 0; -+ this.Bl = 0xc84c64c2 | 0; -+ this.Ch = 0x2393b86b | 0; -+ this.Cl = 0x6f53b151 | 0; -+ this.Dh = 0x96387719 | 0; -+ this.Dl = 0x5940eabd | 0; -+ this.Eh = 0x96283ee2 | 0; -+ this.El = 0xa88effe3 | 0; -+ this.Fh = 0xbe5e1e25 | 0; -+ this.Fl = 0x53863992 | 0; -+ this.Gh = 0x2b0199fc | 0; -+ this.Gl = 0x2c85b8aa | 0; -+ this.Hh = 0x0eb72ddc | 0; -+ this.Hl = 0x81c52ca2 | 0; -+ this.outputLen = 32; -+ } -+} -+exports.SHA512_256 = SHA512_256; -+class SHA384 extends SHA512 { -+ constructor() { -+ super(); -+ // h -- high 32 bits, l -- low 32 bits -+ this.Ah = 0xcbbb9d5d | 0; -+ this.Al = 0xc1059ed8 | 0; -+ this.Bh = 0x629a292a | 0; -+ this.Bl = 0x367cd507 | 0; -+ this.Ch = 0x9159015a | 0; -+ this.Cl = 0x3070dd17 | 0; -+ this.Dh = 0x152fecd8 | 0; -+ this.Dl = 0xf70e5939 | 0; -+ this.Eh = 0x67332667 | 0; -+ this.El = 0xffc00b31 | 0; -+ this.Fh = 0x8eb44a87 | 0; -+ this.Fl = 0x68581511 | 0; -+ this.Gh = 0xdb0c2e0d | 0; -+ this.Gl = 0x64f98fa7 | 0; -+ this.Hh = 0x47b5481d | 0; -+ this.Hl = 0xbefa4fa4 | 0; -+ this.outputLen = 48; -+ } -+} -+exports.SHA384 = SHA384; -+exports.sha512 = (0, utils_js_1.wrapConstructor)(() => new SHA512()); -+exports.sha512_224 = (0, utils_js_1.wrapConstructor)(() => new SHA512_224()); -+exports.sha512_256 = (0, utils_js_1.wrapConstructor)(() => new SHA512_256()); -+exports.sha384 = (0, utils_js_1.wrapConstructor)(() => new SHA384()); -+//# sourceMappingURL=sha512.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.js.map -new file mode 100644 -index 0000000..7836e7c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/sha512.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"sha512.js","sourceRoot":"","sources":["src/sha512.ts"],"names":[],"mappings":"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AAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,iBAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,iBAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,iBAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,iBAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,iBAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3E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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.d.ts b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.d.ts -new file mode 100644 -index 0000000..21254c4 ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.d.ts -@@ -0,0 +1,96 @@ -+/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ -+export declare function isBytes(a: unknown): a is Uint8Array; -+export type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array | Uint16Array | Int16Array | Uint32Array | Int32Array; -+export declare const u8: (arr: TypedArray) => Uint8Array; -+export declare const u32: (arr: TypedArray) => Uint32Array; -+export declare const createView: (arr: TypedArray) => DataView; -+export declare const rotr: (word: number, shift: number) => number; -+export declare const rotl: (word: number, shift: number) => number; -+export declare const isLE: boolean; -+export declare const byteSwap: (word: number) => number; -+export declare const byteSwapIfBE: (n: number) => number; -+export declare function byteSwap32(arr: Uint32Array): void; -+/** -+ * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123' -+ */ -+export declare function bytesToHex(bytes: Uint8Array): string; -+/** -+ * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) -+ */ -+export declare function hexToBytes(hex: string): Uint8Array; -+export declare const nextTick: () => Promise; -+export declare function asyncLoop(iters: number, tick: number, cb: (i: number) => void): Promise; -+/** -+ * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99]) -+ */ -+export declare function utf8ToBytes(str: string): Uint8Array; -+export type Input = Uint8Array | string; -+/** -+ * Normalizes (non-hex) string or Uint8Array to Uint8Array. -+ * Warning: when Uint8Array is passed, it would NOT get copied. -+ * Keep in mind for future mutable operations. -+ */ -+export declare function toBytes(data: Input): Uint8Array; -+/** -+ * Copies several Uint8Arrays into one. -+ */ -+export declare function concatBytes(...arrays: Uint8Array[]): Uint8Array; -+export declare abstract class Hash> { -+ abstract blockLen: number; -+ abstract outputLen: number; -+ abstract update(buf: Input): this; -+ abstract digestInto(buf: Uint8Array): void; -+ abstract digest(): Uint8Array; -+ /** -+ * Resets internal state. Makes Hash instance unusable. -+ * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed -+ * by user, they will need to manually call `destroy()` when zeroing is necessary. -+ */ -+ abstract destroy(): void; -+ /** -+ * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()` -+ * when no options are passed. -+ * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal -+ * buffers are overwritten => causes buffer overwrite which is used for digest in some cases. -+ * There are no guarantees for clean-up because it's impossible in JS. -+ */ -+ abstract _cloneInto(to?: T): T; -+ clone(): T; -+} -+/** -+ * XOF: streaming API to read digest in chunks. -+ * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name. -+ * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot -+ * destroy state, next call can require more bytes. -+ */ -+export type HashXOF> = Hash & { -+ xof(bytes: number): Uint8Array; -+ xofInto(buf: Uint8Array): Uint8Array; -+}; -+type EmptyObj = {}; -+export declare function checkOpts(defaults: T1, opts?: T2): T1 & T2; -+export type CHash = ReturnType; -+export declare function wrapConstructor>(hashCons: () => Hash): { -+ (msg: Input): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(): Hash; -+}; -+export declare function wrapConstructorWithOpts, T extends Object>(hashCons: (opts?: T) => Hash): { -+ (msg: Input, opts?: T): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: T): Hash; -+}; -+export declare function wrapXOFConstructorWithOpts, T extends Object>(hashCons: (opts?: T) => HashXOF): { -+ (msg: Input, opts?: T): Uint8Array; -+ outputLen: number; -+ blockLen: number; -+ create(opts: T): HashXOF; -+}; -+/** -+ * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS. -+ */ -+export declare function randomBytes(bytesLength?: number): Uint8Array; -+export {}; -+//# sourceMappingURL=utils.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.d.ts.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.d.ts.map -new file mode 100644 -index 0000000..ce9133c ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.js b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.js -new file mode 100644 -index 0000000..19078da ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.js -@@ -0,0 +1,211 @@ -+"use strict"; -+/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.Hash = exports.nextTick = exports.byteSwapIfBE = exports.byteSwap = exports.isLE = exports.rotl = exports.rotr = exports.createView = exports.u32 = exports.u8 = void 0; -+exports.isBytes = isBytes; -+exports.byteSwap32 = byteSwap32; -+exports.bytesToHex = bytesToHex; -+exports.hexToBytes = hexToBytes; -+exports.asyncLoop = asyncLoop; -+exports.utf8ToBytes = utf8ToBytes; -+exports.toBytes = toBytes; -+exports.concatBytes = concatBytes; -+exports.checkOpts = checkOpts; -+exports.wrapConstructor = wrapConstructor; -+exports.wrapConstructorWithOpts = wrapConstructorWithOpts; -+exports.wrapXOFConstructorWithOpts = wrapXOFConstructorWithOpts; -+exports.randomBytes = randomBytes; -+// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. -+// node.js versions earlier than v19 don't declare it in global scope. -+// For node.js, package.json#exports field mapping rewrites import -+// from `crypto` to `cryptoNode`, which imports native module. -+// Makes the utils un-importable in browsers without a bundler. -+// Once node.js 18 is deprecated (2025-04-30), we can just drop the import. -+const crypto_1 = require("@noble/hashes/crypto"); -+const _assert_js_1 = require("./_assert.js"); -+// export { isBytes } from './_assert.js'; -+// We can't reuse isBytes from _assert, because somehow this causes huge perf issues -+function isBytes(a) { -+ return (a instanceof Uint8Array || -+ (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array')); -+} -+// Cast array to different type -+const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength); -+exports.u8 = u8; -+const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4)); -+exports.u32 = u32; -+// Cast array to view -+const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength); -+exports.createView = createView; -+// The rotate right (circular right shift) operation for uint32 -+const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift); -+exports.rotr = rotr; -+// The rotate left (circular left shift) operation for uint32 -+const rotl = (word, shift) => (word << shift) | ((word >>> (32 - shift)) >>> 0); -+exports.rotl = rotl; -+exports.isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44; -+// The byte swap operation for uint32 -+const byteSwap = (word) => ((word << 24) & 0xff000000) | -+ ((word << 8) & 0xff0000) | -+ ((word >>> 8) & 0xff00) | -+ ((word >>> 24) & 0xff); -+exports.byteSwap = byteSwap; -+// Conditionally byte swap if on a big-endian platform -+exports.byteSwapIfBE = exports.isLE ? (n) => n : (n) => (0, exports.byteSwap)(n); -+// In place byte swap for Uint32Array -+function byteSwap32(arr) { -+ for (let i = 0; i < arr.length; i++) { -+ arr[i] = (0, exports.byteSwap)(arr[i]); -+ } -+} -+// Array where index 0xf0 (240) is mapped to string 'f0' -+const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0')); -+/** -+ * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123' -+ */ -+function bytesToHex(bytes) { -+ (0, _assert_js_1.bytes)(bytes); -+ // pre-caching improves the speed 6x -+ let hex = ''; -+ for (let i = 0; i < bytes.length; i++) { -+ hex += hexes[bytes[i]]; -+ } -+ return hex; -+} -+// We use optimized technique to convert hex string to byte array -+const asciis = { _0: 48, _9: 57, _A: 65, _F: 70, _a: 97, _f: 102 }; -+function asciiToBase16(char) { -+ if (char >= asciis._0 && char <= asciis._9) -+ return char - asciis._0; -+ if (char >= asciis._A && char <= asciis._F) -+ return char - (asciis._A - 10); -+ if (char >= asciis._a && char <= asciis._f) -+ return char - (asciis._a - 10); -+ return; -+} -+/** -+ * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) -+ */ -+function hexToBytes(hex) { -+ if (typeof hex !== 'string') -+ throw new Error('hex string expected, got ' + typeof hex); -+ const hl = hex.length; -+ const al = hl / 2; -+ if (hl % 2) -+ throw new Error('padded hex string expected, got unpadded hex of length ' + hl); -+ const array = new Uint8Array(al); -+ for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) { -+ const n1 = asciiToBase16(hex.charCodeAt(hi)); -+ const n2 = asciiToBase16(hex.charCodeAt(hi + 1)); -+ if (n1 === undefined || n2 === undefined) { -+ const char = hex[hi] + hex[hi + 1]; -+ throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi); -+ } -+ array[ai] = n1 * 16 + n2; -+ } -+ return array; -+} -+// There is no setImmediate in browser and setTimeout is slow. -+// call of async fn will return Promise, which will be fullfiled only on -+// next scheduler queue processing step and this is exactly what we need. -+const nextTick = async () => { }; -+exports.nextTick = nextTick; -+// Returns control to thread each 'tick' ms to avoid blocking -+async function asyncLoop(iters, tick, cb) { -+ let ts = Date.now(); -+ for (let i = 0; i < iters; i++) { -+ cb(i); -+ // Date.now() is not monotonic, so in case if clock goes backwards we return return control too -+ const diff = Date.now() - ts; -+ if (diff >= 0 && diff < tick) -+ continue; -+ await (0, exports.nextTick)(); -+ ts += diff; -+ } -+} -+/** -+ * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99]) -+ */ -+function utf8ToBytes(str) { -+ if (typeof str !== 'string') -+ throw new Error(`utf8ToBytes expected string, got ${typeof str}`); -+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809 -+} -+/** -+ * Normalizes (non-hex) string or Uint8Array to Uint8Array. -+ * Warning: when Uint8Array is passed, it would NOT get copied. -+ * Keep in mind for future mutable operations. -+ */ -+function toBytes(data) { -+ if (typeof data === 'string') -+ data = utf8ToBytes(data); -+ (0, _assert_js_1.bytes)(data); -+ return data; -+} -+/** -+ * Copies several Uint8Arrays into one. -+ */ -+function concatBytes(...arrays) { -+ let sum = 0; -+ for (let i = 0; i < arrays.length; i++) { -+ const a = arrays[i]; -+ (0, _assert_js_1.bytes)(a); -+ sum += a.length; -+ } -+ const res = new Uint8Array(sum); -+ for (let i = 0, pad = 0; i < arrays.length; i++) { -+ const a = arrays[i]; -+ res.set(a, pad); -+ pad += a.length; -+ } -+ return res; -+} -+// For runtime check if class implements interface -+class Hash { -+ // Safe version that clones internal state -+ clone() { -+ return this._cloneInto(); -+ } -+} -+exports.Hash = Hash; -+const toStr = {}.toString; -+function checkOpts(defaults, opts) { -+ if (opts !== undefined && toStr.call(opts) !== '[object Object]') -+ throw new Error('Options should be object or undefined'); -+ const merged = Object.assign(defaults, opts); -+ return merged; -+} -+function wrapConstructor(hashCons) { -+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest(); -+ const tmp = hashCons(); -+ hashC.outputLen = tmp.outputLen; -+ hashC.blockLen = tmp.blockLen; -+ hashC.create = () => hashCons(); -+ return hashC; -+} -+function wrapConstructorWithOpts(hashCons) { -+ const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest(); -+ const tmp = hashCons({}); -+ hashC.outputLen = tmp.outputLen; -+ hashC.blockLen = tmp.blockLen; -+ hashC.create = (opts) => hashCons(opts); -+ return hashC; -+} -+function wrapXOFConstructorWithOpts(hashCons) { -+ const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest(); -+ const tmp = hashCons({}); -+ hashC.outputLen = tmp.outputLen; -+ hashC.blockLen = tmp.blockLen; -+ hashC.create = (opts) => hashCons(opts); -+ return hashC; -+} -+/** -+ * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS. -+ */ -+function randomBytes(bytesLength = 32) { -+ if (crypto_1.crypto && typeof crypto_1.crypto.getRandomValues === 'function') { -+ return crypto_1.crypto.getRandomValues(new Uint8Array(bytesLength)); -+ } -+ throw new Error('crypto.getRandomValues must be defined'); -+} -+//# sourceMappingURL=utils.js.map -\ No newline at end of file -diff --git a/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.js.map b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.js.map -new file mode 100644 -index 0000000..27240de ---- /dev/null -+++ b/node_modules/@agoric/orchestration/node_modules/@noble/hashes/utils.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"utils.js","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"} -\ No newline at end of file diff --git a/patches/@cosmology+telescope+1.7.1.patch b/patches/@cosmology+telescope+1.7.1.patch deleted file mode 100644 index dcc4a034512..00000000000 --- a/patches/@cosmology+telescope+1.7.1.patch +++ /dev/null @@ -1,1005 +0,0 @@ -diff --git a/node_modules/@cosmology/telescope/main/helpers/internal-for-bigint.js b/node_modules/@cosmology/telescope/main/helpers/internal-for-bigint.js -index 950827a..9e9214c 100644 ---- a/node_modules/@cosmology/telescope/main/helpers/internal-for-bigint.js -+++ b/node_modules/@cosmology/telescope/main/helpers/internal-for-bigint.js -@@ -5,41 +5,11 @@ const getHelperForBigint = (options) => { - return `${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? `import { Dec } from "@keplr-wallet/unit"; - - ` : ""} --declare var self: any | undefined; --declare var window: any | undefined; --declare var global: any | undefined; --var globalThis: any = (() => { -- if (typeof globalThis !== 'undefined') return globalThis; -- if (typeof self !== 'undefined') return self; -- if (typeof window !== 'undefined') return window; -- if (typeof global !== 'undefined') return global; -- throw 'Unable to locate global object'; --})(); -- --const atob: (b64: string) => string = -- globalThis.atob || -- ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); -- --export function bytesFromBase64(b64: string): Uint8Array { -- const bin = atob(b64); -- const arr = new Uint8Array(bin.length); -- for (let i = 0; i < bin.length; ++i) { -- arr[i] = bin.charCodeAt(i); -- } -- return arr; --} -- --const btoa: (bin: string) => string = -- globalThis.btoa || -- ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); -+import { encodeBase64, decodeBase64 } from '@endo/base64'; - --export function base64FromBytes(arr: Uint8Array): string { -- const bin: string[] = []; -- arr.forEach((byte) => { -- bin.push(String.fromCharCode(byte)); -- }); -- return btoa(bin.join('')); --} -+// use Endo for broader compatibility -+export const bytesFromBase64: (input: string) => Uint8Array = decodeBase64; -+export const base64FromBytes: (input: Uint8Array) => string = encodeBase64; - - export interface AminoHeight { - readonly revision_number?: string; -@@ -252,6 +222,88 @@ export function fromJsonTimestamp(o: any): Timestamp { - function numberToLong(number: number) { - return BigInt(Math.trunc(number)); - } -+ -+// 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. -+ * -+ * Instances of this class are immutable. -+ */ -+export class Decimal { -+ public static fromUserInput( -+ input: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ -+ const badCharacter = input.match(/[^0-9.]/); -+ if (badCharacter) { -+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -+ throw new Error( -+ \`Invalid character at position \${badCharacter.index! + 1}\`, -+ ); -+ } -+ -+ let whole: string; -+ let fractional: string; -+ -+ if (input === '') { -+ whole = '0'; -+ fractional = ''; -+ } else if (input.search(/\./) === -1) { -+ // integer format, no separator -+ whole = input; -+ fractional = ''; -+ } else { -+ const parts = input.split('.'); -+ switch (parts.length) { -+ case 0: -+ case 1: -+ throw new Error( -+ 'Fewer than two elements in split result. This must not happen here.', -+ ); -+ case 2: -+ if (!parts[1]) throw new Error('Fractional part missing'); -+ whole = parts[0]; -+ fractional = parts[1].replace(/0+$/, ''); -+ break; -+ default: -+ throw new Error('More than one separator found'); -+ } -+ } -+ -+ if (fractional.length > fractionalDigits) { -+ throw new Error('Got more fractional digits than supported'); -+ } -+ -+ const quantity = \`\${whole}\${fractional.padEnd(fractionalDigits, '0')}\`; -+ -+ return new Decimal(quantity, fractionalDigits); -+ } -+ -+ public static fromAtomics( -+ atomics: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ return new Decimal(atomics, fractionalDigits); -+ } -+ -+ private static verifyFractionalDigits(fractionalDigits: number): void { -+ if (!Number.isInteger(fractionalDigits)) -+ throw new Error('Fractional digits is not an integer'); -+ if (fractionalDigits < 0) -+ throw new Error('Fractional digits must not be negative'); -+ if (fractionalDigits > maxFractionalDigits) { -+ throw new Error( -+ \`Fractional digits must not exceed \${maxFractionalDigits}\`, -+ ); -+ } -+ } -+} -+ - ${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? - ` - export function padDecimal(decStr: string): string{ -diff --git a/node_modules/@cosmology/telescope/main/helpers/internal.js b/node_modules/@cosmology/telescope/main/helpers/internal.js -index b27664f..5cf4c6a 100644 ---- a/node_modules/@cosmology/telescope/main/helpers/internal.js -+++ b/node_modules/@cosmology/telescope/main/helpers/internal.js -@@ -5,6 +5,8 @@ const getHelper = (options) => { - return `import * as _m0 from "protobufjs/minimal"; - import Long from 'long';${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? ` - import { Dec } from "@keplr-wallet/unit"; -+import { encodeBase64, decodeBase64 } from '@endo/base64'; -+ - ` : ""} - - // @ts-ignore -@@ -16,39 +18,9 @@ if (_m0.util.Long !== Long) { - - export { Long }; - --declare var self: any | undefined; --declare var window: any | undefined; --declare var global: any | undefined; --var globalThis: any = (() => { -- if (typeof globalThis !== 'undefined') return globalThis; -- if (typeof self !== 'undefined') return self; -- if (typeof window !== 'undefined') return window; -- if (typeof global !== 'undefined') return global; -- throw 'Unable to locate global object'; --})(); -- --const atob: (b64: string) => string = -- globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); -- --export function bytesFromBase64(b64: string): Uint8Array { -- const bin = atob(b64); -- const arr = new Uint8Array(bin.length); -- for (let i = 0; i < bin.length; ++i) { -- arr[i] = bin.charCodeAt(i); -- } -- return arr; --} -- --const btoa: (bin: string) => string = -- globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); -- --export function base64FromBytes(arr: Uint8Array): string { -- const bin: string[] = []; -- arr.forEach((byte) => { -- bin.push(String.fromCharCode(byte)); -- }); -- return btoa(bin.join('')); --} -+// use Endo for broader compatibility -+export const bytesFromBase64: (input: string) => Uint8Array = decodeBase64; -+export const base64FromBytes: (input: Uint8Array) => string = encodeBase64; - - export interface AminoHeight { - readonly revision_number?: string; -@@ -236,7 +208,91 @@ export function fromJsonTimestamp(o: any): Timestamp { - - function numberToLong(number: number) { - return Long.fromNumber(number); --}${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? ` -+} -+ -+ -+// 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. -+ * -+ * Instances of this class are immutable. -+ */ -+export class Decimal { -+ public static fromUserInput( -+ input: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ -+ const badCharacter = input.match(/[^0-9.]/); -+ if (badCharacter) { -+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -+ throw new Error( -+ \`Invalid character at position \${badCharacter.index! + 1}\`, -+ ); -+ } -+ -+ let whole: string; -+ let fractional: string; -+ -+ if (input === '') { -+ whole = '0'; -+ fractional = ''; -+ } else if (input.search(/\./) === -1) { -+ // integer format, no separator -+ whole = input; -+ fractional = ''; -+ } else { -+ const parts = input.split('.'); -+ switch (parts.length) { -+ case 0: -+ case 1: -+ throw new Error( -+ 'Fewer than two elements in split result. This must not happen here.', -+ ); -+ case 2: -+ if (!parts[1]) throw new Error('Fractional part missing'); -+ whole = parts[0]; -+ fractional = parts[1].replace(/0+$/, ''); -+ break; -+ default: -+ throw new Error('More than one separator found'); -+ } -+ } -+ -+ if (fractional.length > fractionalDigits) { -+ throw new Error('Got more fractional digits than supported'); -+ } -+ -+ const quantity = \`\${whole}\${fractional.padEnd(fractionalDigits, '0')}\`; -+ -+ return new Decimal(quantity, fractionalDigits); -+ } -+ -+ public static fromAtomics( -+ atomics: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ return new Decimal(atomics, fractionalDigits); -+ } -+ -+ private static verifyFractionalDigits(fractionalDigits: number): void { -+ if (!Number.isInteger(fractionalDigits)) -+ throw new Error('Fractional digits is not an integer'); -+ if (fractionalDigits < 0) -+ throw new Error('Fractional digits must not be negative'); -+ if (fractionalDigits > maxFractionalDigits) { -+ throw new Error( -+ \`Fractional digits must not exceed \${maxFractionalDigits}\`, -+ ); -+ } -+ } -+} -+ -+${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? ` - - export function padDecimal(decStr: string): string{ - return decStr ? new Dec(decStr).toString() : decStr; -diff --git a/node_modules/@cosmology/telescope/main/helpers/internalForBigInt.js b/node_modules/@cosmology/telescope/main/helpers/internalForBigInt.js -index 07b6e47..87c78db 100644 ---- a/node_modules/@cosmology/telescope/main/helpers/internalForBigInt.js -+++ b/node_modules/@cosmology/telescope/main/helpers/internalForBigInt.js -@@ -2,41 +2,11 @@ - Object.defineProperty(exports, "__esModule", { value: true }); - exports.internalForBigInt = void 0; - exports.internalForBigInt = ` --declare var self: any | undefined; --declare var window: any | undefined; --declare var global: any | undefined; --var globalThis: any = (() => { -- if (typeof globalThis !== 'undefined') return globalThis; -- if (typeof self !== 'undefined') return self; -- if (typeof window !== 'undefined') return window; -- if (typeof global !== 'undefined') return global; -- throw 'Unable to locate global object'; --})(); -- --const atob: (b64: string) => string = -- globalThis.atob || -- ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); -- --export function bytesFromBase64(b64: string): Uint8Array { -- const bin = atob(b64); -- const arr = new Uint8Array(bin.length); -- for (let i = 0; i < bin.length; ++i) { -- arr[i] = bin.charCodeAt(i); -- } -- return arr; --} -+import { encodeBase64, decodeBase64 } from '@endo/base64'; - --const btoa: (bin: string) => string = -- globalThis.btoa || -- ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); -- --export function base64FromBytes(arr: Uint8Array): string { -- const bin: string[] = []; -- arr.forEach((byte) => { -- bin.push(String.fromCharCode(byte)); -- }); -- return btoa(bin.join('')); --} -+// use Endo for broader compatibility -+export const bytesFromBase64: (input: string) => Uint8Array = decodeBase64; -+export const base64FromBytes: (input: Uint8Array) => string = encodeBase64; - - export interface AminoHeight { - readonly revision_number?: string; -diff --git a/node_modules/@cosmology/telescope/main/utils/index.js b/node_modules/@cosmology/telescope/main/utils/index.js -index 998db7f..3301179 100644 ---- a/node_modules/@cosmology/telescope/main/utils/index.js -+++ b/node_modules/@cosmology/telescope/main/utils/index.js -@@ -36,7 +36,7 @@ exports.UTILS = { - bytesFromBase64: '__helpers__', - BrowserHeaders: 'browser-headers', - connectComet: '@cosmjs/tendermint-rpc', -- Decimal: '@cosmjs/math', -+ Decimal: '__helpers__', - padDecimal: '__helpers__', - createProtobufRpcClient: '@cosmjs/stargate', - Pubkey: '@cosmjs/amino', -diff --git a/node_modules/@cosmology/telescope/module/helpers/internal-for-bigint.js b/node_modules/@cosmology/telescope/module/helpers/internal-for-bigint.js -index 1d19b1c..5a9ec29 100644 ---- a/node_modules/@cosmology/telescope/module/helpers/internal-for-bigint.js -+++ b/node_modules/@cosmology/telescope/module/helpers/internal-for-bigint.js -@@ -2,41 +2,11 @@ export const getHelperForBigint = (options) => { - return `${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? `import { Dec } from "@keplr-wallet/unit"; - - ` : ""} --declare var self: any | undefined; --declare var window: any | undefined; --declare var global: any | undefined; --var globalThis: any = (() => { -- if (typeof globalThis !== 'undefined') return globalThis; -- if (typeof self !== 'undefined') return self; -- if (typeof window !== 'undefined') return window; -- if (typeof global !== 'undefined') return global; -- throw 'Unable to locate global object'; --})(); -- --const atob: (b64: string) => string = -- globalThis.atob || -- ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); -- --export function bytesFromBase64(b64: string): Uint8Array { -- const bin = atob(b64); -- const arr = new Uint8Array(bin.length); -- for (let i = 0; i < bin.length; ++i) { -- arr[i] = bin.charCodeAt(i); -- } -- return arr; --} -+import { encodeBase64, decodeBase64 } from '@endo/base64'; - --const btoa: (bin: string) => string = -- globalThis.btoa || -- ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); -- --export function base64FromBytes(arr: Uint8Array): string { -- const bin: string[] = []; -- arr.forEach((byte) => { -- bin.push(String.fromCharCode(byte)); -- }); -- return btoa(bin.join('')); --} -+// use Endo for broader compatibility -+export const bytesFromBase64: (input: string) => Uint8Array = decodeBase64; -+export const base64FromBytes: (input: Uint8Array) => string = encodeBase64; - - export interface AminoHeight { - readonly revision_number?: string; -@@ -249,11 +219,95 @@ export function fromJsonTimestamp(o: any): Timestamp { - function numberToLong(number: number) { - return BigInt(Math.trunc(number)); - } -+ -+ -+// 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. -+ * -+ * Instances of this class are immutable. -+ */ -+export class Decimal { -+ public static fromUserInput( -+ input: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ -+ const badCharacter = input.match(/[^0-9.]/); -+ if (badCharacter) { -+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -+ throw new Error( -+ \`Invalid character at position \${badCharacter.index! + 1}\`, -+ ); -+ } -+ -+ let whole: string; -+ let fractional: string; -+ -+ if (input === '') { -+ whole = '0'; -+ fractional = ''; -+ } else if (input.search(/\./) === -1) { -+ // integer format, no separator -+ whole = input; -+ fractional = ''; -+ } else { -+ const parts = input.split('.'); -+ switch (parts.length) { -+ case 0: -+ case 1: -+ throw new Error( -+ 'Fewer than two elements in split result. This must not happen here.', -+ ); -+ case 2: -+ if (!parts[1]) throw new Error('Fractional part missing'); -+ whole = parts[0]; -+ fractional = parts[1].replace(/0+$/, ''); -+ break; -+ default: -+ throw new Error('More than one separator found'); -+ } -+ } -+ -+ if (fractional.length > fractionalDigits) { -+ throw new Error('Got more fractional digits than supported'); -+ } -+ -+ const quantity = \`\${whole}\${fractional.padEnd(fractionalDigits, '0')}\`; -+ -+ return new Decimal(quantity, fractionalDigits); -+ } -+ -+ public static fromAtomics( -+ atomics: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ return new Decimal(atomics, fractionalDigits); -+ } -+ -+ private static verifyFractionalDigits(fractionalDigits: number): void { -+ if (!Number.isInteger(fractionalDigits)) -+ throw new Error('Fractional digits is not an integer'); -+ if (fractionalDigits < 0) -+ throw new Error('Fractional digits must not be negative'); -+ if (fractionalDigits > maxFractionalDigits) { -+ throw new Error( -+ \`Fractional digits must not exceed \${maxFractionalDigits}\`, -+ ); -+ } -+ } -+} -+ - ${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? - ` - export function padDecimal(decStr: string): string{ - return decStr ? new Dec(decStr).toString() : decStr; - } -+ - ` : ""} - `; - }; -diff --git a/node_modules/@cosmology/telescope/module/helpers/internal.js b/node_modules/@cosmology/telescope/module/helpers/internal.js -index 28e50cf..c713941 100644 ---- a/node_modules/@cosmology/telescope/module/helpers/internal.js -+++ b/node_modules/@cosmology/telescope/module/helpers/internal.js -@@ -2,6 +2,7 @@ export const getHelper = (options) => { - return `import * as _m0 from "protobufjs/minimal"; - import Long from 'long';${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? ` - import { Dec } from "@keplr-wallet/unit"; -+import { encodeBase64, decodeBase64 } from '@endo/base64'; - ` : ""} - - // @ts-ignore -@@ -13,39 +14,9 @@ if (_m0.util.Long !== Long) { - - export { Long }; - --declare var self: any | undefined; --declare var window: any | undefined; --declare var global: any | undefined; --var globalThis: any = (() => { -- if (typeof globalThis !== 'undefined') return globalThis; -- if (typeof self !== 'undefined') return self; -- if (typeof window !== 'undefined') return window; -- if (typeof global !== 'undefined') return global; -- throw 'Unable to locate global object'; --})(); -- --const atob: (b64: string) => string = -- globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); -- --export function bytesFromBase64(b64: string): Uint8Array { -- const bin = atob(b64); -- const arr = new Uint8Array(bin.length); -- for (let i = 0; i < bin.length; ++i) { -- arr[i] = bin.charCodeAt(i); -- } -- return arr; --} -- --const btoa: (bin: string) => string = -- globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); -- --export function base64FromBytes(arr: Uint8Array): string { -- const bin: string[] = []; -- arr.forEach((byte) => { -- bin.push(String.fromCharCode(byte)); -- }); -- return btoa(bin.join('')); --} -+// use Endo for broader compatibility -+export const bytesFromBase64: (input: string) => Uint8Array = decodeBase64; -+export const base64FromBytes: (input: Uint8Array) => string = encodeBase64; - - export interface AminoHeight { - readonly revision_number?: string; -@@ -231,6 +202,87 @@ export function fromJsonTimestamp(o: any): Timestamp { - } - } - -+// 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. -+ * -+ * Instances of this class are immutable. -+ */ -+export class Decimal { -+ public static fromUserInput( -+ input: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ -+ const badCharacter = input.match(/[^0-9.]/); -+ if (badCharacter) { -+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -+ throw new Error( -+ \`Invalid character at position \${badCharacter.index! + 1}\`, -+ ); -+ } -+ -+ let whole: string; -+ let fractional: string; -+ -+ if (input === '') { -+ whole = '0'; -+ fractional = ''; -+ } else if (input.search(/\./) === -1) { -+ // integer format, no separator -+ whole = input; -+ fractional = ''; -+ } else { -+ const parts = input.split('.'); -+ switch (parts.length) { -+ case 0: -+ case 1: -+ throw new Error( -+ 'Fewer than two elements in split result. This must not happen here.', -+ ); -+ case 2: -+ if (!parts[1]) throw new Error('Fractional part missing'); -+ whole = parts[0]; -+ fractional = parts[1].replace(/0+$/, ''); -+ break; -+ default: -+ throw new Error('More than one separator found'); -+ } -+ } -+ -+ if (fractional.length > fractionalDigits) { -+ throw new Error('Got more fractional digits than supported'); -+ } -+ -+ const quantity = \`\${whole}\${fractional.padEnd(fractionalDigits, '0')}\`; -+ -+ return new Decimal(quantity, fractionalDigits); -+ } -+ -+ public static fromAtomics( -+ atomics: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ return new Decimal(atomics, fractionalDigits); -+ } -+ -+ private static verifyFractionalDigits(fractionalDigits: number): void { -+ if (!Number.isInteger(fractionalDigits)) -+ throw new Error('Fractional digits is not an integer'); -+ if (fractionalDigits < 0) -+ throw new Error('Fractional digits must not be negative'); -+ if (fractionalDigits > maxFractionalDigits) { -+ throw new Error( -+ \`Fractional digits must not exceed \${maxFractionalDigits}\`, -+ ); -+ } -+ } -+} -+ - function numberToLong(number: number) { - return Long.fromNumber(number); - }${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? ` -@@ -238,6 +290,7 @@ function numberToLong(number: number) { - export function padDecimal(decStr: string): string{ - return decStr ? new Dec(decStr).toString() : decStr; - } -+ - ` : ""} - `; - }; -diff --git a/node_modules/@cosmology/telescope/module/helpers/internalForBigInt.js b/node_modules/@cosmology/telescope/module/helpers/internalForBigInt.js -index ecb2e3e..4e96aff 100644 ---- a/node_modules/@cosmology/telescope/module/helpers/internalForBigInt.js -+++ b/node_modules/@cosmology/telescope/module/helpers/internalForBigInt.js -@@ -1,39 +1,9 @@ - export const internalForBigInt = ` --declare var self: any | undefined; --declare var window: any | undefined; --declare var global: any | undefined; --var globalThis: any = (() => { -- if (typeof globalThis !== 'undefined') return globalThis; -- if (typeof self !== 'undefined') return self; -- if (typeof window !== 'undefined') return window; -- if (typeof global !== 'undefined') return global; -- throw 'Unable to locate global object'; --})(); -- --const atob: (b64: string) => string = -- globalThis.atob || -- ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); -- --export function bytesFromBase64(b64: string): Uint8Array { -- const bin = atob(b64); -- const arr = new Uint8Array(bin.length); -- for (let i = 0; i < bin.length; ++i) { -- arr[i] = bin.charCodeAt(i); -- } -- return arr; --} -+import { encodeBase64, decodeBase64 } from '@endo/base64'; - --const btoa: (bin: string) => string = -- globalThis.btoa || -- ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); -- --export function base64FromBytes(arr: Uint8Array): string { -- const bin: string[] = []; -- arr.forEach((byte) => { -- bin.push(String.fromCharCode(byte)); -- }); -- return btoa(bin.join('')); --} -+// use Endo for broader compatibility -+export const bytesFromBase64: (input: string) => Uint8Array = decodeBase64; -+export const base64FromBytes: (input: Uint8Array) => string = encodeBase64; - - export interface AminoHeight { - readonly revision_number?: string; -diff --git a/node_modules/@cosmology/telescope/module/utils/index.js b/node_modules/@cosmology/telescope/module/utils/index.js -index aa561fd..21c4e00 100644 ---- a/node_modules/@cosmology/telescope/module/utils/index.js -+++ b/node_modules/@cosmology/telescope/module/utils/index.js -@@ -18,7 +18,7 @@ export const UTILS = { - bytesFromBase64: '__helpers__', - BrowserHeaders: 'browser-headers', - connectComet: '@cosmjs/tendermint-rpc', -- Decimal: '@cosmjs/math', -+ Decimal: '__helpers__', - padDecimal: '__helpers__', - createProtobufRpcClient: '@cosmjs/stargate', - Pubkey: '@cosmjs/amino', -diff --git a/node_modules/@cosmology/telescope/src/helpers/internal-for-bigint.ts b/node_modules/@cosmology/telescope/src/helpers/internal-for-bigint.ts -index f7daa3d..555ffda 100644 ---- a/node_modules/@cosmology/telescope/src/helpers/internal-for-bigint.ts -+++ b/node_modules/@cosmology/telescope/src/helpers/internal-for-bigint.ts -@@ -4,41 +4,11 @@ export const getHelperForBigint = (options: TelescopeOptions) => { - return `${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? `import { Dec } from "@keplr-wallet/unit"; - - `: ""} --declare var self: any | undefined; --declare var window: any | undefined; --declare var global: any | undefined; --var globalThis: any = (() => { -- if (typeof globalThis !== 'undefined') return globalThis; -- if (typeof self !== 'undefined') return self; -- if (typeof window !== 'undefined') return window; -- if (typeof global !== 'undefined') return global; -- throw 'Unable to locate global object'; --})(); -- --const atob: (b64: string) => string = -- globalThis.atob || -- ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); -- --export function bytesFromBase64(b64: string): Uint8Array { -- const bin = atob(b64); -- const arr = new Uint8Array(bin.length); -- for (let i = 0; i < bin.length; ++i) { -- arr[i] = bin.charCodeAt(i); -- } -- return arr; --} -- --const btoa: (bin: string) => string = -- globalThis.btoa || -- ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); -+import { encodeBase64, decodeBase64 } from '@endo/base64'; - --export function base64FromBytes(arr: Uint8Array): string { -- const bin: string[] = []; -- arr.forEach((byte) => { -- bin.push(String.fromCharCode(byte)); -- }); -- return btoa(bin.join('')); --} -+// use Endo for broader compatibility -+export const bytesFromBase64: (input: string) => Uint8Array = decodeBase64; -+export const base64FromBytes: (input: Uint8Array) => string = encodeBase64; - - export interface AminoHeight { - readonly revision_number?: string; -@@ -251,6 +221,88 @@ export function fromJsonTimestamp(o: any): Timestamp { - function numberToLong(number: number) { - return BigInt(Math.trunc(number)); - } -+ -+// 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. -+ * -+ * Instances of this class are immutable. -+ */ -+export class Decimal { -+ public static fromUserInput( -+ input: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ -+ const badCharacter = input.match(/[^0-9.]/); -+ if (badCharacter) { -+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -+ throw new Error( -+ \`Invalid character at position \${badCharacter.index! + 1}\`, -+ ); -+ } -+ -+ let whole: string; -+ let fractional: string; -+ -+ if (input === '') { -+ whole = '0'; -+ fractional = ''; -+ } else if (input.search(/\./) === -1) { -+ // integer format, no separator -+ whole = input; -+ fractional = ''; -+ } else { -+ const parts = input.split('.'); -+ switch (parts.length) { -+ case 0: -+ case 1: -+ throw new Error( -+ 'Fewer than two elements in split result. This must not happen here.', -+ ); -+ case 2: -+ if (!parts[1]) throw new Error('Fractional part missing'); -+ whole = parts[0]; -+ fractional = parts[1].replace(/0+$/, ''); -+ break; -+ default: -+ throw new Error('More than one separator found'); -+ } -+ } -+ -+ if (fractional.length > fractionalDigits) { -+ throw new Error('Got more fractional digits than supported'); -+ } -+ -+ const quantity = \`\${whole}\${fractional.padEnd(fractionalDigits, '0')}\`; -+ -+ return new Decimal(quantity, fractionalDigits); -+ } -+ -+ public static fromAtomics( -+ atomics: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ return new Decimal(atomics, fractionalDigits); -+ } -+ -+ private static verifyFractionalDigits(fractionalDigits: number): void { -+ if (!Number.isInteger(fractionalDigits)) -+ throw new Error('Fractional digits is not an integer'); -+ if (fractionalDigits < 0) -+ throw new Error('Fractional digits must not be negative'); -+ if (fractionalDigits > maxFractionalDigits) { -+ throw new Error( -+ \`Fractional digits must not exceed \${maxFractionalDigits}\`, -+ ); -+ } -+ } -+} -+ - ${ - options.aminoEncoding?.customTypes?.useCosmosSDKDec ? - ` -diff --git a/node_modules/@cosmology/telescope/src/helpers/internal.ts b/node_modules/@cosmology/telescope/src/helpers/internal.ts -index fc58715..98a1582 100644 ---- a/node_modules/@cosmology/telescope/src/helpers/internal.ts -+++ b/node_modules/@cosmology/telescope/src/helpers/internal.ts -@@ -4,6 +4,8 @@ export const getHelper = (options: TelescopeOptions) => { - return `import * as _m0 from "protobufjs/minimal"; - import Long from 'long';${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? ` - import { Dec } from "@keplr-wallet/unit"; -+import { encodeBase64, decodeBase64 } from '@endo/base64'; -+ - `: ""} - - // @ts-ignore -@@ -15,39 +17,9 @@ if (_m0.util.Long !== Long) { - - export { Long }; - --declare var self: any | undefined; --declare var window: any | undefined; --declare var global: any | undefined; --var globalThis: any = (() => { -- if (typeof globalThis !== 'undefined') return globalThis; -- if (typeof self !== 'undefined') return self; -- if (typeof window !== 'undefined') return window; -- if (typeof global !== 'undefined') return global; -- throw 'Unable to locate global object'; --})(); -- --const atob: (b64: string) => string = -- globalThis.atob || ((b64) => globalThis.Buffer.from(b64, 'base64').toString('binary')); -- --export function bytesFromBase64(b64: string): Uint8Array { -- const bin = atob(b64); -- const arr = new Uint8Array(bin.length); -- for (let i = 0; i < bin.length; ++i) { -- arr[i] = bin.charCodeAt(i); -- } -- return arr; --} -- --const btoa: (bin: string) => string = -- globalThis.btoa || ((bin) => globalThis.Buffer.from(bin, 'binary').toString('base64')); -- --export function base64FromBytes(arr: Uint8Array): string { -- const bin: string[] = []; -- arr.forEach((byte) => { -- bin.push(String.fromCharCode(byte)); -- }); -- return btoa(bin.join('')); --} -+// use Endo for broader compatibility -+export const bytesFromBase64: (input: string) => Uint8Array = decodeBase64; -+export const base64FromBytes: (input: Uint8Array) => string = encodeBase64; - - export interface AminoHeight { - readonly revision_number?: string; -@@ -233,6 +205,87 @@ export function fromJsonTimestamp(o: any): Timestamp { - } - } - -+// 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. -+ * -+ * Instances of this class are immutable. -+ */ -+export class Decimal { -+ public static fromUserInput( -+ input: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ -+ const badCharacter = input.match(/[^0-9.]/); -+ if (badCharacter) { -+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -+ throw new Error( -+ \`Invalid character at position \${badCharacter.index! + 1}\`, -+ ); -+ } -+ -+ let whole: string; -+ let fractional: string; -+ -+ if (input === '') { -+ whole = '0'; -+ fractional = ''; -+ } else if (input.search(/\./) === -1) { -+ // integer format, no separator -+ whole = input; -+ fractional = ''; -+ } else { -+ const parts = input.split('.'); -+ switch (parts.length) { -+ case 0: -+ case 1: -+ throw new Error( -+ 'Fewer than two elements in split result. This must not happen here.', -+ ); -+ case 2: -+ if (!parts[1]) throw new Error('Fractional part missing'); -+ whole = parts[0]; -+ fractional = parts[1].replace(/0+$/, ''); -+ break; -+ default: -+ throw new Error('More than one separator found'); -+ } -+ } -+ -+ if (fractional.length > fractionalDigits) { -+ throw new Error('Got more fractional digits than supported'); -+ } -+ -+ const quantity = \`\${whole}\${fractional.padEnd(fractionalDigits, '0')}\`; -+ -+ return new Decimal(quantity, fractionalDigits); -+ } -+ -+ public static fromAtomics( -+ atomics: string, -+ fractionalDigits: number, -+ ): Decimal { -+ Decimal.verifyFractionalDigits(fractionalDigits); -+ return new Decimal(atomics, fractionalDigits); -+ } -+ -+ private static verifyFractionalDigits(fractionalDigits: number): void { -+ if (!Number.isInteger(fractionalDigits)) -+ throw new Error('Fractional digits is not an integer'); -+ if (fractionalDigits < 0) -+ throw new Error('Fractional digits must not be negative'); -+ if (fractionalDigits > maxFractionalDigits) { -+ throw new Error( -+ \`Fractional digits must not exceed \${maxFractionalDigits}\`, -+ ); -+ } -+ } -+} -+ - function numberToLong(number: number) { - return Long.fromNumber(number); - }${options.aminoEncoding?.customTypes?.useCosmosSDKDec ? ` -diff --git a/node_modules/@cosmology/telescope/src/utils/index.ts b/node_modules/@cosmology/telescope/src/utils/index.ts -index 1ed202f..6d2cc38 100644 ---- a/node_modules/@cosmology/telescope/src/utils/index.ts -+++ b/node_modules/@cosmology/telescope/src/utils/index.ts -@@ -21,7 +21,7 @@ export const UTILS = { - bytesFromBase64: '__helpers__', - BrowserHeaders: 'browser-headers', - connectComet: '@cosmjs/tendermint-rpc', -- Decimal: '@cosmjs/math', -+ Decimal: '__helpers__', - padDecimal: '__helpers__', - createProtobufRpcClient: '@cosmjs/stargate', - Pubkey: '@cosmjs/amino', diff --git a/patches/@endo+lockdown+1.0.7.patch b/patches/@endo+lockdown+1.0.7.patch deleted file mode 100644 index 819e4c9dcac..00000000000 --- a/patches/@endo+lockdown+1.0.7.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/@endo/lockdown/commit-debug.js b/node_modules/@endo/lockdown/commit-debug.js -index 9595aa0..03e02a2 100644 ---- a/node_modules/@endo/lockdown/commit-debug.js -+++ b/node_modules/@endo/lockdown/commit-debug.js -@@ -21,7 +21,7 @@ lockdown({ - // NOTE TO REVIEWERS: If you see the following line commented out, - // this may be a development accident that should be fixed before merging. - // -- errorTaming: 'unsafe', -+ errorTaming: 'unsafe-debug', - - // The default `{stackFiltering: 'concise'}` setting usually makes for a - // better debugging experience, by severely reducing the noisy distractions diff --git a/patches/ses+1.5.0.patch b/patches/ses+1.5.0.patch deleted file mode 100644 index b2c37f96972..00000000000 --- a/patches/ses+1.5.0.patch +++ /dev/null @@ -1,167 +0,0 @@ -diff --git a/node_modules/ses/src/error/tame-error-constructor.js b/node_modules/ses/src/error/tame-error-constructor.js -index 2788c42..db59952 100644 ---- a/node_modules/ses/src/error/tame-error-constructor.js -+++ b/node_modules/ses/src/error/tame-error-constructor.js -@@ -7,6 +7,7 @@ import { - setPrototypeOf, - getOwnPropertyDescriptor, - defineProperty, -+ getOwnPropertyDescriptors, - } from '../commons.js'; - import { NativeErrors } from '../permits.js'; - import { tameV8ErrorConstructor } from './tame-v8-error-constructor.js'; -@@ -29,12 +30,17 @@ const tamedMethods = { - return ''; - }, - }; -+let initialGetStackString = tamedMethods.getStackString; - - export default function tameErrorConstructor( - errorTaming = 'safe', - stackFiltering = 'concise', - ) { -- if (errorTaming !== 'safe' && errorTaming !== 'unsafe') { -+ if ( -+ errorTaming !== 'safe' && -+ errorTaming !== 'unsafe' && -+ errorTaming !== 'unsafe-debug' -+ ) { - throw TypeError(`unrecognized errorTaming ${errorTaming}`); - } - if (stackFiltering !== 'concise' && stackFiltering !== 'verbose') { -@@ -42,9 +48,9 @@ export default function tameErrorConstructor( - } - const ErrorPrototype = FERAL_ERROR.prototype; - -- const platform = -- typeof FERAL_ERROR.captureStackTrace === 'function' ? 'v8' : 'unknown'; - const { captureStackTrace: originalCaptureStackTrace } = FERAL_ERROR; -+ const platform = -+ typeof originalCaptureStackTrace === 'function' ? 'v8' : 'unknown'; - - const makeErrorConstructor = (_ = {}) => { - // eslint-disable-next-line no-shadow -@@ -122,6 +128,45 @@ export default function tameErrorConstructor( - }, - }); - -+ if (errorTaming === 'unsafe-debug' && platform === 'v8') { -+ // This case is a kludge to work around -+ // https://github.com/endojs/endo/issues/1798 -+ // https://github.com/endojs/endo/issues/2348 -+ // https://github.com/Agoric/agoric-sdk/issues/8662 -+ -+ defineProperties(InitialError, { -+ prepareStackTrace: { -+ get() { -+ return FERAL_ERROR.prepareStackTrace; -+ }, -+ set(newPrepareStackTrace) { -+ FERAL_ERROR.prepareStackTrace = newPrepareStackTrace; -+ }, -+ enumerable: false, -+ configurable: true, -+ }, -+ captureStackTrace: { -+ value: FERAL_ERROR.captureStackTrace, -+ writable: true, -+ enumerable: false, -+ configurable: true, -+ }, -+ }); -+ -+ const descs = getOwnPropertyDescriptors(InitialError); -+ defineProperties(SharedError, { -+ stackTraceLimit: descs.stackTraceLimit, -+ prepareStackTrace: descs.prepareStackTrace, -+ captureStackTrace: descs.captureStackTrace, -+ }); -+ -+ return { -+ '%InitialGetStackString%': initialGetStackString, -+ '%InitialError%': InitialError, -+ '%SharedError%': SharedError, -+ }; -+ } -+ - // The default SharedError much be completely powerless even on v8, - // so the lenient `stackTraceLimit` accessor does nothing on all - // platforms. -@@ -171,7 +216,6 @@ export default function tameErrorConstructor( - }); - } - -- let initialGetStackString = tamedMethods.getStackString; - if (platform === 'v8') { - initialGetStackString = tameV8ErrorConstructor( - FERAL_ERROR, -@@ -179,7 +223,7 @@ export default function tameErrorConstructor( - errorTaming, - stackFiltering, - ); -- } else if (errorTaming === 'unsafe') { -+ } else if (errorTaming === 'unsafe' || errorTaming === 'unsafe-debug') { - // v8 has too much magic around their 'stack' own property for it to - // coexist cleanly with this accessor. So only install it on non-v8 - -diff --git a/node_modules/ses/src/lockdown.js b/node_modules/ses/src/lockdown.js -index 107b5d0..dd709e5 100644 ---- a/node_modules/ses/src/lockdown.js -+++ b/node_modules/ses/src/lockdown.js -@@ -58,7 +58,7 @@ import { tameFauxDataProperties } from './tame-faux-data-properties.js'; - - /** @import {LockdownOptions} from '../types.js' */ - --const { Fail, details: d, quote: q } = assert; -+const { Fail, details: X, quote: q } = assert; - - /** @type {Error=} */ - let priorRepairIntrinsics; -@@ -200,7 +200,7 @@ export const repairIntrinsics = (options = {}) => { - priorRepairIntrinsics === undefined || - // eslint-disable-next-line @endo/no-polymorphic-call - assert.fail( -- d`Already locked down at ${priorRepairIntrinsics} (SES_ALREADY_LOCKED_DOWN)`, -+ X`Already locked down at ${priorRepairIntrinsics} (SES_ALREADY_LOCKED_DOWN)`, - TypeError, - ); - // See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_ALREADY_LOCKED_DOWN.md -@@ -298,7 +298,7 @@ export const repairIntrinsics = (options = {}) => { - * @type {((error: any) => string | undefined) | undefined} - */ - let optGetStackString; -- if (errorTaming !== 'unsafe') { -+ if (errorTaming === 'safe') { - optGetStackString = intrinsics['%InitialGetStackString%']; - } - const consoleRecord = tameConsole( -@@ -318,13 +318,17 @@ export const repairIntrinsics = (options = {}) => { - // There doesn't seem to be a cleaner way to reach it. - hostIntrinsics.SafeMap = getPrototypeOf( - // eslint-disable-next-line no-underscore-dangle -- /** @type {any} */ (consoleRecord.console)._times, -+ /** @type {any} */(consoleRecord.console)._times, - ); - } - - // @ts-ignore assert is absent on globalThis type def. -- if (errorTaming === 'unsafe' && globalThis.assert === assert) { -- // If errorTaming is 'unsafe' we replace the global assert with -+ if ( -+ (errorTaming === 'unsafe' || errorTaming === 'unsafe-debug') && -+ globalThis.assert === assert -+ ) { -+ // If errorTaming is 'unsafe' or 'unsafe-debug' we replace the -+ // global assert with - // one whose `details` template literal tag does not redact - // unmarked substitution values. IOW, it blabs information that - // was supposed to be secret from callers, as an aid to debugging -@@ -391,7 +395,7 @@ export const repairIntrinsics = (options = {}) => { - priorHardenIntrinsics === undefined || - // eslint-disable-next-line @endo/no-polymorphic-call - assert.fail( -- d`Already locked down at ${priorHardenIntrinsics} (SES_ALREADY_LOCKED_DOWN)`, -+ X`Already locked down at ${priorHardenIntrinsics} (SES_ALREADY_LOCKED_DOWN)`, - TypeError, - ); - // See https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_ALREADY_LOCKED_DOWN.md diff --git a/scripts/agd-builder.sh b/scripts/agd-builder.sh index 051608e3afd..e467ff8fbfb 100755 --- a/scripts/agd-builder.sh +++ b/scripts/agd-builder.sh @@ -80,6 +80,9 @@ else fi if $need_nodejs; then + export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 + export COREPACK_ENABLE_NETWORK=$($SKIP_DOWNLOAD && echo 0 || echo 1) + # We need to get node at the script top level because it's used by the daemon # as well. case $(node --version 2> /dev/null) in diff --git a/scripts/env-doctor.sh b/scripts/env-doctor.sh new file mode 100755 index 00000000000..6a632be605d --- /dev/null +++ b/scripts/env-doctor.sh @@ -0,0 +1,128 @@ +#!/bin/bash + +set -e + +# Check if running on macOS +if [[ "$(uname)" != "Darwin" ]]; then + echo "Error: This script only works on macOS." + echo "Your current operating system is: $(uname)" + exit 1 +fi + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to run a diagnostic and its remedy +run_diagnostic() { + local description="$1" + local diagnostic="$2" + local remedy_description="$3" + local remedy="$4" + + echo -e "${YELLOW}Diagnostic:${NC} $description" + if eval "$diagnostic"; then + echo -e "${GREEN}✓ Passed${NC}" + else + echo -e "${RED}✗ Failed${NC}" + echo -e "${YELLOW}Remedy:${NC} $remedy_description" + if [[ $AUTO_YES != "true" ]]; then + read -p "Do you want to apply this remedy? (Yes/No/All) " answer + case ${answer:0:1} in + y | Y) ;; + a | A) AUTO_YES=true ;; + *) return ;; + esac + fi + if ! eval "$remedy"; then + echo -e "${RED}Remedy failed. Please seek more help.${NC}" + exit 1 + fi + echo "Remedy applied." + fi + echo +} + +# Diagnostics and remedies +run_diagnostic \ + "Check if fnm is installed" \ + "command -v fnm >/dev/null 2>&1" \ + "Install fnm" \ + "brew install fnm" + +run_diagnostic \ + "Check if Node.js is installed" \ + "command -v node >/dev/null 2>&1" \ + "Install Node.js using fnm" \ + "fnm install --lts && fnm use lts-latest" + +run_diagnostic \ + "Check if Node.js version matches .node-version" \ + "[ \"$(node --version)\" = \"v$(cat .node-version)\" ]" \ + "Install the correct Node.js version using fnm" \ + "fnm install $(cat .node-version) && fnm use $(cat .node-version)" + +run_diagnostic \ + "Check if Yarn version matches package.json" \ + "[ \"$(yarn --version)\" = \"$(node -p "require('./package.json').packageManager.split('@')[1]")\" ]" \ + "Install correct Yarn version" \ + "corepack enable && yarn set version $(node -p "require('./package.json').packageManager.split('@')[1]")" + +run_diagnostic \ + "Check if Git is installed" \ + "command -v git >/dev/null 2>&1" \ + "Install Git" \ + "brew install git" + +run_diagnostic \ + "Check if VSCode is installed" \ + "command -v code >/dev/null 2>&1" \ + "Install Visual Studio Code" \ + "brew install --cask visual-studio-code" + +run_diagnostic \ + "Check if Docker is installed" \ + "command -v docker >/dev/null 2>&1" \ + "Install Docker" \ + "brew install --cask docker" + +run_diagnostic \ + "Build repo" \ + "yarn build" \ + "Clean, reinstall dependencies, and rebuild" \ + "git clean -fdx "**/node_modules" "**/bundles" && yarn install && yarn build" + +# Function to run a recommendation +run_recommendation() { + local description="$1" + local recommendation="$2" + + echo -e "${BLUE}Recommendation:${NC} $description" + if [[ $AUTO_YES != "true" ]]; then + read -p "Do you want to apply this recommendation? (Yes/No/All) " answer + case ${answer:0:1} in + y | Y) ;; + a | A) AUTO_YES=true ;; + *) return ;; + esac + fi + eval "$recommendation" + echo "Recommendation applied." + echo +} + +echo -e "${GREEN}Environment check complete.${NC}" + +# Recommendations +run_recommendation \ + "Configure VS Code with recommended settings" \ + "./scripts/configure-vscode.sh" + +run_recommendation \ + "Run yarn doctor in a3p-integration" \ + "cd a3p-integration && yarn doctor && cd .." + +echo -e "${GREEN}All checks and recommendations complete.${NC}" diff --git a/scripts/gen-github-release.sh b/scripts/gen-github-release.sh index 2a2e1303f20..cf28cc75644 100755 --- a/scripts/gen-github-release.sh +++ b/scripts/gen-github-release.sh @@ -59,7 +59,7 @@ declare -r AWK_REPLACE_PLACEHOLDERS=' BEGIN { for (i = 1; i < ARGC; i++) { arg = ARGV[i]; - if (!match(arg, /^[^/=]+=/)) continue; + if (!match(arg, "^[^/=]+=")) continue; placeholder = "$" substr(arg, 1, RLENGTH - 1); placeholders[placeholder] = 1; subs[placeholder] = substr(arg, RLENGTH + 1, length(arg) - RLENGTH); @@ -116,7 +116,11 @@ The full set of changes in this release can be found at https://github.com/Agori $CHECKS_TEXT. As a chain-halting upgrade, once approved, all chain validators will need to upgrade from `$PREV_RELEASE` to this new version (after the chain halts due to reaching the height required in a governance proposal). -Since the `agoric-upgrade-11` release, state-sync snapshots include more data than before. Nodes which have inadvertently pruned this data (e.g. those created from a state-sync before the `agoric-upgrade-11` release) will not be able to produce such snapshots, and will need to be restored from state-sync. We are aware of continued performance issues related to state-sync. In particular, we've observed that on some deployments, the current implementation can require 100 GB of temporary free disk space and 16GB of memory. +## State-sync + +State-sync snapshots now only include minimal data to restore a node. However there are still continued performance issues related to state-sync. In particular, we've observed that on some deployments, the snapshot taking and restoring process can take multiple hours, require about 20GB of temporary free disk space, and 16GB of memory. + +## Cosmos Upgrade Handler Name Below is the _cosmos upgrade handler name_ for this release. This is the name that can be used in governance proposals to deploy this upgrade. @@ -124,6 +128,8 @@ Below is the _cosmos upgrade handler name_ for this release. This is the name th Cosmos Upgrade Handler Name: $COSMOS_UPGRADE_NAME ``` +## Tags + Below is the git information related to this software release. Note the _git tag_ does not always match the _cosmos upgrade handler name_. ``` @@ -149,6 +155,8 @@ Presuming that your node is running `$PREV_RELEASE`, once the upgrade height for Install supported versions of Go, Node.js, and a compiler such as gcc or clang as documented in the [README](https://github.com/Agoric/agoric-sdk/tree/$TAG#prerequisites). +Make sure that the environment running the agd service has the same Node.js version as the environment used for building. In particular, if using `nvm` to manage Node.js version, the service environment should enable nvm and use the same version. + ### Building ``` @@ -156,15 +164,17 @@ Install supported versions of Go, Node.js, and a compiler such as gcc or clang a cd agoric-sdk git fetch --all git checkout $TAG -git clean -xdf -yarn install -yarn build -(cd packages/cosmic-swingset && make) +git clean -xdf && git submodule foreach --recursive git clean -xdf +./bin/agd build # (start the agd service) ``` Do _not_ copy the `agd` script or Go binary to another location. If you would like to have an executable `agd` in another location, then create a symlink in that location pointing to `agoric-sdk/bin/agd`. +### Troubleshooting `module ... was compiled against a different Node.js version` and `SyntaxError` issues + +The agd service is not using the same version of Node.js as the one used when building. The most likely cause is that `nvm` was used to manage the Node.js version in the shell when building. Either install the required version of Node.js globally using the system's package manager, or enable `nvm` in the environment of the agd service. + ### Troubleshooting `repoconfig.sh: No such file or directory` Unlike typical cosmos-sdk chains where the daemon is a single executable file, Agoric's use of cosmos-sdk depends on many components of `agoric-sdk` at runtime. Copying `agd` to `/usr/local/bin` or the like is unlikely to produce a working installation. For more detail, see: https://github.com/Agoric/agoric-sdk/issues/7825 diff --git a/scripts/get-packed-versions.sh b/scripts/get-packed-versions.sh index ecaf970ee8d..d9459a7d987 100755 --- a/scripts/get-packed-versions.sh +++ b/scripts/get-packed-versions.sh @@ -23,8 +23,6 @@ corepack enable yarn install 1>&2 yarn build 1>&2 -yarn lerna run build:types 1>&2 - npm query .workspace | jq -r '.[].location' | while read -r dir; do # Skip private packages. echo "dir=$dir" 1>&2 diff --git a/scripts/get-versions.sh b/scripts/get-versions.sh index 7495a8035c0..a3ede8aff24 100755 --- a/scripts/get-versions.sh +++ b/scripts/get-versions.sh @@ -7,5 +7,5 @@ WORKDIR=${1:-.} cd -- "$WORKDIR" npm query .workspace \ | jq -r '.[].location | "\(.)/package.json"' \ - | xargs jq '{key: .name, value: "^\(.version)"}' \ + | xargs jq 'select(.private | not) | {key: .name, value: "^\(.version)"}' \ | jq --slurp from_entries diff --git a/scripts/registry.sh b/scripts/registry.sh index 6cc7f442325..752b88c4733 100755 --- a/scripts/registry.sh +++ b/scripts/registry.sh @@ -70,17 +70,10 @@ publish() { yarn build git commit --allow-empty -am "chore: prepare for publishing" - # Convention used in Endo - yarn lerna run build:types - # Publish the packages to our local service. # without concurrency until https://github.com/Agoric/agoric-sdk/issues/8091 - yarn lerna publish --concurrency 1 prerelease --exact \ - --dist-tag="$DISTTAG" --preid=dev \ - --no-push --no-git-reset --no-git-tag-version --no-verify-access --yes - - # Convention used in Endo - yarn lerna run clean:types + yarn lerna version --concurrency 1 prerelease --exact \ + --preid=dev --no-push --no-git-tag-version --yes # Change any version prefices to an exact match, and merge our versions. VERSIONSHASH=$(jq --slurpfile versions <(popd > /dev/null && git cat-file blob "$VERSIONSHASH") \ @@ -91,6 +84,18 @@ publish() { | (popd > /dev/null && git hash-object -w --stdin)) git commit -am "chore: update versions" + + while ! yarn lerna publish from-package \ + --dist-tag="$DISTTAG" --no-git-reset --no-verify-access --yes; do + echo 1>&2 "Retrying publish..." + sleep 5 + done + + git reset --hard HEAD + + # Convention used in Endo + yarn lerna run clean:types + git checkout "$prior" popd done @@ -104,8 +109,6 @@ integrationTest() { # Install the Agoric CLI on this machine's $PATH. case $1 in link-cli | link-cli/*) - # Prevent retries from failing with "must not already exist" - rm -f "$HOME/bin/agoric" yarn link-cli "$HOME/bin/agoric" persistVar AGORIC_CMD "[\"$HOME/bin/agoric\"]" ;; @@ -121,7 +124,7 @@ integrationTest() { ;; *) yarn global add "agoric@$DISTTAG" - persistVar AGORIC_CMD '["agoric"]' + persistVar AGORIC_CMD "[\"$(yarn global bin)/agoric\"]" ;; esac diff --git a/scripts/replace-packages.sh b/scripts/replace-packages.sh index 7d6817a649f..125f7461a4c 100755 --- a/scripts/replace-packages.sh +++ b/scripts/replace-packages.sh @@ -14,8 +14,7 @@ DSTDIR=${2-$PWD/node_modules} pushd "$SRCDIR" yarn install npm run build -# Endo requires this -npx lerna run build:types || true + npm query .workspace | jq -r '.[].location' | while read -r dir; do # Skip private packages. test "$(jq .private < "$dir/package.json")" != true || continue diff --git a/scripts/resolve-versions.sh b/scripts/resolve-versions.sh index 98cee14f406..7f3fb050883 100755 --- a/scripts/resolve-versions.sh +++ b/scripts/resolve-versions.sh @@ -8,7 +8,7 @@ set -ueo pipefail DIR=$(dirname -- "${BASH_SOURCE[0]}") -cd -- "$DIR/.." +cd -- "${1-$DIR/..}" override=$(jq 'to_entries | map({ key: ("**/" + .key), value: .value }) | from_entries') diff --git a/scripts/update-typedoc-functions-path.cjs b/scripts/update-typedoc-functions-path.cjs new file mode 100644 index 00000000000..734df479437 --- /dev/null +++ b/scripts/update-typedoc-functions-path.cjs @@ -0,0 +1,210 @@ +#!/usr/bin/env node + +/** + * Help us workaround a limitation in Cloudflare Pages that prevents us from + * publishing static files to a top-level `/functions` directory. (Cloudflare + * reserves this namespace for Worker Functions as of + * https://github.com/cloudflare/workers-sdk/pull/2103). + * + * This script - + * 1. renames `/functions` directory to `/function` + * 2. updates generated urls in html files to reference new url path + * 3. updates base64 encoded navigation state to reference new url path + * + * If an `md` argument is supplied - versus the optional default `html` document - + * a different set of logic will run to update paths are links for markdown files. + * + * See https://github.com/TypeStrong/typedoc/issues/2111 for more solutions + * on how to workaround this. + * + * See https://github.com/Agoric/agoric-sdk/issues/9729 for tracking of the + * issue in this project. If a different solution is arrived at, we can remove + * this file and the accompanying `yarn docs:update-functions-path`. + */ + +const fsp = require('fs').promises; +const path = require('path'); +const zlib = require('zlib'); +const process = require('process'); + +const config = { + oldDirName: 'functions', + newDirName: 'funcs', + apiDocsDir: path.join(__dirname, '..', 'api-docs'), + navigationFilePath: path.join( + __dirname, + '..', + 'api-docs', + 'assets', + 'navigation.js', + ), +}; + +// Decodes and decompresses the TypeDoc navigation data +function decodeTypeDocNavigation(encodedData) { + return new Promise((resolve, reject) => { + const base64Data = encodedData.replace( + /^data:application\/octet-stream;base64,/, + '', + ); + const buffer = Buffer.from(base64Data, 'base64'); + + zlib.gunzip(buffer, (err, decompressed) => { + if (err) { + reject(new Error(`Failed to decompress data: ${err.message}`)); + return; + } + + try { + const jsonData = JSON.parse(decompressed.toString('utf-8')); + resolve(jsonData); + } catch (parseError) { + reject(new Error(`Failed to parse JSON: ${parseError.message}`)); + } + }); + }); +} + +// Compresses and encodes the TypeDoc navigation data +function encodeTypeDocNavigation(jsonData) { + return new Promise((resolve, reject) => { + const jsonString = JSON.stringify(jsonData); + + zlib.gzip(jsonString, (err, compressed) => { + if (err) { + reject(new Error(`Failed to compress data: ${err.message}`)); + return; + } + + const base64Data = compressed.toString('base64'); + resolve(`data:application/octet-stream;base64,${base64Data}`); + }); + }); +} + +// Recursively updates URLs in the navigation data +function updateUrls(data, searchString, replaceString) { + if (typeof data === 'object' && data !== null) { + for (const key in data) { + if ( + typeof data[key] === 'string' && + data[key].includes(`${searchString}/`) + ) { + data[key] = data[key].replace( + new RegExp(`${searchString}/`, 'g'), + `${replaceString}/`, + ); + } else if (typeof data[key] === 'object') { + updateUrls(data[key], searchString, replaceString); + } + } + } + return data; +} + +// Updates js-based navigation state +async function updateNavigationFile() { + const fileContent = await fsp.readFile(config.navigationFilePath, 'utf8'); + const match = fileContent.match(/window\.navigationData = "(.*?)"/); + if (!match) { + throw new Error('Navigation data not found in file'); + } + const encodedData = match[1]; + + const decodedData = await decodeTypeDocNavigation(encodedData); + const updatedData = updateUrls( + decodedData, + config.oldDirName, + config.newDirName, + ); + const newEncodedData = await encodeTypeDocNavigation(updatedData); + const newFileContent = `window.navigationData = "${newEncodedData}"`; + await fsp.writeFile(config.navigationFilePath, newFileContent); + console.log('Navigation file updated successfully'); +} + +/** + * Updates files in a directory + * @param {string} dir - Directory to update + * @param {string} fileExtension - File extension to process + * @param {Function} updateFunction - Function to update file content + */ +async function updateFiles(dir, fileExtension, updateFunction) { + const files = await fsp.readdir(dir); + for (const file of files) { + const filePath = path.join(dir, file); + const stat = await fsp.stat(filePath); + if (stat.isDirectory()) { + if (file === config.oldDirName) { + const newPath = path.join(dir, config.newDirName); + await fsp.rename(filePath, newPath); + console.log(`Renamed directory: ${filePath} to ${newPath}`); + await updateFiles(newPath, fileExtension, updateFunction); + } else { + await updateFiles(filePath, fileExtension, updateFunction); + } + } else if (path.extname(file) === fileExtension) { + const content = await fsp.readFile(filePath, 'utf8'); + const updatedContent = updateFunction(content); + if (content !== updatedContent) { + await fsp.writeFile(filePath, updatedContent); + console.log(`Updated: ${filePath}`); + } + } + } +} + +/** + * Updates content in Markdown files + * @param {string} content - The Markdown content to update + * @returns {string} - The updated Markdown content + */ +function updateMarkdownContentLinks(content) { + return ( + content + // Update links like [text](functions/file.md) + .replace( + new RegExp(`\\[(.*?)\\]\\(${config.oldDirName}/`, 'g'), + `[$1](${config.newDirName}/`, + ) + // Update links like [text](../functions/file.md) + .replace( + new RegExp(`\\[(.*?)\\]\\(\\.\\./${config.oldDirName}/`, 'g'), + `[$1](../${config.newDirName}/`, + ) + ); +} + +/** + * Updates content in HTML files + * @param {string} content - The HTML content to update + * @returns {string} - The updated HTML content + */ +function updateHtmlContentLinks(content) { + return content.replace( + new RegExp(`/${config.oldDirName}/`, 'g'), + `/${config.newDirName}/`, + ); +} + +/** + * Main function to run the script + */ +async function main() { + const fileType = process.argv[2] || 'html'; + await null; + switch (fileType) { + case 'html': + await updateFiles(config.apiDocsDir, '.html', updateHtmlContentLinks); + return updateNavigationFile(); + case 'md': + return updateFiles(config.apiDocsDir, '.md', updateMarkdownContentLinks); + default: + throw new Error('Invalid file type. Use "html" or "md".'); + } +} + +main().catch(e => { + console.error(`Error: ${e.message}`); + process.exit(1); +}); diff --git a/tsconfig.json b/tsconfig.json index 247fab83052..f5ff8dc3a0d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ "downlevelIteration": true, "strictNullChecks": true, "noImplicitThis": true, + "noUncheckedSideEffectImports": true, "noEmit": true }, "include": [ diff --git a/typedoc.json b/typedoc.json index 685abaab401..90667d1f50f 100644 --- a/typedoc.json +++ b/typedoc.json @@ -9,5 +9,10 @@ "entryPointStrategy": "packages", "out": "api-docs", "includeVersion": true, + "visibilityFilters": { + "@alpha": false, + "@internal": false, + "private": false, + }, "logLevel": "Verbose" } diff --git a/yarn.lock b/yarn.lock index f8047a89fee..2dc7dd17b95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1296,34 +1296,35 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.3.tgz#5dcaee6dd7cc846cdc073e9a7a7f63242f5f7e31" integrity sha512-WCZK4yksj2hBDz4w7xFZQTRZQ/RJhBX26uFHmmQFIcNUUVAihrLO+RerqJgk0dZqC42wstM9pEUQGtPmLcIYvg== -"@cosmology/ast@^1.7.1": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@cosmology/ast/-/ast-1.7.1.tgz#a93e38d08c1c35d6e209cb04e580cd2b325a1110" - integrity sha512-dLqKUpxy9G8iS4Imd9JRDnP6Ca7EkyiqWWwgZacBLLuFK0mIDed0Fb8JP85pExV26XTC/Un3Nhi8yWiNQlKakQ== +"@cosmology/ast@^1.8.1": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@cosmology/ast/-/ast-1.8.1.tgz#35a32fc117b007d6f7c9f5dcc82613989d206883" + integrity sha512-wjJDf3qk0SLaJsS6KJJqQpz+0iLl4V8V1cE7HwgwZT3F4nhTLfyK/13NbJcf0MhEfQ7+tNKFnVJIJJGfUxTPKQ== dependencies: "@babel/types" "7.23.6" - "@cosmology/types" "^1.7.0" - "@cosmology/utils" "^1.7.0" + "@cosmology/types" "^1.8.1" + "@cosmology/utils" "^1.8.1" case "1.6.3" dotty "0.1.2" -"@cosmology/proto-parser@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@cosmology/proto-parser/-/proto-parser-1.7.0.tgz#8d7abd40a91ee26bd1cc0518a84d871216a35434" - integrity sha512-7qJmGNUUaFG6Y2OgpO1x/ro0t5yOs+bILYwV2lYmqqTDqGJU3FTPewxFMx9vTZ2SHeVTVG1iQgdZslmwmRX/iQ== +"@cosmology/proto-parser@^1.8.1": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@cosmology/proto-parser/-/proto-parser-1.8.1.tgz#2b6d8864b9593e518b20cd5dacbbcc68bd028f16" + integrity sha512-XgvhZH2af/6lJRYO19ozbdKdNziJu4p6HTv4u4CmUAgUpVG/tSA81cXTOMM+nJo1PPrhtqh9Nad9ISwLePvx2A== dependencies: - "@cosmology/protobufjs" "6.11.6" - "@cosmology/types" "^1.7.0" - "@cosmology/utils" "^1.7.0" + "@cosmology/protobufjs" "7.3.2" + "@cosmology/types" "^1.8.1" + "@cosmology/utils" "^1.8.1" dotty "0.1.2" + fast-json-patch "3.1.1" glob "8.0.3" minimatch "5.1.0" mkdirp "3.0.0" -"@cosmology/protobufjs@6.11.6": - version "6.11.6" - resolved "https://registry.yarnpkg.com/@cosmology/protobufjs/-/protobufjs-6.11.6.tgz#6f7bd340ab4a27969b1f75b4bff21a74e03b971a" - integrity sha512-k1opGC9CTX5vD2447pUqLmleVv0Kb8RasBUxkZHudVOvuXs2qAAGONmMIEGRCROKTodhTY9fdTnGU2lCZqAwNw== +"@cosmology/protobufjs@7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@cosmology/protobufjs/-/protobufjs-7.3.2.tgz#6c2acdaec9e4b7aab4647bb236da1258e7526a87" + integrity sha512-zHf/yqGQ7QSjIYvv7kvGKY9yXNjqj55kWdRyntrXwnte/tY8uMTuCFD/EWC48LGhGu3P7nbzTlhyCGMc3xm9bw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -1335,23 +1336,22 @@ "@protobufjs/path" "^1.1.2" "@protobufjs/pool" "^1.1.0" "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" + "@types/long" "^5.0.0" "@types/node" ">=13.7.0" - long "^4.0.0" + long "^5.0.0" -"@cosmology/telescope@^1.7.1": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@cosmology/telescope/-/telescope-1.7.1.tgz#1d4357bfc49c41a03c5fbe91fe60c028ffbdfcf6" - integrity sha512-mB/h8iGfVNi+ZV3KzEy6xFKVlAe9d9pOTz/Vu+OCMcrEFS/xHgWMs+eNDGAbWuaCp06qYyZSc0pN7rMVojnElg== +"@cosmology/telescope@https://gitpkg.vercel.app/agoric-labs/telescope/packages/telescope?8d2c2f6ba637a5578eead09a7368dc41c262a9d0": + version "1.8.3" + resolved "https://gitpkg.vercel.app/agoric-labs/telescope/packages/telescope?8d2c2f6ba637a5578eead09a7368dc41c262a9d0#6cbf7b95125ced918760fc7382bcf9b52b209923" dependencies: "@babel/generator" "^7.23.6" "@babel/parser" "^7.23.6" "@babel/traverse" "7.23.6" "@babel/types" "7.23.6" - "@cosmology/ast" "^1.7.1" - "@cosmology/proto-parser" "^1.7.0" - "@cosmology/types" "^1.7.0" - "@cosmology/utils" "^1.7.0" + "@cosmology/ast" "^1.8.1" + "@cosmology/proto-parser" "^1.8.1" + "@cosmology/types" "^1.8.1" + "@cosmology/utils" "^1.8.1" "@cosmwasm/ts-codegen" "0.35.7" "@types/parse-package-name" "0.1.0" case "1.6.3" @@ -1369,19 +1369,20 @@ rimraf "5.0.0" yaml "^2.3.4" -"@cosmology/types@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@cosmology/types/-/types-1.7.0.tgz#089b43227b0ae4e4799be2d2e1f1b71a0091d422" - integrity sha512-BdevNk957uA/I12mgp24Dp4lrfN4lOgb1xoSJTvlmOJuks1q+vcQHiRyVfncxE5aFRNCG6ROHHu9IFckBW07hQ== +"@cosmology/types@^1.8.1": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@cosmology/types/-/types-1.8.1.tgz#782868b232a214b55f41908353be87afa79c9302" + integrity sha512-M/4HZZu0mNwwzK7ITa5A4biVKGVk8EtaQJlHuuctygKvjKcvmmAglna754o9CdkfPEyUXBzYnLU6q7UIFgcO+g== dependencies: case "1.6.3" + fast-json-patch "3.1.1" -"@cosmology/utils@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@cosmology/utils/-/utils-1.7.0.tgz#7a09bee4d4fa65f1049dcb5a88939fe55fbbd5d4" - integrity sha512-TLaRenW/CTy8wo8z3mvSq0koM9XwL2aLcmdZEWUqhhVyUA0VOfDloh+3d/oLQxsBBzAiaDauX+wju3dkrY8moA== +"@cosmology/utils@^1.8.1": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@cosmology/utils/-/utils-1.8.1.tgz#9fd7f0815da726f7a2a11d713f7e8886f94f0a6b" + integrity sha512-PrZffk81GQ0pJHH7kRJi9PZVt4qWa/9V3mbUyc3vXIWqeAk1bQ+5O5MLKirtRj4cEM3zt5WnDUISPCrt4VIQkA== dependencies: - "@cosmology/types" "^1.7.0" + "@cosmology/types" "^1.8.1" dotty "0.1.2" "@cosmwasm/ts-codegen@0.35.7": @@ -1471,265 +1472,266 @@ resolved "https://registry.yarnpkg.com/@datadog/sketches-js/-/sketches-js-2.1.0.tgz#8c7e8028a5fc22ad102fa542b0a446c956830455" integrity sha512-smLocSfrt3s53H/XSVP3/1kP42oqvrkjUPtyaFd1F79ux24oE31BKt+q0c6lsa6hOYrFzsIwyc5GXAI5JmfOew== -"@endo/base64@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@endo/base64/-/base64-1.0.5.tgz#821a5107d1efc988cc630ba92aa31dab9fecfc45" - integrity sha512-onumize4hsF15ah85C6xPCI3LzvC9NOjf8QUuIhnAKLVR5bnQqhCAjKyt1EUMcsEGcDgJsq5DZFQrbU/tjWJAg== - -"@endo/bundle-source@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@endo/bundle-source/-/bundle-source-3.2.3.tgz#414634151ed78a71b69d4e616be221512c5c6ed2" - integrity sha512-D/qcyeIQzWw9AP+vdadjGdajGpanLAFCqpjPHewGz/vojEuIo+uFrbkNOSttoxbKc+CfoCRHsOCBWUNANiD/QQ== - dependencies: - "@endo/base64" "^1.0.5" - "@endo/compartment-mapper" "^1.1.5" - "@endo/evasive-transform" "^1.1.2" - "@endo/init" "^1.1.2" - "@endo/promise-kit" "^1.1.2" - "@endo/where" "^1.0.5" +"@endo/base64@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@endo/base64/-/base64-1.0.7.tgz#7cd3bd1a44fb48d0dd8fd2dd30b8833ec3b849e8" + integrity sha512-Wsq8+54aPy/WdykgBt3WQ32Xk3tU6jk/hWJkwW1kMl4eVwuEoXXAXxvqs6g+AZt/a6mf1IIvF9LRXIQnBy6wAQ== + +"@endo/bundle-source@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@endo/bundle-source/-/bundle-source-3.4.0.tgz#863e4d8103b513e8706e4f318876bb6e6354624d" + integrity sha512-qDNx4cx92kakY+CKgrPrxQUP4Sas/sMDucwGx3jelu7zvQQzf6p3aGgE+pHbF7RJHgZJEcyMYWKf6s/hD8fqKw== + dependencies: + "@endo/base64" "^1.0.7" + "@endo/compartment-mapper" "^1.2.2" + "@endo/evasive-transform" "^1.3.0" + "@endo/init" "^1.1.4" + "@endo/promise-kit" "^1.1.5" + "@endo/where" "^1.0.7" "@rollup/plugin-commonjs" "^19.0.0" + "@rollup/plugin-json" "^6.1.0" "@rollup/plugin-node-resolve" "^13.0.0" acorn "^8.2.4" rollup "^2.79.1" -"@endo/captp@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@endo/captp/-/captp-4.2.0.tgz#18b820d37d3a2b47efc00580d5bcee01c50a090d" - integrity sha512-nauPor3d1883jiv/L+mQ49vTV4kdshGtPGl9uUxCR7fn+DlhJa2tBmkY9fLWGyERZkto4A9PhwVbFpjZ/nrf+Q== +"@endo/captp@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@endo/captp/-/captp-4.3.0.tgz#e2a45d7447cb9c8e0a5718b314b3a92e28d29b95" + integrity sha512-tASU0w8KwqgTemzkkIrCRoBdubZZNMBgVnWieouIdnKKLT2tVnlYFZh4hmA+DFvYfBFoifLdhuaHNwI+/kaJdA== dependencies: - "@endo/errors" "^1.2.2" - "@endo/eventual-send" "^1.2.2" - "@endo/marshal" "^1.5.0" - "@endo/nat" "^5.0.7" - "@endo/promise-kit" "^1.1.2" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/marshal" "^1.5.3" + "@endo/nat" "^5.0.10" + "@endo/promise-kit" "^1.1.5" -"@endo/check-bundle@^1.0.7": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@endo/check-bundle/-/check-bundle-1.0.7.tgz#908d7dcf5d381ef920a5f4109ddbc687dc5b2fb4" - integrity sha512-7tQA5sJSfTOMv9o8YclDxeugbbrzh35FmyXTxDZXyueKSmXEIKGmUFzivVeFMqcHOpylqZo8fGA9CPjdB1T93g== +"@endo/check-bundle@^1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@endo/check-bundle/-/check-bundle-1.0.9.tgz#654bb5152b0142c9e5b1d365972f4b93ddf17472" + integrity sha512-CpYcdRrN1ylx8kADctl1I5mOMzx087IwettthcwXPAjT3pHZKVD5vDd4CKZAKG9YuS/V3E9jjN5EhR8wp4vH/Q== dependencies: - "@endo/base64" "^1.0.5" - "@endo/compartment-mapper" "^1.1.5" - "@endo/errors" "^1.2.2" + "@endo/base64" "^1.0.7" + "@endo/compartment-mapper" "^1.2.2" + "@endo/errors" "^1.2.5" -"@endo/cjs-module-analyzer@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@endo/cjs-module-analyzer/-/cjs-module-analyzer-1.0.5.tgz#5f3f7584a383317cd341c0b47dadfb7bea62a5a0" - integrity sha512-YFz2wiEiUJqo/AuYn00+1rsiqydzAGbrSgqFTnI48V/nLOmWofAA5Tl5qMqcL/Z33K6WaK9Bzgv9zdaAl6uMyw== +"@endo/cjs-module-analyzer@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@endo/cjs-module-analyzer/-/cjs-module-analyzer-1.0.7.tgz#01baecf1a8f9aa0ef79e258190ad5d5cc35c153f" + integrity sha512-N5FkKj/okwWVwGDIJldTLz1bhInzZ1VQrcC9FJJpdXkEdoGUDKo8/jUMrhqGLqqVSkO5A+KgKcdhoQrV741ncw== -"@endo/common@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@endo/common/-/common-1.2.2.tgz#4f0c761eebd373e6b6e75595e5b414e8512c11cf" - integrity sha512-JUHj2FyYiH8DqpG+DDLahJUsFLuRgIWS5vX6uiDjtE5iGcMKuZQiFCsJ7OnLtUEvYXdAyvjLZwzkeEl78hZFUg== +"@endo/common@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@endo/common/-/common-1.2.5.tgz#4f7a64d756dbb9a88bf8b0bef942f7943e2cd7e6" + integrity sha512-bl9s95aYe0xCJy5IbuFxhizzFQHa/wiQa5FIZK6Rm8uV5g7iS/wdfCJOdNKicxAsJWTPx96AwAmLlgEV8NdUJg== dependencies: - "@endo/errors" "^1.2.2" - "@endo/eventual-send" "^1.2.2" - "@endo/promise-kit" "^1.1.2" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/promise-kit" "^1.1.5" -"@endo/compartment-mapper@^1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@endo/compartment-mapper/-/compartment-mapper-1.1.5.tgz#c836c319853c4de80c3cb54c4c54ca1f6a61747f" - integrity sha512-k/ddX/g5qsTWrqpTyS5BbzAM7mEUMck/uQVTxhxIegPVY2Ik0Lnjy1WJXRD21skAYNAWtb12tfSsK0oR59OLuQ== +"@endo/compartment-mapper@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@endo/compartment-mapper/-/compartment-mapper-1.2.2.tgz#6a2d7d4c1245cf07cef07895650e7c611bc84097" + integrity sha512-ARPxQp+EphK3sHJwnTofz91AXZT6K6jtrNURIL6NNhX7pQT8XTFBKU029cfAc4/RLug24NjrNonAoElqrMDPkQ== dependencies: - "@endo/cjs-module-analyzer" "^1.0.5" - "@endo/static-module-record" "^1.1.2" - "@endo/zip" "^1.0.5" - ses "^1.5.0" + "@endo/cjs-module-analyzer" "^1.0.7" + "@endo/module-source" "^1.0.2" + "@endo/zip" "^1.0.7" + ses "^1.8.0" -"@endo/env-options@^1.1.4": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@endo/env-options/-/env-options-1.1.4.tgz#b40ce43a6b9fd9659ffe7b6533dd2cd277628bb1" - integrity sha512-hBwS+uijkN+KDFcEM4FRMvkCeusqm/drC2WuUXZA2aqjzaWgNjneIks3m5VcFmGvEZSpjDmGtGydAS31vdk7Mw== +"@endo/env-options@^1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@endo/env-options/-/env-options-1.1.6.tgz#f4e2dcb22f19f33c0431303c7387c7f5b54c757f" + integrity sha512-Uqy94PwLTco90Yfign43muvDtjsYTbL6Ck4W5sSWQUqJiFOL+YP8kiBOoGyQynDsGTY0MCQvMxEPfphaJKnzlQ== -"@endo/errors@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@endo/errors/-/errors-1.2.2.tgz#34d0f721df09c79744cd2cf89dddd3511bba64fa" - integrity sha512-PQWkU8gR/asxaJnPxu95r+OyM87usCAUZHgWCXSnEjecxlnCjn1UjhBfijmTh+/DmJP0XmdYYSDPOSYemqzEfw== +"@endo/errors@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@endo/errors/-/errors-1.2.5.tgz#158bc584b9e648e4ca2978a240b57cb45df05c03" + integrity sha512-iZ8Kv0DoE70Z4GDoXZQK3mS3BzDnA1kSeDdE97I02ESWe9tR30TGCHW++CqbCt/lZ6bG/RBq1a6JNuOae+WKlw== dependencies: - ses "^1.5.0" + ses "^1.8.0" -"@endo/eslint-plugin@^2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@endo/eslint-plugin/-/eslint-plugin-2.1.3.tgz#2151d169deb3104f58ea48e092981625f34ec5cf" - integrity sha512-/WSyjPDMpqs6BaTc2x3wR1sRteHH65r4sX5ubDDT1eoEu8oB8Z6ZSc1qNkY/6JTSSdQB7UF2AYfhLrAqevqctw== +"@endo/eslint-plugin@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@endo/eslint-plugin/-/eslint-plugin-2.2.1.tgz#1d05e63b80f71ff9cad9d318c0063a78dd0f1e18" + integrity sha512-w8nFie6R/BLP1PUrpLefr4cHVgr7VB5+ffaBBdB9fFJHcqziKc9pG57BByEAoSVrTg0BBDUUbs3t+DeCw5v8Vw== dependencies: requireindex "~1.1.0" ts-api-utils "~1.0.1" tsutils "~3.21.0" - typescript "~5.5.0-dev.20240327" + typescript "~5.6.1-rc" typescript-eslint "^7.3.1" -"@endo/evasive-transform@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@endo/evasive-transform/-/evasive-transform-1.1.2.tgz#a5d9aaf9eb51b699e0c9bfb87c907653eead9144" - integrity sha512-lRjNWOTh1CvNAXSBTuroikn6bXs6XNQYX8a06uIoTLT9Yxr+ITZulDx0NFJW/2tWT3l1AO9dFwj1li9j8HAz3g== +"@endo/evasive-transform@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@endo/evasive-transform/-/evasive-transform-1.3.0.tgz#f6f72631a843a4efaae991098060488857ffd6de" + integrity sha512-dzU0H2Ys5DNWueLRxMPYsF6HHl5xXaGOS5ub5p2W5Yoj/DCALGROOYLPeIipcyHu5aEkE5dRkxqqPDYszccm+g== dependencies: "@agoric/babel-generator" "^7.17.6" "@babel/parser" "^7.23.6" "@babel/traverse" "^7.23.6" - source-map "0.7.4" + source-map-js "^1.2.0" -"@endo/eventual-send@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@endo/eventual-send/-/eventual-send-1.2.2.tgz#68cb93f104a9c5e28737be4358d6e58bfc624e1f" - integrity sha512-6CCLM440idVuQJV4fpZZ/F5++tJZQLVNYI1LHiZk5BA9KJxDwSHTYmCIqw4THiRYCE32zt1f/xL5BU0RH5YIFQ== +"@endo/eventual-send@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@endo/eventual-send/-/eventual-send-1.2.5.tgz#f6aef45f6f8d30c42a57512315aa43a4215f425b" + integrity sha512-Ssbwyih2+paHduMiEpdFPJiViBMa4gc9OPNPSklrI5eyBAcGXKLr4/LySbDH9+PVRAnr69tzQsdx4HCM3GPXEA== dependencies: - "@endo/env-options" "^1.1.4" + "@endo/env-options" "^1.1.6" -"@endo/exo@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@endo/exo/-/exo-1.5.0.tgz#97ea9354f6f48c75b6fb893a19cbb82d090c02ba" - integrity sha512-YiZYQQATh5vQ6ex+8yLqZLXnr4M6U7pgX+D7KPZP+LRkDCs3sF5rT+AR24ErdEPUDLrcYco7BbUw4uy/im1uWQ== - dependencies: - "@endo/common" "^1.2.2" - "@endo/env-options" "^1.1.4" - "@endo/errors" "^1.2.2" - "@endo/eventual-send" "^1.2.2" - "@endo/far" "^1.1.2" - "@endo/pass-style" "^1.4.0" - "@endo/patterns" "^1.4.0" - -"@endo/far@^1.0.0", "@endo/far@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@endo/far/-/far-1.1.2.tgz#a120ce86f508ea06f0117861d16c6356f0f9d817" - integrity sha512-cyq5ZbHwiLcvHal+uyhx5molas/SJhVvykmijxv0gT80RqclM7nU59fwnocmp42YljdpMsmPU/o2HP84uMchCg== +"@endo/exo@^1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@endo/exo/-/exo-1.5.3.tgz#a0f24f76805cd07c5bbad6b5af365913ba4f7425" + integrity sha512-qI3Sq/lwY7wckEhnQeP/p8B24iQ2G+hYlBrT9zG70S/mT0x4JsYpIPVlmEy65rMZbLoNshzktY7BgW6HBeoVqQ== dependencies: - "@endo/errors" "^1.2.2" - "@endo/eventual-send" "^1.2.2" - "@endo/pass-style" "^1.4.0" + "@endo/common" "^1.2.5" + "@endo/env-options" "^1.1.6" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/far" "^1.1.5" + "@endo/pass-style" "^1.4.3" + "@endo/patterns" "^1.4.3" -"@endo/import-bundle@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@endo/import-bundle/-/import-bundle-1.1.2.tgz#d2a3c70cd17ae9a70eca8c1a3c87a22be3bd74d3" - integrity sha512-Q0V1z/vU6TOHsU82utt8BIElg3WQIBhWH13G05jeqYv9crYDyaNauEoXfO1DnRxn2LAoahI25TdwUMnt6HXlMQ== +"@endo/far@^1.0.0", "@endo/far@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@endo/far/-/far-1.1.5.tgz#182530eac9a3dbc129bb6bf60f4dddce1fda4523" + integrity sha512-x4D8OjzHBqMD0mjq09iZE46xbuhGDkqypE6dGGNTJkQNpMp8y6oWxvLj+Be2YQJ7dkXCZMnLfn1CcrQGhI0N2g== dependencies: - "@endo/base64" "^1.0.5" - "@endo/compartment-mapper" "^1.1.5" - "@endo/errors" "^1.2.2" - "@endo/where" "^1.0.5" - ses "^1.5.0" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/pass-style" "^1.4.3" -"@endo/init@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@endo/init/-/init-1.1.2.tgz#7ce21a9823c95ebf5c42d1952f138f0d9b140f48" - integrity sha512-PW853bLeNOdsL3e/YrwTUIu3IG+bbnkaozjbIjGtQAd6UvCjNK9LxEAXsubzWWrPLz2XNXrHxrTHlYN1opxggQ== +"@endo/import-bundle@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@endo/import-bundle/-/import-bundle-1.2.2.tgz#6a0cf3a6f91862970f2c677e4d4a6fd1972aaf31" + integrity sha512-cb4aCO6osd5yJpCOjdxcPggri/2BLxSsjQQyAEP9uO9u6xrMR0wFkaBwfyHyyOzDOX366N+T4weeGurEJSqRVQ== dependencies: - "@endo/base64" "^1.0.5" - "@endo/eventual-send" "^1.2.2" - "@endo/lockdown" "^1.0.7" - "@endo/promise-kit" "^1.1.2" + "@endo/base64" "^1.0.7" + "@endo/compartment-mapper" "^1.2.2" + "@endo/errors" "^1.2.5" + "@endo/where" "^1.0.7" + ses "^1.8.0" -"@endo/lockdown@^1.0.7": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@endo/lockdown/-/lockdown-1.0.7.tgz#2dfea315d225bd1ac14c34cc4cf86dac4ab63d6e" - integrity sha512-MGnCxgJJvzQIa7oRoHXQ6mzaEPfFyYdg5bKnm3ZAaFf2nDmbqCoi+xyy8fBIAvZyqUbRgdd7jAveuLROTKd/aA== +"@endo/init@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@endo/init/-/init-1.1.4.tgz#5f17826d8b60afe9b39e3a1f9da851fff942443a" + integrity sha512-xy57TLRxxFEMaunC7RusJz4gwWKCV9vmHSXbSAVlSd3lQYmS62kNU3paY0sX7bt2yWUUTybPLVYZ/lrWZAFVxQ== dependencies: - ses "^1.5.0" + "@endo/base64" "^1.0.7" + "@endo/eventual-send" "^1.2.5" + "@endo/lockdown" "^1.0.10" + "@endo/promise-kit" "^1.1.5" -"@endo/marshal@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@endo/marshal/-/marshal-1.5.0.tgz#c7f87da2fe83d9da07855bd14e7f6cd202781561" - integrity sha512-06pMvo4Z3zRsMxKXrarMFlR4jn/Vlit5XasTj84cww6Wqp7z9sIVGy8llPczKcp3af+xFhlHE2qqEGiD86mEqA== - dependencies: - "@endo/common" "^1.2.2" - "@endo/errors" "^1.2.2" - "@endo/eventual-send" "^1.2.2" - "@endo/nat" "^5.0.7" - "@endo/pass-style" "^1.4.0" - "@endo/promise-kit" "^1.1.2" - -"@endo/nat@^5.0.7": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@endo/nat/-/nat-5.0.7.tgz#cd504f14f595981a847555ceb1ea3ca9582f6400" - integrity sha512-yAuIktN8nMW8xYTrpteHNu0NZ/HAc+5FfSdEwvVnLCVwQXnE899qhtlzVhjMOmQQ/qb3kNifVW7e/6bInlCSYQ== - -"@endo/netstring@^1.0.7": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@endo/netstring/-/netstring-1.0.7.tgz#7bdcfa2c956c2c83cb1a581f662323dd3802b3d7" - integrity sha512-tf8GmoUMkcRab9RCdFTfPwGBaUCvj+04mWzf3QvSpB7Wg8QAi/hgwwZJjQmZcHgPkQV3D2iy35GmiggNh2wVuw== +"@endo/lockdown@^1.0.10": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@endo/lockdown/-/lockdown-1.0.10.tgz#1aa127aae0425214f01cd10cbd3fdd6995685950" + integrity sha512-Uw5nFtRL08obUCkQMqiLiu+D6ZQiKa20ATMKci96ju/yHe1UFUUa/3Xw0gR6vfjVBWerhSC/GyBnZ9Mku9G8cw== dependencies: - "@endo/init" "^1.1.2" - "@endo/promise-kit" "^1.1.2" - "@endo/stream" "^1.2.2" - ses "^1.5.0" + ses "^1.8.0" -"@endo/pass-style@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@endo/pass-style/-/pass-style-1.4.0.tgz#30b36b18fdc2646c1efb0386cb488df628fc119c" - integrity sha512-DH4+x/idq/IGV1t8L80ZRZWGIvA8IBr2QXDMHBQzHaNDJV8pgBNb0yloopB0luSDaRqcyHcwS6mezOkY0+IgnA== +"@endo/marshal@^1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@endo/marshal/-/marshal-1.5.3.tgz#0eadff5442169561ab40748207a0b703b0db2c42" + integrity sha512-gRd3nVebI1CecJcaIaGY0AbDfVe/0E8N7MZ0+dOoOnk1LcqcEY8Cq9vYxIcDRkXm/buAq4cdsfxY5khAVyOr1g== dependencies: - "@endo/env-options" "^1.1.4" - "@endo/errors" "^1.2.2" - "@endo/eventual-send" "^1.2.2" - "@endo/promise-kit" "^1.1.2" - "@fast-check/ava" "^1.1.5" + "@endo/common" "^1.2.5" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/nat" "^5.0.10" + "@endo/pass-style" "^1.4.3" + "@endo/promise-kit" "^1.1.5" -"@endo/patterns@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@endo/patterns/-/patterns-1.4.0.tgz#56213b66af196684ddce23e32dc49d8353a34006" - integrity sha512-/HHfV3pskSAFhlEIPHCKK5FrpvM47opta01SgWBF63ZSbs0jobYdQJgtKrPgxPKNcG0kRTema8VGCdJT/XyluQ== +"@endo/module-source@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@endo/module-source/-/module-source-1.0.2.tgz#8b6558ba9bfc8e39518c49bf126fb769fdfd0de8" + integrity sha512-YlweCYiEsLOlG5gR7d69hq+xhcgetkM/NJbNrYtplwY0QeEA5oBGPRYLf2i/JS1YMLT2fEwM70zc5JGCSXdxZw== dependencies: - "@endo/common" "^1.2.2" - "@endo/errors" "^1.2.2" - "@endo/eventual-send" "^1.2.2" - "@endo/marshal" "^1.5.0" - "@endo/promise-kit" "^1.1.2" + "@agoric/babel-generator" "^7.17.6" + "@babel/parser" "^7.23.6" + "@babel/traverse" "^7.23.6" + "@babel/types" "^7.24.0" + ses "^1.8.0" -"@endo/promise-kit@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@endo/promise-kit/-/promise-kit-1.1.2.tgz#0c4866be4e300e50595a5beb4e97e20a091ea1d5" - integrity sha512-FPcwVyZYKhFqmPkTYPyVVleqB8mLBfAwhjiNIYEA4x+Qa66y+zVAXd1Muiwr0d8YU+afcB3+tg8mMsPXbZJwQg== +"@endo/nat@^5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@endo/nat/-/nat-5.0.10.tgz#2c843bd2ddb1587c5aaf5c489d58e1f946f52bb4" + integrity sha512-yo+wss3Ng8QXHrmjgp5AmlJ5r8nf0AdGMZjpH0C1sOvbvw9RF2v6B/RGkO0i4dANgdAyHGK9WMYTV6w9/IA2eg== + +"@endo/netstring@^1.0.10": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@endo/netstring/-/netstring-1.0.10.tgz#f06d9912c31efce864b65ad4d2979e8b656677b5" + integrity sha512-yPPQlxlUi+DBaMBeP5ektMIVDuD6maweqaQGmfl8FRGiE0cdmWc8FvjvTyBTC+MpWWBIFa0GDUpoVVeXJ2/LhA== + dependencies: + "@endo/init" "^1.1.4" + "@endo/promise-kit" "^1.1.5" + "@endo/stream" "^1.2.5" + ses "^1.8.0" + +"@endo/pass-style@^1.4.3": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@endo/pass-style/-/pass-style-1.4.3.tgz#9449ce2bc297c5bcaf81fe0c4e29692b61586b52" + integrity sha512-3AGJIrflbVkvSGqSK4EAO9H2ihJ58BmzK8pp4Us5e7AJ9MH0yp5JIkYXnYI32vBUE0fJyfe2mRU06NnXJ4SX4A== + dependencies: + "@endo/env-options" "^1.1.6" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/promise-kit" "^1.1.5" + "@fast-check/ava" "^1.1.5" + +"@endo/patterns@^1.4.3": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@endo/patterns/-/patterns-1.4.3.tgz#4f97c789421abc3112ed5535e535ebab24fae705" + integrity sha512-G7jy4YRRuU4ahPGW03mjqqKn7sTy20jXJTTAB/xZonaPxCVPY+4giYT2SVPC125NjvEAo2rcsW/qJtGW2GiC0A== dependencies: - ses "^1.5.0" + "@endo/common" "^1.2.5" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/marshal" "^1.5.3" + "@endo/promise-kit" "^1.1.5" -"@endo/ses-ava@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@endo/ses-ava/-/ses-ava-1.2.2.tgz#4d819b8b64e24d476e57b171a5c845105e23112e" - integrity sha512-Ah9sOQwGys0NLjrMCsysQekDe3z64D3w4d6fG174u3J5hMuXhYCe+Z3fPy1uflQp+BhybgXB1vsYeOr9jTGpPA== +"@endo/promise-kit@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@endo/promise-kit/-/promise-kit-1.1.5.tgz#75f369ae967ab5ffb47f187059deea0ea50994c3" + integrity sha512-a/+z4U625idhLtTtD5s68Uk5mukcM0899rxMpc9fXhFW3S+OFw3rbZYID4MwcKNTC7TaBR1fTpW74Fj4YBsvNg== dependencies: - "@endo/env-options" "^1.1.4" - "@endo/init" "^1.1.2" - ses "^1.5.0" + ses "^1.8.0" -"@endo/static-module-record@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@endo/static-module-record/-/static-module-record-1.1.2.tgz#21f133cba7e44881a3b4f51a439b86fb48a7ef07" - integrity sha512-Rzw6r/tdN6vsqZJRUcItNpZXy4qTtSRy0nCm52p/4rz3MNIiMd/Jfth+Etm0q4klhEMWLnBxSY80hnESfBzkqw== +"@endo/ses-ava@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@endo/ses-ava/-/ses-ava-1.2.5.tgz#d6a35b6b88dacd9e1e471f3fff96c12fcde50cf9" + integrity sha512-VH4QBR9yoCQF7vaWhsydsWj1NIMxm8CRw5szL62wINswIQle9VRE6SKYy3twSXG8FJJWdr0CYKvd1DYZ3tzN3Q== dependencies: - "@agoric/babel-generator" "^7.17.6" - "@babel/parser" "^7.23.6" - "@babel/traverse" "^7.23.6" - "@babel/types" "^7.24.0" - ses "^1.5.0" + "@endo/env-options" "^1.1.6" + "@endo/init" "^1.1.4" + ses "^1.8.0" -"@endo/stream-node@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@endo/stream-node/-/stream-node-1.1.2.tgz#34f16f1ef7b710f677b89f38db2026f46926daf1" - integrity sha512-BqRIJO/8Sll9hQBLe66adY34RE5E1m+Q/uDUI5AgsdFzBGirsnuvgr7ijst9IqYVCgpQXlMzi/M3nU9HP1t1tA== +"@endo/stream-node@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@endo/stream-node/-/stream-node-1.1.5.tgz#3cfe3f8eff407a7d3eb1901b05f7e2491a08ff45" + integrity sha512-0nON5mjeaxkEtqEXgZLqHHPwZtOJF16UC450UK/xBFzAKLxmdOWPA5Z/BY5bahxTzmYZetC4DX+bin61fa+TWw== dependencies: - "@endo/errors" "^1.2.2" - "@endo/init" "^1.1.2" - "@endo/stream" "^1.2.2" - ses "^1.5.0" + "@endo/errors" "^1.2.5" + "@endo/init" "^1.1.4" + "@endo/stream" "^1.2.5" + ses "^1.8.0" -"@endo/stream@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@endo/stream/-/stream-1.2.2.tgz#d207d5b7bee43623de07037bad607169582d0d87" - integrity sha512-5BA5U6JTE2oPyeyyJ/OBULuEN+dQSynFJSXpAk2y5jgbrD0Iwj6GGnOa5Dn9GuJfsAyPWiN3Hv9Q1nuQqhuPGg== +"@endo/stream@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@endo/stream/-/stream-1.2.5.tgz#585b83dd904297272a674202f96cf8ea43a59c54" + integrity sha512-U0wbtnZk4U5ugA12q8nwYoYtonYyCMn/oH7RTFea7AK4FxHdFffk+rK1M9mDi1hIwhfjVHWrGZZ/lQlPu+eJBQ== dependencies: - "@endo/eventual-send" "^1.2.2" - "@endo/promise-kit" "^1.1.2" - ses "^1.5.0" + "@endo/eventual-send" "^1.2.5" + "@endo/promise-kit" "^1.1.5" + ses "^1.8.0" -"@endo/where@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@endo/where/-/where-1.0.5.tgz#7b7f8d572a9dd071c71865d711c4c82240ed7d4f" - integrity sha512-E4OwISkbzxVayQ8mQW7y+27Jo8puHal8Wdg99l5oW7BdVUl02lNmC77V22EzyfP079jmBvhPb014xpkqBEcwMw== +"@endo/where@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@endo/where/-/where-1.0.7.tgz#d2df5cfade72daa2689e2bf9e85b11fbf9594bee" + integrity sha512-kM+hKI6T2sqJsWB3i95oMShUoI/L4fnDtNaYWBMwJ4sH5SGbOyVqlX35ylPMMALm8rPFm6ANOtdn7P3FR900ig== -"@endo/zip@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@endo/zip/-/zip-1.0.5.tgz#213f074da3b0bedc1cb388c26ae8ebc9931bfc43" - integrity sha512-YW+O6fsmKmoA5iqtmcsVqEfRXqG9shWKrRkZXDPqmO2obfA7B3Q56wSlHw+2pX1ly11GpFZCgr4yaullbJiH5A== +"@endo/zip@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@endo/zip/-/zip-1.0.7.tgz#8cce0cbe5073fd12371e51520f1f0c2ee005bbd3" + integrity sha512-FCMItF+QzIQk4nR9cbr4DPIBRZ/TdG4Ah1/ZkJYs0DlkciKONRLHlLvc7+9j7tmgPU53ksc21fHhPsrx+2MQeg== "@es-joy/jsdoccomment@~0.43.1": version "0.43.1" @@ -2775,14 +2777,10 @@ npmlog "^6.0.2" write-file-atomic "^4.0.1" -"@noble/hashes@^1", "@noble/hashes@^1.0.0": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" - integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== - -"@noble/hashes@github:paulmillr/noble-hashes#ae060da": - version "1.4.0" - resolved "https://codeload.github.com/paulmillr/noble-hashes/tar.gz/ae060daa6252f3ff2aa2f84e887de0aab491281d" +"@noble/hashes@^1", "@noble/hashes@^1.0.0", "@noble/hashes@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" + integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -3342,6 +3340,13 @@ magic-string "^0.25.7" resolve "^1.17.0" +"@rollup/plugin-json@^6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.1.0.tgz#fbe784e29682e9bb6dee28ea75a1a83702e7b805" + integrity sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA== + dependencies: + "@rollup/pluginutils" "^5.1.0" + "@rollup/plugin-node-resolve@^13.0.0": version "13.0.0" resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.0.tgz#352f07e430ff377809ec8ec8a6fd636547162dc4" @@ -3363,6 +3368,30 @@ estree-walker "^1.0.1" picomatch "^2.2.2" +"@rollup/pluginutils@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + +"@shikijs/core@1.16.3": + version "1.16.3" + resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.16.3.tgz#082b53928bf201a8d7cfbe0b5540dc1c609d0a5e" + integrity sha512-yETIvrETCeC39gSPIiSADmjri9FwKmxz0QvONMtTIUYlKZe90CJkvcjPksayC2VQOtzOJonEiULUa8v8crUQvA== + dependencies: + "@shikijs/vscode-textmate" "^9.2.0" + "@types/hast" "^3.0.4" + oniguruma-to-js "0.3.3" + regex "4.3.2" + +"@shikijs/vscode-textmate@^9.2.0": + version "9.2.2" + resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-9.2.2.tgz#24571f50625c7cd075f9efe0def8b9d2c0930ada" + integrity sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg== + "@sinclair/typebox@^0.24.1": version "0.24.51" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" @@ -3476,6 +3505,13 @@ dependencies: "@types/node" "*" +"@types/hast@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" + "@types/http-proxy@^1.17.8": version "1.17.9" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" @@ -3517,10 +3553,12 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== -"@types/long@^4.0.1": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" - integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== +"@types/long@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/long/-/long-5.0.0.tgz#daaa7b7f74c919c946ff74889d5ca2afe363b2cd" + integrity sha512-eQs9RsucA/LNjnMoJvWG/nXa7Pot/RbBzilF/QRIU/xRl+0ApxrSUFsV5lmf01SvSlqMzJ7Zwxe440wmz2SJGA== + dependencies: + long "*" "@types/mdast@^4.0.0": version "4.0.4" @@ -3571,20 +3609,12 @@ dependencies: "@types/node" "*" -"@types/node-fetch@^2.6.2": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" - integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*", "@types/node@>=13.7.0", "@types/node@^18.19.24": - version "18.19.24" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.24.tgz#707d8a4907e55901466e60e8f7a62bc6197ace95" - integrity sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw== +"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.0.0": + version "22.0.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.0.0.tgz#04862a2a71e62264426083abe1e27e87cac05a30" + integrity sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw== dependencies: - undici-types "~5.26.4" + undici-types "~6.11.1" "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -3678,67 +3708,62 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@7.15.0", "@typescript-eslint/eslint-plugin@^7.0.1": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz#8eaf396ac2992d2b8f874b68eb3fcd6b179cb7f3" - integrity sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA== +"@typescript-eslint/eslint-plugin@7.18.0", "@typescript-eslint/eslint-plugin@^7.0.1": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3" + integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "7.15.0" - "@typescript-eslint/type-utils" "7.15.0" - "@typescript-eslint/utils" "7.15.0" - "@typescript-eslint/visitor-keys" "7.15.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/type-utils" "7.18.0" + "@typescript-eslint/utils" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@7.15.0", "@typescript-eslint/parser@^7.0.1": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.15.0.tgz#f4a536e5fc6a1c05c82c4d263a2bfad2da235c80" - integrity sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A== +"@typescript-eslint/parser@7.18.0", "@typescript-eslint/parser@^7.0.1": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.18.0.tgz#83928d0f1b7f4afa974098c64b5ce6f9051f96a0" + integrity sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg== dependencies: - "@typescript-eslint/scope-manager" "7.15.0" - "@typescript-eslint/types" "7.15.0" - "@typescript-eslint/typescript-estree" "7.15.0" - "@typescript-eslint/visitor-keys" "7.15.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz#201b34b0720be8b1447df17b963941bf044999b2" - integrity sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw== +"@typescript-eslint/scope-manager@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" + integrity sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA== dependencies: - "@typescript-eslint/types" "7.15.0" - "@typescript-eslint/visitor-keys" "7.15.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" -"@typescript-eslint/type-utils@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz#5b83c904c6de91802fb399305a50a56d10472c39" - integrity sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg== +"@typescript-eslint/type-utils@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" + integrity sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA== dependencies: - "@typescript-eslint/typescript-estree" "7.15.0" - "@typescript-eslint/utils" "7.15.0" + "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/utils" "7.18.0" debug "^4.3.4" ts-api-utils "^1.3.0" -"@typescript-eslint/types@7.15.0", "@typescript-eslint/types@^7.2.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.15.0.tgz#fb894373a6e3882cbb37671ffddce44f934f62fc" - integrity sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw== +"@typescript-eslint/types@7.18.0", "@typescript-eslint/types@^7.2.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" + integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== -"@typescript-eslint/types@7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.16.0.tgz#60a19d7e7a6b1caa2c06fac860829d162a036ed2" - integrity sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw== - -"@typescript-eslint/typescript-estree@7.15.0", "@typescript-eslint/typescript-estree@^7.15.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz#98ac779d526fab2a781e5619c9250f3e33867c09" - integrity sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw== +"@typescript-eslint/typescript-estree@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" + integrity sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA== dependencies: - "@typescript-eslint/types" "7.16.0" - "@typescript-eslint/visitor-keys" "7.16.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -3746,30 +3771,22 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.15.0.tgz#9e6253c4599b6e7da2fb64ba3f549c73eb8c1960" - integrity sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA== +"@typescript-eslint/utils@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" + integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "7.15.0" - "@typescript-eslint/types" "7.15.0" - "@typescript-eslint/typescript-estree" "7.15.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/typescript-estree" "7.18.0" -"@typescript-eslint/visitor-keys@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz#1da0726201a859343fe6a05742a7c1792fff5b66" - integrity sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw== +"@typescript-eslint/visitor-keys@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" + integrity sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg== dependencies: - "@typescript-eslint/types" "7.15.0" - eslint-visitor-keys "^3.4.3" - -"@typescript-eslint/visitor-keys@7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz#a1d99fa7a3787962d6e0efd436575ef840e23b06" - integrity sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg== - dependencies: - "@typescript-eslint/types" "7.16.0" + "@typescript-eslint/types" "7.18.0" eslint-visitor-keys "^3.4.3" "@ungap/structured-clone@^1.2.0": @@ -3952,11 +3969,6 @@ ansi-regex@^6.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== -ansi-sequence-parser@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf" - integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg== - ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -5603,6 +5615,11 @@ enquirer@~2.3.6: dependencies: ansi-colors "^4.1.1" +entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + env-paths@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" @@ -6140,7 +6157,7 @@ estree-walker@^1.0.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== -estree-walker@^2.0.1: +estree-walker@^2.0.1, estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== @@ -6319,6 +6336,11 @@ fast-glob@3.2.7: merge2 "^1.3.0" micromatch "^4.0.4" +fast-json-patch@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.1.tgz#85064ea1b1ebf97a3f7ad01e23f9337e72c66947" + integrity sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ== + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -6495,15 +6517,6 @@ foreground-child@^3.1.0, foreground-child@^3.1.1: cross-spawn "^7.0.0" signal-exit "^4.0.1" -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -7851,7 +7864,7 @@ json5@^2.2.1, json5@^2.2.2, json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonc-parser@3.2.0, jsonc-parser@^3.2.0: +jsonc-parser@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== @@ -8012,6 +8025,13 @@ lines-and-columns@~2.0.3: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== +linkify-it@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421" + integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ== + dependencies: + uc.micro "^2.0.0" + load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -8146,12 +8166,7 @@ logform@^2.2.0, logform@^2.3.2: safe-stable-stringify "^2.3.1" triple-beam "^1.3.0" -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -long@^5.0.0, long@^5.2.0, long@^5.2.1: +long@*, long@^5.0.0, long@^5.2.0, long@^5.2.1: version "5.2.3" resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== @@ -8288,10 +8303,17 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== -marked@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" - integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== +markdown-it@^14.1.0: + version "14.1.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45" + integrity sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg== + dependencies: + argparse "^2.0.1" + entities "^4.4.0" + linkify-it "^5.0.0" + mdurl "^2.0.0" + punycode.js "^2.3.1" + uc.micro "^2.1.0" matcher@^5.0.0: version "5.0.0" @@ -8332,6 +8354,11 @@ mdast-util-to-string@^4.0.0: dependencies: "@types/mdast" "^4.0.0" +mdurl@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0" + integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -8700,10 +8727,10 @@ minimatch@5.1.0: dependencies: brace-expansion "^2.0.1" -"minimatch@6 || 7 || 8 || 9", minimatch@^9.0.1, minimatch@^9.0.3, minimatch@^9.0.4: - version "9.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" - integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== +"minimatch@6 || 7 || 8 || 9", minimatch@^9.0.1, minimatch@^9.0.4, minimatch@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== dependencies: brace-expansion "^2.0.1" @@ -9012,7 +9039,7 @@ node-addon-api@^6.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== -node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: +node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -9400,6 +9427,11 @@ onetime@^6.0.0: dependencies: mimic-fn "^4.0.0" +oniguruma-to-js@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/oniguruma-to-js/-/oniguruma-to-js-0.3.3.tgz#3527f7e0fb9e5259c10962a7b015f28c602280dd" + integrity sha512-m90/WEhgs8g4BxG37+Nu3YrMfJDs2YXtYtIllhsEPR+wP3+K4EZk6dDUvy2v2K4MNFDDOYKL4/yqYPXDqyozTQ== + open@^7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" @@ -10046,6 +10078,11 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +punycode.js@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7" + integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA== + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -10262,6 +10299,11 @@ regenerator-transform@^0.15.2: dependencies: "@babel/runtime" "^7.8.4" +regex@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/regex/-/regex-4.3.2.tgz#a68a68c9b337a77bf4ce4ed0b4b1a49d97cb3b7b" + integrity sha512-kK/AA3A9K6q2js89+VMymcboLOlF5lZRCYJv3gzszXFHBr6kO6qLGzbm+UIugBEV8SMMKCTR59txoY6ctRHYVw== + regexp.prototype.flags@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" @@ -10557,12 +10599,12 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" -ses@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/ses/-/ses-1.5.0.tgz#c1b8491a77fb3ee8141bb9ffa6247fe5b45dfe45" - integrity sha512-mtbONkuHpOZbJn0ueOMpBzIdNual1Ou+Tg1LbStRNsWnRljzg9ZLnoF0PyuzPPQG7kiwv2V2tN3GSJMXHPrQWg== +ses@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ses/-/ses-1.8.0.tgz#8031ba3ce5bd55ced0e7a805c9cc906b9f5e29da" + integrity sha512-pis9agyAy7s9lDApaYY9OSktkzc10gkBggSbhHXwTf3cWL9H8xA7oKiXIfT/uVNf8dzZN3o2TtPYjer9/axIhw== dependencies: - "@endo/env-options" "^1.1.4" + "@endo/env-options" "^1.1.6" set-blocking@^2.0.0: version "2.0.0" @@ -10655,15 +10697,14 @@ shelljs@0.8.5: interpret "^1.0.0" rechoir "^0.6.2" -shiki@^0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.7.tgz#c3c9e1853e9737845f1d2ef81b31bcfb07056d4e" - integrity sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg== +shiki@^1.16.2: + version "1.16.3" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.16.3.tgz#d78b0c644c2a46b25ec638a9a58861999bd3495c" + integrity sha512-GypUE+fEd06FqDs63LSAVlmq7WsahhPQU62cgZxGF+TJT5LjD2k7HTxXj4/CKOVuMM3+wWQ1t4Y5oooeJFRRBQ== dependencies: - ansi-sequence-parser "^1.1.0" - jsonc-parser "^3.2.0" - vscode-oniguruma "^1.7.0" - vscode-textmate "^8.0.0" + "@shikijs/core" "1.16.3" + "@shikijs/vscode-textmate" "^9.2.0" + "@types/hast" "^3.0.4" side-channel@^1.0.4: version "1.0.4" @@ -10792,6 +10833,11 @@ sort-keys@^4.0.0: dependencies: is-plain-obj "^2.0.0" +source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + source-map-support@^0.5.21: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -10800,11 +10846,6 @@ source-map-support@^0.5.21: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@0.7.4, source-map@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - source-map@^0.5.0: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -10815,6 +10856,11 @@ source-map@^0.6.0, source-map@^0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + sourcemap-codec@^1.4.4: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" @@ -11580,41 +11626,45 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typedoc-plugin-markdown@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.17.1.tgz#c33f42363c185adf842f4699166015f7fe0ed02b" - integrity sha512-QzdU3fj0Kzw2XSdoL15ExLASt2WPqD7FbLeaqwT70+XjKyTshBnUlQA5nNREO1C2P8Uen0CDjsBLMsCQ+zd0lw== - dependencies: - handlebars "^4.7.7" +typedoc-plugin-markdown@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.2.1.tgz#b32fddc246c5bfe7e4879834fc3f8b1486de7286" + integrity sha512-7hQt/1WaW/VI4+x3sxwcCGsEylP1E1GvF6OTTELK5sfTEp6AeK+83jkCOgZGp1pI2DiOammMYQMnxxOny9TKsQ== -typedoc@^0.25.13: - version "0.25.13" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.25.13.tgz#9a98819e3b2d155a6d78589b46fa4c03768f0922" - integrity sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ== +typedoc@^0.26.7: + version "0.26.7" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.26.7.tgz#1980e3ed51c6c315b7a09786b2b9af1106a3aa80" + integrity sha512-gUeI/Wk99vjXXMi8kanwzyhmeFEGv1LTdTQsiyIsmSYsBebvFxhbcyAx7Zjo4cMbpLGxM4Uz3jVIjksu/I2v6Q== dependencies: lunr "^2.3.9" - marked "^4.3.0" - minimatch "^9.0.3" - shiki "^0.14.7" + markdown-it "^14.1.0" + minimatch "^9.0.5" + shiki "^1.16.2" + yaml "^2.5.1" -typescript-eslint@^7.15.0, typescript-eslint@^7.3.1: - version "7.15.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-7.15.0.tgz#44caca31461cc8afa829c4e5ab11aa9e0f7e175d" - integrity sha512-Ta40FhMXBCwHura4X4fncaCVkVcnJ9jnOq5+Lp4lN8F4DzHZtOwZdRvVBiNUGznUDHPwdGnrnwxmUOU2fFQqFA== +typescript-eslint@^7.18.0, typescript-eslint@^7.3.1: + version "7.18.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-7.18.0.tgz#e90d57649b2ad37a7475875fa3e834a6d9f61eb2" + integrity sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA== dependencies: - "@typescript-eslint/eslint-plugin" "7.15.0" - "@typescript-eslint/parser" "7.15.0" - "@typescript-eslint/utils" "7.15.0" + "@typescript-eslint/eslint-plugin" "7.18.0" + "@typescript-eslint/parser" "7.18.0" + "@typescript-eslint/utils" "7.18.0" "typescript@^3 || ^4": version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -typescript@^5.5.3, typescript@~5.5.0-dev.20240327: - version "5.5.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.3.tgz#e1b0a3c394190838a0b168e771b0ad56a0af0faa" - integrity sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ== +typescript@^5.6.2, typescript@~5.6.1-rc, typescript@~5.6.2: + version "5.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" + integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== + +uc.micro@^2.0.0, uc.micro@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" + integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A== uglify-js@^3.1.4: version "3.17.4" @@ -11631,10 +11681,10 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.11.1: + version "6.11.1" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.11.1.tgz#432ea6e8efd54a48569705a699e62d8f4981b197" + integrity sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" @@ -11792,16 +11842,6 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -vscode-oniguruma@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" - integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== - -vscode-textmate@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== - walk-up-path@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e" @@ -12066,10 +12106,10 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yaml@^2.2.2, yaml@^2.3.4: - version "2.4.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.2.tgz#7a2b30f2243a5fc299e1f14ca58d475ed4bc5362" - integrity sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA== +yaml@^2.2.2, yaml@^2.3.4, yaml@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130" + integrity sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q== yargs-parser@20.2.4: version "20.2.4"