|
82 | 82 |
|
83 | 83 | # --------------------------------------------------------------------------- |
84 | 84 | echo "=== deploying the 4 new implementations ===" |
85 | | -# Deploy creation bytecode; surface the cast error (and abort) on failure. |
86 | | -deploy(){ |
| 85 | +# Use an explicit, locally-incremented nonce from the PENDING count. forno's |
| 86 | +# 'latest' nonce can lag the sequencer, so cast's auto-nonce may submit a stale |
| 87 | +# value ("nonce too low"). Anchoring to pending once and incrementing per deploy |
| 88 | +# keeps the 5 sequential deploys in lock-step with the sequencer. |
| 89 | +DEPLOYER_ADDR=$(cast wallet address --private-key "$DEPLOY_KEY") |
| 90 | +NEXT_NONCE=$(( $(cast rpc --rpc-url "$RPC" eth_getTransactionCount "$DEPLOYER_ADDR" pending | tr -d '"') )) |
| 91 | +echo " deployer $DEPLOYER_ADDR starting at nonce $NEXT_NONCE" |
| 92 | +# Deploy creation bytecode at the given nonce; echo the address or abort. |
| 93 | +# NOTE: nonce is passed in and incremented by the CALLER (this function runs in |
| 94 | +# a $(...) subshell, so an increment here would not reach the parent). |
| 95 | +deploy(){ # <bytecode> <nonce> |
87 | 96 | local out addr |
88 | | - out=$(cast send --rpc-url "$RPC" --private-key "$DEPLOY_KEY" $SEND_EXTRA --create "$1" --json 2>/tmp/deploy-err.log) |
| 97 | + out=$(cast send --rpc-url "$RPC" --private-key "$DEPLOY_KEY" $SEND_EXTRA --nonce "$2" --create "$1" --json 2>/tmp/deploy-err.log) |
89 | 98 | addr=$(echo "$out" | jq -r '.contractAddress // empty' 2>/dev/null) |
90 | 99 | if [ -z "$addr" ] || [ "$addr" = "null" ]; then |
91 | | - echo "DEPLOY FAILED:" >&2; tail -5 /tmp/deploy-err.log >&2; return 1 |
| 100 | + echo "DEPLOY FAILED (nonce $2):" >&2; tail -5 /tmp/deploy-err.log >&2; return 1 |
92 | 101 | fi |
93 | 102 | echo "$addr" |
94 | 103 | } |
95 | | -A_IMPL=$(deploy "$(jq -r .bytecode artifacts/contracts/Account.sol/Account.json)") || exit 1 |
96 | | -M_IMPL=$(deploy "$(jq -r .bytecode artifacts/contracts/Manager.sol/Manager.json)") || exit 1 |
97 | | -S_IMPL=$(deploy "$(jq -r .bytecode artifacts/contracts/SpecificGroupStrategy.sol/SpecificGroupStrategy.json)") || exit 1 |
98 | | -LIB=$(deploy "$(jq -r .bytecode artifacts/contracts/common/linkedlists/AddressSortedLinkedList.sol/AddressSortedLinkedList.json)") || exit 1 |
| 104 | +A_IMPL=$(deploy "$(jq -r .bytecode artifacts/contracts/Account.sol/Account.json)" "$NEXT_NONCE") || exit 1; NEXT_NONCE=$((NEXT_NONCE+1)) |
| 105 | +M_IMPL=$(deploy "$(jq -r .bytecode artifacts/contracts/Manager.sol/Manager.json)" "$NEXT_NONCE") || exit 1; NEXT_NONCE=$((NEXT_NONCE+1)) |
| 106 | +S_IMPL=$(deploy "$(jq -r .bytecode artifacts/contracts/SpecificGroupStrategy.sol/SpecificGroupStrategy.json)" "$NEXT_NONCE") || exit 1; NEXT_NONCE=$((NEXT_NONCE+1)) |
| 107 | +LIB=$(deploy "$(jq -r .bytecode artifacts/contracts/common/linkedlists/AddressSortedLinkedList.sol/AddressSortedLinkedList.json)" "$NEXT_NONCE") || exit 1; NEXT_NONCE=$((NEXT_NONCE+1)) |
99 | 108 | # Link DefaultStrategy to the deployed library. The placeholder must be replaced |
100 | 109 | # by the full 40-hex address (lowercased, 0x stripped, LEADING ZEROS PRESERVED). |
101 | 110 | LIB_HEX=$(echo "${LIB#0x}" | tr 'A-Z' 'a-z') |
102 | 111 | DBC=$(jq -r .bytecode artifacts/contracts/DefaultStrategy.sol/DefaultStrategy.json | sed "s/__\$[0-9a-f]*\$__/$LIB_HEX/g") |
103 | 112 | case "$DBC" in *'__$'*) echo "ERROR: DefaultStrategy bytecode still has an unlinked library placeholder" >&2; exit 1;; esac |
104 | | -D_IMPL=$(deploy "$DBC") || exit 1 |
| 113 | +D_IMPL=$(deploy "$DBC" "$NEXT_NONCE") || exit 1; NEXT_NONCE=$((NEXT_NONCE+1)) |
105 | 114 | for v in "$A_IMPL:Account" "$M_IMPL:Manager" "$S_IMPL:SpecificGroupStrategy" "$D_IMPL:DefaultStrategy" "$LIB:AddressSortedLinkedList"; do |
106 | 115 | [ -n "${v%%:*}" ] && [ "${v%%:*}" != null ] || { echo "deploy failed: ${v##*:}"; exit 1; } |
107 | 116 | echo " ${v##*:}: ${v%%:*}" |
|
0 commit comments