Skip to content

Commit

Permalink
Merge branch 'master' into fast_confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
amsanghi authored Jul 11, 2024
2 parents 29b51d2 + 1fcaf60 commit 4f73761
Show file tree
Hide file tree
Showing 28 changed files with 1,559 additions and 178 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,20 @@ jobs:
run: |
cd nitro-testnode
./test-node.bash --init --dev &
- name: Wait for rpc to come up
shell: bash
run: |
${{ github.workspace }}/.github/workflows/waitForNitro.sh
- name: Print WAVM module root
id: module-root
run: |
# Unfortunately, `docker cp` seems to always result in a "permission denied"
# We work around this by piping a tarball through stdout
docker run --rm --entrypoint tar localhost:5000/nitro-node-dev:latest -cf - target/machines/latest | tar xf -
module_root="$(cat "target/machines/latest/module-root.txt")"
echo "name=module-root=$module_root" >> $GITHUB_STATE
echo "module-root=$module_root" >> "$GITHUB_OUTPUT"
echo -e "\x1b[1;34mWAVM module root:\x1b[0m $module_root"
- name: Upload WAVM machine as artifact
Expand Down
42 changes: 32 additions & 10 deletions .github/workflows/merge-checks.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
name: Merge Checks

on:
pull_request:
pull_request_target:
branches: [ master ]
types: [synchronize, opened, reopened, labeled, unlabeled]

permissions:
statuses: write

jobs:
design-approved-check:
if: ${{ !contains(github.event.*.labels.*.name, 'design-approved') }}
name: Design Approved Check
check-design-approved:
name: Check if Design Approved
runs-on: ubuntu-latest
steps:
- name: Check for design-approved label
- name: Check if design approved and update status
run: |
echo "Pull request is missing the 'design-approved' label"
echo "This workflow fails so that the pull request cannot be merged"
exit 1
set -x pipefail
status_state="pending"
if ${{ contains(github.event.*.labels.*.name, 'design-approved') }}; then
status_state="success"
else
resp="$(curl -sSL --fail-with-body \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/commits/${{ github.event.pull_request.head.sha }}/statuses")"
if ! jq -e '.[] | select(.context == "Design Approved Check")' > /dev/null <<< "$resp"; then
# Design not approved yet and no status exists
# Keep it without a status to keep the green checkmark appearing
# Otherwise, the commit and PR's CI will appear to be indefinitely pending
# Merging will still be blocked until the required status appears
exit 0
fi
fi
curl -sSL --fail-with-body \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/statuses/${{ github.event.pull_request.head.sha }}" \
-d '{"context":"Design Approved Check","state":"'"$status_state"'"}'
49 changes: 25 additions & 24 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM debian:bookworm-slim as brotli-wasm-builder
FROM debian:bookworm-slim AS brotli-wasm-builder
WORKDIR /workspace
RUN apt-get update && \
apt-get install -y cmake make git lbzip2 python3 xz-utils && \
Expand All @@ -10,21 +10,21 @@ COPY scripts/build-brotli.sh scripts/
COPY brotli brotli
RUN cd emsdk && . ./emsdk_env.sh && cd .. && ./scripts/build-brotli.sh -w -t /workspace/install/

FROM scratch as brotli-wasm-export
FROM scratch AS brotli-wasm-export
COPY --from=brotli-wasm-builder /workspace/install/ /

FROM debian:bookworm-slim as brotli-library-builder
FROM debian:bookworm-slim AS brotli-library-builder
WORKDIR /workspace
COPY scripts/build-brotli.sh scripts/
COPY brotli brotli
RUN apt-get update && \
apt-get install -y cmake make gcc git && \
./scripts/build-brotli.sh -l -t /workspace/install/

FROM scratch as brotli-library-export
FROM scratch AS brotli-library-export
COPY --from=brotli-library-builder /workspace/install/ /

FROM node:18-bookworm-slim as contracts-builder
FROM node:18-bookworm-slim AS contracts-builder
RUN apt-get update && \
apt-get install -y git python3 make g++ curl
RUN curl -L https://foundry.paradigm.xyz | bash && . ~/.bashrc && ~/.foundry/bin/foundryup
Expand All @@ -37,11 +37,11 @@ RUN cd safe-smart-account && yarn install
COPY Makefile .
RUN . ~/.bashrc && NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-solidity

FROM debian:bookworm-20231218 as wasm-base
FROM debian:bookworm-20231218 AS wasm-base
WORKDIR /workspace
RUN apt-get update && apt-get install -y curl build-essential=12.9

FROM wasm-base as wasm-libs-builder
FROM wasm-base AS wasm-libs-builder
# clang / lld used by soft-float wasm
RUN apt-get update && \
apt-get install -y clang=1:14.0-55.7~deb12u1 lld=1:14.0-55.7~deb12u1 wabt
Expand All @@ -61,10 +61,10 @@ COPY --from=brotli-wasm-export / target/
RUN apt-get update && apt-get install -y cmake
RUN . ~/.cargo/env && NITRO_BUILD_IGNORE_TIMESTAMPS=1 RUSTFLAGS='-C symbol-mangling-version=v0' make build-wasm-libs

FROM scratch as wasm-libs-export
FROM scratch AS wasm-libs-export
COPY --from=wasm-libs-builder /workspace/ /

FROM wasm-base as wasm-bin-builder
FROM wasm-base AS wasm-bin-builder
# pinned go version
RUN curl -L https://golang.org/dl/go1.21.10.linux-`dpkg --print-architecture`.tar.gz | tar -C /usr/local -xzf -
COPY ./Makefile ./go.mod ./go.sum ./
Expand Down Expand Up @@ -94,7 +94,7 @@ COPY --from=contracts-builder workspace/contracts/node_modules/@offchainlabs/upg
COPY --from=contracts-builder workspace/.make/ .make/
RUN PATH="$PATH:/usr/local/go/bin" NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-wasm-bin

FROM rust:1.75-slim-bookworm as prover-header-builder
FROM rust:1.75-slim-bookworm AS prover-header-builder
WORKDIR /workspace
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
Expand All @@ -116,10 +116,10 @@ COPY brotli brotli
RUN apt-get update && apt-get install -y cmake
RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-prover-header

FROM scratch as prover-header-export
FROM scratch AS prover-header-export
COPY --from=prover-header-builder /workspace/target/ /

FROM rust:1.75-slim-bookworm as prover-builder
FROM rust:1.75-slim-bookworm AS prover-builder
WORKDIR /workspace
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
Expand Down Expand Up @@ -159,10 +159,10 @@ RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-prover-lib
RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-prover-bin
RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-jit

FROM scratch as prover-export
FROM scratch AS prover-export
COPY --from=prover-builder /workspace/target/ /

FROM debian:bookworm-slim as module-root-calc
FROM debian:bookworm-slim AS module-root-calc
WORKDIR /workspace
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
Expand All @@ -185,7 +185,7 @@ COPY ./contracts ./contracts
COPY ./safe-smart-account ./safe-smart-account
RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-replay-env

FROM debian:bookworm-slim as machine-versions
FROM debian:bookworm-slim AS machine-versions
RUN apt-get update && apt-get install -y unzip wget curl
WORKDIR /workspace/machines
# Download WAVM machines
Expand All @@ -209,8 +209,9 @@ COPY ./scripts/download-machine.sh .
#RUN ./download-machine.sh consensus-v11.1 0x68e4fe5023f792d4ef584796c84d710303a5e12ea02d6e37e2b5e9c4332507c4
#RUN ./download-machine.sh consensus-v20 0x8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4
RUN ./download-machine.sh consensus-v30 0xb0de9cb89e4d944ae6023a3b62276e54804c242fd8c4c2d8e6cc4450f5fa8b1b && true
RUN ./download-machine.sh consensus-v31 0x260f5fa5c3176a856893642e149cf128b5a8de9f828afec8d11184415dd8dc69

FROM golang:1.21.10-bookworm as node-builder
FROM golang:1.21.10-bookworm AS node-builder
WORKDIR /workspace
ARG version=""
ARG datetime=""
Expand Down Expand Up @@ -238,17 +239,17 @@ RUN mkdir -p target/bin
COPY .nitro-tag.txt /nitro-tag.txt
RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build

FROM node-builder as fuzz-builder
FROM node-builder AS fuzz-builder
RUN mkdir fuzzers/
RUN ./scripts/fuzz.bash --build --binary-path /workspace/fuzzers/

FROM debian:bookworm-slim as nitro-fuzzer
FROM debian:bookworm-slim AS nitro-fuzzer
COPY --from=fuzz-builder /workspace/fuzzers/*.fuzz /usr/local/bin/
COPY ./scripts/fuzz.bash /usr/local/bin
RUN mkdir /fuzzcache
ENTRYPOINT [ "/usr/local/bin/fuzz.bash", "FuzzStateTransition", "--binary-path", "/usr/local/bin/", "--fuzzcache-path", "/fuzzcache" ]

FROM debian:bookworm-slim as nitro-node-slim
FROM debian:bookworm-slim AS nitro-node-slim
WORKDIR /home/user
COPY --from=node-builder /workspace/target/bin/nitro /usr/local/bin/
COPY --from=node-builder /workspace/target/bin/relay /usr/local/bin/
Expand Down Expand Up @@ -276,9 +277,9 @@ USER user
WORKDIR /home/user/
ENTRYPOINT [ "/usr/local/bin/nitro" ]

FROM offchainlabs/nitro-node:v2.3.4-rc.5-b4cc111 as nitro-legacy
FROM offchainlabs/nitro-node:v2.3.4-rc.5-b4cc111 AS nitro-legacy

FROM nitro-node-slim as nitro-node
FROM nitro-node-slim AS nitro-node
USER root
COPY --from=prover-export /bin/jit /usr/local/bin/
COPY --from=node-builder /workspace/target/bin/daserver /usr/local/bin/
Expand All @@ -298,7 +299,7 @@ ENTRYPOINT [ "/usr/local/bin/nitro" , "--validation.wasm.allowed-wasm-module-roo

USER user

FROM nitro-node as nitro-node-validator
FROM nitro-node AS nitro-node-validator
USER root
COPY --from=nitro-legacy /usr/local/bin/nitro-val /home/user/nitro-legacy/bin/nitro-val
COPY --from=nitro-legacy /usr/local/bin/jit /home/user/nitro-legacy/bin/jit
Expand All @@ -310,7 +311,7 @@ COPY scripts/split-val-entry.sh /usr/local/bin
ENTRYPOINT [ "/usr/local/bin/split-val-entry.sh" ]
USER user

FROM nitro-node-validator as nitro-node-dev
FROM nitro-node-validator AS nitro-node-dev
USER root
# Copy in latest WASM module root
RUN rm -f /home/user/target/machines/latest
Expand All @@ -334,5 +335,5 @@ RUN export DEBIAN_FRONTEND=noninteractive && \

USER user

FROM nitro-node as nitro-node-default
FROM nitro-node AS nitro-node-default
# Just to ensure nitro-node-dist is default
48 changes: 37 additions & 11 deletions arbnode/batch_poster.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ type BatchPosterConfig struct {
UseAccessLists bool `koanf:"use-access-lists" reload:"hot"`
GasEstimateBaseFeeMultipleBips arbmath.Bips `koanf:"gas-estimate-base-fee-multiple-bips"`
Dangerous BatchPosterDangerousConfig `koanf:"dangerous"`
ReorgResistanceMargin time.Duration `koanf:"reorg-resistance-margin" reload:"hot"`

gasRefunder common.Address
l1BlockBound l1BlockBound
Expand Down Expand Up @@ -219,6 +220,7 @@ func BatchPosterConfigAddOptions(prefix string, f *pflag.FlagSet) {
f.Duration(prefix+".l1-block-bound-bypass", DefaultBatchPosterConfig.L1BlockBoundBypass, "post batches even if not within the layer 1 future bounds if we're within this margin of the max delay")
f.Bool(prefix+".use-access-lists", DefaultBatchPosterConfig.UseAccessLists, "post batches with access lists to reduce gas usage (disabled for L3s)")
f.Uint64(prefix+".gas-estimate-base-fee-multiple-bips", uint64(DefaultBatchPosterConfig.GasEstimateBaseFeeMultipleBips), "for gas estimation, use this multiple of the basefee (measured in basis points) as the max fee per gas")
f.Duration(prefix+".reorg-resistance-margin", DefaultBatchPosterConfig.ReorgResistanceMargin, "do not post batch if its within this duration from layer 1 minimum bounds. Requires l1-block-bound option not be set to \"ignore\"")
redislock.AddConfigOptions(prefix+".redis-lock", f)
dataposter.DataPosterConfigAddOptions(prefix+".data-poster", f, dataposter.DefaultDataPosterConfig)
genericconf.WalletConfigAddOptions(prefix+".parent-chain-wallet", f, DefaultBatchPosterConfig.ParentChainWallet.Pathname)
Expand Down Expand Up @@ -248,6 +250,7 @@ var DefaultBatchPosterConfig = BatchPosterConfig{
UseAccessLists: true,
RedisLock: redislock.DefaultCfg,
GasEstimateBaseFeeMultipleBips: arbmath.OneInBips * 3 / 2,
ReorgResistanceMargin: 10 * time.Minute,
}

var DefaultBatchPosterL1WalletConfig = genericconf.WalletConfig{
Expand Down Expand Up @@ -1136,6 +1139,8 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error)
var l1BoundMaxTimestamp uint64 = math.MaxUint64
var l1BoundMinBlockNumber uint64
var l1BoundMinTimestamp uint64
var l1BoundMinBlockNumberWithBypass uint64
var l1BoundMinTimestampWithBypass uint64
hasL1Bound := config.l1BlockBound != l1BlockBoundIgnore
if hasL1Bound {
var l1Bound *types.Header
Expand Down Expand Up @@ -1180,17 +1185,19 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error)
l1BoundMaxBlockNumber = arbmath.SaturatingUAdd(l1BoundBlockNumber, arbmath.BigToUintSaturating(maxTimeVariationFutureBlocks))
l1BoundMaxTimestamp = arbmath.SaturatingUAdd(l1Bound.Time, arbmath.BigToUintSaturating(maxTimeVariationFutureSeconds))

latestHeader, err := b.l1Reader.LastHeader(ctx)
if err != nil {
return false, err
}
latestBlockNumber := arbutil.ParentHeaderToL1BlockNumber(latestHeader)
l1BoundMinBlockNumber = arbmath.SaturatingUSub(latestBlockNumber, arbmath.BigToUintSaturating(maxTimeVariationDelayBlocks))
l1BoundMinTimestamp = arbmath.SaturatingUSub(latestHeader.Time, arbmath.BigToUintSaturating(maxTimeVariationDelaySeconds))

if config.L1BlockBoundBypass > 0 {
latestHeader, err := b.l1Reader.LastHeader(ctx)
if err != nil {
return false, err
}
latestBlockNumber := arbutil.ParentHeaderToL1BlockNumber(latestHeader)
blockNumberWithPadding := arbmath.SaturatingUAdd(latestBlockNumber, uint64(config.L1BlockBoundBypass/ethPosBlockTime))
timestampWithPadding := arbmath.SaturatingUAdd(latestHeader.Time, uint64(config.L1BlockBoundBypass/time.Second))

l1BoundMinBlockNumber = arbmath.SaturatingUSub(blockNumberWithPadding, arbmath.BigToUintSaturating(maxTimeVariationDelayBlocks))
l1BoundMinTimestamp = arbmath.SaturatingUSub(timestampWithPadding, arbmath.BigToUintSaturating(maxTimeVariationDelaySeconds))
l1BoundMinBlockNumberWithBypass = arbmath.SaturatingUSub(blockNumberWithPadding, arbmath.BigToUintSaturating(maxTimeVariationDelayBlocks))
l1BoundMinTimestampWithBypass = arbmath.SaturatingUSub(timestampWithPadding, arbmath.BigToUintSaturating(maxTimeVariationDelaySeconds))
}
}

Expand All @@ -1200,13 +1207,14 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error)
log.Error("error getting message from streamer", "error", err)
break
}
if msg.Message.Header.BlockNumber < l1BoundMinBlockNumber || msg.Message.Header.Timestamp < l1BoundMinTimestamp {
if msg.Message.Header.BlockNumber < l1BoundMinBlockNumberWithBypass || msg.Message.Header.Timestamp < l1BoundMinTimestampWithBypass {
log.Error(
"disabling L1 bound as batch posting message is close to the maximum delay",
"blockNumber", msg.Message.Header.BlockNumber,
"l1BoundMinBlockNumber", l1BoundMinBlockNumber,
"l1BoundMinBlockNumberWithBypass", l1BoundMinBlockNumberWithBypass,
"timestamp", msg.Message.Header.Timestamp,
"l1BoundMinTimestamp", l1BoundMinTimestamp,
"l1BoundMinTimestampWithBypass", l1BoundMinTimestampWithBypass,
"l1BlockBoundBypass", config.L1BlockBoundBypass,
)
l1BoundMaxBlockNumber = math.MaxUint64
l1BoundMaxTimestamp = math.MaxUint64
Expand Down Expand Up @@ -1242,6 +1250,24 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error)
b.building.msgCount++
}

if hasL1Bound && config.ReorgResistanceMargin > 0 {
firstMsgBlockNumber := firstMsg.Message.Header.BlockNumber
firstMsgTimeStamp := firstMsg.Message.Header.Timestamp
batchNearL1BoundMinBlockNumber := firstMsgBlockNumber <= arbmath.SaturatingUAdd(l1BoundMinBlockNumber, uint64(config.ReorgResistanceMargin/ethPosBlockTime))
batchNearL1BoundMinTimestamp := firstMsgTimeStamp <= arbmath.SaturatingUAdd(l1BoundMinTimestamp, uint64(config.ReorgResistanceMargin/time.Second))
if batchNearL1BoundMinTimestamp || batchNearL1BoundMinBlockNumber {
log.Error(
"Disabling batch posting due to batch being within reorg resistance margin from layer 1 minimum block or timestamp bounds",
"reorgResistanceMargin", config.ReorgResistanceMargin,
"firstMsgTimeStamp", firstMsgTimeStamp,
"l1BoundMinTimestamp", l1BoundMinTimestamp,
"firstMsgBlockNumber", firstMsgBlockNumber,
"l1BoundMinBlockNumber", l1BoundMinBlockNumber,
)
return false, errors.New("batch is within reorg resistance margin from layer 1 minimum block or timestamp bounds")
}
}

if !forcePostBatch || !b.building.haveUsefulMessage {
// the batch isn't full yet and we've posted a batch recently
// don't post anything for now
Expand Down
5 changes: 4 additions & 1 deletion broadcastclient/broadcastclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (

"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"

"github.com/offchainlabs/nitro/arbutil"
m "github.com/offchainlabs/nitro/broadcaster/message"
"github.com/offchainlabs/nitro/util/contracts"
Expand Down Expand Up @@ -292,6 +291,10 @@ func (bc *BroadcastClient) connect(ctx context.Context, nextSeqNum arbutil.Messa
return nil, err
}
if err != nil {
connectionRejectedError := &ws.ConnectionRejectedError{}
if errors.As(err, &connectionRejectedError) && connectionRejectedError.StatusCode() == 429 {
log.Error("rate limit exceeded, please run own local relay because too many nodes are connecting to feed from same IP address", "err", err)
}
return nil, fmt.Errorf("broadcast client unable to connect: %w", err)
}
if config.RequireChainId && !foundChainId {
Expand Down
Loading

0 comments on commit 4f73761

Please sign in to comment.