@@ -16,18 +16,19 @@ set -o pipefail
16
16
# # for 20 slices, this is about 1.8TB
17
17
18
18
NETWORK=" mainnet" # # network to replay
19
- REPO_DIR=" $HOME /stacks-inspect " # # where to build the source
19
+ REPO_DIR=" $HOME /stacks-core " # # where to build the source
20
20
REMOTE_REPO=" stacks-network/stacks-core" # # remote git repo to build stacks-inspect from
21
21
SCRATCH_DIR=" $HOME /scratch" # # root folder for the replay slices
22
22
TIMESTAMP=$( date +%Y-%m-%d-%s) # # use a simple date format year-month-day-epoch
23
- LOG_DIR=" /tmp/ replay_${TIMESTAMP} " # # location of logfiles for the replay
23
+ LOG_DIR=" $HOME / replay_${TIMESTAMP} " # # location of logfiles for the replay
24
24
SLICE_DIR=" ${SCRATCH_DIR} /slice" # # location of slice dirs
25
25
TMUX_SESSION=" replay" # # tmux session name to run the replay
26
26
TERM_OUT=false # # terminal friendly output
27
27
TESTING=false # # only run a replay on a few thousand blocks
28
28
BRANCH=" develop" # # default branch to build stacks-inspect from
29
29
CORES=$( grep -c processor /proc/cpuinfo) # # retrieve total number of CORES on the system
30
- RESERVED=10 # # reserve this many CORES for other processes as default
30
+ RESERVED=8 # # reserve this many CORES for other processes as default
31
+ LOCAL_CHAINSTATE= # # path to local chainstate to use instead of snapshot download
31
32
32
33
# # ansi color codes for terminal output
33
34
COLRED=$' \033 [31m' # # Red
@@ -94,19 +95,25 @@ configure_replay_slices() {
94
95
echo " ${COLRED} Error${COLRESET} creating dir ${SLICE_DIR} "
95
96
exit 1
96
97
}
97
- echo " Downloading latest ${NETWORK} chainstate archive ${COLYELLOW} https://archive.hiro.so/${NETWORK} /stacks-blockchain/${NETWORK} -stacks-blockchain-latest.tar.gz${COLRESET} "
98
- # # curl had some random issues retrying the download when network issues arose. wget has resumed more consistently, so we'll use that binary
99
- # curl -L --proto '=https' --tlsv1.2 https://archive.hiro.so/${NETWORK}/stacks-blockchain/${NETWORK}-stacks-blockchain-latest.tar.gz -o ${SCRATCH_DIR}/${NETWORK}-stacks-blockchain-latest.tar.gz || {
100
- wget -O " ${SCRATCH_DIR} /${NETWORK} -stacks-blockchain-latest.tar.gz" " https://archive.hiro.so/${NETWORK} /stacks-blockchain/${NETWORK} -stacks-blockchain-latest.tar.gz" || {
101
- echo " ${COLRED} Error${COLRESET} downlaoding latest ${NETWORK} chainstate archive"
102
- exit 1
103
- }
104
- # # extract downloaded archive
105
- echo " Extracting downloaded archive: ${COLYELLOW}${SCRATCH_DIR} /${NETWORK} -stacks-blockchain-latest.tar.gz${COLRESET} "
106
- tar --strip-components=1 -xzf " ${SCRATCH_DIR} /${NETWORK} -stacks-blockchain-latest.tar.gz" -C " ${SLICE_DIR} 0" || {
107
- echo " ${COLRED} Error${COLRESET} extracting ${NETWORK} chainstate archive"
108
- exit
109
- }
98
+
99
+ if [[ -n " ${LOCAL_CHAINSTATE} " ]]; then
100
+ echo " Copying local chainstate '${LOCAL_CHAINSTATE} '"
101
+ cp -r " ${LOCAL_CHAINSTATE} " /* " ${SLICE_DIR} 0"
102
+ else
103
+ echo " Downloading latest ${NETWORK} chainstate archive ${COLYELLOW} https://archive.hiro.so/${NETWORK} /stacks-blockchain/${NETWORK} -stacks-blockchain-latest.tar.gz${COLRESET} "
104
+ # # curl had some random issues retrying the download when network issues arose. wget has resumed more consistently, so we'll use that binary
105
+ # curl -L --proto '=https' --tlsv1.2 https://archive.hiro.so/${NETWORK}/stacks-blockchain/${NETWORK}-stacks-blockchain-latest.tar.gz -o ${SCRATCH_DIR}/${NETWORK}-stacks-blockchain-latest.tar.gz || {
106
+ wget -O " ${SCRATCH_DIR} /${NETWORK} -stacks-blockchain-latest.tar.gz" " https://archive.hiro.so/${NETWORK} /stacks-blockchain/${NETWORK} -stacks-blockchain-latest.tar.gz" || {
107
+ echo " ${COLRED} Error${COLRESET} downlaoding latest ${NETWORK} chainstate archive"
108
+ exit 1
109
+ }
110
+ # # extract downloaded archive
111
+ echo " Extracting downloaded archive: ${COLYELLOW}${SCRATCH_DIR} /${NETWORK} -stacks-blockchain-latest.tar.gz${COLRESET} "
112
+ tar --strip-components=1 -xzf " ${SCRATCH_DIR} /${NETWORK} -stacks-blockchain-latest.tar.gz" -C " ${SLICE_DIR} 0" || {
113
+ echo " ${COLRED} Error${COLRESET} extracting ${NETWORK} chainstate archive"
114
+ exit
115
+ }
116
+ fi
110
117
echo " Moving marf database: ${SLICE_DIR} 0/chainstate/vm/clarity/marf.sqlite.blobs -> ${COLYELLOW}${SCRATCH_DIR} /marf.sqlite.blobs${COLRESET} "
111
118
mv " ${SLICE_DIR} " 0/chainstate/vm/clarity/marf.sqlite.blobs " ${SCRATCH_DIR} " /
112
119
echo " Symlinking marf database: ${SCRATCH_DIR} /marf.sqlite.blobs -> ${COLYELLOW}${SLICE_DIR} 0/chainstate/vm/clarity/marf.sqlite.blobs${COLRESET} "
@@ -377,6 +384,8 @@ usage() {
377
384
echo " ${COLYELLOW} -t|--terminal${COLRESET} : more terminal friendly output"
378
385
echo " ${COLYELLOW} -n|--network${COLRESET} : run block replay against specific network (default: mainnet)"
379
386
echo " ${COLYELLOW} -b|--branch${COLRESET} : branch of stacks-core to build stacks-inspect from (default: develop)"
387
+ echo " ${COLYELLOW} -c|--chainstate${COLRESET} : local chainstate copy to use instead of downloading a chainstaet snapshot"
388
+ echo " ${COLYELLOW} -l|--logdir${COLRESET} : use existing log directory"
380
389
echo " ${COLYELLOW} -r|--reserved${COLRESET} : how many cpu cores to reserve for system tasks"
381
390
echo
382
391
echo " ex: ${COLCYAN}${0} -t -u ${COLRESET} "
@@ -386,9 +395,30 @@ usage() {
386
395
387
396
388
397
# # install missing dependencies
389
- for cmd in curl tmux git wget tar gzip grep cargo pgrep; do
398
+ HAS_APT=1
399
+ HAS_SUDO=1
400
+ for cmd in apt-get sudo curl tmux git wget tar gzip grep cargo pgrep tput find; do
401
+ # in Alpine, `find` might be linked to `busybox` and won't work
402
+ if [ " ${cmd} " == " find" ] && [ -L " ${cmd} " ]; then
403
+ local rp=" $( readlink " $( command -v " ${cmd} " || echo " NOTLINK" ) " ) "
404
+ if [ " ${rp} " == " /bin/busybox" ]; then
405
+ echo " ${COLRED} ERROR${COLRESET} Busybox 'find' is not supported. Please install 'findutils' or similar."
406
+ exit 1
407
+ fi
408
+ fi
409
+
390
410
command -v " ${cmd} " > /dev/null 2>&1 || {
391
411
case " ${cmd} " in
412
+ " apt-get" )
413
+ echo " ${COLYELLOW} WARN${COLRESET} 'apt-get' not found; automatic package installation will fail"
414
+ HAS_APT=0
415
+ continue
416
+ ;;
417
+ " sudo" )
418
+ echo " ${COLYELLOW} WARN${COLRESET} 'sudo' not found; automatic package installation will fail"
419
+ HAS_SUDO=0
420
+ continue
421
+ ;;
392
422
" cargo" )
393
423
install_cargo
394
424
;;
@@ -399,6 +429,11 @@ for cmd in curl tmux git wget tar gzip grep cargo pgrep; do
399
429
package=" ${cmd} "
400
430
;;
401
431
esac
432
+
433
+ if [[ ${HAS_APT} = 0 ]] || [[ ${HAS_SUDO} = 0 ]]; then
434
+ echo " ${COLRED} Error${COLRESET} Missing command '${cmd} '"
435
+ exit 1
436
+ fi
402
437
(sudo apt-get update && sudo apt-get install " ${package} " ) || {
403
438
echo " ${COLRED} Error${COLRESET} installing $package "
404
439
exit 1
@@ -422,6 +457,7 @@ while [ ${#} -gt 0 ]; do
422
457
# required if not mainnet
423
458
if [ " ${2} " == " " ]; then
424
459
echo " Missing required value for ${1} "
460
+ exit 1
425
461
fi
426
462
NETWORK=${2}
427
463
shift
@@ -430,10 +466,29 @@ while [ ${#} -gt 0 ]; do
430
466
# build from specific branch
431
467
if [ " ${2} " == " " ]; then
432
468
echo " Missing required value for ${1} "
469
+ exit 1
433
470
fi
434
471
BRANCH=${2}
435
472
shift
436
- ;;
473
+ ;;
474
+ -c|--chainstate)
475
+ # use a local chainstate
476
+ if [ " ${2} " == " " ]; then
477
+ echo " Missing required value for ${1} "
478
+ exit 1
479
+ fi
480
+ LOCAL_CHAINSTATE=" ${2} "
481
+ shift
482
+ ;;
483
+ -l|--logdir)
484
+ # use a given logdir
485
+ if [ " ${2} " == " " ]; then
486
+ echo " Missing required value for ${1} "
487
+ exit 1
488
+ fi
489
+ LOG_DIR=" ${2} "
490
+ shift
491
+ ;;
437
492
-r|--RESERVED)
438
493
# reserve this many cpus for the system (default is 10)
439
494
if [ " ${2} " == " " ]; then
458
513
# # clear display before starting
459
514
tput reset
460
515
echo " Replay Started: ${COLYELLOW} $( date) ${COLRESET} "
461
- build_stacks_inspect # # comment if using an existing chainstate/slice dir (ex: replay was performed already, and a second run is desired)
462
- configure_replay_slices # # comment if using an existing chainstate/slice dir (ex: replay was performed already, and a second run is desired)
516
+ build_stacks_inspect # # comment if using an existing chainstate/slice dir (ex: replay was performed already, and a second run is desired)
517
+ configure_replay_slices # # comment if using an existing chainstate/slice dir (ex: replay was performed already, and a second run is desired)
463
518
setup_replay # # configure logdir and tmux sessions
464
519
start_replay # # replay pre-nakamoto blocks (2.x)
465
520
start_replay nakamoto # # replay nakamoto blocks
0 commit comments