Advance forge rollout, Ethereum rails, and NBC sources

This commit is contained in:
every.channel 2026-04-01 15:58:49 -07:00
parent be26313225
commit 7d84510eac
No known key found for this signature in database
88 changed files with 11230 additions and 302 deletions

View file

@ -0,0 +1,127 @@
#!/usr/bin/env bash
set -euo pipefail
remote="${EVERY_CHANNEL_REALITY_SMOKE_REMOTE:-root@git.every.channel}"
remote_jsonl="${EVERY_CHANNEL_REALITY_SMOKE_JSONL:-/var/lib/every-channel/manifests/la-cbs/video0.m4s.jsonl}"
remote_identity_file="${EVERY_CHANNEL_REALITY_SMOKE_SSH_IDENTITY_FILE:-${HOME}/.ssh/id_ed25519}"
anvil_port="${EVERY_CHANNEL_REALITY_SMOKE_ANVIL_PORT:-8545}"
results_dir="${EVERY_CHANNEL_REALITY_SMOKE_RESULTS_DIR:-./test-results}"
anvil_pk0="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
anvil_pk1="0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
anvil_pk2="0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"
mkdir -p "${results_dir}"
anvil_log="${results_dir}/anvil-reality-smoke.log"
deploy_json="${results_dir}/observation-ledger-deploy.json"
result_json="${results_dir}/anvil-reality-smoke.json"
cleanup() {
if [[ -n "${anvil_pid:-}" ]]; then
kill "${anvil_pid}" >/dev/null 2>&1 || true
wait "${anvil_pid}" >/dev/null 2>&1 || true
fi
}
trap cleanup EXIT
anvil --port "${anvil_port}" >"${anvil_log}" 2>&1 &
anvil_pid=$!
for _ in $(seq 1 30); do
if curl -fsS -X POST -H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
"http://127.0.0.1:${anvil_port}" >/dev/null 2>&1; then
break
fi
sleep 1
done
rpc_url="http://127.0.0.1:${anvil_port}"
owner_file="$(mktemp)"
printf '%s\n' "${anvil_pk0}" >"${owner_file}"
EVERY_CHANNEL_RPC_URL="${rpc_url}" \
EVERY_CHANNEL_PRIVATE_KEY_FILE="${owner_file}" \
EVERY_CHANNEL_OBSERVATION_DEPLOY_OUT="${deploy_json}" \
./scripts/op-stack/deploy-observation-ledger.sh >/dev/null
registry="$(jq -r '.registry' <"${deploy_json}")"
ledger="$(jq -r '.ledger' <"${deploy_json}")"
witness1="$(cast wallet address --private-key "${anvil_pk1}")"
witness2="$(cast wallet address --private-key "${anvil_pk2}")"
cast send "${registry}" "addWitness(address)" "${witness1}" --rpc-url "${rpc_url}" --private-key "${anvil_pk0}" >/dev/null
cast send "${registry}" "addWitness(address)" "${witness2}" --rpc-url "${rpc_url}" --private-key "${anvil_pk0}" >/dev/null
remote_jsonl_escaped="$(printf '%q' "${remote_jsonl}")"
entry="$(ssh \
-i "${remote_identity_file}" \
-o IdentityAgent=none \
-o IdentitiesOnly=yes \
-o BatchMode=yes \
-o ConnectTimeout=10 \
"${remote}" \
"head -n 1 -- ${remote_jsonl_escaped}")"
if [[ -z "${entry}" ]]; then
echo "no remote archive entry found" >&2
exit 1
fi
broadcast_name="$(jq -r '.broadcast_name' <<<"${entry}")"
track_name="$(jq -r '.track_name' <<<"${entry}")"
group_sequence="$(jq -r '.group_sequence' <<<"${entry}")"
received_unix_ms="$(jq -r '.received_unix_ms' <<<"${entry}")"
blake3_hex="$(jq -r '.blake3' <<<"${entry}")"
locator_material="$(jq -c '{relay_url,broadcast_name,track_name,group_sequence,cas_path}' <<<"${entry}")"
stream_hash="$(cast keccak "${broadcast_name}:${track_name}")"
epoch_hash="$(cast keccak "${broadcast_name}:${track_name}:${group_sequence}")"
parent_hash="0x0000000000000000000000000000000000000000000000000000000000000000"
data_root="0x${blake3_hex}"
locator_hash="$(cast keccak "${locator_material}")"
observation_tuple="(${stream_hash},${epoch_hash},${parent_hash},${data_root},${locator_hash},${received_unix_ms},${group_sequence})"
cast send "${ledger}" \
"proposeObservation((bytes32,bytes32,bytes32,bytes32,bytes32,uint64,uint64))" \
"${observation_tuple}" \
--rpc-url "${rpc_url}" \
--private-key "${anvil_pk1}" >/dev/null
observation_hash="$(cast call "${ledger}" \
"hashObservationHeader((bytes32,bytes32,bytes32,bytes32,bytes32,uint64,uint64))(bytes32)" \
"${observation_tuple}" \
--rpc-url "${rpc_url}")"
slot_hash="$(cast call "${ledger}" \
"observationSlot(bytes32,bytes32)(bytes32)" \
"${stream_hash}" "${epoch_hash}" \
--rpc-url "${rpc_url}")"
cast send "${ledger}" "attestObservation(bytes32)" "${observation_hash}" \
--rpc-url "${rpc_url}" \
--private-key "${anvil_pk2}" >/dev/null
finalized="$(cast call "${ledger}" "finalizedObservationBySlot(bytes32)(bytes32)" "${slot_hash}" --rpc-url "${rpc_url}")"
cat >"${result_json}" <<EOF
{
"remote": "${remote}",
"remote_jsonl": "${remote_jsonl}",
"broadcast_name": "${broadcast_name}",
"track_name": "${track_name}",
"group_sequence": ${group_sequence},
"stream_hash": "${stream_hash}",
"epoch_hash": "${epoch_hash}",
"observation_hash": "${observation_hash}",
"finalized_hash": "${finalized}",
"registry": "${registry}",
"ledger": "${ledger}"
}
EOF
if [[ "${finalized}" != "${observation_hash}" ]]; then
echo "observation did not finalize" >&2
exit 1
fi
printf '%s\n' "${result_json}"

View file

@ -0,0 +1,46 @@
#!/usr/bin/env bash
set -euo pipefail
rpc_url="${EVERY_CHANNEL_RPC_URL:?set EVERY_CHANNEL_RPC_URL}"
private_key_file="${EVERY_CHANNEL_PRIVATE_KEY_FILE:?set EVERY_CHANNEL_PRIVATE_KEY_FILE}"
quorum="${EVERY_CHANNEL_OBSERVATION_QUORUM:-2}"
out="${EVERY_CHANNEL_OBSERVATION_DEPLOY_OUT:-./test-results/observation-ledger-deploy.json}"
private_key="$(tr -d '\r\n' <"${private_key_file}")"
private_key="${private_key#0x}"
mkdir -p "$(dirname "${out}")"
forge build >/dev/null
owner="$(cast wallet address --private-key "0x${private_key}")"
registry_output="$(forge create contracts/EveryChannelWitnessRegistry.sol:EveryChannelWitnessRegistry \
--rpc-url "${rpc_url}" \
--private-key "0x${private_key}" \
--broadcast \
--constructor-args "${owner}")"
registry_address="$(printf '%s\n' "${registry_output}" | awk '/Deployed to:/ { print $3 }' | tail -n1)"
ledger_output="$(forge create contracts/EveryChannelObservationLedger.sol:EveryChannelObservationLedger \
--rpc-url "${rpc_url}" \
--private-key "0x${private_key}" \
--broadcast \
--constructor-args "${registry_address}" "${quorum}")"
ledger_address="$(printf '%s\n' "${ledger_output}" | awk '/Deployed to:/ { print $3 }' | tail -n1)"
if [[ -z "${registry_address}" || -z "${ledger_address}" ]]; then
echo "failed to deploy contracts" >&2
exit 1
fi
cat >"${out}" <<EOF
{
"owner": "${owner}",
"registry": "${registry_address}",
"ledger": "${ledger_address}",
"quorum": ${quorum}
}
EOF
printf '%s\n' "${out}"

View file

@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -euo pipefail
tag="${EVERY_CHANNEL_OP_DEPLOYER_TAG:-op-deployer/v0.6.0-rc.3}"
out="${EVERY_CHANNEL_OP_DEPLOYER_OUT:-./op-deployer}"
log() {
printf '[op-deployer] %s\n' "$*" >&2
}
detect_platform() {
local os arch
case "$(uname -s)" in
Darwin) os="darwin" ;;
Linux) os="linux" ;;
*) echo "unsupported-os" ; return 1 ;;
esac
case "$(uname -m)" in
aarch64|arm64) arch="arm64" ;;
x86_64|amd64) arch="amd64" ;;
*) echo "unsupported-arch" ; return 1 ;;
esac
printf '%s-%s\n' "$os" "$arch"
}
platform="$(detect_platform)"
if [[ "$platform" == unsupported-* ]]; then
log "unsupported platform: $(uname -s)/$(uname -m)"
exit 2
fi
version="${tag#op-deployer/v}"
archive="op-deployer-${version}-${platform}.tar.gz"
url="https://github.com/ethereum-optimism/optimism/releases/download/${tag}/${archive}"
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
log "downloading ${tag} for ${platform}"
curl -fsSL "$url" -o "${tmpdir}/archive.tar.gz"
tar -xzf "${tmpdir}/archive.tar.gz" -C "$tmpdir"
candidate="$(find "$tmpdir" -type f -name 'op-deployer*' -perm -u+x | head -n 1)"
if [[ -z "$candidate" ]]; then
log "failed to locate extracted op-deployer binary"
exit 1
fi
install -m 0755 "$candidate" "$out"
log "wrote ${out}"

245
scripts/op-stack/setup-rollup.sh Executable file
View file

@ -0,0 +1,245 @@
#!/usr/bin/env bash
set -euo pipefail
root="${EVERY_CHANNEL_OP_STACK_ROOT:?set EVERY_CHANNEL_OP_STACK_ROOT}"
private_key_file="${EVERY_CHANNEL_OP_STACK_PRIVATE_KEY_FILE:?set EVERY_CHANNEL_OP_STACK_PRIVATE_KEY_FILE}"
l1_rpc_url="${EVERY_CHANNEL_OP_STACK_L1_RPC_URL:-https://ethereum-sepolia-rpc.publicnode.com}"
l1_beacon_url="${EVERY_CHANNEL_OP_STACK_L1_BEACON_URL:-https://ethereum-sepolia-beacon-api.publicnode.com}"
chain_id="${EVERY_CHANNEL_OP_STACK_CHAIN_ID:-245245}"
p2p_advertise_ip="${EVERY_CHANNEL_OP_STACK_P2P_ADVERTISE_IP:-127.0.0.1}"
op_deployer_bin="${EVERY_CHANNEL_OP_DEPLOYER_BIN:-${root}/bin/op-deployer}"
download_script="${EVERY_CHANNEL_OP_DEPLOYER_DOWNLOAD_SCRIPT:-}"
download_tag="${EVERY_CHANNEL_OP_DEPLOYER_TAG:-op-deployer/v0.6.0-rc.3}"
skip_apply="${EVERY_CHANNEL_OP_STACK_SKIP_APPLY:-false}"
challenger_prestate_file="${EVERY_CHANNEL_OP_STACK_CHALLENGER_PRESTATE_FILE:-}"
deployer_dir="${root}/deployer"
sequencer_dir="${root}/sequencer"
batcher_dir="${root}/batcher"
proposer_dir="${root}/proposer"
challenger_dir="${root}/challenger"
dispute_mon_dir="${root}/dispute-mon"
challenger_prestate_name=""
log() {
printf '[op-stack] %s\n' "$*" >&2
}
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
log "missing required command: $1"
exit 2
}
}
trimmed_file_contents() {
tr -d '\r\n' <"$1"
}
set_toml_value() {
local key="$1"
local value="$2"
local file="$3"
if ! grep -q "^${key} = " "$file"; then
log "missing key ${key} in ${file}"
exit 1
fi
python - "$key" "$value" "$file" <<'PY'
import sys
from pathlib import Path
key, value, path = sys.argv[1:]
text = Path(path).read_text()
needle = f"{key} = "
out = []
replaced = False
for line in text.splitlines():
if line.startswith(needle):
out.append(f'{key} = "{value}"')
replaced = True
else:
out.append(line)
if not replaced:
raise SystemExit(f"failed to replace {key}")
Path(path).write_text("\n".join(out) + "\n")
PY
}
mkdir -p "${root}/bin" "$deployer_dir" "$sequencer_dir" "$batcher_dir" "$proposer_dir" \
"$challenger_dir" "$challenger_dir/data" "$dispute_mon_dir"
require_cmd cast
require_cmd curl
require_cmd jq
require_cmd openssl
if [[ ! -x "$op_deployer_bin" ]]; then
if [[ -z "$download_script" ]]; then
log "op-deployer missing and no download script configured"
exit 2
fi
log "downloading op-deployer via ${download_script}"
EVERY_CHANNEL_OP_DEPLOYER_TAG="$download_tag" \
EVERY_CHANNEL_OP_DEPLOYER_OUT="$op_deployer_bin" \
"$download_script"
fi
private_key="$(trimmed_file_contents "$private_key_file")"
private_key="${private_key#0x}"
if [[ ${#private_key} -ne 64 ]]; then
log "private key file must contain exactly 32 bytes of hex"
exit 2
fi
operator_address="$(cast wallet address --private-key "0x${private_key}")"
cat > "${deployer_dir}/.env" <<EOF
L1_RPC_URL=${l1_rpc_url}
PRIVATE_KEY=${private_key}
EOF
if [[ ! -d "${deployer_dir}/.deployer" ]]; then
"$op_deployer_bin" init \
--l1-chain-id 11155111 \
--l2-chain-ids "${chain_id}" \
--workdir "${deployer_dir}/.deployer" \
--intent-type standard-overrides
fi
intent="${deployer_dir}/.deployer/intent.toml"
chain_id_hex="$(printf '0x%064x' "${chain_id}")"
set_toml_value "id" "${chain_id_hex}" "${intent}"
for key in \
baseFeeVaultRecipient \
l1FeeVaultRecipient \
sequencerFeeVaultRecipient \
operatorFeeVaultRecipient \
chainFeesRecipient \
systemConfigOwner \
unsafeBlockSigner \
batcher \
proposer \
challenger
do
set_toml_value "${key}" "${operator_address}" "${intent}"
done
python - "${intent}" <<'PY'
import sys
from pathlib import Path
path = Path(sys.argv[1])
text = path.read_text()
if 'fundDevAccounts = false' not in text:
text = text.replace('fundDevAccounts = true', 'fundDevAccounts = false')
path.write_text(text)
PY
if [[ "${skip_apply}" != "true" && ! -f "${deployer_dir}/.deployer/state.json" ]]; then
"$op_deployer_bin" apply \
--workdir "${deployer_dir}/.deployer" \
--l1-rpc-url "${l1_rpc_url}" \
--private-key "${private_key}"
fi
if [[ ! -f "${deployer_dir}/.deployer/state.json" ]]; then
log "state.json missing; bootstrap did not complete"
exit 1
fi
"$op_deployer_bin" inspect genesis --workdir "${deployer_dir}/.deployer" "${chain_id_hex}" >"${sequencer_dir}/genesis.json"
"$op_deployer_bin" inspect rollup --workdir "${deployer_dir}/.deployer" "${chain_id_hex}" >"${sequencer_dir}/rollup.json"
openssl rand -hex 32 >"${sequencer_dir}/jwt.txt"
chmod 0600 "${sequencer_dir}/jwt.txt"
state_json="${deployer_dir}/.deployer/state.json"
system_config_proxy="$(jq -r '.opChainDeployments[0].systemConfigProxyAddress // .opChainDeployments[0].SystemConfigProxy // empty' <"${state_json}")"
dispute_game_factory="$(jq -r '.opChainDeployments[0].disputeGameFactoryProxyAddress // .opChainDeployments[0].DisputeGameFactoryProxy // empty' <"${state_json}")"
l1_standard_bridge="$(jq -r '.opChainDeployments[0].l1StandardBridgeProxyAddress // .opChainDeployments[0].L1StandardBridgeProxy // empty' <"${state_json}")"
if [[ -z "${system_config_proxy}" || "${system_config_proxy}" == "null" ]]; then
log "failed to extract systemConfigProxyAddress from state.json"
exit 1
fi
if [[ -z "${dispute_game_factory}" || "${dispute_game_factory}" == "null" ]]; then
log "failed to extract disputeGameFactoryProxyAddress from state.json"
exit 1
fi
if [[ -n "${challenger_prestate_file}" ]]; then
if [[ ! -f "${challenger_prestate_file}" ]]; then
log "challenger prestate file does not exist: ${challenger_prestate_file}"
exit 1
fi
challenger_prestate_name="$(basename "${challenger_prestate_file}")"
cp "${challenger_prestate_file}" "${challenger_dir}/${challenger_prestate_name}"
chmod 0640 "${challenger_dir}/${challenger_prestate_name}"
fi
cat > "${sequencer_dir}/.env" <<EOF
L1_RPC_URL=${l1_rpc_url}
L1_BEACON_URL=${l1_beacon_url}
PRIVATE_KEY=${private_key}
P2P_ADVERTISE_IP=${p2p_advertise_ip}
L2_CHAIN_ID=${chain_id}
EOF
cat > "${batcher_dir}/.env" <<EOF
L1_RPC_URL=${l1_rpc_url}
L2_RPC_URL=http://127.0.0.1:8545
ROLLUP_RPC_URL=http://127.0.0.1:8547
PRIVATE_KEY=${private_key}
BATCH_INBOX_ADDRESS=${system_config_proxy}
EOF
cat > "${proposer_dir}/.env" <<EOF
L1_RPC_URL=${l1_rpc_url}
ROLLUP_RPC_URL=http://127.0.0.1:8547
GAME_FACTORY_ADDRESS=${dispute_game_factory}
PRIVATE_KEY=${private_key}
PROPOSAL_INTERVAL=3600s
EOF
cp "${sequencer_dir}/genesis.json" "${challenger_dir}/genesis.json"
cp "${sequencer_dir}/rollup.json" "${challenger_dir}/rollup.json"
cat > "${challenger_dir}/.env" <<EOF
L1_RPC_URL=${l1_rpc_url}
L1_BEACON_URL=${l1_beacon_url}
L2_RPC_URL=http://127.0.0.1:8545
ROLLUP_RPC_URL=http://127.0.0.1:8547
GAME_FACTORY_ADDRESS=${dispute_game_factory}
PRIVATE_KEY=${private_key}
EOF
if [[ -n "${challenger_prestate_name}" ]]; then
cat >> "${challenger_dir}/.env" <<EOF
CANNON_PRESTATE=/workspace/${challenger_prestate_name}
EOF
fi
cat > "${dispute_mon_dir}/.env" <<EOF
OP_DISPUTE_MON_L1_ETH_RPC=${l1_rpc_url}
OP_DISPUTE_MON_ROLLUP_RPC=http://127.0.0.1:8547
OP_DISPUTE_MON_HONEST_ACTORS=${operator_address}
OP_DISPUTE_MON_GAME_FACTORY_ADDRESS=${dispute_game_factory}
OP_DISPUTE_MON_MONITOR_INTERVAL=10s
OP_DISPUTE_MON_NETWORK=ecp-sepolia
OP_DISPUTE_MON_LOG_LEVEL=debug
OP_DISPUTE_MON_LOG_FORMAT=logfmt
OP_DISPUTE_MON_METRICS_ADDR=0.0.0.0
OP_DISPUTE_MON_METRICS_ENABLED=true
OP_DISPUTE_MON_METRICS_PORT=7300
EOF
cat > "${root}/deployment.json" <<EOF
{
"chain_id": ${chain_id},
"operator_address": "${operator_address}",
"l1_rpc_url": "${l1_rpc_url}",
"l1_beacon_url": "${l1_beacon_url}",
"p2p_advertise_ip": "${p2p_advertise_ip}",
"system_config_proxy": "${system_config_proxy}",
"dispute_game_factory": "${dispute_game_factory}",
"l1_standard_bridge": "${l1_standard_bridge}"
}
EOF
log "wrote bootstrap outputs under ${root}"