#!/usr/bin/env bash
###
### arching-kaos-tools
### Tools to interact and build an Arching Kaos Infochain
### Copyright (C) 2021 - 2025 kaotisk
###
### This program is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### This program is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with this program. If not, see .
###
source $AK_LIBDIR/_ak_log
source $AK_LIBDIR/_ak_ipfs
source $AK_LIBDIR/_ak_zblock
source $AK_LIBDIR/_ak_script
_ak_zchain_reset(){
_ak_log_info "Reseting AK_ZLATEST to AK_ZGENESIS"
cp $AK_ZGENESIS $AK_ZLATEST
if [ $? -ne 0 ]
then
_ak_log_error "Failed to reset AK_ZLATEST to AK_ZGENESIS"
exit 1
fi
_ak_log_info "Checking if /zarchive directory exists"
_ak_ipfs_files_stat /zarchive > /dev/null
if [ $? -ne 0 ]
then
_ak_ipfs_files_mkdir /zarchive
if [ $? -ne 0 ]
then
_ak_log_error "Could not create directory /zarchive"
exit 1
fi
else
_ak_log_info "/zarchive directory exists"
fi
_ak_log_info "Checking if /zlatest file exists"
_ak_ipfs_files_stat /zlatest > /dev/null 2>&1
if [ $? -eq 0 ]
then
_ak_log_info "Archive the previous AK_ZLATEST"
_ak_ipfs_files_cp /zlatest /zarchive/$(date -u +%s)-$(_ak_ipfs_files_stat /zlatest | head -n 1)
if [ $? -ne 0 ]
then
_ak_log_error "Failed to copy /zlatest to /zarchive"
exit 1
fi
_ak_log_info "Removing previous /zlatest entry"
_ak_ipfs_files_rm /zlatest
if [ $? -ne 0 ]
then
_ak_log_error "Failed to remove /zlatest"
exit 1
fi
else
_ak_log_info "/zlatest not found, skipping backup"
fi
_ak_log_info "Copying reset AK_ZLATEST"
CZLATEST="$(cat $AK_ZLATEST)"
_ak_ipfs_files_cp /ipfs/$CZLATEST /zlatest
if [ $? -ne 0 ]
then
_ak_log_error "Failed to copy AK_ZLATEST to /zlatest"
exit 1
fi
_ak_log_info "Publishing new (reset) AK_ZLATEST"
_ak_ipfs_name_publish --key=zchain /ipfs/$(cat $AK_ZLATEST)
if [ $? -ne 0 ]
then
_ak_log_error "Failed to publish updated zchain"
exit 1
fi
_ak_config_publish
if [ $? -ne 0 ]
then
_ak_log_error "Could not publish new configuration"
exit 1
fi
_ak_log_info "Reset was successful"
exit 0
}
_ak_zchain_rebase(){
if [ ! -n "$1" ]; then exit 1; fi
ZTARGET="$1"
echo "Reseting ZLATEST to ZTARGET"
echo $ZTARGET > $AK_ZLATEST
if [ $? != 0 ]; then exit 1; fi
echo "Make sure /zarchive folder exists within IPFS FS"
_ak_ipfs_files_mkdir /zarchive
if [ $? != 0 ]; then echo "Folder already there"; fi
echo "Archive the previous ZLATEST"
_ak_ipfs_files_cp /zlatest /zarchive/$(date -u +%s)-$(_ak_ipfs_files_stat /zlatest | head -n 1)
if [ $? != 0 ]; then exit 1; fi
echo "Removing previous /zlatest entry"
_ak_ipfs_files_rm /zlatest
if [ $? != 0 ]; then exit 1; fi
echo "Copying rebased ZLATEST"
CZLATEST="$(cat $AK_ZLATEST)"
_ak_ipfs_files_cp /ipfs/$CZLATEST /zlatest
if [ $? != 0 ]; then exit 1; fi
echo "Publishing new (rebased) ZLATEST"
_ak_ipfs_name_publish --key=zchain /ipfs/$(cat $AK_ZLATEST)
if [ $? != 0 ]; then exit 1; fi
_ak_config_publish
if [ $? -ne 0 ]
then
_ak_log_error "Could not publish new configuration"
exit 1
fi
echo "Rebase was successful"
exit 0
}
_ak_zchain_extract_cids(){
if [ ! -z $1 ] && [ -n "$1" ]
then
_ak_zchain_crawl $1 | jq -M | grep Qm | sed -e 's/".*"://g; s/ //g; s/[{,"]//g' | sort | uniq
else
_ak_zchain_crawl | jq -M | grep Qm | sed -e 's/".*"://g; s/ //g; s/[{,"]//g' | sort | uniq
fi
}
_ak_zchain_extract_cids_limit(){
if [ ! -z $1 ] && [ -n "$1" ] && [ ! -z $2 ] && [ -n "$2" ]
then
_ak_zchain_crawl -l $2 $1 | jq -M | grep Qm | sed -e 's/".*"://g; s/ //g; s/[{,"]//g' | sort | uniq
else
_ak_zchain_crawl | jq -M | grep Qm | sed -e 's/".*"://g; s/ //g; s/[{,"]//g' | sort | uniq
fi
}
_ak_zchain_extract_data_cids(){
if [ ! -z $1 ]
then
_ak_zchain_crawl $1 | jq | grep ipfs | awk '{print $2}' | sed -e 's/"//g;s/,//g'
else
_ak_zchain_crawl | jq | grep ipfs | awk '{print $2}' | sed -e 's/"//g;s/,//g'
fi
}
_ak_zchain_calculate_size(){
temp="$(_ak_make_temp_directory)"
cd $temp
if [ ! -z $1 ] && [ -n "$1" ]
then
_ak_zchain_extract_cids $1 > to_stats
else
_ak_zchain_extract_cids > to_stats
fi
sum=0 ; while IFS="" read -r p || [ -n "$p" ]
do
if [ "$p" != "" ]
then
_ak_ipfs_get $p
num="$( (du -b $p || du -A $p)2>/dev/null | cut -d $'\t' -f 1)"
else
num=0
fi
sum=$(expr $sum + $num )
done < to_stats
echo "Chain is : $sum bytes"
cd ~
rm -rf $temp
}
_ak_zchain_crawl(){
entrance="$(cat $AK_ZLATEST)"
verify=1
limit=0
fromIpns=0
while [ "$#" ]; do
case "$1" in
-h | --help)
printf "Zchain crawler
==============
ak zchain --crawl [-N | --no-verify] [-l | --limit ] [zblock]
ak zchain --crawl [-N | --no-verify] [-l | --limit ] -n
Usage:
--help, -h Print this help and exit
--chain , -n Crawl specified chain
--no-verify, -N Don't verify signatures
Specify IPFS CID for entrance
Note that combined flags don't work for now
Running with no flags crawls your chain based on AK_ZLATEST environment
variable
"
exit 1
;;
-l | --limit)
limit=$2
shift 2
;;
-N | --no-verify)
verify=0
shift
;;
-n | --chain | --ipns)
fromIpns=1
ipns=$1
shift
ol=$1
entrance="$(_ak_ipns_resolve $1)"
if [ $? -ne 0 ]
then
_ak_log_error "Could not resolve IPNS name"
exit 1
fi
shift
;;
*)
test="$1"
if [ ! -z "$test" ] && [ $fromIpns -eq 0 ]
then
_ak_ipfs_cid_v0_check "$test"
entrance="$test"
elif [ -z "$entrance" ] && [ $fromIpns -eq 1 ]
then
entrance="$(cat $AK_ZLATEST)"
fi
break
esac
done
# We assign the IPFS CIDv0 of an empty file as this is used
# as our GENESIS block, hence the "seed" that the tree grows
# from.
seed="$(cat $AK_ZGENESIS)"
# We assume that we found the entrance inside a block, hence
# ZBLOCK is labeled as previous
zblock="$entrance"
# Enter temp folder
TEMPASSIN="$(_ak_make_temp_directory)"
cd $TEMPASSIN
counter=0
# The loop
# We break the loop from inside the loop
while true
do
if [ $counter -eq 0 ]
then
echo -n '['
fi
counter=$(($counter + 1))
_ak_zblock_show "$zblock"
if [ $limit -ne 0 ] && [ $limit -eq $counter ]
then
echo -n ']'
exit 0
else
echo -n ','
fi
done
}
_ak_zchain_crawl_self(){
_ak_zchain_crawl
}
_ak_zchain_crawl_remote_ipfs(){
_ak_zchain_crawl $1
}
_ak_zchain_crawl_remote_ipns(){
_ak_zchain_crawl -n $1
}
_ak_zchain_get_latest(){
_ak_ipfs_files_stat /zlatest | head -n 1| tr -d '\n'
}
# _ak_zchain_announce(){}
# PROGRAM="$(basename $0)"
# printf '[%s]\n' "$PROGRAM"
# printf "TEST\t/v0/announce/zchain\n"
# # curl http://127.0.0.1:8610/v0/announce/zchain
# printf "\t01:\tendpoint with valid data"
# curl \
# --connect-timeout 3 \
# -POST http://localhost:8610/v0/announce/zchain \
# --header 'Content-Type: application/json' \
# --data-raw '{"zchain":"k51qzi5uqu5dgapvk7bhxmchuqya9immqdpbz0f1r91ckpdqzub63afn3d5apr"}' 2>/dev/null | jq -M -c > /dev/null
# if [ $? -eq 0 ]
# then
# printf "\t\t\033[0;32mPASSED\033[0;0m"
# else
# printf "\t\033[0;31mFAILED\033[0;0m"
# fi
# printf "\n"
#
# printf "\t02:\tendpoint with invalid data"
# curl \
# --connect-timeout 3 \
# -POST http://localhost:8610/v0/announce/zchain \
# --header 'Content-Type: application/json' \
# --data-raw '{"zchain":"k51qzi5uqu5dgapvk7bhxmchuqya9immqdpbz0f1r91ckpdqzub63afn3d5aar"}' 2>/dev/null | jq -M -c > /dev/null
# if [ $? -eq 0 ]
# then
# printf "\t\t\033[0;32mPASSED\033[0;0m"
# else
# printf "\t\033[0;31mFAILED\033[0;0m"
# fi
# printf "\n"
#
# printf "\t03:\tendpoint no data"
# curl \
# --connect-timeout 3 \
# -POST http://localhost:8610/v0/announce/zchain \
# --header 'Content-Type: application/json' \
# --data-raw '{"zchain":""}' 2>/dev/null | jq -M -c > /dev/null
# if [ $? -eq 0 ]
# then
# printf "\t\t\t\033[0;32mPASSED\033[0;0m"
# else
# printf "\t\t\t\033[0;31mFAILED\033[0;0m"
# fi
# printf "\n"
# }
# _ak_zchain_chk(){
# ##
# ## -h, --help Prints this help message
# ##
# fullprogrampath="$(realpath $0)"
# PROGRAM=$(basename $0)
# descriptionString="Quick description"
# source $AK_LIBDIR/_ak_log
# source $AK_LIBDIR/_ak_script
# source $AK_LIBDIR/_ak_ipfs
#
# fix="0"
# usage(){
# echo "zchain-chk - Check and fix zchain"
# echo "---------------------------------"
# echo "Usage:"
# echo " --help, -h Print this help and exit"
# echo " --chain , -n Crawl specified chain"
# echo " --fix #TODO Fix your chain"
# echo ""
# echo "Note that combined flags don't work for now"
# echo "Running with no flags crawls your chain"
# }
#
# if [ ! -z "$1" ] && [ "$1" == "-h" ] || [ "$1" == "--help" ]
# then
# usage
# exit
# elif [ ! -z "$1" ] && [ "$1" == "-f" ] || [ "$1" == "--fix" ]
# then
# fix="1"
# entrance="$(cat $AK_ZLATEST)"
# elif [ ! -z "$1" ] && [ "$1" == "-n" ] || [ "$1" == "--chain" ]
# then
# entrance="$(_ak_ipns_resolve $2)"
# elif [ ! -z "$1" ]
# then
# entrance="$1"
# else
# # By default we ak-enter from the latest block
# # We can alter this by changing this value
# entrance="$(cat $AK_ZLATEST)"
# fi
#
# # We assign the IPFS CIDv0 of an empty file as this is used
# # as our GENESIS block, hence the "seed" that the tree grows
# # from.
# seed="$(cat $AK_ZGENESIS)"
#
# # We assume that we found the entrance inside a block, hence
# # ZBLOCK is labeled as previous
# zblock="$entrance"
# declare -A blocks_found
#
# # Enter temp folder
# TEMPASSIN="$(_ak_make_temp_directory)"
# cd $TEMPASSIN
# counter=0
#
# # The loop
# # We break the loop from inside the loop
# while true
# do
# if [ $counter == 0 ]
# then
# echo 'Start checking'
# fi
# counter=$(expr $counter + 1)
#
# # Check if $zblock exists as variable
# if [ ! -v $zblock ]
# then
# # Check if it is not our seed cause if it is we skip this part
# if [ "$zblock" != "$seed" ]
# then
# # Reset timestamp since it's introduced later
# timestamp=''
# # Announce to stdout which ZBLOCK is being read at the moment
# _ak_log_info "Examining $zblock"
#
# # We create files named after each ZBLOCK IPFS CID for later
# # reference. Files are empty.
# touch $AK_ZBLOCKDIR/$zblock
# _ak_log_info "Created reference"
#
# # We concatenate the zblock's contents, pipe them through filter
# # ak-json2bash and output them to tmp-file
# _ak_ipfs_cat $zblock | ak-json2bash > tmp-zblock
# _ak_log_info "ZBLOCK $zblock READ"
#
# # Supposingly you are on a safe environment and you only have
# # access to your chain, I would consider mild secure to source
# # the files into your bash.
# # File an issue/pull request if you think it can be done better!!
# source tmp-zblock
# _ak_log_info "ZBLOCK SOURCED"
#
# # Same as above applies to BLOCK and DATA subparts of each ZBLOCK
# # BLOCKS
# _ak_ipfs_cat $block | ak-json2bash > tmp-block
# source tmp-block
# _ak_log_info "BLOCK $block SOURCED"
# touch $AK_BLOCKDIR/$block
# _ak_log_info "BLOCK REFERENCED"
# module="$(echo $action | sed -e 's/\// /g' | awk '{ print $1 }')"
# _ak_log_info "DATA is $module module."
# command="$(echo $action | sed -e 's/\// /g' | awk '{ print $2 }')"
# _ak_log_info "COMMAND is $command"
# if [ ! -v $timestamp ]
# then
# echo "$timestamp : $zblock -> $block -> $previous"
# blocks_found[$counter]="$block"
# fi
# touch $AK_DATADIR/$data
#
# # Now, since we sourced the BLOCK to our terminal, we can search
# # for $previous variable. In case we don't find one, we exit with
# # code 0
# if [ -v $previous ]
# then
# _ak_log_error "Block $block has no previous zblock"
# echo "Chain with no genesis"
# if [ "$fix" == "1" ]
# then
# echo "LOL"
# else
# echo "Blocks found and need repacking..."
# for value in ${blocks_found[@]}
# do
# echo $value
# _ak_ipfs_cat $value | jq -M
# done
# fi
# exit 0
# # Otherwise, we inform of the sequence
# else
# zblock=$previous
# fi
# # Now check if it is equal to the seed
# # which apparently means we reached the seed.
# elif [ "$zblock" == "$seed" ]
# then
# echo "Chain is OK with GENESIS block = $seed"
# _ak_log_info "Counter $counter"
# exit 0
# fi
# # And finally, if nothing is there exit with error
# else
# _ak_log_error "Check not passed... No previous IPFS CID"
# exit 1
# fi
# done
# }