Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force xsnap rebuild #9618

Merged
merged 3 commits into from
Jul 1, 2024
Merged

Force xsnap rebuild #9618

merged 3 commits into from
Jul 1, 2024

Conversation

mhofman
Copy link
Member

@mhofman mhofman commented Jun 30, 2024

closes: #9614
closes: #7012
refs: agoric-labs/xsnap-pub#49

Description

Wire a mechanism to force rebuilds of xsnap when some build environments change, or if the xsnap binary is found to be out of date through the embedded xsnap package version.

Moves the agd build check to depend on a version check implemented by the xsnap package, which now only depends on the package version that is dynamically inserted instead of an explicit magic string that wasn't getting updated.

#7012 (comment) expressed concerns with relying on the xsnap package version, however:

  • any changes to xsnap-pub or moddable submodules would result in a change to the checked in build.env file, which would be detected by lerna during the publish process. While a version bump would not apply for contributors of the sdk (aka not every xsnap change results in a version change), it will apply for anyone using published versions, even if the change is in submodules only.
  • By having the version check look up the expected version from the package.json file directly, we avoid having to modify both the package.json file and the check itself. Only the automatically generated single publish commit will trigger a forced rebuild, and satisfy the check on its own,
  • At the same time we remove the dependency of agd build onto the the internal structure of xsnap.

Security Considerations

Forces all validators to use the expected version of xsnap

Scaling Considerations

Does a few more checks when building xsnap, and causes full rebuilds in some cases where they might not be strictly necessary.

Documentation Considerations

Should all be transparent

Testing Considerations

Manually tested by touching the xsnap package version, or reverting just the release binary to a previous copy (or deleting altogether). If the binary is meddled with like this, agd build checks will fail, but a manual yarn build will fix. I thought this was better than transparently forcing a rebuild in that abnormal situation.

Upgrade Considerations

Smoother upgrades by validators

@mhofman mhofman requested review from warner and kriskowal June 30, 2024 08:36
@mhofman mhofman added the force:integration Force integration tests to run on PR label Jun 30, 2024
@michaelfig
Copy link
Member

Inserting myself as a reviewer, since I'm intimately familiar with the current xsnap build mechanism.

@michaelfig michaelfig self-requested a review June 30, 2024 18:01
Copy link
Member

@michaelfig michaelfig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address shell quoting and sed portability fixes. Otherwise, this looks really good! I'm glad to see your evolution of the build process.

@@ -1,4 +1,4 @@
MODDABLE_URL=https://github.com/agoric-labs/moddable.git
MODDABLE_COMMIT_HASH=f6c5951fc055e4ca592b9166b9ae3cbb9cca6bf0
XSNAP_NATIVE_URL=https://github.com/agoric-labs/xsnap-pub
XSNAP_NATIVE_COMMIT_HASH=2d8ccb76b8508e490d9e03972bb4c64f402d5135
XSNAP_NATIVE_COMMIT_HASH=6e7161a3022dc40d70cbf49f02b07dbc5a10c013
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I audited the differences between these two commits, and verified that the changes looked beneficial and non-breaking.

esac

# extract the xsnap package version from the long version printed by xsnap-worker
./xsnap-native/xsnap/build/bin/${platform}/release/xsnap-worker -v | sed -e 's/^xsnap\s\+\([^\s]\+\)\s\+(XS\s\+[^)]\+)$/\1/g'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses sed features that aren't available under Darwin (\s and \+), which makes me suspect they're GNUish or otherwise non-POSIX (possibly just a newer POSIX than macOS). Can we use something more straightforward?

Also, please habitually quote shell variable expansions in things you'd expect to be a single token. (They're also not strictly necessary for vname=$anything or case $vname. Yes, shell quoting rules are really weird and have lots of corner cases.)

Suggested change
./xsnap-native/xsnap/build/bin/${platform}/release/xsnap-worker -v | sed -e 's/^xsnap\s\+\([^\s]\+\)\s\+(XS\s\+[^)]\+)$/\1/g'
"./xsnap-native/xsnap/build/bin/${platform}/release/xsnap-worker" -v | sed -e 's/^xsnap *\([^( ]*\).*/\1/'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I got an error under linux (a docker container, under a macOS host):

node $ yarn build
yarn run v1.22.22
$ yarn build:bin && yarn build:env
$ if test -d ./test; then node src/build.js; else yarn build:from-env; fi
./scripts/get_xsnap_version.sh: 3: set: Illegal option -o pipefail
sh: 1: [[: not found

If I change the script to use /bin/bash instead of /bin/sh, it stops complaining about -o pipefail, but I still get the [[: not found error.

In both cases, the exit code is zero, so somehow this [[: not found is not actually causing a failure, so in my environment yarn check-version isn't really enforcing the version. I double-checked this by modifying my package.json to tweak the version: property, then re-ran yarn check-version without first doing a yarn build, and the exit code was still zero. So I think the [[: not found error is inhibiting the intended check and giving a false positive result.

If I change the package.json script line from [[ to [ (and ]] to ]), it seems to work as intended. Is the double-[[ something to deal with quoting?

I'd suggest moving the comparison logic into a separate scripts/check_xsnap_version.js, which knows how to run xsnap as a child process, use a real RegExp to parse the result (avoiding sed and the tricky shell quoting), can sense whether $npm_package_version is missing (indicating someone is mistakenly running the script outside of a yarn context), and which can exit(1) internally. Basically, avoid using a shell for anything except launching a JS program :).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sed is indeed a pain, it doesn't support common regular expression features unless you get into non posix land. Anyway, I simplified the expression. It should still work without issues as long as we don't tweak the -v output.

scripts/agd-builder.sh Outdated Show resolved Hide resolved
Comment on lines -225 to -236
# the xsnap binary lives in a platform-specific directory
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) platform=lin ;;
Darwin*) platform=mac ;;
*) platform=win ;;
esac

# check the xsnap version against our baked-in notion of what version we should be using
xsnap_version=$("${thisdir}/../packages/xsnap/xsnap-native/xsnap/build/bin/${platform}/release/xsnap-worker" -n)
[[ "${xsnap_version}" == "${XSNAP_VERSION}" ]] || fatal "xsnap version mismatch; expected ${XSNAP_VERSION}, got ${xsnap_version}"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to see this go! 💯

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well arguably it moved

Copy link

cloudflare-workers-and-pages bot commented Jun 30, 2024

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2b53896
Status: ✅  Deploy successful!
Preview URL: https://0bb9313b.agoric-sdk.pages.dev
Branch Preview URL: https://mhofman-9614-xsnap-rebuild.agoric-sdk.pages.dev

View logs


const expectedConfigEnvs = configEnvs.concat('').join('\n');
if (forceBuild || existingConfigEnvs.trim() !== expectedConfigEnvs.trim()) {
await fs.writeFile(configEnvFile, expectedConfigEnvs);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, so we update build.config.env if it differs from the const configEnvs here in build.js, and build.config.env is added as a *.o dependency via EXTRA_DEPS, so modifying most of src/build.js won't cause a rebuild, but modifying the -D__has_builtin or the XSNAP_VERSION value will.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or if forceBuild is passed, which is if we detect a version mismatch, in case someone mucked around with the binary directly

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good enough, it assumes that bash is available, but I'll admit that's likely, and easier than figuring out how to write this in the purely sh subset

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well arguably this is already posix 2022 compliant, it's just that most shells still don't support -o pipefail in their posix mode.

I suppose I could check for the existence of the binary first before trying to invoke it

Copy link
Member

@warner warner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • confirmed that touch build.config.env && yarn build does a full rebuild
  • confirmed that subsequent yarn build does not rebuild
  • confirmed that yarn check-version fails (with rc=1) when I modify the package.json xsnap version:
  • confirmed: changing the -D__has_builtin in const configEnvs inside src/build.js, makes yarn build do a full build
  • confirmed: overwriting ./xsnap-native/xsnap/build/bin/lin/release/xsnap-worker with a stale version, causes yarn build to do a rebuild

Looks good to me.

@mhofman mhofman added the automerge:rebase Automatically rebase updates, then merge label Jul 1, 2024
@mhofman mhofman force-pushed the mhofman/9614-xsnap-rebuild branch from ace552a to 2b53896 Compare July 1, 2024 00:52
@mergify mergify bot merged commit 78b6fec into master Jul 1, 2024
77 checks passed
@mergify mergify bot deleted the mhofman/9614-xsnap-rebuild branch July 1, 2024 01:25
mhofman pushed a commit that referenced this pull request Jul 1, 2024
closes: #9614
closes: #7012
refs: agoric-labs/xsnap-pub#49

## Description
Wire a mechanism to force rebuilds of xsnap when some build environments change, or if the xsnap binary is found to be out of date through the embedded xsnap package version.

Moves the `agd build` check to depend on a version check implemented by the xsnap package, which now only depends on the package version that is dynamically inserted instead of an explicit magic string that wasn't getting updated.

#7012 (comment) expressed concerns with relying on the xsnap package version, however:
- any changes to `xsnap-pub` or `moddable` submodules would result in a change to the checked in `build.env` file, which would be detected by `lerna` during the publish process. While a version bump would not apply for contributors of the sdk (aka not every xsnap change results in a version change), it will apply for anyone using published versions, even if the change is in submodules only.
- By having the version check look up the expected version from the `package.json` file directly, we avoid having to modify both  the `package.json` file and the check itself. Only the automatically generated single publish commit will trigger a forced rebuild, and satisfy the check on its own,
- At the same time we remove the dependency of `agd build` onto the the internal structure of xsnap.

### Security Considerations
Forces all validators to use the expected version of xsnap

### Scaling Considerations
Does a few more checks when building xsnap, and causes full rebuilds in some cases where they might not be strictly necessary.

### Documentation Considerations
Should all be transparent

### Testing Considerations
Manually tested by touching the xsnap package version, or reverting just the release binary to a previous copy (or deleting altogether). If the binary is meddled with like this, `agd build` checks will fail, but a manual `yarn build` will fix. I thought this was better than transparently forcing a rebuild in that abnormal situation.

### Upgrade Considerations
Smoother upgrades by validators
gibson042 added a commit that referenced this pull request Jul 1, 2024
Rebase todo

```
# Branch fix-vow-include-vat-js-in-package-files-9607-
label base-fix-vow-include-vat-js-in-package-files-9607-
pick b6ffa6f fix(vow): include vat.js in package files
label fix-vow-include-vat-js-in-package-files-9607-
reset base-fix-vow-include-vat-js-in-package-files-9607-
merge -C a3826e9 fix-vow-include-vat-js-in-package-files-9607- # fix(vow): include vat.js in package files (#9607)

# Pull Request #9601
pick 6bc363b fix(cosmos): only allow snapshot export at latest height (#9601)

# Branch Force-xsnap-rebuild-9618-
label base-Force-xsnap-rebuild-9618-
pick 467435a fix(xsnap): force rebuild if build config changes
pick a22772e fix(agd): check xsnap was rebuilt
pick 2b53896 feat(xsnap): force rebuild if binary version mismatch
label Force-xsnap-rebuild-9618-
reset base-Force-xsnap-rebuild-9618-
merge -C 78b6fec Force-xsnap-rebuild-9618- # Force xsnap rebuild (#9618)

# Branch agd-enforce-Node-js-version-9623-
label base-agd-enforce-Node-js-version-9623-
#pick 4b35caf revert fix: typescript-estree does not support Node.js LTS (#9619)
pick 5f01bef fix(agd): force own node.js version check
label agd-enforce-Node-js-version-9623-
reset base-agd-enforce-Node-js-version-9623-
merge -C 4f70e66 agd-enforce-Node-js-version-9623- # agd enforce Node.js version (#9623)

# Branch gibson-9623-followup
label base-gibson-9623-followup
pick 6102eb9 fix: Disallow Node.js major version >20
label gibson-9623-followup
reset base-gibson-9623-followup
merge -C caaec05 gibson-9623-followup # (upstream/master) fix: Disallow Node.js major version >20 (#9630)
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge force:integration Force integration tests to run on PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

xsnap doesn't rebuild when make env changes Enforce xsnap version on chain start
3 participants