Commit f1ec8e63 authored by Matthew Slipper's avatar Matthew Slipper

ctb: Fix multithreaded test race

`generate-l2-genesis.sh` is causing spurious test failures. The `.testdata/genesis.json` file comes up as zero-length in tests, even when the script checks for its length before exiting. I believe this is because multiple processes are executing the `generate-l2-genesis.sh` file at once, which causes a race condition where different invocations of the script cause the genesis file to be truncated.

This PR attempts to fix the issue by using a temporary directory as a lock to prevent multiple invocations of the `generate-l2-genesis.sh` script from running at the same time. Directory creations are atomic in Bash, so we can use this technique to create a mutex. If the directory can't be created, then the script will assume that another script is writing the genesis file and wait up to 5 minutes for it to be created. The script uses `trap` to delete the mutex directory when it's done.
parent 9216562e
...@@ -18,30 +18,59 @@ TESTDATA_DIR="$CONTRACTS_DIR/.testdata" ...@@ -18,30 +18,59 @@ TESTDATA_DIR="$CONTRACTS_DIR/.testdata"
OUTFILE_L2="$TESTDATA_DIR/genesis.json" OUTFILE_L2="$TESTDATA_DIR/genesis.json"
OUTFILE_ROLLUP="$TESTDATA_DIR/rollup.json" OUTFILE_ROLLUP="$TESTDATA_DIR/rollup.json"
mkdir -p "$TESTDATA_DIR"
LOCKDIR="/tmp/lock-generate-l2-genesis"
if [ ! -f "$DEPLOY_ARTIFACT" ]; then
forge script $CONTRACTS_DIR/scripts/Deploy.s.sol:Deploy > /dev/null 2>&1 cleanup() {
fi rm -rf -- "$LOCKDIR"
}
if [ ! -f "$OUTFILE_L2" ]; then
go run $OP_NODE genesis l2 \ # Wait for the L2 outfile to be over 8M for up to $2 iterations
--deploy-config "$CONTRACTS_DIR/deploy-config/hardhat.json" \ # of $1 seconds. This is a hack to ensure that the outfile is fully
--l1-deployments "$DEPLOY_ARTIFACT" \ # written before the solidity tests try to read it
--l1-starting-block "$L1_STARTING_BLOCK_PATH" \ wait_l2_outfile() {
--outfile.l2 "$OUTFILE_L2" \ i=1
--outfile.rollup "$OUTFILE_ROLLUP" > /dev/null 2>&1 while [ $i -le $2 ]; do
fi i=$(($i + 1))
# Wait for the L2 outfile to be over 8M for up to 2 seconds if [ ! -f "$OUTFILE_L2" ]; then
# This is a hack to ensure that the outfile is fully written sleep $1
# before the solidity tests try to read it continue
for i in {1..8}; do fi
if [ $(du -m "$OUTFILE_L2" | cut -f1) -ge 8 ]; then
if [ $(du -m "$OUTFILE_L2" | cut -f1) -lt 8 ]; then
sleep $1
continue
fi
exit 0 exit 0
done
echo "L2 genesis file not generated in time. Exiting."
exit 1
}
# Directory creations are atomic, so we can use mkdir to
# create a lockfile that prevents subsequent invocations
# of the script from running concurrently.
if mkdir -- "$LOCKDIR" > /dev/null 2>&1; then
trap 'cleanup' EXIT
mkdir -p "$TESTDATA_DIR"
if [ ! -f "$DEPLOY_ARTIFACT" ]; then
forge script $CONTRACTS_DIR/scripts/Deploy.s.sol:Deploy > /dev/null 2>&1
fi fi
sleep 0.25
done
echo "L2 genesis file not generated in time. Exiting." if [ ! -f "$OUTFILE_L2" ]; then
exit 1 go run $OP_NODE genesis l2 \
\ No newline at end of file --deploy-config "$CONTRACTS_DIR/deploy-config/hardhat.json" \
--l1-deployments "$DEPLOY_ARTIFACT" \
--l1-starting-block "$L1_STARTING_BLOCK_PATH" \
--outfile.l2 "$OUTFILE_L2" \
--outfile.rollup "$OUTFILE_ROLLUP" > /dev/null 2>&1
fi
else
# Wait up to 5 minutes for the lock to be released
wait_l2_outfile 0.25 1200
fi
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment