|
2 | 2 | # SPDX-License-Identifier: LicenseRef-DCL-1.0 |
3 | 3 | # SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd |
4 | 4 |
|
5 | | -# Refresh the RaindexV6 deploy-block bookkeeping after a release. |
6 | | -# |
7 | | -# Finds the exact block at which the newest released RaindexV6 (the last entry |
8 | | -# of LibRaindexV6Released) was deployed on each mainnet by binary-searching |
9 | | -# `eth_getCode` over an archive RPC, then rewrites the new per-chain blocks + |
10 | | -# that address into: |
11 | | -# - the RAINDEX_START_BLOCK_* constants in src/lib/deploy/LibRaindexV6StartBlock.sol |
12 | | -# - subgraph/networks.json (address + startBlock per network) |
13 | | -# - subgraph/subgraph.yaml (data source address) |
14 | | -# |
15 | | -# RaindexV6 is CREATE2-deployed, so its address only ever holds the one bytecode |
16 | | -# it was created with: the first block with code at that address IS the deploy |
17 | | -# block. Per-chain RPCs come from the foundry rpc_endpoints env vars, falling |
18 | | -# back to public archive endpoints. Set BUILD_START_BLOCKS_INPUT to a file of |
19 | | -# `STARTBLOCK <network> <block>` lines to skip the (RPC-bound) search, e.g. for |
20 | | -# tests. |
| 5 | +# Rewrites subgraph/networks.json from chain (script/BuildSubgraphNetworks.sol) |
| 6 | +# and points subgraph/subgraph.yaml at the candidate RaindexV6. Needs an |
| 7 | +# archive RPC per supported network in the `[rpc_endpoints]` env vars. |
21 | 8 | set -euo pipefail |
22 | 9 |
|
23 | | -LIB="src/lib/deploy/LibRaindexV6StartBlock.sol" |
24 | | -RELEASED="src/lib/LibRaindexV6Released.sol" |
25 | | -NET="subgraph/networks.json" |
26 | | -YAML="subgraph/subgraph.yaml" |
27 | | -TAG=$(grep -aoE 'storedDeployedAddress: RaindexV6_[A-Za-z0-9_]+_DEPLOYED_ADDRESS' "$RELEASED" | tail -1 \ |
28 | | - | sed -E 's/.*RaindexV6_(.+)_DEPLOYED_ADDRESS/\1/' || true) |
29 | | -PTR="src/generated/${TAG}/RaindexV6.sol" |
30 | | -[ -n "$TAG" ] && [ -f "$PTR" ] || { echo "could not read the newest released RaindexV6 snapshot from $RELEASED" >&2; exit 1; } |
| 10 | +ADDR=$(grep -aoE 'DEPLOYED_ADDRESS = address\(0x[0-9a-fA-F]{40}' src/generated/candidate/RaindexV6.sol | grep -aoE '0x[0-9a-fA-F]{40}') |
| 11 | +[ -n "$ADDR" ] || { echo "could not read DEPLOYED_ADDRESS from src/generated/candidate/RaindexV6.sol" >&2; exit 1; } |
31 | 12 |
|
32 | | -ARB_RPC="${ARBITRUM_RPC_URL:-https://arbitrum.drpc.org}" |
33 | | -BASE_RPC="${BASE_RPC_URL:-https://mainnet.base.org}" |
34 | | -FLARE_RPC="${FLARE_RPC_URL:-https://flare-api.flare.network/ext/C/rpc}" |
35 | | -POLY_RPC="${POLYGON_RPC_URL:-https://polygon.drpc.org}" |
36 | | - |
37 | | -ADDR=$(grep -aoE 'DEPLOYED_ADDRESS = address\(0x[0-9a-fA-F]{40}' "$PTR" | grep -aoE '0x[0-9a-fA-F]{40}') |
38 | | -[ -n "$ADDR" ] || { echo "could not read RAINDEX_DEPLOYED_ADDRESS from $PTR" >&2; exit 1; } |
39 | | - |
40 | | -# rpc_call <rpc> <method> <params-json> -> raw JSON (empty on transport error). |
41 | | -rpc_call() { |
42 | | - curl -fsSL -m 25 -X POST "$1" -H 'Content-Type: application/json' \ |
43 | | - -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"$2\",\"params\":$3}" 2>/dev/null || true |
44 | | -} |
45 | | - |
46 | | -# code_at <rpc> <addr> <block-dec> -> yes | no | err. Distinguishes an RPC error |
47 | | -# (retryable) from a genuinely empty account, so the search never mistakes an |
48 | | -# archive-window/timeout boundary for the deploy block. |
49 | | -code_at() { |
50 | | - local hex res |
51 | | - hex=$(printf '0x%x' "$3") |
52 | | - res=$(rpc_call "$1" eth_getCode "[\"$2\",\"$hex\"]") |
53 | | - case "$res" in |
54 | | - *'"result":"0x"'*) echo no ;; |
55 | | - *'"result":"0x'*) echo yes ;; |
56 | | - *) echo err ;; |
57 | | - esac |
58 | | -} |
59 | | - |
60 | | -head_of() { |
61 | | - local res |
62 | | - res=$(rpc_call "$1" eth_blockNumber "[]") |
63 | | - printf '%d' "$(printf '%s' "$res" | grep -aoE '"result":"0x[0-9a-f]+"' | grep -aoE '0x[0-9a-f]+')" |
64 | | -} |
65 | | - |
66 | | -# find_deploy_block <rpc> <addr> -> first block with code (the CREATE2 deploy). |
67 | | -find_deploy_block() { |
68 | | - local rpc=$1 addr=$2 head delta floor lo hi mid errs=0 |
69 | | - head=$(head_of "$rpc") |
70 | | - [ "${head:-0}" -gt 0 ] || { echo "could not read head block from $rpc" >&2; return 1; } |
71 | | - [ "$(code_at "$rpc" "$addr" "$head")" = "yes" ] || { echo "no code for $addr at head on $rpc" >&2; return 1; } |
72 | | - |
73 | | - # Walk a lower bound back in growing steps until the address has no code, |
74 | | - # so the search holds however long ago the deploy happened. |
75 | | - delta=250000 |
76 | | - floor=$(( head > delta ? head - delta : 1 )) |
77 | | - while [ "$floor" -gt 1 ] && [ "$(code_at "$rpc" "$addr" "$floor")" = "yes" ]; do |
78 | | - delta=$(( delta * 4 )) |
79 | | - floor=$(( head > delta ? head - delta : 1 )) |
80 | | - done |
81 | | - |
82 | | - lo=$floor; hi=$head |
83 | | - while [ "$lo" -lt "$hi" ]; do |
84 | | - mid=$(( (lo + hi) / 2 )) |
85 | | - case "$(code_at "$rpc" "$addr" "$mid")" in |
86 | | - yes) hi=$mid ;; |
87 | | - no) lo=$(( mid + 1 )) ;; |
88 | | - err) |
89 | | - errs=$(( errs + 1 )) |
90 | | - [ "$errs" -gt 12 ] && { echo "too many RPC errors searching $rpc" >&2; return 1; } |
91 | | - sleep 2 |
92 | | - ;; |
93 | | - esac |
94 | | - done |
95 | | - |
96 | | - # Verify the boundary on a second, independent read to catch load-balanced |
97 | | - # archives that answer the same historical block inconsistently. |
98 | | - [ "$(code_at "$rpc" "$addr" "$lo")" = "yes" ] || { echo "boundary check failed: no code at $lo on $rpc" >&2; return 1; } |
99 | | - [ "$lo" -le 1 ] || [ "$(code_at "$rpc" "$addr" "$(( lo - 1 ))")" = "no" ] \ |
100 | | - || { echo "boundary check failed: code already at $(( lo - 1 )) on $rpc" >&2; return 1; } |
101 | | - echo "$lo" |
102 | | -} |
103 | | - |
104 | | -if [ -n "${BUILD_START_BLOCKS_INPUT:-}" ]; then |
105 | | - OUT=$(cat "$BUILD_START_BLOCKS_INPUT") |
106 | | -else |
107 | | - echo "finding RaindexV6 ($ADDR) deploy block on each chain..." >&2 |
108 | | - OUT="STARTBLOCK arbitrum $(find_deploy_block "$ARB_RPC" "$ADDR") |
109 | | -STARTBLOCK base $(find_deploy_block "$BASE_RPC" "$ADDR") |
110 | | -STARTBLOCK flare $(find_deploy_block "$FLARE_RPC" "$ADDR") |
111 | | -STARTBLOCK polygon $(find_deploy_block "$POLY_RPC" "$ADDR")" |
112 | | -fi |
113 | | - |
114 | | -get() { printf '%s\n' "$OUT" | grep -aoE "STARTBLOCK $1 [0-9]+" | grep -aoE '[0-9]+$' | head -1; } |
115 | | -ARB=$(get arbitrum); BASE=$(get base); FLARE=$(get flare); POLY=$(get polygon) |
116 | | -for pair in "arbitrum:$ARB" "base:$BASE" "flare:$FLARE" "polygon:$POLY"; do |
117 | | - [ -n "${pair#*:}" ] || { echo "missing start block for ${pair%%:*}; finder output:" >&2; printf '%s\n' "$OUT" >&2; exit 1; } |
118 | | -done |
119 | | - |
120 | | -sed -i -E "s/(RAINDEX_START_BLOCK_ARBITRUM = )[0-9]+/\1${ARB}/" "$LIB" |
121 | | -sed -i -E "s/(RAINDEX_START_BLOCK_BASE = )[0-9]+/\1${BASE}/" "$LIB" |
122 | | -sed -i -E "s/(RAINDEX_START_BLOCK_FLARE = )[0-9]+/\1${FLARE}/" "$LIB" |
123 | | -sed -i -E "s/(RAINDEX_START_BLOCK_POLYGON = )[0-9]+/\1${POLY}/" "$LIB" |
124 | | - |
125 | | -sed -i -E "s/(address: \")0x[0-9a-fA-F]+(\")/\1${ADDR}\2/" "$YAML" |
126 | | - |
127 | | -jq --arg addr "$ADDR" --argjson arb "$ARB" --argjson base "$BASE" --argjson flare "$FLARE" --argjson poly "$POLY" ' |
128 | | - ."arbitrum-one".Raindex = {address: $addr, startBlock: $arb} |
129 | | - | .matic.Raindex = {address: $addr, startBlock: $poly} |
130 | | - | .base.Raindex = {address: $addr, startBlock: $base} |
131 | | - | .flare.Raindex = {address: $addr, startBlock: $flare} |
132 | | -' "$NET" >"${NET}.tmp" && mv "${NET}.tmp" "$NET" |
133 | | - |
134 | | -echo "start blocks: arbitrum=${ARB} base=${BASE} flare=${FLARE} polygon=${POLY} address=${ADDR}" |
| 13 | +forge script script/BuildSubgraphNetworks.sol |
| 14 | +sed -i -E "s/(address: \")0x[0-9a-fA-F]+(\")/\1${ADDR}\2/" subgraph/subgraph.yaml |
0 commit comments