Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: parse price object in price_script_generic.sh #216

Merged
merged 3 commits into from
Aug 16, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 44 additions & 38 deletions charts/akash-provider/scripts/price_script_generic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# WARNING: the runtime of this script should NOT exceed 5 seconds! (Perhaps can be amended via AKASH_BID_PRICE_SCRIPT_PROCESS_TIMEOUT env variable)
# Requirements:
# curl jq bc mawk ca-certificates
# Version: Aug-14-2023
# Version: Aug-16-2023
set -o pipefail

# Example:
Expand All @@ -23,21 +23,11 @@ if ! [[ -z $WHITELIST_URL ]]; then
fi

if ! grep -qw "$AKASH_OWNER" $WHITELIST; then
echo "$AKASH_OWNER is not whitelisted" >&2
echo -n "$AKASH_OWNER is not whitelisted" >&2
exit 1
fi
fi

data_in=$(jq .)
# Pull the pricing data from the deployment request
price=$(echo "$data_in" | jq -r '.price? // empty')

## DEBUG
if ! [[ -z $DEBUG_BID_SCRIPT ]]; then
echo "$(TZ=UTC date -R)" >> /tmp/${AKASH_OWNER}.log
echo "$data_in" >> /tmp/${AKASH_OWNER}.log
fi

function get_akt_price {
# cache AKT price for 60 minutes to reduce the API pressure as well as to slightly accelerate the bidding (+5s)
CACHE_FILE=/tmp/aktprice.cache
Expand All @@ -55,34 +45,56 @@ function get_akt_price {
# check price is an integer/floating number
re='^[0-9]+([.][0-9]+)?$'
if ! [[ $usd_per_akt =~ $re ]]; then
echo "$usd_per_akt is not an integer/floating number!" >&2
echo -n "$usd_per_akt is not an integer/floating number!" >&2
exit 1
fi

# make sure price is in the permitted range
if ! (( $(echo "$usd_per_akt > 0" | bc -l) && \
$(echo "$usd_per_akt <= 1000000" | bc -l) )); then
echo "$usd_per_akt is outside the permitted range (>0, <=1000000)" >&2
echo -n "$usd_per_akt is outside the permitted range (>0, <=1000000)" >&2
exit 1
fi

echo "$usd_per_akt" > $CACHE_FILE
fi

# TODO: figure some sort of monitoring to inform the provider in the event API breaks
# TODO: figure some monitoring to inform the provider in the event API breaks
fi

# Fail if script can't read CACHE_FILE for some reason
# Fail if the script can't read CACHE_FILE for some reason
set -e
usd_per_akt=$(cat $CACHE_FILE)
echo $usd_per_akt
set +e
}


# bid script starts reading the deployment order request specs here (passed by the Akash Provider)
data_in=$(jq .)

## DEBUG
if ! [[ -z $DEBUG_BID_SCRIPT ]]; then
echo "$(TZ=UTC date -R)" >> /tmp/${AKASH_OWNER}.log
echo "$data_in" >> /tmp/${AKASH_OWNER}.log
fi

# Pull the pricing data from the deployment request
hasPrice=$(echo "$data_in" | jq -r 'has("price")?')

# default price precision to 6 (for backward compatibility)
precision=$(jq -r '.price_precision? // 6' <<<"$data_in")

# If the price parameter is set, new rate calculations will be used
# otherwise, the original rate calculations will be used (for backwards compatibility)
if ! [[ -z "$price" ]]; then
isDenom=true
# otherwise, the original rate calculations will be used (for backward compatibility)
if [[ "$hasPrice" == true ]]; then
isObject=$(jq -r 'if .price?|type == "object" then true else false end' <<<"$data_in")
if [[ "$isObject" != true ]]; then
echo -n "price must be an object! make sure you are using the latest akash-provider." >&2
exit 1
fi
denom=$(jq -r '.price.denom' <<<"$data_in")
amount=$(jq -r '.price.amount' <<<"$data_in")

# strip off the .price by setting data_in to .resources
data_in=$(echo "$data_in" | jq -r '.resources')
Expand Down Expand Up @@ -145,38 +157,33 @@ total_cost_akt_target=$(bc -l <<<"(${total_cost_usd_target}/$usd_per_akt)")
total_cost_uakt_target=$(bc -l <<<"(${total_cost_akt_target}*1000000)")
rate_per_block_uakt=$(bc -l <<<"(${total_cost_uakt_target}/${blocks_a_month})")
rate_per_block_usd=$(bc -l <<<"(${total_cost_usd_target}/${blocks_a_month})")
total_cost_uakt="$(printf "%.18f" $rate_per_block_uakt)"
total_cost_uakt="$(printf "%.*f" $precision $rate_per_block_uakt)"

# NOTE: max_rate_usd, max_rate_uakt = are per block rates !

if [[ $isDenom = true ]]; then
denom=$(echo '{"price":"'$price'"}' | jq -r '.price | capture("^[0-9]*\\.?[0-9]*(?<denom>.*)") | .denom')

case "$price" in

*"uakt")
max_rate_uakt=$(echo '{"price":"'$price'"}' | jq -r '.price | gsub("[^0-9.]"; "")')
if [[ $hasPrice = true ]]; then
case "$denom" in
"uakt")
# Hint: bc <<< "$a > $b" (if a is greater than b, it will return 1, otherwise 0)
if bc <<< "$rate_per_block_uakt > $max_rate_uakt" | grep -qw 1; then
printf "requested rate is too low. min expected %.18f%s" "$rate_per_block_uakt" "$denom" >&2
if bc <<< "$rate_per_block_uakt > $amount" | grep -qw 1; then
printf "requested rate is too low. min expected %.*f%s" "$precision" "$rate_per_block_uakt" "$denom" >&2
exit 1
fi

# tell the provider uakt/block rate
echo $total_cost_uakt
printf "%.*f" "$precision" "$total_cost_uakt"
;;

# sandbox: Axelar USDC
*"ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84")
max_rate_usd=$(echo '{"price":"'$price'"}' | jq -r '.price | gsub("[^0-9.]"; "")')
rate_per_block_usd_normalized=$(bc -l <<<"(${rate_per_block_usd}*1000000)" | awk '{printf "%.18f", $0}')
if bc <<< "$rate_per_block_usd_normalized > $max_rate_usd" | grep -qw 1; then
printf "requested rate is too low. min expected %.18f%s" "$rate_per_block_usd_normalized" "$denom" >&2
"ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84")
rate_per_block_usd_normalized=$(bc -l <<<"(${rate_per_block_usd}*1000000)" | awk -v precision="$precision" '{printf "%.*f", precision, $0}')
if bc <<< "$rate_per_block_usd_normalized > $amount" | grep -qw 1; then
printf "requested rate is too low. min expected %.*f%s" "$precision" "$rate_per_block_usd_normalized" "$denom" >&2
exit 1
fi

# tell the provider usd/block rate
echo $rate_per_block_usd_normalized
printf "%.*f" "$precision" "$rate_per_block_usd_normalized"
;;

*)
Expand All @@ -188,6 +195,5 @@ if [[ $isDenom = true ]]; then

else
# provider only accepts rate in uakt/block when no price is received in structure (backwards compatibility)
echo $total_cost_uakt
printf "%.f" "$total_cost_uakt"
fi