Skip to content

Commit

Permalink
feat(op-program): Minimal Reproducible Absolute Prestate (#8957)
Browse files Browse the repository at this point in the history
* feat(op-program): Very minimal reproducible absolute prestate build

* fix(cannon): Update docs to use reproducible absolute prestate

* feat(ci): validate absolute prestate in ci

* fix(ci): enable docker buildkit

* fix(op-program): clean up docs and remove ci

* fix(op-program): clean up dockerfile inline docs

* fix(op-program): reproducible absolute pre-state hash fixes

* fix(cannon): Add back docs
  • Loading branch information
refcell authored Jan 12, 2024
1 parent cef704a commit c7bd8fa
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ cannon:
make -C ./cannon cannon
.PHONY: cannon

reproducible-prestate:
make -C ./op-program reproducible-prestate
.PHONY: reproducible-prestate

cannon-prestate: op-program cannon
./cannon/bin/cannon load-elf --path op-program/bin/op-program-client.elf --out op-program/bin/prestate.json --meta op-program/bin/meta.json
./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate.json --meta op-program/bin/meta.json --proof-fmt 'op-program/bin/%d.json' --output ""
Expand Down
51 changes: 51 additions & 0 deletions op-program/Dockerfile.repro
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
FROM golang:1.21.3-alpine3.18 as builder

RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash

COPY ./go.mod /app/go.mod
COPY ./go.sum /app/go.sum

WORKDIR /app

RUN echo "go mod cache: $(go env GOMODCACHE)"
RUN echo "go build cache: $(go env GOCACHE)"

RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go mod download

COPY . /app

# We avoid copying the full .git dir into the build for just some metadata.
# Instead, specify:
# --build-arg GIT_COMMIT=$(git rev-parse HEAD)
# --build-arg GIT_DATE=$(git show -s --format='%ct')
ARG GIT_COMMIT
ARG GIT_DATE

ARG CANNON_VERSION=v0.0.0
ARG OP_PROGRAM_VERSION=v0.0.0

ARG TARGETOS TARGETARCH

# Build the cannon, op-program, and op-program-client.elf binaries.
RUN --mount=type=cache,target=/root/.cache/go-build cd cannon && make cannon \
GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$CANNON_VERSION"
RUN --mount=type=cache,target=/root/.cache/go-build cd op-program && make op-program-host \
GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_PROGRAM_VERSION"
RUN --mount=type=cache,target=/root/.cache/go-build cd op-program && make op-program-client-mips \
GOOS=linux GOARCH=mips GOMIPS=softfloat GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_PROGRAM_VERSION"

# Run the op-program-client.elf binary directly through cannon's load-elf subcommand.
RUN /app/cannon/bin/cannon load-elf --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate.json --meta ""

# Generate the prestate proof containing the absolute pre-state hash.
RUN /app/cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input /app/op-program/bin/prestate.json --meta "" --proof-fmt '/app/op-program/bin/%d.json' --output ""
RUN mv /app/op-program/bin/0.json /app/op-program/bin/prestate-proof.json

# Exports files to the specified output location.
# Writing files to host requires buildkit to be enabled.
# e.g. `BUILDKIT=1 docker build ...`
FROM scratch AS export-stage
COPY --from=builder /app/op-program/bin/op-program .
COPY --from=builder /app/op-program/bin/op-program-client.elf .
COPY --from=builder /app/op-program/bin/prestate.json .
COPY --from=builder /app/op-program/bin/prestate-proof.json .
6 changes: 6 additions & 0 deletions op-program/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ op-program-client-mips:
# verify output with: readelf -h bin/op-program-client.elf
# result is mips32, big endian, R3000

reproducible-prestate:
@docker build --output ./bin/ --progress plain -f Dockerfile.repro ../
@echo "Absolute prestate hash:"
@cat ./bin/prestate-proof.json | jq -r .pre
.PHONY: reproducible-prestate

clean:
rm -rf bin "$(COMPAT_DIR)"

Expand Down
20 changes: 20 additions & 0 deletions op-program/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,23 @@ From within the `op-program` directory, options can be reviewed with:
```shell
./bin/op-program --help
```

## Generating the Absolute Prestate

The absolute pre-state of the op-program can be generated by executing the makefile
`reproducible-prestate` target. Effectively, this builds a docker image specified
by [Dockerfile.repro](./Dockerfile.repro) pinned with the following dependencies:
- golang version `1.21.3`
- alpine `3.18`

After running `make reproducible-prestate`, the following files can be found in
[./bin/](./bin/):
- [`op-program`](./bin/op-program)
- [`op-program-client.elf`](./bin/op-program-client.elf)
- [`prestate.json`](./bin/prestate.json)
- [`prestate-proof.json`](./bin/prestate-proof.json)

The `prestate-proof.json` file is what contains the absolute pre-state hash under
the `.pre` key that is also used by the [contracts][ctb] deploy script.

[ctb]: ../packages/contracts-bedrock/

0 comments on commit c7bd8fa

Please sign in to comment.