From 6b6ff31324e80d854b012aec30bf396e0435f55d Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 10 Sep 2024 17:37:21 +0200 Subject: [PATCH 01/19] Add vote threshold and vote type checks --- scripts/cnode-helper-scripts/cntools.library | 208 +++++++++++++++++-- scripts/cnode-helper-scripts/cntools.sh | 44 +++- scripts/cnode-helper-scripts/env | 2 + 3 files changed, 225 insertions(+), 29 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index f0de3b99c..18ef951a7 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -1312,25 +1312,32 @@ getWalletVoteDelegation() { return 1 } -# Command : getGovAction [action id] +# Command : getGovAction [tx_id] [index] # Description : fetch governance action information by id (cli format) -# Return : populates ${vote_action} ${proposal_url} ${proposal_hash} +# Return : populates ${vote_action} ${proposal_url} ${proposal_hash} ${proposal_type} ${isParameterSecurityGroup} # : 0 = ok, 1 = action not found, 2 = invalid url or content, 3 = hash doesn't match getGovAction() { - unset vote_action proposal_url proposal_hash proposal_meta_file - [[ -z $1 ]] && return 1 + unset vote_action proposal_url proposal_hash proposal_meta_file proposal_type + [[ -z $1 || -z $2 ]] && return 1 + isParameterSecurityGroup=N + isNetworkGroup=N + isEconomicGroup=N + isTechnicalGroup=N + isGovernanceGroup=N if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then HEADERS=("${KOIOS_API_HEADERS[@]}" -H "accept: application/json") println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/proposal_list?proposal_tx_hash=eq.${1}&proposal_index=eq.${2}" ! vote_action=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/proposal_list?proposal_tx_hash=eq.${1}&proposal_index=eq.${2}" 2>&1) && println "ERROR" "\n${FG_RED}KOIOS_API ERROR${NC}: ${vote_action}\n" && return 1 # print error and return [[ ${vote_action} = '[]' ]] && return 1 vote_action=$(jq -er .[0] <<< "${vote_action}") - IFS=',' read -r proposal_url proposal_hash < <( jq -cr '"\(.meta_url//""),\(.meta_hash//"")"' <<< "${vote_action}" ) + IFS=',' read -r proposal_url proposal_hash proposal_type < <( jq -cr '"\(.meta_url//""),\(.meta_hash//""),\(.proposal_type//"")"' <<< "${vote_action}" ) + [[ ${proposal_type} = "ParameterChange" ]] && parameterChange=$(jq -e '.param_proposal | keys[]' <<< "${vote_action}") && getParameterChangeGroups elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then println ACTION "${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -r --arg govActionId \"$1\" 'first(.proposals | to_entries[] | select(.value.actionId.txId | contains(\$govActionId))) | .value'" vote_action=$(${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -r --arg govActionId "$1" 'first(.proposals | to_entries[] | select(.value.actionId.txId | contains($govActionId))) | .value') [[ -z ${vote_action} ]] && return 1 - IFS=',' read -r proposal_url proposal_hash < <( jq -cr '"\(.proposalProcedure.anchor.url//""),\(.proposalProcedure.anchor.dataHash//"")"' <<< "${vote_action}" ) + IFS=',' read -r proposal_url proposal_hash proposal_type < <( jq -cr '"\(.proposalProcedure.anchor.url//""),\(.proposalProcedure.anchor.dataHash//""),\(.proposalProcedure.govAction.tag//"")"' <<< "${vote_action}" ) + [[ ${proposal_type} = "ParameterChange" ]] && parameterChange=$(jq -e '.proposalProcedure.govAction.contents[1] | keys[]' <<< "${vote_action}") && getParameterChangeGroups else return 1 fi @@ -1349,24 +1356,40 @@ getGovAction() { return 0 } +# Command : getAllGovActions +# Return : csv array of governance actions with different data depending on LIGHT VS LOCAL mode getAllGovActions() { unset vote_action_list _vote_action_list _vote_action_votes if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then + getCurrentCommittee; getParameterThresholds # to fetch thresholds HEADERS=("${KOIOS_API_HEADERS[@]}" -H "accept: text/csv") - println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/proposal_list?select=block_time,ratified_epoch,enacted_epoch,dropped_epoch,expired_epoch,proposal_id,proposal_tx_hash,proposal_index,proposal_type,proposed_epoch,expiration,meta_url&ratified_epoch=is.null&enacted_epoch=is.null&dropped_epoch=is.null&expired_epoch=is.null&order=block_time.desc" - _vote_action_list=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/proposal_list?select=block_time,ratified_epoch,enacted_epoch,dropped_epoch,expired_epoch,proposal_id,proposal_tx_hash,proposal_index,proposal_type,proposed_epoch,expiration,meta_url&ratified_epoch=is.null&enacted_epoch=is.null&dropped_epoch=is.null&expired_epoch=is.null&order=block_time.desc" 2>&1) || return 1 + println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/proposal_list?select=block_time,ratified_epoch,enacted_epoch,dropped_epoch,expired_epoch,proposal_id,proposal_tx_hash,proposal_index,proposal_type,proposed_epoch,expiration,meta_url,param_proposal&ratified_epoch=is.null&enacted_epoch=is.null&dropped_epoch=is.null&expired_epoch=is.null&order=block_time.desc" + _vote_action_list=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/proposal_list?select=block_time,ratified_epoch,enacted_epoch,dropped_epoch,expired_epoch,proposal_id,proposal_tx_hash,proposal_index,proposal_type,proposed_epoch,expiration,meta_url,param_proposal&ratified_epoch=is.null&enacted_epoch=is.null&dropped_epoch=is.null&expired_epoch=is.null&order=block_time.desc" 2>&1) || return 1 vote_action_list=() - while IFS=',' read -r _block_time _ratified_epoch _enacted_epoch _dropped_epoch _expired_epoch _proposal_id _proposal_tx_hash _proposal_index _proposal_type _proposed_epoch _expiration _meta_url; do + while IFS=',' read -r _block_time _ratified_epoch _enacted_epoch _dropped_epoch _expired_epoch _proposal_id _proposal_tx_hash _proposal_index _proposal_type _proposed_epoch _expiration _meta_url _param_proposal; do println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/proposal_voting_summary?_proposal_id=${_proposal_id}&select=drep_yes_votes_cast,drep_yes_vote_power,drep_yes_pct,drep_no_votes_cast,drep_no_vote_power,drep_no_pct,pool_yes_votes_cast,pool_yes_vote_power,pool_yes_pct,pool_no_votes_cast,pool_no_vote_power,pool_no_pct,committee_yes_votes_cast,committee_yes_pct,committee_no_votes_cast,committee_no_pct" _vote_action_votes=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/proposal_voting_summary?_proposal_id=${_proposal_id}&select=drep_yes_votes_cast,drep_yes_vote_power,drep_yes_pct,drep_no_votes_cast,drep_no_vote_power,drep_no_pct,pool_yes_votes_cast,pool_yes_vote_power,pool_yes_pct,pool_no_votes_cast,pool_no_vote_power,pool_no_pct,committee_yes_votes_cast,committee_yes_pct,committee_no_votes_cast,committee_no_pct" 2>&1) || continue IFS=',' read -r drep_yes_votes_cast drep_yes_vote_power drep_yes_pct drep_no_votes_cast drep_no_vote_power drep_no_pct pool_yes_votes_cast pool_yes_vote_power pool_yes_pct pool_no_votes_cast pool_no_vote_power pool_no_pct committee_yes_votes_cast committee_yes_pct committee_no_votes_cast committee_no_pct <<< "$(tail -n +2 <<< ${_vote_action_votes})" - vote_action_list+=( "${_proposal_tx_hash}#${_proposal_index},${_proposal_type},${_proposed_epoch},${_expiration:=0},${_meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${pool_yes_votes_cast},${pool_yes_vote_power},${pool_yes_pct},${pool_no_votes_cast},${pool_no_vote_power},${pool_no_pct},${committee_yes_votes_cast},${committee_yes_pct},${committee_no_votes_cast},${committee_no_pct}" ) + if [[ ${_proposal_type} = "ParameterChange" ]]; then + param_proposal_unescaped=${_param_proposal:1: -1} # remove first and last char (quotation) + param_proposal_unescaped=$(sed 's/""/"/g' <<< "${param_proposal_unescaped}") # remove all double quotes, sed seems to perform better than bash string manipulation + parameterChange=$(jq -e '. | keys[]' <<< "${param_proposal_unescaped}") + getParameterChangeGroups + fi + getVoteThreshold ${_proposal_type} + vote_action_list+=( "${_proposal_tx_hash}#${_proposal_index},${_proposal_type},${_proposed_epoch},${_expiration:=0},${_meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${pool_yes_votes_cast},${pool_yes_vote_power},${pool_yes_pct},${pool_no_votes_cast},${pool_no_vote_power},${pool_no_pct},${committee_yes_votes_cast},${committee_yes_pct},${committee_no_votes_cast},${committee_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) done <<< "$(tail -n +2 <<< ${_vote_action_list})" elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then + getCurrentCommittee; getParameterThresholds # to fetch thresholds vote_action_list=(); _vote_action_list=() println ACTION "${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64'" for vote_action in $(${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64' 2>/dev/null); do - _vote_action_list+=( "$(jq -cr '"\((.actionId.txId//"") + "#" + (.actionId.govActionIx//0|tostring)),\(.proposalProcedure.govAction.tag//""),\(.proposedIn//0),\(.expiresAfter//0),\(.proposalProcedure.anchor.url//""),\(.dRepVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1))"' <<< "$(base64 -d <<< "${vote_action}")")" ) + if [[ $(jq -r '.proposalProcedure.govAction.tag') = "ParameterChange" ]]; then + parameterChange=$(jq -e '.proposalProcedure.govAction.contents[1] | keys[]' <<< "$(base64 -d <<< "${vote_action}")") + getParameterChangeGroups + fi + getVoteThreshold "$(jq -r '.proposalProcedure.govAction.tag' <<< "$(base64 -d <<< "${vote_action}")")" + _vote_action_list+=( "$(jq -cr '"\((.actionId.txId//"") + "#" + (.actionId.govActionIx//0|tostring)),\(.proposalProcedure.govAction.tag//""),\(.proposedIn//0),\(.expiresAfter//0),\(.proposalProcedure.anchor.url//""),\(.dRepVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1))"' <<< "$(base64 -d <<< "${vote_action}")"),${drep_vt},${spo_vt},${cc_vt}" ) done # reverse order for ((i=${#_vote_action_list[@]}-1; i>=0; i--)); do @@ -1375,21 +1398,166 @@ getAllGovActions() { fi } +# Command : getParameterChangeGroups +# Description : assumed parameterChange is populated with list of parameter changes, including quotation marks +# Return : sets isParameterSecurityGroup isNetworkGroup isEconomicGroup isTechnicalGroup isGovernanceGroup +getParameterChangeGroups() { + unset isParameterSecurityGroup isNetworkGroup isEconomicGroup isTechnicalGroup isGovernanceGroup + [[ -z ${vote_action} ]] && return 1 + if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then + [[ $parameterChange =~ (\"max_block_size\"|\"max_tx_size\"|\"max_bh_size\"|\"max_val_size\"|\"max_block_ex_|\"min_fee_a\"|\"min_fee_b\"|\"coins_per_utxo_size\"|\"gov_action_deposit\"|\"min_fee_ref_script_cost_per_byte\") ]] && isParameterSecurityGroup=Y + [[ $parameterChange =~ (\"max_block_size\"|\"max_tx_size\"|\"max_bh_size\"|\"max_val_size\"|\"max_tx_ex_|\"max_block_ex_|\"max_collateral_inputs\") ]] && isNetworkGroup=Y + [[ $parameterChange =~ (\"min_fee_a\"|\"min_fee_b\"|\"key_deposit\"|\"pool_deposit\"|\"monetary_expand_rate\"|\"treasury_growth_rate\"|\"min_pool_cost\"|\"coins_per_utxo_size\"|\"coins_per_utxo_size\"|\"price_) ]] && isEconomicGroup=Y + [[ $parameterChange =~ (\"influence\"|\"max_epoch\"|\"optimal_pool_count\"|\"cost_model_id\"|\"collateral_percent\") ]] && isTechnicalGroup=Y + [[ $parameterChange =~ (\"gov_action_lifetime\"|\"gov_action_deposit\"|\"drep_deposit\"|\"drep_activity\"|\"committee_min_size\"|\"committee_max_term_length\"|\"pvt_|\"dvt_) ]] && isGovernanceGroup=Y + elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then + [[ $parameterChange =~ (\"maxBlockBodySize\"|\"maxTxSize\"|\"maxBlockHeaderSize\"|\"maxValueSize\"|\"maxBlockExecutionUnits\"|\"txFeePerByte\"|\"txFeeFixed\"|\"utxoCostPerByte\"|\"govActionDeposit\"|\"minFeeRefScriptCostPerByte\") ]] && isParameterSecurityGroup=Y + [[ $parameterChange =~ (\"maxBlockBodySize\"|\"maxTxSize\"|\"maxBlockHeaderSize\"|\"maxValueSize\"|\"maxTxExecutionUnits\"|\"maxBlockExecutionUnits\"|\"maxCollateralInputs\") ]] && isNetworkGroup=Y + [[ $parameterChange =~ (\"txFeePerByte\"|\"txFeeFixed\"|\"stakeAddressDeposit\"|\"stakePoolDeposit\"|\"monetaryExpansion\"|\"treasuryCut\"|\"minPoolCost\"|\"utxoCostPerByte\"|\"executionUnitPrices\") ]] && isEconomicGroup=Y + [[ $parameterChange =~ (\"poolPledgeInfluence\"|\"poolRetireMaxEpoch\"|\"stakePoolTargetNum\"|\"costModels\"|\"collateralPercentage\") ]] && isTechnicalGroup=Y + [[ $parameterChange =~ (\"govActionLifetime\"|\"govActionDeposit\"|\"dRepDeposit\"|\"dRepActivity\"|\"committeeMinSize\"|\"committeeMaxTermLength\"|\"VotingThresholds\") ]] && isGovernanceGroup=Y + fi +} + +# Command : getVoteThreshold [type] +# Description : assumed getCurrentCommittee, getParameterThresholds & getParameterChangeGroups are called before this one +# Return : Threshold for each type returned as a percentage. '-' if not valid for type. +getVoteThreshold() { + case ${1} in + "InfoAction") : ;; # no thresholds + "NoConfidence") + drep_vt=${dvt_motionNoConf} + spo_vt=${pvt_motionNoConf} + unset cc_vt + ;; + "HardForkInitiation") + drep_vt=${dvt_HFInit} + spo_vt=${pvt_HFInit} + cc_vt=${cc_threshold} + ;; + "NewCommittee"|"UpdateCommittee") + # TODO: Are we in Normal or NoConfidence state? + drep_vt=${dvt_newCCNormal} + spo_vt=${pvt_newCCNormal} + unset cc_vt + ;; + "TreasuryWithdrawals") + drep_vt=${dvt_treasuryWithdrawal} + unset spo_vt + cc_vt=${cc_threshold} + ;; + "ParameterChange") + if versionCheck "10.0" "${PROT_VERSION}"; then + # get highest of matching groups + drep_vt=0 + if [[ ${isNetworkGroup} = Y ]] && (( $(bc -l <<< "${dvt_ppNetGrp} > ${drep_vt}") )); then drep_vt=${dvt_ppNetGrp} + elif [[ ${isEconomicGroup} = Y ]] && (( $(bc -l <<< "${dvt_ppEcoGrp} > ${drep_vt}") )); then drep_vt=${dvt_ppEcoGrp} + elif [[ ${isTechnicalGroup} = Y ]] && (( $(bc -l <<< "${dvt_ppTechGrp} > ${drep_vt}") )); then drep_vt=${dvt_ppTechGrp} + elif [[ ${isGovernanceGroup} = Y ]] && (( $(bc -l <<< "${dvt_ppGovGrp} > ${drep_vt}") )); then drep_vt=${dvt_ppGovGrp} + else unset drep_vt + fi + else + unset drep_vt + fi + [[ ${isParameterSecurityGroup} = Y ]] && spo_vt=${pvt_ppSecGrp} || unset spo_vt + cc_vt=${cc_threshold} + ;; + "NewConstitution") + drep_vt=${dvt_newConst} + unset spo_vt + cc_vt=${cc_threshold} + ;; + *) unset drep_vt spo_vt cc_vt + esac +} + +# Command : isAllowedToVote [role] [type] [isParameterSecurityGroup (Y|N)] +# Return : 0 = ok +# 1 = not allowed by role +# 2 = parameter change not of type Security Group +# 3 = chang-1 limitation +isAllowedToVote() { + [[ -z $1 || -z $2 || -z $3 ]] && return 1 + case ${2} in + "NoConfidence") + [[ $1 = committee ]] && return 1 + ;; + "HardForkInitiation") + versionCheck "10.0" "${PROT_VERSION}" || return 3 + ;; + "InfoAction") + : ;; # always allowed by all + "NewCommittee"|"UpdateCommittee") + [[ $1 = committee ]] && return 1 + ;; + "TreasuryWithdrawals") + [[ $1 = spo ]] && return 1 + ;; + "ParameterChange") + [[ $1 = spo && $3 = Y ]] && return 2 + if [[ $1 = drep ]] && ! versionCheck "10.0" "${PROT_VERSION}"; then return 3; fi + ;; + "NewConstitution") + [[ $1 = spo ]] && return 1 + ;; + esac + return 0 +} + +# Command : getParameterThresholds +# Description : fetches DRep / SPO thresholds from PROT_PARAMS into variables +getParameterThresholds() { + read -r dvt_newCCNoConf dvt_newCCNormal dvt_HFInit dvt_motionNoConf dvt_ppEcoGrp dvt_ppGovGrp dvt_ppNetGrp dvt_ppTechGrp dvt_treasuryWithdrawal dvt_newConst pvt_newCCNoConf pvt_newCCNormal pvt_HFInit pvt_motionNoConf pvt_ppSecGrp <<<"$(jq -r '[ + (.dRepVotingThresholds.committeeNoConfidence //0) * 100, + (.dRepVotingThresholds.committeeNormal //0) * 100, + (.dRepVotingThresholds.hardForkInitiation //0) * 100, + (.dRepVotingThresholds.motionNoConfidence //0) * 100, + (.dRepVotingThresholds.ppEconomicGroup //0) * 100, + (.dRepVotingThresholds.ppGovGroup //0) * 100, + (.dRepVotingThresholds.ppNetworkGroup //0) * 100, + (.dRepVotingThresholds.ppTechnicalGroup //0) * 100, + (.dRepVotingThresholds.treasuryWithdrawal //0) * 100, + (.dRepVotingThresholds.updateToConstitution //0) * 100, + (.poolVotingThresholds.committeeNoConfidence //0) * 100, + (.poolVotingThresholds.committeeNormal //0) * 100, + (.poolVotingThresholds.hardForkInitiation //0) * 100, + (.poolVotingThresholds.motionNoConfidence //0) * 100, + (.poolVotingThresholds.ppSecurityGroup //0) * 100 + ] | @tsv' <<<"${PROT_PARAMS}" 2>/dev/null)" +} + +# Command : getCurrentCommittee +# Return : 0 = valid member, 1 = not a member, 2 = not authorized +getCurrentCommittee() { + unset committee_info + if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then + HEADERS=("${KOIOS_API_HEADERS[@]}" -H "accept: application/json") + println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/committee_info" + committee_info=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/committee_info") + cc_threshold=$(jq -r '(.[0].quorum_numerator //0) / (.[0].quorum_denominator //1) * 100' <<< "${committee_info}") + elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then + println ACTION "${CCLI} conway query committee-state ${NETWORK_IDENTIFIER}" + committee_info=$(${CCLI} conway query committee-state ${NETWORK_IDENTIFIER}) + cc_threshold=$(jq -r '(.threshold //0) * 100' <<< "${committee_info}") + fi +} + # Command : isCommitteeMember [cold hash] [hot hash] # Description : check if supplied hash is part of current committee list -# Return : 0 = valid member, 1 = not a member, 2 = not authorized +# Return : 0 = valid member, 1 = not a member, 2 = not authorized, 3 = resigned isCommitteeMember() { [[ -z $1 || -z $2 ]] && return 1 + getCurrentCommittee if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then - HEADERS=("${KOIOS_API_HEADERS[@]}" -H "accept: application/json") - println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/committee_info?select=members | tail -n +2" - members=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/committee_info?select=members" | tail -n +2) - elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then - println ACTION "${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -r '.committee.members | keys[]' | grep -q $1" - members=$(${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -r '.committee.members | keys[]') + grep -q $1 <<< "${committee_info}" || return 1 + grep -q resigned <<< "${committee_info}" && return 3 + grep -q $2 <<< "${committee_info}" || return 2 + else + committee_member=$(jq -r --arg cc_cold_hash "$1" 'first(.committee | to_entries[] | select(.key | contains($cc_cold_hash))) | .value' <<< "${committee_info}") + [[ -z ${committee_member} ]] && return 1 + grep -i -q resigned <<< "${committee_member}" && return 3 + grep -q $2 <<< "$(jq -r '.hotCredsAuthStatus.contents // [] | .[]' <<< "$committee_member")" || return 1 fi - grep -q $1 <<< "${members}" || return 1 - grep -q $2 <<< "${members}" || return 2 return 0 } diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index 18104ff2b..9835e76af 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -3392,7 +3392,7 @@ function main { for otx_witness_name in $(jq -r '.witness[].name' <<< "${offlineJSON}"); do [[ ${otx_witness_name} = "${otx_signing_name}" ]] && hasWitness=true && break done - [[ -z ${hasWitness} ]] && println DEBUG "${FG_LGRAY}${otx_signing_name}${NC} ${FG_RED}x${NC}" || println DEBUG "${FG_LGRAY}${otx_signing_name}${NC} ${FG_GREEN}\u2714${NC}" + [[ -z ${hasWitness} ]] && println DEBUG "${FG_LGRAY}${otx_signing_name}${NC} ${FG_RED}${ICON_CROSS}${NC}" || println DEBUG "${FG_LGRAY}${otx_signing_name}${NC} ${FG_GREEN}${ICON_CHECK}${NC}" done for otx_script in $(jq -r '."script-file"[] | @base64' <<< "${offlineJSON}"); do _jq() { base64 -d <<< ${otx_script} | jq -r "${1}"; } @@ -3416,11 +3416,11 @@ function main { found_wallet_name="${wallet_name}"; break fi done < <(find "${WALLET_FOLDER}" -mindepth 1 -maxdepth 1 -type d -print0) - [[ -z ${hasWitness} ]] && println DEBUG " ${FG_LGRAY}${sig}${NC} ${FG_RED}x${NC}" || println DEBUG " ${FG_LGRAY}$([[ -n ${found_wallet_name} ]] && echo ${found_wallet_name} || echo ${sig})${NC} ${FG_GREEN}\u2714${NC}" + [[ -z ${hasWitness} ]] && println DEBUG " ${FG_LGRAY}${sig}${NC} ${FG_RED}${ICON_CROSS}${NC}" || println DEBUG " ${FG_LGRAY}$([[ -n ${found_wallet_name} ]] && echo ${found_wallet_name} || echo ${sig})${NC} ${FG_GREEN}${ICON_CHECK}${NC}" done done - [[ $(jq -r '."signed-txBody" | length' <<< ${offlineJSON}) -gt 0 ]] && println INFO "\n${FG_GREEN}\u2714${NC} Transaction already signed, please submit transaction to complete!" && waitToProceed && continue + [[ $(jq -r '."signed-txBody" | length' <<< ${offlineJSON}) -gt 0 ]] && println INFO "\n${FG_GREEN}${ICON_CHECK}${NC} Transaction already signed, please submit transaction to complete!" && waitToProceed && continue [[ $(date '+%s' --date="${otx_date_expire}") -lt $(date '+%s') ]] && println ERROR "\n${FG_RED}ERROR${NC}: Transaction expired! please create a new one with long enough Time To Live (TTL)" && waitToProceed && continue for otx_signing_file in $(jq -r '."signing-file"[] | @base64' <<< "${offlineJSON}"); do @@ -4157,7 +4157,7 @@ function main { for vote_action in "${vote_action_list[@]:${start_idx}:${page_entries}}"; do [[ $idx -ne 1 ]] && printf "|$(printf "%${total_len}s" | tr " " "-")|\n" if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then - IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_yes_power drep_yes_pct drep_no drep_no_power drep_no_pct spo_yes spo_yes_power spo_yes_pct spo_no spo_no_power spo_no_pct cc_yes cc_yes_pct cc_no cc_no_pct <<< "${vote_action}" + IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_yes_power drep_yes_pct drep_no drep_no_power drep_no_pct spo_yes spo_yes_power spo_yes_pct spo_no spo_no_power spo_no_pct cc_yes cc_yes_pct cc_no cc_no_pct drep_vt spo_vt cc_vt <<< "${vote_action}" max_yes_len=${#drep_yes} max_no_len=${#drep_no} [[ ${#spo_yes} -gt ${max_yes_len} ]] && max_yes_len=${#spo_yes} @@ -4174,8 +4174,11 @@ function main { [[ ${#spo_no_pct} -gt ${max_no_pct_len} ]] && max_no_pct_len=${#spo_no_pct} [[ ${#cc_yes_pct} -gt ${max_yes_pct_len} ]] && max_yes_pct_len=${#cc_yes_pct} [[ ${#cc_no_pct} -gt ${max_no_pct_len} ]] && max_no_pct_len=${#cc_no_pct} + max_vt_len=${#drep_vt} + [[ ${#spo_vt} -gt ${max_vt_len} ]] && max_vt_len=${#spo_vt} + [[ ${#cc_vt} -gt ${max_vt_len} ]] && max_vt_len=${#cc_vt} else - IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_no drep_abstain spo_yes spo_no spo_abstain cc_yes cc_no cc_abstain <<< "${vote_action}" + IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_no drep_abstain spo_yes spo_no spo_abstain cc_yes cc_no cc_abstain drep_vt spo_vt cc_vt <<< "${vote_action}" max_yes_len=${#drep_yes} max_no_len=${#drep_no} max_abstain_len=${#drep_abstain} @@ -4199,10 +4202,25 @@ function main { fi printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Anchor URL" "${anchor_url}" if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then - chars_left=$((max_len-max_yes_len-max_yes_pct_len-max_yes_power_len-max_no_len-max_no_pct_len-max_no_power_len-31)) - printf "| %-13s : Yes=${FG_LBLUE}%-${max_yes_len}s${NC} -> ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP | No=${FG_LBLUE}%-${max_no_len}s${NC} -> ${FG_LBLUE}%${max_no_pct_len}s${NC}%% @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_pct}" "${drep_yes_power}" "${drep_no}" "${drep_no_pct}" "${drep_no_power}" "|" - printf "| %-13s : Yes=${FG_LBLUE}%-${max_yes_len}s${NC} -> ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP | No=${FG_LBLUE}%-${max_no_len}s${NC} -> ${FG_LBLUE}%${max_no_pct_len}s${NC}%% @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_pct}" "${spo_yes_power}" "${spo_no}" "${spo_no_pct}" "${spo_no_power}" "|" - printf "| %-13s : Yes=${FG_LBLUE}%-${max_yes_len}s${NC} -> ${FG_LBLUE}%${max_yes_pct_len}s${NC}%%%$((max_yes_power_len+6))s | No=${FG_LBLUE}%-${max_no_len}s${NC} -> ${FG_LBLUE}%${max_no_pct_len}s${NC}%%%$((max_no_power_len+6))s %${chars_left}s\n" "Committee" "${cc_yes}" "${cc_yes_pct}" " " "${cc_no}" "${cc_no_pct}" " " "|" + chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-25)) + if [[ -n ${drep_vt} ]]; then + (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "${drep_vt}" "|" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' + fi + if [[ -n ${spo_vt} ]]; then + (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "${spo_vt}" "|" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' + fi + if [[ -n ${cc_vt} ]]; then + (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+6))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "${cc_vt}" "|" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' + fi else chars_left=$((max_len-max_yes_len-max_no_len-max_abstain_len-16)) printf "| %-13s : Yes=${FG_LBLUE}%-${max_yes_len}s${NC} No=${FG_LBLUE}%-${max_no_len}s${NC} Abstain=${FG_LBLUE}%-${max_abstain_len}s${NC} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_no}" "${drep_abstain}" "|" @@ -4315,6 +4333,8 @@ function main { waitToProceed && continue ;; 2) println ERROR "\n${FG_RED}ERROR${NC}: selected wallet is an active committee member but have not authorized hot credential for voting!" waitToProceed && continue ;; + 3) println ERROR "\n${FG_RED}ERROR${NC}: selected wallet has resigned as a committee member!" + waitToProceed && continue ;; esac hash_type="keyHash" elif [[ ${vote_mode} = "drep" ]]; then @@ -4356,6 +4376,12 @@ function main { esac ;; esac + isAllowedToVote ${vote_mode} ${proposal_type} ${isParameterSecurityGroup} + case $? in + 1) println ERROR "\n${FG_RED}ERROR${NC}: Voter of type '${vote_mode}' is not allowed to vote on an action of type '${proposal_type}'!"; waitToProceed && continue ;; + 2) println ERROR "\n${FG_RED}ERROR${NC}: This proposal does not contain a parameter of the SecurityGroup, so voter of type '${vote_mode}' is not allowed to vote!"; waitToProceed && continue ;; + 3) println ERROR "\n${FG_RED}ERROR${NC}: Voter of type '${vote_mode}' is not allowed to vote on an action of type '${proposal_type}' during Conway bootstrap phase (Chang-1)!"; waitToProceed && continue ;; + esac println DEBUG "\nPrint governance action details?" select_opt "[y] Yes" "[n] No" case $? in diff --git a/scripts/cnode-helper-scripts/env b/scripts/cnode-helper-scripts/env index 20346b617..a44d47b64 100644 --- a/scripts/cnode-helper-scripts/env +++ b/scripts/cnode-helper-scripts/env @@ -1004,6 +1004,8 @@ set_default_vars() { STANDOUT='\e[7m' BOLD='\e[1m' NC='\e[0m' + ICON_CROSS='❌' + ICON_CHECK='✅' # Due to bug introduced in bash upstream at 5.2.21, need to temporarily enable POSIX mode for newer bash versions, until fix is live # https://github.com/bminor/bash/commit/e327891b52513bef0b34aac625c44f8fa6811f53 versionCheck 5.2.20 ${BASH_VERSION//(*/} && set -o posix From df329e5314d43c12eebcf83397ec5fafb88f22c1 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 10 Sep 2024 18:28:25 +0200 Subject: [PATCH 02/19] various fixes --- scripts/cnode-helper-scripts/cntools.library | 16 ++++++++++------ scripts/cnode-helper-scripts/cntools.sh | 12 +++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index 18ef951a7..fa2b93cbb 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -15,7 +15,7 @@ CNTOOLS_MAJOR_VERSION=13 # Minor: Changes and features of minor character that can be applied without breaking existing functionality or workflow CNTOOLS_MINOR_VERSION=2 # Patch: Backwards compatible bug fixes. No additional functionality or major changes -CNTOOLS_PATCH_VERSION=0 +CNTOOLS_PATCH_VERSION=1 CNTOOLS_VERSION="${CNTOOLS_MAJOR_VERSION}.${CNTOOLS_MINOR_VERSION}.${CNTOOLS_PATCH_VERSION}" DUMMYFEE=20000 @@ -1370,6 +1370,12 @@ getAllGovActions() { println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/proposal_voting_summary?_proposal_id=${_proposal_id}&select=drep_yes_votes_cast,drep_yes_vote_power,drep_yes_pct,drep_no_votes_cast,drep_no_vote_power,drep_no_pct,pool_yes_votes_cast,pool_yes_vote_power,pool_yes_pct,pool_no_votes_cast,pool_no_vote_power,pool_no_pct,committee_yes_votes_cast,committee_yes_pct,committee_no_votes_cast,committee_no_pct" _vote_action_votes=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/proposal_voting_summary?_proposal_id=${_proposal_id}&select=drep_yes_votes_cast,drep_yes_vote_power,drep_yes_pct,drep_no_votes_cast,drep_no_vote_power,drep_no_pct,pool_yes_votes_cast,pool_yes_vote_power,pool_yes_pct,pool_no_votes_cast,pool_no_vote_power,pool_no_pct,committee_yes_votes_cast,committee_yes_pct,committee_no_votes_cast,committee_no_pct" 2>&1) || continue IFS=',' read -r drep_yes_votes_cast drep_yes_vote_power drep_yes_pct drep_no_votes_cast drep_no_vote_power drep_no_pct pool_yes_votes_cast pool_yes_vote_power pool_yes_pct pool_no_votes_cast pool_no_vote_power pool_no_pct committee_yes_votes_cast committee_yes_pct committee_no_votes_cast committee_no_pct <<< "$(tail -n +2 <<< ${_vote_action_votes})" + drep_yes_pct=$(printf '%.4g' "${drep_yes_pct}") + drep_no_pct=$(printf '%.4g' "${drep_no_pct}") + pool_yes_pct=$(printf '%.4g' "${pool_yes_pct}") + pool_no_pct=$(printf '%.4g' "${pool_no_pct}") + committee_yes_pct=$(printf '%.4g' "${committee_yes_pct}") + committee_no_pct=$(printf '%.4g' "${committee_no_pct}") if [[ ${_proposal_type} = "ParameterChange" ]]; then param_proposal_unescaped=${_param_proposal:1: -1} # remove first and last char (quotation) param_proposal_unescaped=$(sed 's/""/"/g' <<< "${param_proposal_unescaped}") # remove all double quotes, sed seems to perform better than bash string manipulation @@ -1403,7 +1409,6 @@ getAllGovActions() { # Return : sets isParameterSecurityGroup isNetworkGroup isEconomicGroup isTechnicalGroup isGovernanceGroup getParameterChangeGroups() { unset isParameterSecurityGroup isNetworkGroup isEconomicGroup isTechnicalGroup isGovernanceGroup - [[ -z ${vote_action} ]] && return 1 if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then [[ $parameterChange =~ (\"max_block_size\"|\"max_tx_size\"|\"max_bh_size\"|\"max_val_size\"|\"max_block_ex_|\"min_fee_a\"|\"min_fee_b\"|\"coins_per_utxo_size\"|\"gov_action_deposit\"|\"min_fee_ref_script_cost_per_byte\") ]] && isParameterSecurityGroup=Y [[ $parameterChange =~ (\"max_block_size\"|\"max_tx_size\"|\"max_bh_size\"|\"max_val_size\"|\"max_tx_ex_|\"max_block_ex_|\"max_collateral_inputs\") ]] && isNetworkGroup=Y @@ -1424,7 +1429,7 @@ getParameterChangeGroups() { # Return : Threshold for each type returned as a percentage. '-' if not valid for type. getVoteThreshold() { case ${1} in - "InfoAction") : ;; # no thresholds + "InfoAction") unset drep_vt spo_vt cc_vt ;; # no thresholds "NoConfidence") drep_vt=${dvt_motionNoConf} spo_vt=${pvt_motionNoConf} @@ -1467,7 +1472,6 @@ getVoteThreshold() { unset spo_vt cc_vt=${cc_threshold} ;; - *) unset drep_vt spo_vt cc_vt esac } @@ -1534,11 +1538,11 @@ getCurrentCommittee() { HEADERS=("${KOIOS_API_HEADERS[@]}" -H "accept: application/json") println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/committee_info" committee_info=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/committee_info") - cc_threshold=$(jq -r '(.[0].quorum_numerator //0) / (.[0].quorum_denominator //1) * 100' <<< "${committee_info}") + cc_threshold=$(printf '%.4g' "$(jq -r '(.[0].quorum_numerator //0) / (.[0].quorum_denominator //1) * 100' <<< "${committee_info}")") elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then println ACTION "${CCLI} conway query committee-state ${NETWORK_IDENTIFIER}" committee_info=$(${CCLI} conway query committee-state ${NETWORK_IDENTIFIER}) - cc_threshold=$(jq -r '(.threshold //0) * 100' <<< "${committee_info}") + cc_threshold=$(printf '%.4g' "$(jq -r '(.threshold //0) * 100' <<< "${committee_info}")") fi } diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index 9835e76af..0f7ac4d37 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4201,23 +4201,25 @@ function main { printf "| %-13s : epoch ${FG_LBLUE}%-$(( max_len - 6 ))s${NC} |\n" "Expires After" "${expires_after}" fi printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Anchor URL" "${anchor_url}" - if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then - chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-25)) + if [[ ${action_type} = "InfoAction" ]]; then + : # ignore + elif [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then + chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-44)) if [[ -n ${drep_vt} ]]; then (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "${drep_vt}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "${drep_vt}" "|" else printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' fi if [[ -n ${spo_vt} ]]; then (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "${spo_vt}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "${spo_vt}" "|" else printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' fi if [[ -n ${cc_vt} ]]; then (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+6))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "${cc_vt}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "${cc_vt}" "|" else printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' fi From 94a70fa4ca79694a5fa76e1e340d781554708517 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 10 Sep 2024 18:38:09 +0200 Subject: [PATCH 03/19] Add back InfoAction votes --- scripts/cnode-helper-scripts/cntools.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index 0f7ac4d37..a852303ce 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4202,7 +4202,10 @@ function main { fi printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Anchor URL" "${anchor_url}" if [[ ${action_type} = "InfoAction" ]]; then - : # ignore + chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-36)) + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "|" elif [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-44)) if [[ -n ${drep_vt} ]]; then From a22fd9b5b7ada3f8a67fdb7625246fed0f0e9897 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 10 Sep 2024 18:39:21 +0200 Subject: [PATCH 04/19] Only for light mode --- scripts/cnode-helper-scripts/cntools.sh | 48 +++++++++++++------------ 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index a852303ce..d905958ec 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4201,30 +4201,32 @@ function main { printf "| %-13s : epoch ${FG_LBLUE}%-$(( max_len - 6 ))s${NC} |\n" "Expires After" "${expires_after}" fi printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Anchor URL" "${anchor_url}" - if [[ ${action_type} = "InfoAction" ]]; then - chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-36)) - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "|" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "|" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "|" - elif [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then - chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-44)) - if [[ -n ${drep_vt} ]]; then - (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "${drep_vt}" "|" - else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' - fi - if [[ -n ${spo_vt} ]]; then - (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "${spo_vt}" "|" - else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' - fi - if [[ -n ${cc_vt} ]]; then - (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "${cc_vt}" "|" + if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then + if [[ ${action_type} = "InfoAction" ]]; then + chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-36)) + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "|" else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' + chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-44)) + if [[ -n ${drep_vt} ]]; then + (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "${drep_vt}" "|" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' + fi + if [[ -n ${spo_vt} ]]; then + (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "${spo_vt}" "|" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' + fi + if [[ -n ${cc_vt} ]]; then + (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "${cc_vt}" "|" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' + fi fi else chars_left=$((max_len-max_yes_len-max_no_len-max_abstain_len-16)) From 5639004e3fc71d12bcd9cd03c3632e74efee6ac5 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 10 Sep 2024 18:43:05 +0200 Subject: [PATCH 05/19] minor ui tweak --- scripts/cnode-helper-scripts/cntools.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index d905958ec..a58419ce1 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4203,7 +4203,7 @@ function main { printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Anchor URL" "${anchor_url}" if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then if [[ ${action_type} = "InfoAction" ]]; then - chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-36)) + chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-35)) printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "|" printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "|" printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "|" From 1d9a5dced83468084b03cad846a74c009506dca7 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 10 Sep 2024 18:49:05 +0200 Subject: [PATCH 06/19] changelog --- docs/Scripts/cntools-changelog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/Scripts/cntools-changelog.md b/docs/Scripts/cntools-changelog.md index b532556ec..65ac78cec 100644 --- a/docs/Scripts/cntools-changelog.md +++ b/docs/Scripts/cntools-changelog.md @@ -6,6 +6,11 @@ All notable changes to this tool will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [13.2.1] - 2024-09-10 +#### Added +- Added gov vote validation for role and type +- Gov proposal list when run in `light` mode now have additional vote data + ## [13.2.0] - 2024-09-08 #### Added - `light` mode support for all governance functions. From 5ff07cd402135e4f88b302fedd355c8a59b3acc0 Mon Sep 17 00:00:00 2001 From: Ola Date: Wed, 11 Sep 2024 12:10:30 +0200 Subject: [PATCH 07/19] Fix for selectWallet reward mode when missing keys --- scripts/cnode-helper-scripts/cntools.library | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index fa2b93cbb..61b7af410 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -584,7 +584,7 @@ selectWallet() { [[ -n ${reward_addr} ]] && reward_addr_list+=(${reward_addr}) else getWalletRewards ${dir} - [[ ${reward_lovelace} -eq 0 ]] && continue + [[ ${reward_lovelace} -le 0 ]] && continue rewards_available[${reward_addr}]=${reward_lovelace} fi wallet_dirs+=("${dir}_balance_") From 5f998ccfb7afd2ad9180732c3ee4ba029a83088a Mon Sep 17 00:00:00 2001 From: Ola Date: Thu, 12 Sep 2024 10:06:54 +0200 Subject: [PATCH 08/19] Calculate vote power/pct also for cli --- scripts/cnode-helper-scripts/cntools.library | 59 +++++++++- scripts/cnode-helper-scripts/cntools.sh | 108 ++++++++----------- 2 files changed, 103 insertions(+), 64 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index 61b7af410..789850b63 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -1387,6 +1387,21 @@ getAllGovActions() { done <<< "$(tail -n +2 <<< ${_vote_action_list})" elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then getCurrentCommittee; getParameterThresholds # to fetch thresholds + # get current DRep distribution + println ACTION "${CCLI} conway query drep-stake-distribution --all-dreps ${NETWORK_IDENTIFIER}" + all_drep_vote_power=$(${CCLI} conway query drep-stake-distribution --all-dreps ${NETWORK_IDENTIFIER}) + # sum of all drep stake distribution entries without the alwaysAbstain and alwaysNoConfidence + drep_power_total_no_abstain=$(jq -r '[.[] | select(.[0] == "drep-always-abstain" | not) | .[1]] | add //0' <<< "${all_drep_vote_power}" 2>/dev/null) + # get current Pool distribution (available from cardano-cli 9.3.0.0) + unset all_spo_vote_power spo_power_total + if versionCheckNode "9.3.0.0" "${cli_version}"; then + println ACTION "${CCLI} conway query spo-stake-distribution --all-spos ${NETWORK_IDENTIFIER}" + all_spo_vote_power=$(${CCLI} conway query spo-stake-distribution --all-spos ${NETWORK_IDENTIFIER}) + spo_power_total=$(jq -r '[.[][1]] | add' <<< "${poolStakeDistributionJSON}" 2>/dev/null) + fi + # get committee vote power (sum of authorized committee members) + println ACTION "${CCLI} conway query committee-state ${NETWORK_IDENTIFIER} | jq -r 'reduce(select(.committee[].hotCredsAuthStatus.tag|strings==\"MemberAuthorized\")) as \$_ (0; .+1)'" + cc_power_authorized=$(${CCLI} conway query committee-state ${NETWORK_IDENTIFIER} | jq -r 'reduce(select(.committee[].hotCredsAuthStatus.tag|strings=="MemberAuthorized")) as $_ (0; .+1)' 2>/dev/null) vote_action_list=(); _vote_action_list=() println ACTION "${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64'" for vote_action in $(${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64' 2>/dev/null); do @@ -1395,7 +1410,49 @@ getAllGovActions() { getParameterChangeGroups fi getVoteThreshold "$(jq -r '.proposalProcedure.govAction.tag' <<< "$(base64 -d <<< "${vote_action}")")" - _vote_action_list+=( "$(jq -cr '"\((.actionId.txId//"") + "#" + (.actionId.govActionIx//0|tostring)),\(.proposalProcedure.govAction.tag//""),\(.proposedIn//0),\(.expiresAfter//0),\(.proposalProcedure.anchor.url//""),\(.dRepVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="Abstain")) as $_ (0; .+1))"' <<< "$(base64 -d <<< "${vote_action}")"),${drep_vt},${spo_vt},${cc_vt}" ) + # get list of drep voters based on vote + drep_yes_voters="$(jq '[.dRepVotes | to_entries[] | select(.value=="VoteYes") | ("drep-" + .key)]' <<< "$(base64 -d <<< "${vote_action}")")" + drep_no_voters="$(jq '[.dRepVotes | to_entries[] | select(.value=="VoteNo") | ("drep-" + .key)]' <<< "$(base64 -d <<< "${vote_action}")")" + drep_abstain_voters="$(jq '[.dRepVotes | to_entries[] | select(.value=="Abstain") | ("drep-" + .key)]' <<< "$(base64 -d <<< "${vote_action}")")" + # get sum of vote power for each type + drep_yes_vote_power="$(jq -r --argjson v "${drep_yes_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" + drep_no_vote_power="$(jq -r --argjson v "${drep_no_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" + drep_abstain_vote_power="$(jq -r --argjson v "${drep_abstain_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" + drep_power_total=$(( drep_power_total_no_abstain - drep_abstain_vote_power )) + # calculate percentages + drep_yes_pct=$(printf '%.4g' "$(bc -l <<< "${drep_yes_vote_power}*100/${drep_power_total}")") + drep_no_pct=$(printf '%.4g' "$(bc -l <<< "${drep_no_vote_power}*100/${drep_power_total}")") + if [[ -n ${spo_power_total} ]]; then + # get list of spo voters based on vote + spo_yes_voters="$(jq '[.stakePoolVotes | to_entries[] | select(.value=="VoteYes") | .key]' <<< "$(base64 -d <<< "${vote_action}")")" + spo_no_voters="$(jq '[.stakePoolVotes | to_entries[] | select(.value=="VoteNo") | .key]' <<< "$(base64 -d <<< "${vote_action}")")" + spo_abstain_voters="$(jq '[.stakePoolVotes | to_entries[] | select(.value=="Abstain") | .key]' <<< "$(base64 -d <<< "${vote_action}")")" + # get sum of vote power for each type + spo_yes_vote_power="$(jq -r --argjson v "${spo_yes_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" + spo_no_vote_power="$(jq -r --argjson v "${spo_no_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" + spo_abstain_vote_power="$(jq -r --argjson v "${spo_abstain_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" + spo_power_total=$(( drep_power_total_no_abstain - spo_abstain_vote_power )) + # calculate percentages + spo_yes_pct=$(printf '%.4g' "$(bc -l <<< "${spo_yes_vote_power}*100/${spo_power_total}")") + spo_no_pct=$(printf '%.4g' "$(bc -l <<< "${spo_no_vote_power}*100/${spo_power_total}")") + else + unset spo_yes_vote_power spo_no_vote_power spo_yes_pct spo_no_pct + fi + # get list of cc voters based on vote + cc_yes_voters="$(jq '[.committeeVotes | to_entries[] | select(.value=="VoteYes")] | length' <<< "$(base64 -d <<< "${vote_action}")")" + cc_no_voters="$(jq '[.committeeVotes | to_entries[] | select(.value=="VoteYes")] | length' <<< "$(base64 -d <<< "${vote_action}")")" + cc_abstain_voters="$(jq '[.committeeVotes | to_entries[] | select(.value=="VoteYes")] | length' <<< "$(base64 -d <<< "${vote_action}")")" + cc_power_total=$(( cc_power_authorized - cc_abstain_voters )) + # calculate percentages + if [[ ${cc_power_total} -eq 0 ]]; then + cc_yes_pct=0 + cc_no_pct=0 + else + cc_yes_pct=$(printf '%.4g' "$(bc -l <<< "${cc_yes_voters}*100/${cc_power_total}")") + cc_no_pct=$(printf '%.4g' "$(bc -l <<< "${cc_no_voters}*100/${cc_power_total}")") + fi + IFS=',' read -r proposal_id proposal_type proposed_epoch expiration meta_url drep_yes_votes_cast drep_no_votes_cast spo_yes_votes_cast spo_no_votes_cast cc_yes_votes_cast cc_no_votes_cast < <( jq -cr '"\((.actionId.txId//"") + "#" + (.actionId.govActionIx//0|tostring)),\(.proposalProcedure.govAction.tag//""),\(.proposedIn//0),\(.expiresAfter//0),\(.proposalProcedure.anchor.url//""),\(.dRepVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1))"' <<< "$(base64 -d <<< "${vote_action}")" ) + vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) done # reverse order for ((i=${#_vote_action_list[@]}-1; i>=0; i--)); do diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index a58419ce1..dfbe6aa68 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4156,39 +4156,28 @@ function main { idx=1 for vote_action in "${vote_action_list[@]:${start_idx}:${page_entries}}"; do [[ $idx -ne 1 ]] && printf "|$(printf "%${total_len}s" | tr " " "-")|\n" - if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then - IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_yes_power drep_yes_pct drep_no drep_no_power drep_no_pct spo_yes spo_yes_power spo_yes_pct spo_no spo_no_power spo_no_pct cc_yes cc_yes_pct cc_no cc_no_pct drep_vt spo_vt cc_vt <<< "${vote_action}" - max_yes_len=${#drep_yes} - max_no_len=${#drep_no} - [[ ${#spo_yes} -gt ${max_yes_len} ]] && max_yes_len=${#spo_yes} - [[ ${#spo_no} -gt ${max_no_len} ]] && max_no_len=${#spo_no} - [[ ${#cc_yes} -gt ${max_yes_len} ]] && max_yes_len=${#cc_yes} - [[ ${#cc_no} -gt ${max_no_len} ]] && max_no_len=${#cc_no} - drep_yes_power="$(formatLovelaceHuman ${drep_yes_power})"; max_yes_power_len=${#drep_yes_power} - drep_no_power="$(formatLovelaceHuman ${drep_no_power})"; max_no_power_len=${#drep_no_power} - spo_yes_power="$(formatLovelaceHuman ${spo_yes_power})"; [[ ${#spo_yes_power} -gt ${max_yes_power_len} ]] && max_yes_power_len=${#spo_yes_power} - spo_no_power="$(formatLovelaceHuman ${spo_no_power})"; [[ ${#spo_no_power} -gt ${max_no_power_len} ]] && max_no_power_len=${#spo_no_power} - max_yes_pct_len=${#drep_yes_pct} - max_no_pct_len=${#drep_no_pct} - [[ ${#spo_yes_pct} -gt ${max_yes_pct_len} ]] && max_yes_pct_len=${#spo_yes_pct} - [[ ${#spo_no_pct} -gt ${max_no_pct_len} ]] && max_no_pct_len=${#spo_no_pct} - [[ ${#cc_yes_pct} -gt ${max_yes_pct_len} ]] && max_yes_pct_len=${#cc_yes_pct} - [[ ${#cc_no_pct} -gt ${max_no_pct_len} ]] && max_no_pct_len=${#cc_no_pct} - max_vt_len=${#drep_vt} - [[ ${#spo_vt} -gt ${max_vt_len} ]] && max_vt_len=${#spo_vt} - [[ ${#cc_vt} -gt ${max_vt_len} ]] && max_vt_len=${#cc_vt} - else - IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_no drep_abstain spo_yes spo_no spo_abstain cc_yes cc_no cc_abstain drep_vt spo_vt cc_vt <<< "${vote_action}" - max_yes_len=${#drep_yes} - max_no_len=${#drep_no} - max_abstain_len=${#drep_abstain} - [[ ${#spo_yes} -gt ${max_yes_len} ]] && max_yes_len=${#spo_yes} - [[ ${#spo_no} -gt ${max_no_len} ]] && max_no_len=${#spo_no} - [[ ${#spo_abstain} -gt ${max_abstain_len} ]] && max_abstain_len=${#spo_abstain} - [[ ${#cc_yes} -gt ${max_yes_len} ]] && max_yes_len=${#cc_yes} - [[ ${#cc_no} -gt ${max_no_len} ]] && max_no_len=${#cc_no} - [[ ${#cc_abstain} -gt ${max_abstain_len} ]] && max_abstain_len=${#cc_abstain} - fi + # calculate length of strings + IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_yes_power drep_yes_pct drep_no drep_no_power drep_no_pct spo_yes spo_yes_power spo_yes_pct spo_no spo_no_power spo_no_pct cc_yes cc_yes_pct cc_no cc_no_pct drep_vt spo_vt cc_vt <<< "${vote_action}" + max_yes_len=${#drep_yes} + max_no_len=${#drep_no} + [[ ${#spo_yes} -gt ${max_yes_len} ]] && max_yes_len=${#spo_yes} + [[ ${#spo_no} -gt ${max_no_len} ]] && max_no_len=${#spo_no} + [[ ${#cc_yes} -gt ${max_yes_len} ]] && max_yes_len=${#cc_yes} + [[ ${#cc_no} -gt ${max_no_len} ]] && max_no_len=${#cc_no} + drep_yes_power="$(formatLovelaceHuman ${drep_yes_power})"; max_yes_power_len=${#drep_yes_power} + drep_no_power="$(formatLovelaceHuman ${drep_no_power})"; max_no_power_len=${#drep_no_power} + spo_yes_power="$(formatLovelaceHuman ${spo_yes_power})"; [[ ${#spo_yes_power} -gt ${max_yes_power_len} ]] && max_yes_power_len=${#spo_yes_power} + spo_no_power="$(formatLovelaceHuman ${spo_no_power})"; [[ ${#spo_no_power} -gt ${max_no_power_len} ]] && max_no_power_len=${#spo_no_power} + max_yes_pct_len=${#drep_yes_pct} + max_no_pct_len=${#drep_no_pct} + [[ ${#spo_yes_pct} -gt ${max_yes_pct_len} ]] && max_yes_pct_len=${#spo_yes_pct} + [[ ${#spo_no_pct} -gt ${max_no_pct_len} ]] && max_no_pct_len=${#spo_no_pct} + [[ ${#cc_yes_pct} -gt ${max_yes_pct_len} ]] && max_yes_pct_len=${#cc_yes_pct} + [[ ${#cc_no_pct} -gt ${max_no_pct_len} ]] && max_no_pct_len=${#cc_no_pct} + max_vt_len=${#drep_vt} + [[ ${#spo_vt} -gt ${max_vt_len} ]] && max_vt_len=${#spo_vt} + [[ ${#cc_vt} -gt ${max_vt_len} ]] && max_vt_len=${#cc_vt} + # print data IFS='#' read -r proposal_tx_id proposal_index <<< "${action_id}" getGovActionId ${proposal_tx_id} ${proposal_index} printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Action ID" "${action_id}" @@ -4201,38 +4190,31 @@ function main { printf "| %-13s : epoch ${FG_LBLUE}%-$(( max_len - 6 ))s${NC} |\n" "Expires After" "${expires_after}" fi printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Anchor URL" "${anchor_url}" - if [[ ${CNTOOLS_MODE} = "LIGHT" ]]; then - if [[ ${action_type} = "InfoAction" ]]; then - chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-35)) - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "|" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "|" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "|" + if [[ ${action_type} = "InfoAction" ]]; then + chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-35)) + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "|" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "|" + else + chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-44)) + if [[ -n ${drep_vt} ]]; then + (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "${drep_vt}" "|" else - chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-44)) - if [[ -n ${drep_vt} ]]; then - (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "${drep_vt}" "|" - else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' - fi - if [[ -n ${spo_vt} ]]; then - (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "${spo_vt}" "|" - else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' - fi - if [[ -n ${cc_vt} ]]; then - (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "${cc_vt}" "|" - else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' - fi + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' + fi + if [[ -n ${spo_vt} ]]; then + (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "${spo_vt}" "|" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' + fi + if [[ -n ${cc_vt} ]]; then + (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" + printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "${cc_vt}" "|" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' fi - else - chars_left=$((max_len-max_yes_len-max_no_len-max_abstain_len-16)) - printf "| %-13s : Yes=${FG_LBLUE}%-${max_yes_len}s${NC} No=${FG_LBLUE}%-${max_no_len}s${NC} Abstain=${FG_LBLUE}%-${max_abstain_len}s${NC} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_no}" "${drep_abstain}" "|" - printf "| %-13s : Yes=${FG_LBLUE}%-${max_yes_len}s${NC} No=${FG_LBLUE}%-${max_no_len}s${NC} Abstain=${FG_LBLUE}%-${max_abstain_len}s${NC} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_no}" "${spo_abstain}" "|" - printf "| %-13s : Yes=${FG_LBLUE}%-${max_yes_len}s${NC} No=${FG_LBLUE}%-${max_no_len}s${NC} Abstain=${FG_LBLUE}%-${max_abstain_len}s${NC} %${chars_left}s\n" "Committee" "${cc_yes}" "${cc_no}" "${cc_abstain}" "|" fi ((idx++)) done From de34f17b4630c7828252d1fc858e713d675fcbd9 Mon Sep 17 00:00:00 2001 From: Ola Date: Thu, 12 Sep 2024 15:02:31 +0200 Subject: [PATCH 09/19] various vote calculation fixes --- scripts/cnode-helper-scripts/cntools.library | 37 +++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index 789850b63..940785836 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -1391,21 +1391,21 @@ getAllGovActions() { println ACTION "${CCLI} conway query drep-stake-distribution --all-dreps ${NETWORK_IDENTIFIER}" all_drep_vote_power=$(${CCLI} conway query drep-stake-distribution --all-dreps ${NETWORK_IDENTIFIER}) # sum of all drep stake distribution entries without the alwaysAbstain and alwaysNoConfidence - drep_power_total_no_abstain=$(jq -r '[.[] | select(.[0] == "drep-always-abstain" | not) | .[1]] | add //0' <<< "${all_drep_vote_power}" 2>/dev/null) + drep_power_total_no_abstain=$(jq -r '[.[] | select(.[0] == "drep-alwaysAbstain" | not) | .[1]] | add //0' <<< "${all_drep_vote_power}" 2>/dev/null) # get current Pool distribution (available from cardano-cli 9.3.0.0) unset all_spo_vote_power spo_power_total if versionCheckNode "9.3.0.0" "${cli_version}"; then println ACTION "${CCLI} conway query spo-stake-distribution --all-spos ${NETWORK_IDENTIFIER}" all_spo_vote_power=$(${CCLI} conway query spo-stake-distribution --all-spos ${NETWORK_IDENTIFIER}) - spo_power_total=$(jq -r '[.[][1]] | add' <<< "${poolStakeDistributionJSON}" 2>/dev/null) + spo_power_total=$(jq -r '[.[][1]] | add' <<< "${all_spo_vote_power}" 2>/dev/null) fi # get committee vote power (sum of authorized committee members) - println ACTION "${CCLI} conway query committee-state ${NETWORK_IDENTIFIER} | jq -r 'reduce(select(.committee[].hotCredsAuthStatus.tag|strings==\"MemberAuthorized\")) as \$_ (0; .+1)'" - cc_power_authorized=$(${CCLI} conway query committee-state ${NETWORK_IDENTIFIER} | jq -r 'reduce(select(.committee[].hotCredsAuthStatus.tag|strings=="MemberAuthorized")) as $_ (0; .+1)' 2>/dev/null) + cc_power_authorized=$(jq -r 'reduce(select(.committee[].hotCredsAuthStatus.tag|strings=="MemberAuthorized")) as $_ (0; .+1)' <<< "${committee_info}") vote_action_list=(); _vote_action_list=() println ACTION "${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64'" for vote_action in $(${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64' 2>/dev/null); do - if [[ $(jq -r '.proposalProcedure.govAction.tag') = "ParameterChange" ]]; then + IFS=',' read -r proposal_id proposal_type proposed_epoch expiration meta_url drep_yes_votes_cast drep_no_votes_cast spo_yes_votes_cast spo_no_votes_cast cc_yes_votes_cast cc_no_votes_cast < <( jq -cr '"\((.actionId.txId//"") + "#" + (.actionId.govActionIx//0|tostring)),\(.proposalProcedure.govAction.tag//""),\(.proposedIn//0),\(.expiresAfter//0),\(.proposalProcedure.anchor.url//""),\(.dRepVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1))"' <<< "$(base64 -d <<< "${vote_action}")" ) + if [[ $(jq -r '.proposalProcedure.govAction.tag' <<< "$(base64 -d <<< "${vote_action}")") = "ParameterChange" ]]; then parameterChange=$(jq -e '.proposalProcedure.govAction.contents[1] | keys[]' <<< "$(base64 -d <<< "${vote_action}")") getParameterChangeGroups fi @@ -1419,22 +1419,26 @@ getAllGovActions() { drep_no_vote_power="$(jq -r --argjson v "${drep_no_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" drep_abstain_vote_power="$(jq -r --argjson v "${drep_abstain_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" drep_power_total=$(( drep_power_total_no_abstain - drep_abstain_vote_power )) + if [[ ${proposal_type} = "NoConfidence" ]]; then + # add alwaysNoConfidence power to yes vote + drep_yes_vote_power=$(( drep_yes_vote_power + $(jq -r '[.[] | select(.[0] == "drep-alwaysNoConfidence") | .[1]] | add //0' <<< "${all_drep_vote_power}" 2>/dev/null) )) + fi # calculate percentages - drep_yes_pct=$(printf '%.4g' "$(bc -l <<< "${drep_yes_vote_power}*100/${drep_power_total}")") - drep_no_pct=$(printf '%.4g' "$(bc -l <<< "${drep_no_vote_power}*100/${drep_power_total}")") + drep_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${drep_yes_vote_power}/${drep_power_total})*100")") + drep_no_pct=$(printf '%.4g' "$(bc -l <<< "(${drep_no_vote_power}/${drep_power_total})*100")") if [[ -n ${spo_power_total} ]]; then # get list of spo voters based on vote spo_yes_voters="$(jq '[.stakePoolVotes | to_entries[] | select(.value=="VoteYes") | .key]' <<< "$(base64 -d <<< "${vote_action}")")" spo_no_voters="$(jq '[.stakePoolVotes | to_entries[] | select(.value=="VoteNo") | .key]' <<< "$(base64 -d <<< "${vote_action}")")" spo_abstain_voters="$(jq '[.stakePoolVotes | to_entries[] | select(.value=="Abstain") | .key]' <<< "$(base64 -d <<< "${vote_action}")")" # get sum of vote power for each type - spo_yes_vote_power="$(jq -r --argjson v "${spo_yes_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" - spo_no_vote_power="$(jq -r --argjson v "${spo_no_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" - spo_abstain_vote_power="$(jq -r --argjson v "${spo_abstain_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" - spo_power_total=$(( drep_power_total_no_abstain - spo_abstain_vote_power )) + spo_yes_vote_power="$(jq -r --argjson v "${spo_yes_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_spo_vote_power}")" + spo_no_vote_power="$(jq -r --argjson v "${spo_no_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_spo_vote_power}")" + spo_abstain_vote_power="$(jq -r --argjson v "${spo_abstain_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_spo_vote_power}")" + spo_power_total=$(( spo_power_total - spo_abstain_vote_power )) # calculate percentages - spo_yes_pct=$(printf '%.4g' "$(bc -l <<< "${spo_yes_vote_power}*100/${spo_power_total}")") - spo_no_pct=$(printf '%.4g' "$(bc -l <<< "${spo_no_vote_power}*100/${spo_power_total}")") + spo_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${spo_yes_vote_power}/${spo_power_total})*100")") + spo_no_pct=$(printf '%.4g' "$(bc -l <<< "(${spo_no_vote_power}/${spo_power_total})*100")") else unset spo_yes_vote_power spo_no_vote_power spo_yes_pct spo_no_pct fi @@ -1448,10 +1452,9 @@ getAllGovActions() { cc_yes_pct=0 cc_no_pct=0 else - cc_yes_pct=$(printf '%.4g' "$(bc -l <<< "${cc_yes_voters}*100/${cc_power_total}")") - cc_no_pct=$(printf '%.4g' "$(bc -l <<< "${cc_no_voters}*100/${cc_power_total}")") + cc_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${cc_yes_voters}/${cc_power_total})*100")") + cc_no_pct=$(printf '%.4g' "$(bc -l <<< "(${cc_no_voters}/${cc_power_total})*100")") fi - IFS=',' read -r proposal_id proposal_type proposed_epoch expiration meta_url drep_yes_votes_cast drep_no_votes_cast spo_yes_votes_cast spo_no_votes_cast cc_yes_votes_cast cc_no_votes_cast < <( jq -cr '"\((.actionId.txId//"") + "#" + (.actionId.govActionIx//0|tostring)),\(.proposalProcedure.govAction.tag//""),\(.proposedIn//0),\(.expiresAfter//0),\(.proposalProcedure.anchor.url//""),\(.dRepVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1))"' <<< "$(base64 -d <<< "${vote_action}")" ) vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) done # reverse order @@ -1599,7 +1602,7 @@ getCurrentCommittee() { elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then println ACTION "${CCLI} conway query committee-state ${NETWORK_IDENTIFIER}" committee_info=$(${CCLI} conway query committee-state ${NETWORK_IDENTIFIER}) - cc_threshold=$(printf '%.4g' "$(jq -r '(.threshold //0) * 100' <<< "${committee_info}")") + cc_threshold=$(printf '%.4g' "$(jq -r '(.threshold.numerator //0) / (.threshold.denominator //1) * 100' <<< "${committee_info}")") fi } From fa9c28d3aee743d3fc70a4b0da17979e143d54d2 Mon Sep 17 00:00:00 2001 From: Ola Date: Thu, 12 Sep 2024 15:39:06 +0200 Subject: [PATCH 10/19] adjust calculation to match that of Koios --- scripts/cnode-helper-scripts/cntools.library | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index 940785836..2ee1e7bc8 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -1419,13 +1419,16 @@ getAllGovActions() { drep_no_vote_power="$(jq -r --argjson v "${drep_no_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" drep_abstain_vote_power="$(jq -r --argjson v "${drep_abstain_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_drep_vote_power}")" drep_power_total=$(( drep_power_total_no_abstain - drep_abstain_vote_power )) + drep_no_vote_power_total=$(( drep_power_total - drep_yes_vote_power )) # total drep power - always abstain - proposal abstain - proposal yes if [[ ${proposal_type} = "NoConfidence" ]]; then # add alwaysNoConfidence power to yes vote - drep_yes_vote_power=$(( drep_yes_vote_power + $(jq -r '[.[] | select(.[0] == "drep-alwaysNoConfidence") | .[1]] | add //0' <<< "${all_drep_vote_power}" 2>/dev/null) )) + drep_always_no_confidence="$(jq -r '[.[] | select(.[0] == "drep-alwaysNoConfidence") | .[1]] | add //0' <<< "${all_drep_vote_power}" 2>/dev/null)" + drep_yes_vote_power=$(( drep_yes_vote_power + drep_always_no_confidence )) + drep_no_vote_power_total=$(( drep_no_vote_power_total - (drep_always_no_confidence * 2) )) fi # calculate percentages drep_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${drep_yes_vote_power}/${drep_power_total})*100")") - drep_no_pct=$(printf '%.4g' "$(bc -l <<< "(${drep_no_vote_power}/${drep_power_total})*100")") + drep_no_pct=$(printf '%.4g' "$(bc -l <<< "(${drep_no_vote_power_total}/${drep_power_total})*100")") if [[ -n ${spo_power_total} ]]; then # get list of spo voters based on vote spo_yes_voters="$(jq '[.stakePoolVotes | to_entries[] | select(.value=="VoteYes") | .key]' <<< "$(base64 -d <<< "${vote_action}")")" @@ -1436,9 +1439,10 @@ getAllGovActions() { spo_no_vote_power="$(jq -r --argjson v "${spo_no_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_spo_vote_power}")" spo_abstain_vote_power="$(jq -r --argjson v "${spo_abstain_voters}" '[.[] | select(.[0] | IN($v[])) | .[1]] | add //0' <<< "${all_spo_vote_power}")" spo_power_total=$(( spo_power_total - spo_abstain_vote_power )) + spo_no_vote_power_total=$(( spo_power_total - spo_yes_vote_power )) # total spo power - proposal abstain - proposal yes # calculate percentages spo_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${spo_yes_vote_power}/${spo_power_total})*100")") - spo_no_pct=$(printf '%.4g' "$(bc -l <<< "(${spo_no_vote_power}/${spo_power_total})*100")") + spo_no_pct=$(printf '%.4g' "$(bc -l <<< "(${spo_no_vote_power_total}/${spo_power_total})*100")") else unset spo_yes_vote_power spo_no_vote_power spo_yes_pct spo_no_pct fi @@ -1447,15 +1451,16 @@ getAllGovActions() { cc_no_voters="$(jq '[.committeeVotes | to_entries[] | select(.value=="VoteYes")] | length' <<< "$(base64 -d <<< "${vote_action}")")" cc_abstain_voters="$(jq '[.committeeVotes | to_entries[] | select(.value=="VoteYes")] | length' <<< "$(base64 -d <<< "${vote_action}")")" cc_power_total=$(( cc_power_authorized - cc_abstain_voters )) + cc_no_voters_total=$(( cc_power_total - cc_yes_voters )) # total cc power - proposal abstain - proposal yes # calculate percentages if [[ ${cc_power_total} -eq 0 ]]; then cc_yes_pct=0 cc_no_pct=0 else cc_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${cc_yes_voters}/${cc_power_total})*100")") - cc_no_pct=$(printf '%.4g' "$(bc -l <<< "(${cc_no_voters}/${cc_power_total})*100")") + cc_no_pct=$(printf '%.4g' "$(bc -l <<< "(${cc_no_voters_total}/${cc_power_total})*100")") fi - vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) + vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power_total},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power_total},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) done # reverse order for ((i=${#_vote_action_list[@]}-1; i>=0; i--)); do From 81d625b1dffe056c53ca647f0b4a5f24c322be48 Mon Sep 17 00:00:00 2001 From: Ola Date: Thu, 12 Sep 2024 16:01:19 +0200 Subject: [PATCH 11/19] add info about vote data shown in proposal list --- docs/Scripts/cntools-changelog.md | 2 +- scripts/cnode-helper-scripts/cntools.sh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/Scripts/cntools-changelog.md b/docs/Scripts/cntools-changelog.md index 65ac78cec..5684a7b42 100644 --- a/docs/Scripts/cntools-changelog.md +++ b/docs/Scripts/cntools-changelog.md @@ -9,7 +9,7 @@ and this adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [13.2.1] - 2024-09-10 #### Added - Added gov vote validation for role and type -- Gov proposal list when run in `light` mode now have additional vote data +- Gov proposal list now have additional vote data ## [13.2.0] - 2024-09-08 #### Added diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index dfbe6aa68..7c2d8e15c 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4219,6 +4219,12 @@ function main { ((idx++)) done println DEBUG "${border_line}" + println DEBUG "\n${FG_BLUE}INFO${NC}" + println DEBUG "${FG_GREEN}YES${NC} = Total power of 'yes' votes" + println DEBUG "${FG_RED}NO${NC} = Total power of 'no' votes, including buckets of 'no vote cate' and 'always no confidence'" + println DEBUG " ${FG_LGRAY}For motion of no confidence, 'always no confidence' power is switched to yes bucket${NC}" + println DEBUG "${FG_LBLUE}PCT${NC} = Percent of yes votes compared to total valid vote power. If above vote threshold for all, proposal is to be enacted." + println DEBUG "\n${FG_LGRAY}Info action doesn't have any threshold.${NC}" [[ ${pages} -eq 1 ]] && waitToProceed && continue 2 unset hasPrev hasNext println OFF "\nPage ${FG_LBLUE}${page}${NC} of ${FG_LGRAY}${pages}${NC}\n" From 13b9038f3a74e7b716d78c215339ef8e0a7c9bde Mon Sep 17 00:00:00 2001 From: Ola Date: Thu, 12 Sep 2024 16:06:56 +0200 Subject: [PATCH 12/19] typo --- scripts/cnode-helper-scripts/cntools.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index 7c2d8e15c..b0afc88ef 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4219,10 +4219,10 @@ function main { ((idx++)) done println DEBUG "${border_line}" - println DEBUG "\n${FG_BLUE}INFO${NC}" - println DEBUG "${FG_GREEN}YES${NC} = Total power of 'yes' votes" - println DEBUG "${FG_RED}NO${NC} = Total power of 'no' votes, including buckets of 'no vote cate' and 'always no confidence'" - println DEBUG " ${FG_LGRAY}For motion of no confidence, 'always no confidence' power is switched to yes bucket${NC}" + println DEBUG "\n- ${FG_BLUE}INFO${NC} -" + println DEBUG "${FG_GREEN}YES${NC} = Total power of 'yes' votes." + println DEBUG "${FG_RED}NO${NC} = Total power of 'no' votes, including buckets of 'no vote cast' and 'always no confidence'." + println DEBUG " ${FG_LGRAY}For motion of no confidence, 'always no confidence' power is switched to yes bucket.${NC}" println DEBUG "${FG_LBLUE}PCT${NC} = Percent of yes votes compared to total valid vote power. If above vote threshold for all, proposal is to be enacted." println DEBUG "\n${FG_LGRAY}Info action doesn't have any threshold.${NC}" [[ ${pages} -eq 1 ]] && waitToProceed && continue 2 From 1f8f01bcc89b7a592150269688ff96e7ba731659 Mon Sep 17 00:00:00 2001 From: Ola Date: Sun, 15 Sep 2024 00:54:50 +0200 Subject: [PATCH 13/19] change proposal list ui --- scripts/cnode-helper-scripts/cntools.library | 30 +++---- scripts/cnode-helper-scripts/cntools.sh | 90 ++++++++++++++------ scripts/cnode-helper-scripts/env | 1 + 3 files changed, 78 insertions(+), 43 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index 2ee1e7bc8..c28af5789 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -1370,12 +1370,12 @@ getAllGovActions() { println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/proposal_voting_summary?_proposal_id=${_proposal_id}&select=drep_yes_votes_cast,drep_yes_vote_power,drep_yes_pct,drep_no_votes_cast,drep_no_vote_power,drep_no_pct,pool_yes_votes_cast,pool_yes_vote_power,pool_yes_pct,pool_no_votes_cast,pool_no_vote_power,pool_no_pct,committee_yes_votes_cast,committee_yes_pct,committee_no_votes_cast,committee_no_pct" _vote_action_votes=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/proposal_voting_summary?_proposal_id=${_proposal_id}&select=drep_yes_votes_cast,drep_yes_vote_power,drep_yes_pct,drep_no_votes_cast,drep_no_vote_power,drep_no_pct,pool_yes_votes_cast,pool_yes_vote_power,pool_yes_pct,pool_no_votes_cast,pool_no_vote_power,pool_no_pct,committee_yes_votes_cast,committee_yes_pct,committee_no_votes_cast,committee_no_pct" 2>&1) || continue IFS=',' read -r drep_yes_votes_cast drep_yes_vote_power drep_yes_pct drep_no_votes_cast drep_no_vote_power drep_no_pct pool_yes_votes_cast pool_yes_vote_power pool_yes_pct pool_no_votes_cast pool_no_vote_power pool_no_pct committee_yes_votes_cast committee_yes_pct committee_no_votes_cast committee_no_pct <<< "$(tail -n +2 <<< ${_vote_action_votes})" - drep_yes_pct=$(printf '%.4g' "${drep_yes_pct}") - drep_no_pct=$(printf '%.4g' "${drep_no_pct}") - pool_yes_pct=$(printf '%.4g' "${pool_yes_pct}") - pool_no_pct=$(printf '%.4g' "${pool_no_pct}") - committee_yes_pct=$(printf '%.4g' "${committee_yes_pct}") - committee_no_pct=$(printf '%.4g' "${committee_no_pct}") + drep_yes_pct=$(printf '%.2f' "${drep_yes_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + drep_no_pct=$(printf '%.2f' "${drep_no_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + pool_yes_pct=$(printf '%.2f' "${pool_yes_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + pool_no_pct=$(printf '%.2f' "${pool_no_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + committee_yes_pct=$(printf '%.2f' "${committee_yes_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + committee_no_pct=$(printf '%.2f' "${committee_no_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') if [[ ${_proposal_type} = "ParameterChange" ]]; then param_proposal_unescaped=${_param_proposal:1: -1} # remove first and last char (quotation) param_proposal_unescaped=$(sed 's/""/"/g' <<< "${param_proposal_unescaped}") # remove all double quotes, sed seems to perform better than bash string manipulation @@ -1383,7 +1383,7 @@ getAllGovActions() { getParameterChangeGroups fi getVoteThreshold ${_proposal_type} - vote_action_list+=( "${_proposal_tx_hash}#${_proposal_index},${_proposal_type},${_proposed_epoch},${_expiration:=0},${_meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${pool_yes_votes_cast},${pool_yes_vote_power},${pool_yes_pct},${pool_no_votes_cast},${pool_no_vote_power},${pool_no_pct},${committee_yes_votes_cast},${committee_yes_pct},${committee_no_votes_cast},${committee_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) + vote_action_list+=( "${_proposal_tx_hash}#${_proposal_index},${_proposal_type},${_proposed_epoch},$((_expiration-1)),${_meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${pool_yes_votes_cast},${pool_yes_vote_power},${pool_yes_pct},${pool_no_votes_cast},${pool_no_vote_power},${pool_no_pct},${committee_yes_votes_cast},${committee_yes_pct},${committee_no_votes_cast},${committee_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) done <<< "$(tail -n +2 <<< ${_vote_action_list})" elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then getCurrentCommittee; getParameterThresholds # to fetch thresholds @@ -1427,8 +1427,8 @@ getAllGovActions() { drep_no_vote_power_total=$(( drep_no_vote_power_total - (drep_always_no_confidence * 2) )) fi # calculate percentages - drep_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${drep_yes_vote_power}/${drep_power_total})*100")") - drep_no_pct=$(printf '%.4g' "$(bc -l <<< "(${drep_no_vote_power_total}/${drep_power_total})*100")") + drep_yes_pct=$(printf '%.2f' "$(bc -l <<< "(${drep_yes_vote_power}/${drep_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + drep_no_pct=$(printf '%.2f' "$(bc -l <<< "(${drep_no_vote_power_total}/${drep_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') if [[ -n ${spo_power_total} ]]; then # get list of spo voters based on vote spo_yes_voters="$(jq '[.stakePoolVotes | to_entries[] | select(.value=="VoteYes") | .key]' <<< "$(base64 -d <<< "${vote_action}")")" @@ -1441,8 +1441,8 @@ getAllGovActions() { spo_power_total=$(( spo_power_total - spo_abstain_vote_power )) spo_no_vote_power_total=$(( spo_power_total - spo_yes_vote_power )) # total spo power - proposal abstain - proposal yes # calculate percentages - spo_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${spo_yes_vote_power}/${spo_power_total})*100")") - spo_no_pct=$(printf '%.4g' "$(bc -l <<< "(${spo_no_vote_power_total}/${spo_power_total})*100")") + spo_yes_pct=$(printf '%.2f' "$(bc -l <<< "(${spo_yes_vote_power}/${spo_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + spo_no_pct=$(printf '%.2f' "$(bc -l <<< "(${spo_no_vote_power_total}/${spo_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') else unset spo_yes_vote_power spo_no_vote_power spo_yes_pct spo_no_pct fi @@ -1457,8 +1457,8 @@ getAllGovActions() { cc_yes_pct=0 cc_no_pct=0 else - cc_yes_pct=$(printf '%.4g' "$(bc -l <<< "(${cc_yes_voters}/${cc_power_total})*100")") - cc_no_pct=$(printf '%.4g' "$(bc -l <<< "(${cc_no_voters_total}/${cc_power_total})*100")") + cc_yes_pct=$(printf '%.2f' "$(bc -l <<< "(${cc_yes_voters}/${cc_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + cc_no_pct=$(printf '%.2f' "$(bc -l <<< "(${cc_no_voters_total}/${cc_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') fi vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power_total},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power_total},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) done @@ -1603,11 +1603,11 @@ getCurrentCommittee() { HEADERS=("${KOIOS_API_HEADERS[@]}" -H "accept: application/json") println ACTION "curl -sSL -f -X GET ${HEADERS[*]} ${KOIOS_API}/committee_info" committee_info=$(curl -sSL -f -X GET "${HEADERS[@]}" "${KOIOS_API}/committee_info") - cc_threshold=$(printf '%.4g' "$(jq -r '(.[0].quorum_numerator //0) / (.[0].quorum_denominator //1) * 100' <<< "${committee_info}")") + cc_threshold=$(printf '%.2f' "$(jq -r '(.[0].quorum_numerator //0) / (.[0].quorum_denominator //1) * 100' <<< "${committee_info}")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then println ACTION "${CCLI} conway query committee-state ${NETWORK_IDENTIFIER}" committee_info=$(${CCLI} conway query committee-state ${NETWORK_IDENTIFIER}) - cc_threshold=$(printf '%.4g' "$(jq -r '(.threshold.numerator //0) / (.threshold.denominator //1) * 100' <<< "${committee_info}")") + cc_threshold=$(printf '%.2f' "$(jq -r '(.threshold.numerator //0) / (.threshold.denominator //1) * 100' <<< "${committee_info}")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') fi } diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index b0afc88ef..fbdbb44c9 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4183,39 +4183,73 @@ function main { printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Action ID" "${action_id}" printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" " CIP-129" "${action_id_cip129}" printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Type" "${action_type}" - printf "| %-13s : epoch ${FG_LBLUE}%-$(( max_len - 6 ))s${NC} |\n" "Proposed In" "${proposed_in}" + printf "| %-13s : ${FG_LGRAY}epoch${NC} ${FG_LBLUE}%-$(( max_len - 6 ))s${NC} |\n" "Proposed In" "${proposed_in}" if [[ ${expires_after} -lt ${curr_epoch} ]]; then - printf "| %-13s : epoch ${FG_RED}%-$(( max_len - 6 ))s${NC} |\n" "Expires After" "${expires_after}" + printf "| %-13s : ${FG_LGRAY}epoch${NC} ${FG_RED}%-$(( max_len - 6 ))s${NC} |\n" "Expires After" "${expires_after}" else - printf "| %-13s : epoch ${FG_LBLUE}%-$(( max_len - 6 ))s${NC} |\n" "Expires After" "${expires_after}" + printf "| %-13s : ${FG_LGRAY}epoch${NC} ${FG_LBLUE}%-$(( max_len - 6 ))s${NC} |\n" "Expires After" "${expires_after}" fi printf "| %-13s : ${FG_LGRAY}%-${max_len}s${NC} |\n" "Anchor URL" "${anchor_url}" - if [[ ${action_type} = "InfoAction" ]]; then - chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-35)) - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "|" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "|" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "|" - else - chars_left=$((max_len-max_yes_len-max_yes_power_len-max_no_len-max_no_power_len-max_yes_pct_len-max_vt_len-44)) - if [[ -n ${drep_vt} ]]; then - (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "DRep" "${drep_yes}" "${drep_yes_power}" "${drep_no}" "${drep_no_power}" "${drep_yes_pct}" "${drep_vt}" "|" - else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' - fi - if [[ -n ${spo_vt} ]]; then - (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} @ ${FG_LBLUE}%${max_yes_power_len}s${NC} VP <> No = ${FG_LBLUE}%-${max_no_len}s${NC} @ ${FG_LBLUE}%${max_no_power_len}s${NC} VP => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "SPO" "${spo_yes}" "${spo_yes_power}" "${spo_no}" "${spo_no_power}" "${spo_yes_pct}" "${spo_vt}" "|" - else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' - fi - if [[ -n ${cc_vt} ]]; then - (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && vote_status="${FG_GREEN}${ICON_CHECK}${NC}" || vote_status="${FG_RED}${ICON_CROSS}${NC}" - printf "| %-13s : Yes = ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LBLUE}%$((max_yes_power_len+4))s${NC} <> No = ${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LBLUE}%$((max_no_power_len+4))s${NC} => ${FG_LBLUE}%${max_yes_pct_len}s${NC}%% ${FG_LGRAY}of${NC} ${FG_LBLUE}%-${max_vt_len}s${NC}%% ${vote_status} %${chars_left}s\n" "Committee" "${cc_yes}" " " "${cc_no}" " " "${cc_yes_pct}" "${cc_vt}" "|" - else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' - fi + three_col_width=$(( max_len / 3 )) + three_col_start=18 + three_col_2_start=$(( three_col_start + three_col_width )) + three_col_3_start=$(( three_col_2_start + three_col_width )) + # Header + printf "|${FG_LGRAY}$(printf "%17s" | tr " " "-")${NC}${FG_BLACK}\e[42mYES${NC}${FG_LGRAY}$(printf "%$((three_col_width-3))s" | tr " " "-")${NC}${FG_BLACK}\e[41mNO${NC}${FG_LGRAY}$(printf "%$((three_col_width-2))s" | tr " " "-")${NC}${FG_BLACK}\e[47mSTATUS${NC}${FG_LGRAY}$(printf "%$(((max_len-(2*three_col_width))-5))s" | tr " " "-")${NC}|\n" + # DRep YES + printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_yes_power_len}s${NC} ${FG_LGRAY}VP${NC}" "DRep" "${drep_yes}" "${drep_yes_power}" + # move to second column + printf "\033[72D\033[${three_col_2_start}C" + # DRep NO + printf "${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_no_power_len}s${NC} ${FG_LGRAY}VP${NC}" "${drep_no}" "${drep_no_power}" + # move to third column + printf "\033[72D\033[${three_col_3_start}C" + # DRep STATUS + if [[ -n ${drep_vt} ]]; then + (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " + fi + printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#drep_yes_pct}+1))s${NC}" "${drep_yes_pct}" "%" + if [[ -n ${drep_vt} ]]; then + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#drep_vt}+1))s${NC}" "${drep_vt}" "%" + fi + # move to end and close line + printf "\033[72D\033[${total_len}C |\n" + # SPO YES + printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_yes_power_len}s${NC} ${FG_LGRAY}VP${NC}" "SPO" "${spo_yes}" "${spo_yes_power}" + # move to second column + printf "\033[72D\033[${three_col_2_start}C" + # SPO NO + printf "${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_no_power_len}s${NC} ${FG_LGRAY}VP${NC}" "${spo_no}" "${spo_no_power}" + # move to third column + printf "\033[72D\033[${three_col_3_start}C" + # SPO STATUS + if [[ -n ${spo_vt} ]]; then + (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " + fi + printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#spo_yes_pct}+1))s${NC}" "${spo_yes_pct}" "%" + if [[ -n ${spo_vt} ]]; then + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#spo_vt}+1))s${NC}" "${spo_vt}" "%" + fi + # move to end and close line + printf "\033[72D\033[${total_len}C |\n" + # CC YES + printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC}" "Committee" "${cc_yes}" + # move to second column + printf "\033[72D\033[${three_col_2_start}C" + # CC NO + printf "${FG_LBLUE}%-${max_no_len}s${NC}" "${cc_no}" + # move to third column + printf "\033[72D\033[${three_col_3_start}C" + # CC STATUS + if [[ -n ${cc_vt} ]]; then + (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " + fi + printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#cc_yes_pct}+1))s${NC}" "${cc_yes_pct}" "%" + if [[ -n ${cc_vt} ]]; then + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#cc_vt}+1))s${NC}" "${cc_vt}" "%" fi + # move to end and close line + printf "\033[72D\033[${total_len}C |\n" ((idx++)) done println DEBUG "${border_line}" diff --git a/scripts/cnode-helper-scripts/env b/scripts/cnode-helper-scripts/env index a44d47b64..1335988ed 100644 --- a/scripts/cnode-helper-scripts/env +++ b/scripts/cnode-helper-scripts/env @@ -1006,6 +1006,7 @@ set_default_vars() { NC='\e[0m' ICON_CROSS='❌' ICON_CHECK='✅' + ICON_UNKNOWN='❔' # Due to bug introduced in bash upstream at 5.2.21, need to temporarily enable POSIX mode for newer bash versions, until fix is live # https://github.com/bminor/bash/commit/e327891b52513bef0b34aac625c44f8fa6811f53 versionCheck 5.2.20 ${BASH_VERSION//(*/} && set -o posix From da8104a7ff5d233be84dfc6d66a9480b740904e0 Mon Sep 17 00:00:00 2001 From: Ola Date: Sun, 15 Sep 2024 00:57:17 +0200 Subject: [PATCH 14/19] minor ui tweak --- scripts/cnode-helper-scripts/cntools.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index fbdbb44c9..0539427b6 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4254,10 +4254,10 @@ function main { done println DEBUG "${border_line}" println DEBUG "\n- ${FG_BLUE}INFO${NC} -" - println DEBUG "${FG_GREEN}YES${NC} = Total power of 'yes' votes." - println DEBUG "${FG_RED}NO${NC} = Total power of 'no' votes, including buckets of 'no vote cast' and 'always no confidence'." + println DEBUG "${FG_GREEN}YES${NC} = Total power of 'yes' votes." + println DEBUG "${FG_RED}NO${NC} = Total power of 'no' votes, including buckets of 'no vote cast' and 'always no confidence'." println DEBUG " ${FG_LGRAY}For motion of no confidence, 'always no confidence' power is switched to yes bucket.${NC}" - println DEBUG "${FG_LBLUE}PCT${NC} = Percent of yes votes compared to total valid vote power. If above vote threshold for all, proposal is to be enacted." + println DEBUG "${FG_DGRAY}STATUS${NC} = Percent of yes votes compared to total valid vote power. If above vote threshold for all, proposal is to be enacted." println DEBUG "\n${FG_LGRAY}Info action doesn't have any threshold.${NC}" [[ ${pages} -eq 1 ]] && waitToProceed && continue 2 unset hasPrev hasNext From 7491e1495a46804c640f8a8ef57c69e557141391 Mon Sep 17 00:00:00 2001 From: Ola Date: Sun, 15 Sep 2024 01:20:04 +0200 Subject: [PATCH 15/19] add back NA mode --- scripts/cnode-helper-scripts/cntools.library | 6 +- scripts/cnode-helper-scripts/cntools.sh | 116 ++++++++++--------- 2 files changed, 68 insertions(+), 54 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index c28af5789..938415625 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -1376,6 +1376,7 @@ getAllGovActions() { pool_no_pct=$(printf '%.2f' "${pool_no_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') committee_yes_pct=$(printf '%.2f' "${committee_yes_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') committee_no_pct=$(printf '%.2f' "${committee_no_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') + unset isParameterSecurityGroup if [[ ${_proposal_type} = "ParameterChange" ]]; then param_proposal_unescaped=${_param_proposal:1: -1} # remove first and last char (quotation) param_proposal_unescaped=$(sed 's/""/"/g' <<< "${param_proposal_unescaped}") # remove all double quotes, sed seems to perform better than bash string manipulation @@ -1383,7 +1384,7 @@ getAllGovActions() { getParameterChangeGroups fi getVoteThreshold ${_proposal_type} - vote_action_list+=( "${_proposal_tx_hash}#${_proposal_index},${_proposal_type},${_proposed_epoch},$((_expiration-1)),${_meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${pool_yes_votes_cast},${pool_yes_vote_power},${pool_yes_pct},${pool_no_votes_cast},${pool_no_vote_power},${pool_no_pct},${committee_yes_votes_cast},${committee_yes_pct},${committee_no_votes_cast},${committee_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) + vote_action_list+=( "${_proposal_tx_hash}#${_proposal_index},${_proposal_type},${_proposed_epoch},$((_expiration-1)),${_meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power},${drep_no_pct},${pool_yes_votes_cast},${pool_yes_vote_power},${pool_yes_pct},${pool_no_votes_cast},${pool_no_vote_power},${pool_no_pct},${committee_yes_votes_cast},${committee_yes_pct},${committee_no_votes_cast},${committee_no_pct},${drep_vt},${spo_vt},${cc_vt},${isParameterSecurityGroup}" ) done <<< "$(tail -n +2 <<< ${_vote_action_list})" elif [[ ${CNTOOLS_MODE} = "LOCAL" ]]; then getCurrentCommittee; getParameterThresholds # to fetch thresholds @@ -1405,6 +1406,7 @@ getAllGovActions() { println ACTION "${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64'" for vote_action in $(${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64' 2>/dev/null); do IFS=',' read -r proposal_id proposal_type proposed_epoch expiration meta_url drep_yes_votes_cast drep_no_votes_cast spo_yes_votes_cast spo_no_votes_cast cc_yes_votes_cast cc_no_votes_cast < <( jq -cr '"\((.actionId.txId//"") + "#" + (.actionId.govActionIx//0|tostring)),\(.proposalProcedure.govAction.tag//""),\(.proposedIn//0),\(.expiresAfter//0),\(.proposalProcedure.anchor.url//""),\(.dRepVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1))"' <<< "$(base64 -d <<< "${vote_action}")" ) + unset isParameterSecurityGroup if [[ $(jq -r '.proposalProcedure.govAction.tag' <<< "$(base64 -d <<< "${vote_action}")") = "ParameterChange" ]]; then parameterChange=$(jq -e '.proposalProcedure.govAction.contents[1] | keys[]' <<< "$(base64 -d <<< "${vote_action}")") getParameterChangeGroups @@ -1460,7 +1462,7 @@ getAllGovActions() { cc_yes_pct=$(printf '%.2f' "$(bc -l <<< "(${cc_yes_voters}/${cc_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') cc_no_pct=$(printf '%.2f' "$(bc -l <<< "(${cc_no_voters_total}/${cc_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') fi - vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power_total},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power_total},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt}" ) + vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power_total},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power_total},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt},${isParameterSecurityGroup}" ) done # reverse order for ((i=${#_vote_action_list[@]}-1; i>=0; i--)); do diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index 0539427b6..712ef1ddd 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4157,7 +4157,7 @@ function main { for vote_action in "${vote_action_list[@]:${start_idx}:${page_entries}}"; do [[ $idx -ne 1 ]] && printf "|$(printf "%${total_len}s" | tr " " "-")|\n" # calculate length of strings - IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_yes_power drep_yes_pct drep_no drep_no_power drep_no_pct spo_yes spo_yes_power spo_yes_pct spo_no spo_no_power spo_no_pct cc_yes cc_yes_pct cc_no cc_no_pct drep_vt spo_vt cc_vt <<< "${vote_action}" + IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_yes_power drep_yes_pct drep_no drep_no_power drep_no_pct spo_yes spo_yes_power spo_yes_pct spo_no spo_no_power spo_no_pct cc_yes cc_yes_pct cc_no cc_no_pct drep_vt spo_vt cc_vt isParameterSecurityGroup <<< "${vote_action}" max_yes_len=${#drep_yes} max_no_len=${#drep_no} [[ ${#spo_yes} -gt ${max_yes_len} ]] && max_yes_len=${#spo_yes} @@ -4196,60 +4196,72 @@ function main { three_col_3_start=$(( three_col_2_start + three_col_width )) # Header printf "|${FG_LGRAY}$(printf "%17s" | tr " " "-")${NC}${FG_BLACK}\e[42mYES${NC}${FG_LGRAY}$(printf "%$((three_col_width-3))s" | tr " " "-")${NC}${FG_BLACK}\e[41mNO${NC}${FG_LGRAY}$(printf "%$((three_col_width-2))s" | tr " " "-")${NC}${FG_BLACK}\e[47mSTATUS${NC}${FG_LGRAY}$(printf "%$(((max_len-(2*three_col_width))-5))s" | tr " " "-")${NC}|\n" - # DRep YES - printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_yes_power_len}s${NC} ${FG_LGRAY}VP${NC}" "DRep" "${drep_yes}" "${drep_yes_power}" - # move to second column - printf "\033[72D\033[${three_col_2_start}C" - # DRep NO - printf "${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_no_power_len}s${NC} ${FG_LGRAY}VP${NC}" "${drep_no}" "${drep_no_power}" - # move to third column - printf "\033[72D\033[${three_col_3_start}C" - # DRep STATUS - if [[ -n ${drep_vt} ]]; then - (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " - fi - printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#drep_yes_pct}+1))s${NC}" "${drep_yes_pct}" "%" - if [[ -n ${drep_vt} ]]; then - printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#drep_vt}+1))s${NC}" "${drep_vt}" "%" - fi - # move to end and close line - printf "\033[72D\033[${total_len}C |\n" - # SPO YES - printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_yes_power_len}s${NC} ${FG_LGRAY}VP${NC}" "SPO" "${spo_yes}" "${spo_yes_power}" - # move to second column - printf "\033[72D\033[${three_col_2_start}C" - # SPO NO - printf "${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_no_power_len}s${NC} ${FG_LGRAY}VP${NC}" "${spo_no}" "${spo_no_power}" - # move to third column - printf "\033[72D\033[${three_col_3_start}C" - # SPO STATUS - if [[ -n ${spo_vt} ]]; then - (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " - fi - printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#spo_yes_pct}+1))s${NC}" "${spo_yes_pct}" "%" - if [[ -n ${spo_vt} ]]; then - printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#spo_vt}+1))s${NC}" "${spo_vt}" "%" + if isAllowedToVote "${action_type}" "drep" "${isParameterSecurityGroup}"; then + # DRep YES + printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_yes_power_len}s${NC} ${FG_LGRAY}VP${NC}" "DRep" "${drep_yes}" "${drep_yes_power}" + # move to second column + printf "\033[72D\033[${three_col_2_start}C" + # DRep NO + printf "${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_no_power_len}s${NC} ${FG_LGRAY}VP${NC}" "${drep_no}" "${drep_no_power}" + # move to third column + printf "\033[72D\033[${three_col_3_start}C" + # DRep STATUS + if [[ -n ${drep_vt} ]]; then + (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " + fi + printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#drep_yes_pct}+1))s${NC}" "${drep_yes_pct}" "%" + if [[ -n ${drep_vt} ]]; then + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#drep_vt}+1))s${NC}" "${drep_vt}" "%" + fi + # move to end and close line + printf "\033[72D\033[${total_len}C |\n" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' fi - # move to end and close line - printf "\033[72D\033[${total_len}C |\n" - # CC YES - printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC}" "Committee" "${cc_yes}" - # move to second column - printf "\033[72D\033[${three_col_2_start}C" - # CC NO - printf "${FG_LBLUE}%-${max_no_len}s${NC}" "${cc_no}" - # move to third column - printf "\033[72D\033[${three_col_3_start}C" - # CC STATUS - if [[ -n ${cc_vt} ]]; then - (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " + if isAllowedToVote "${action_type}" "spo" "${isParameterSecurityGroup}"; then + # SPO YES + printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_yes_power_len}s${NC} ${FG_LGRAY}VP${NC}" "SPO" "${spo_yes}" "${spo_yes_power}" + # move to second column + printf "\033[72D\033[${three_col_2_start}C" + # SPO NO + printf "${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_no_power_len}s${NC} ${FG_LGRAY}VP${NC}" "${spo_no}" "${spo_no_power}" + # move to third column + printf "\033[72D\033[${three_col_3_start}C" + # SPO STATUS + if [[ -n ${spo_vt} ]]; then + (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " + fi + printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#spo_yes_pct}+1))s${NC}" "${spo_yes_pct}" "%" + if [[ -n ${spo_vt} ]]; then + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#spo_vt}+1))s${NC}" "${spo_vt}" "%" + fi + # move to end and close line + printf "\033[72D\033[${total_len}C |\n" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' fi - printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#cc_yes_pct}+1))s${NC}" "${cc_yes_pct}" "%" - if [[ -n ${cc_vt} ]]; then - printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#cc_vt}+1))s${NC}" "${cc_vt}" "%" + if isAllowedToVote "${action_type}" "spo" "${isParameterSecurityGroup}"; then + # CC YES + printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC}" "Committee" "${cc_yes}" + # move to second column + printf "\033[72D\033[${three_col_2_start}C" + # CC NO + printf "${FG_LBLUE}%-${max_no_len}s${NC}" "${cc_no}" + # move to third column + printf "\033[72D\033[${three_col_3_start}C" + # CC STATUS + if [[ -n ${cc_vt} ]]; then + (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " + fi + printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#cc_yes_pct}+1))s${NC}" "${cc_yes_pct}" "%" + if [[ -n ${cc_vt} ]]; then + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#cc_vt}+1))s${NC}" "${cc_vt}" "%" + fi + # move to end and close line + printf "\033[72D\033[${total_len}C |\n" + else + printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' fi - # move to end and close line - printf "\033[72D\033[${total_len}C |\n" ((idx++)) done println DEBUG "${border_line}" From 1c256cfce02f8f3a11965304164d2a8c3eb36d5f Mon Sep 17 00:00:00 2001 From: Ola Date: Sun, 15 Sep 2024 02:09:03 +0200 Subject: [PATCH 16/19] various ui fixes --- scripts/cnode-helper-scripts/cntools.library | 10 ++-- scripts/cnode-helper-scripts/cntools.sh | 59 +++++++++++++------- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index 938415625..fae1e34dd 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -1376,7 +1376,7 @@ getAllGovActions() { pool_no_pct=$(printf '%.2f' "${pool_no_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') committee_yes_pct=$(printf '%.2f' "${committee_yes_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') committee_no_pct=$(printf '%.2f' "${committee_no_pct}" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') - unset isParameterSecurityGroup + isParameterSecurityGroup=N if [[ ${_proposal_type} = "ParameterChange" ]]; then param_proposal_unescaped=${_param_proposal:1: -1} # remove first and last char (quotation) param_proposal_unescaped=$(sed 's/""/"/g' <<< "${param_proposal_unescaped}") # remove all double quotes, sed seems to perform better than bash string manipulation @@ -1406,7 +1406,7 @@ getAllGovActions() { println ACTION "${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64'" for vote_action in $(${CCLI} conway query gov-state ${NETWORK_IDENTIFIER} | jq -er '.proposals[] | @base64' 2>/dev/null); do IFS=',' read -r proposal_id proposal_type proposed_epoch expiration meta_url drep_yes_votes_cast drep_no_votes_cast spo_yes_votes_cast spo_no_votes_cast cc_yes_votes_cast cc_no_votes_cast < <( jq -cr '"\((.actionId.txId//"") + "#" + (.actionId.govActionIx//0|tostring)),\(.proposalProcedure.govAction.tag//""),\(.proposedIn//0),\(.expiresAfter//0),\(.proposalProcedure.anchor.url//""),\(.dRepVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.dRepVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.stakePoolVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteYes")) as $_ (0; .+1)),\(.committeeVotes | reduce(..|select(strings=="VoteNo")) as $_ (0; .+1))"' <<< "$(base64 -d <<< "${vote_action}")" ) - unset isParameterSecurityGroup + isParameterSecurityGroup=N if [[ $(jq -r '.proposalProcedure.govAction.tag' <<< "$(base64 -d <<< "${vote_action}")") = "ParameterChange" ]]; then parameterChange=$(jq -e '.proposalProcedure.govAction.contents[1] | keys[]' <<< "$(base64 -d <<< "${vote_action}")") getParameterChangeGroups @@ -1554,7 +1554,7 @@ isAllowedToVote() { [[ $1 = committee ]] && return 1 ;; "HardForkInitiation") - versionCheck "10.0" "${PROT_VERSION}" || return 3 + [[ $1 = drep ]] && ! versionCheck "10.0" "${PROT_VERSION}" && return 3 ;; "InfoAction") : ;; # always allowed by all @@ -1565,8 +1565,8 @@ isAllowedToVote() { [[ $1 = spo ]] && return 1 ;; "ParameterChange") - [[ $1 = spo && $3 = Y ]] && return 2 - if [[ $1 = drep ]] && ! versionCheck "10.0" "${PROT_VERSION}"; then return 3; fi + [[ $1 = spo && $3 = N ]] && return 2 + [[ $1 = drep ]] && ! versionCheck "10.0" "${PROT_VERSION}" && return 3 ;; "NewConstitution") [[ $1 = spo ]] && return 1 diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index 712ef1ddd..f5c0d8c77 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4196,71 +4196,92 @@ function main { three_col_3_start=$(( three_col_2_start + three_col_width )) # Header printf "|${FG_LGRAY}$(printf "%17s" | tr " " "-")${NC}${FG_BLACK}\e[42mYES${NC}${FG_LGRAY}$(printf "%$((three_col_width-3))s" | tr " " "-")${NC}${FG_BLACK}\e[41mNO${NC}${FG_LGRAY}$(printf "%$((three_col_width-2))s" | tr " " "-")${NC}${FG_BLACK}\e[47mSTATUS${NC}${FG_LGRAY}$(printf "%$(((max_len-(2*three_col_width))-5))s" | tr " " "-")${NC}|\n" - if isAllowedToVote "${action_type}" "drep" "${isParameterSecurityGroup}"; then + tput sc + if isAllowedToVote "drep" "${action_type}" "${isParameterSecurityGroup:=N}"; then # DRep YES printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_yes_power_len}s${NC} ${FG_LGRAY}VP${NC}" "DRep" "${drep_yes}" "${drep_yes_power}" # move to second column - printf "\033[72D\033[${three_col_2_start}C" + tput rc && tput cuf ${three_col_2_start} # DRep NO printf "${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_no_power_len}s${NC} ${FG_LGRAY}VP${NC}" "${drep_no}" "${drep_no_power}" # move to third column - printf "\033[72D\033[${three_col_3_start}C" + tput rc && tput cuf ${three_col_3_start} # DRep STATUS if [[ -n ${drep_vt} ]]; then (( $(bc -l <<< "${drep_yes_pct} >= ${drep_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " fi printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#drep_yes_pct}+1))s${NC}" "${drep_yes_pct}" "%" if [[ -n ${drep_vt} ]]; then - printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#drep_vt}+1))s${NC}" "${drep_vt}" "%" + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_vt_len-${#drep_vt}+1))s${NC}" "${drep_vt}" "%" fi # move to end and close line - printf "\033[72D\033[${total_len}C |\n" + tput rc && tput cuf ${total_len} && printf " |\n" else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'DRep' 'N|A' + printf "| %-13s : ${FG_DGRAY}N|A${NC}" 'DRep' + # move to second column and print NA + tput rc && tput cuf ${three_col_2_start} && printf "${FG_DGRAY}N|A${NC}" + # move to third column and print NA + tput rc && tput cuf ${three_col_3_start} && printf "${FG_DGRAY}N|A${NC}" + # move to end and close line + tput rc && tput cuf ${total_len} && printf " |\n" fi - if isAllowedToVote "${action_type}" "spo" "${isParameterSecurityGroup}"; then + tput sc + if isAllowedToVote "spo" "${action_type}" "${isParameterSecurityGroup:=N}"; then # SPO YES printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_yes_power_len}s${NC} ${FG_LGRAY}VP${NC}" "SPO" "${spo_yes}" "${spo_yes_power}" # move to second column - printf "\033[72D\033[${three_col_2_start}C" + tput rc && tput cuf ${three_col_2_start} # SPO NO printf "${FG_LBLUE}%-${max_no_len}s${NC} ${FG_LGRAY}@${NC} ${FG_LBLUE}%${max_no_power_len}s${NC} ${FG_LGRAY}VP${NC}" "${spo_no}" "${spo_no_power}" # move to third column - printf "\033[72D\033[${three_col_3_start}C" + tput rc && tput cuf ${three_col_3_start} # SPO STATUS if [[ -n ${spo_vt} ]]; then (( $(bc -l <<< "${spo_yes_pct} >= ${spo_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " fi printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#spo_yes_pct}+1))s${NC}" "${spo_yes_pct}" "%" if [[ -n ${spo_vt} ]]; then - printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#spo_vt}+1))s${NC}" "${spo_vt}" "%" + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_vt_len-${#spo_vt}+1))s${NC}" "${spo_vt}" "%" fi # move to end and close line - printf "\033[72D\033[${total_len}C |\n" + tput rc && tput cuf ${total_len} && printf " |\n" else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'SPO' 'N|A' + printf "| %-13s : ${FG_DGRAY}N|A${NC}" 'SPO' + # move to second column and print NA + tput rc && tput cuf ${three_col_2_start} && printf "${FG_DGRAY}N|A${NC}" + # move to third column and print NA + tput rc && tput cuf ${three_col_3_start} && printf "${FG_DGRAY}N|A${NC}" + # move to end and close line + tput rc && tput cuf ${total_len} && printf " |\n" fi - if isAllowedToVote "${action_type}" "spo" "${isParameterSecurityGroup}"; then + tput sc + if isAllowedToVote "committee" "${action_type}" "${isParameterSecurityGroup:=N}"; then # CC YES printf "| %-13s : ${FG_LBLUE}%-${max_yes_len}s${NC}" "Committee" "${cc_yes}" # move to second column - printf "\033[72D\033[${three_col_2_start}C" + tput rc && tput cuf ${three_col_2_start} # CC NO printf "${FG_LBLUE}%-${max_no_len}s${NC}" "${cc_no}" # move to third column - printf "\033[72D\033[${three_col_3_start}C" + tput rc && tput cuf ${three_col_3_start} # CC STATUS if [[ -n ${cc_vt} ]]; then (( $(bc -l <<< "${cc_yes_pct} >= ${cc_vt}") )) && printf "${FG_GREEN}${ICON_CHECK}${NC} " || printf "${FG_RED}${ICON_CROSS}${NC} " fi printf "${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_yes_pct_len-${#cc_yes_pct}+1))s${NC}" "${cc_yes_pct}" "%" if [[ -n ${cc_vt} ]]; then - printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%${max_vt_len}s${NC} ${FG_LGRAY}%-$((max_vt_len-${#cc_vt}+1))s${NC}" "${cc_vt}" "%" + printf " ${FG_LGRAY}of${NC} ${FG_LBLUE}%s${NC} ${FG_LGRAY}%-$((max_vt_len-${#cc_vt}+1))s${NC}" "${cc_vt}" "%" fi # move to end and close line - printf "\033[72D\033[${total_len}C |\n" + tput rc && tput cuf ${total_len} && printf " |\n" else - printf "| %-13s : ${FG_DGRAY}%-${max_len}s${NC} |\n" 'Committee' 'N|A' + printf "| %-13s : ${FG_DGRAY}N|A${NC}" 'Committee' + # move to second column and print NA + tput rc && tput cuf ${three_col_2_start} && printf "${FG_DGRAY}N|A${NC}" + # move to third column and print NA + tput rc && tput cuf ${three_col_3_start} && printf "${FG_DGRAY}N|A${NC}" + # move to end and close line + tput rc && tput cuf ${total_len} && printf " |\n" fi ((idx++)) done @@ -4268,7 +4289,7 @@ function main { println DEBUG "\n- ${FG_BLUE}INFO${NC} -" println DEBUG "${FG_GREEN}YES${NC} = Total power of 'yes' votes." println DEBUG "${FG_RED}NO${NC} = Total power of 'no' votes, including buckets of 'no vote cast' and 'always no confidence'." - println DEBUG " ${FG_LGRAY}For motion of no confidence, 'always no confidence' power is switched to yes bucket.${NC}" + println DEBUG " ${FG_LGRAY}For motion of no confidence, 'always no confidence' power is switched to yes bucket.${NC}" println DEBUG "${FG_DGRAY}STATUS${NC} = Percent of yes votes compared to total valid vote power. If above vote threshold for all, proposal is to be enacted." println DEBUG "\n${FG_LGRAY}Info action doesn't have any threshold.${NC}" [[ ${pages} -eq 1 ]] && waitToProceed && continue 2 From dcdc06f4f8b855224ecd1cba11f51ea53774980f Mon Sep 17 00:00:00 2001 From: Ola Date: Sun, 15 Sep 2024 02:12:09 +0200 Subject: [PATCH 17/19] ui --- scripts/cnode-helper-scripts/cntools.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index f5c0d8c77..493790bfc 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4286,8 +4286,7 @@ function main { ((idx++)) done println DEBUG "${border_line}" - println DEBUG "\n- ${FG_BLUE}INFO${NC} -" - println DEBUG "${FG_GREEN}YES${NC} = Total power of 'yes' votes." + println DEBUG "\n${FG_GREEN}YES${NC} = Total power of 'yes' votes." println DEBUG "${FG_RED}NO${NC} = Total power of 'no' votes, including buckets of 'no vote cast' and 'always no confidence'." println DEBUG " ${FG_LGRAY}For motion of no confidence, 'always no confidence' power is switched to yes bucket.${NC}" println DEBUG "${FG_DGRAY}STATUS${NC} = Percent of yes votes compared to total valid vote power. If above vote threshold for all, proposal is to be enacted." From c2b0bd20f007ee864064eb0f7db02324b007ee40 Mon Sep 17 00:00:00 2001 From: Ola Date: Sun, 15 Sep 2024 02:16:21 +0200 Subject: [PATCH 18/19] reverse order for cli list --- scripts/cnode-helper-scripts/cntools.library | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cnode-helper-scripts/cntools.library b/scripts/cnode-helper-scripts/cntools.library index fae1e34dd..8b9efe415 100644 --- a/scripts/cnode-helper-scripts/cntools.library +++ b/scripts/cnode-helper-scripts/cntools.library @@ -1462,7 +1462,7 @@ getAllGovActions() { cc_yes_pct=$(printf '%.2f' "$(bc -l <<< "(${cc_yes_voters}/${cc_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') cc_no_pct=$(printf '%.2f' "$(bc -l <<< "(${cc_no_voters_total}/${cc_power_total})*100")" | sed '/\./ s/\.\{0,1\}0\{1,\}$//') fi - vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power_total},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power_total},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt},${isParameterSecurityGroup}" ) + _vote_action_list+=( "${proposal_id},${proposal_type},${proposed_epoch},${expiration:=0},${meta_url},${drep_yes_votes_cast},${drep_yes_vote_power},${drep_yes_pct},${drep_no_votes_cast},${drep_no_vote_power_total},${drep_no_pct},${spo_yes_votes_cast},${spo_yes_vote_power},${spo_yes_pct},${spo_no_votes_cast},${spo_no_vote_power_total},${spo_no_pct},${cc_yes_votes_cast},${cc_yes_pct},${cc_no_votes_cast},${cc_no_pct},${drep_vt},${spo_vt},${cc_vt},${isParameterSecurityGroup}" ) done # reverse order for ((i=${#_vote_action_list[@]}-1; i>=0; i--)); do From cb9c3c8c2566af5ddf5e18a8072b6764c5b43ac5 Mon Sep 17 00:00:00 2001 From: Ola Date: Sun, 15 Sep 2024 12:57:52 +0200 Subject: [PATCH 19/19] Make shellcheck happy --- scripts/cnode-helper-scripts/cntools.sh | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/scripts/cnode-helper-scripts/cntools.sh b/scripts/cnode-helper-scripts/cntools.sh index 493790bfc..22d8f68af 100755 --- a/scripts/cnode-helper-scripts/cntools.sh +++ b/scripts/cnode-helper-scripts/cntools.sh @@ -4149,13 +4149,13 @@ function main { [[ ${#vote_action_arr[4]} -gt ${max_len} ]] && max_len=${#vote_action_arr[4]} done total_len=$(( max_len + 13 + 5 )) - border_line="|$(printf "%${total_len}s" | tr " " "=")|" # max value length + longest title (13) + spacing (5) + border_line="|$(printf "%${total_len}s" "" | tr " " "=")|" # max value length + longest title (13) + spacing (5) println DEBUG "Current epoch : ${FG_LBLUE}$(getEpoch)${NC}" println DEBUG "Proposals : ${FG_LBLUE}${action_cnt}${NC}" println DEBUG "\n${border_line}" idx=1 for vote_action in "${vote_action_list[@]:${start_idx}:${page_entries}}"; do - [[ $idx -ne 1 ]] && printf "|$(printf "%${total_len}s" | tr " " "-")|\n" + [[ $idx -ne 1 ]] && printf "|$(printf "%${total_len}s" "" | tr " " "-")|\n" # calculate length of strings IFS=',' read -r action_id action_type proposed_in expires_after anchor_url drep_yes drep_yes_power drep_yes_pct drep_no drep_no_power drep_no_pct spo_yes spo_yes_power spo_yes_pct spo_no spo_no_power spo_no_pct cc_yes cc_yes_pct cc_no cc_no_pct drep_vt spo_vt cc_vt isParameterSecurityGroup <<< "${vote_action}" max_yes_len=${#drep_yes} @@ -4195,7 +4195,7 @@ function main { three_col_2_start=$(( three_col_start + three_col_width )) three_col_3_start=$(( three_col_2_start + three_col_width )) # Header - printf "|${FG_LGRAY}$(printf "%17s" | tr " " "-")${NC}${FG_BLACK}\e[42mYES${NC}${FG_LGRAY}$(printf "%$((three_col_width-3))s" | tr " " "-")${NC}${FG_BLACK}\e[41mNO${NC}${FG_LGRAY}$(printf "%$((three_col_width-2))s" | tr " " "-")${NC}${FG_BLACK}\e[47mSTATUS${NC}${FG_LGRAY}$(printf "%$(((max_len-(2*three_col_width))-5))s" | tr " " "-")${NC}|\n" + printf "|${FG_LGRAY}$(printf "%17s" "" | tr " " "-")${NC}${FG_BLACK}\e[42mYES${NC}${FG_LGRAY}$(printf "%$((three_col_width-3))s" " " | tr "" "-")${NC}${FG_BLACK}\e[41mNO${NC}${FG_LGRAY}$(printf "%$((three_col_width-2))s" "" | tr " " "-")${NC}${FG_BLACK}\e[47mSTATUS${NC}${FG_LGRAY}$(printf "%$(((max_len-(2*three_col_width))-5))s" "" | tr " " "-")${NC}|\n" tput sc if isAllowedToVote "drep" "${action_type}" "${isParameterSecurityGroup:=N}"; then # DRep YES @@ -5344,9 +5344,9 @@ function main { [[ ${ideal_len} -lt 5 ]] && ideal_len=5 luck_len=$(sqlite3 "${BLOCKLOG_DB}" "SELECT LENGTH(max_performance) FROM epochdata WHERE epoch BETWEEN ${first_epoch} and ${current_epoch} ORDER BY LENGTH(max_performance) DESC LIMIT 1;") [[ $((luck_len+1)) -le 4 ]] && luck_len=4 || luck_len=$((luck_len+1)) - printf '|'; printf "%$((5+6+ideal_len+luck_len+7+9+6+7+6+7+27+2))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((5+6+ideal_len+luck_len+7+9+6+7+6+7+27+2))s" "" | tr " " "="; printf '|\n' printf "| %-5s | %-6s | %-${ideal_len}s | %-${luck_len}s | ${FG_LBLUE}%-7s${NC} | ${FG_GREEN}%-9s${NC} | ${FG_RED}%-6s${NC} | ${FG_RED}%-7s${NC} | ${FG_RED}%-6s${NC} | ${FG_RED}%-7s${NC} |\n" "Epoch" "Leader" "Ideal" "Luck" "Adopted" "Confirmed" "Missed" "Ghosted" "Stolen" "Invalid" - printf '|'; printf "%$((5+6+ideal_len+luck_len+7+9+6+7+6+7+27+2))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((5+6+ideal_len+luck_len+7+9+6+7+6+7+27+2))s" "" | tr " " "="; printf '|\n' while [[ ${current_epoch} -gt ${first_epoch} ]]; do invalid_cnt=$(sqlite3 "${BLOCKLOG_DB}" "SELECT COUNT(*) FROM blocklog WHERE epoch=${current_epoch} AND status='invalid';" 2>/dev/null) missed_cnt=$(sqlite3 "${BLOCKLOG_DB}" "SELECT COUNT(*) FROM blocklog WHERE epoch=${current_epoch} AND status='missed';" 2>/dev/null) @@ -5364,7 +5364,7 @@ function main { printf "| ${FG_LGRAY}%-5s${NC} | ${FG_LGRAY}%-6s${NC} | ${FG_LGRAY}%-${ideal_len}s${NC} | ${FG_LGRAY}%-${luck_len}s${NC} | ${FG_LBLUE}%-7s${NC} | ${FG_GREEN}%-9s${NC} | ${FG_RED}%-6s${NC} | ${FG_RED}%-7s${NC} | ${FG_RED}%-6s${NC} | ${FG_RED}%-7s${NC} |\n" "${current_epoch}" "${leader_cnt}" "${epoch_stats[0]}" "${epoch_stats[1]}" "${adopted_cnt}" "${confirmed_cnt}" "${missed_cnt}" "${ghosted_cnt}" "${stolen_cnt}" "${invalid_cnt}" ((current_epoch--)) done - printf '|'; printf "%$((5+6+ideal_len+luck_len+7+9+6+7+6+7+27+2))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((5+6+ideal_len+luck_len+7+9+6+7+6+7+27+2))s" "" | tr " " "="; printf '|\n' else println OFF "Block Status:\n" println OFF "Leader - Scheduled to make block at this slot" @@ -5423,11 +5423,11 @@ function main { fi [[ ${#epoch_stats[0]} -gt 5 ]] && ideal_len=${#epoch_stats[0]} || ideal_len=5 [[ ${#epoch_stats[1]} -gt 4 ]] && luck_len=${#epoch_stats[1]} || luck_len=4 - printf '|'; printf "%$((6+ideal_len+luck_len+7+9+6+7+6+7+24+2))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((6+ideal_len+luck_len+7+9+6+7+6+7+24+2))s" "" | tr " " "="; printf '|\n' printf "| %-6s | %-${ideal_len}s | %-${luck_len}s | ${FG_LBLUE}%-7s${NC} | ${FG_GREEN}%-9s${NC} | ${FG_RED}%-6s${NC} | ${FG_RED}%-7s${NC} | ${FG_RED}%-6s${NC} | ${FG_RED}%-7s${NC} |\n" "Leader" "Ideal" "Luck" "Adopted" "Confirmed" "Missed" "Ghosted" "Stolen" "Invalid" - printf '|'; printf "%$((6+ideal_len+luck_len+7+9+6+7+6+7+24+2))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((6+ideal_len+luck_len+7+9+6+7+6+7+24+2))s" "" | tr " " "="; printf '|\n' printf "| ${FG_LGRAY}%-6s${NC} | ${FG_LGRAY}%-${ideal_len}s${NC} | ${FG_LGRAY}%-${luck_len}s${NC} | ${FG_LBLUE}%-7s${NC} | ${FG_GREEN}%-9s${NC} | ${FG_RED}%-6s${NC} | ${FG_RED}%-7s${NC} | ${FG_RED}%-6s${NC} | ${FG_RED}%-7s${NC} |\n" "${leader_cnt}" "${epoch_stats[0]}" "${epoch_stats[1]}" "${adopted_cnt}" "${confirmed_cnt}" "${missed_cnt}" "${ghosted_cnt}" "${stolen_cnt}" "${invalid_cnt}" - printf '|'; printf "%$((6+ideal_len+luck_len+7+9+6+7+6+7+24+2))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((6+ideal_len+luck_len+7+9+6+7+6+7+24+2))s" "" | tr " " "="; printf '|\n' echo # print block table block_cnt=1 @@ -5445,31 +5445,31 @@ function main { hash_len=$(sqlite3 "${BLOCKLOG_DB}" "SELECT LENGTH(hash) FROM blocklog WHERE epoch=${epoch_enter} ORDER BY LENGTH(hash) DESC LIMIT 1;") [[ ${hash_len} -lt 4 ]] && hash_len=4 if [[ ${view} -eq 1 ]]; then - printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+17))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+17))s" "" | tr " " "="; printf '|\n' printf "| %-${#leader_cnt}s | %-${status_len}s | %-${block_len}s | %-${slot_len}s | %-${slot_in_epoch_len}s | %-${at_len}s |\n" "#" "Status" "Block" "Slot" "SlotInEpoch" "Scheduled At" - printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+17))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+17))s" "" | tr " " "="; printf '|\n' while IFS='|' read -r status block slot slot_in_epoch at; do at=$(TZ="${BLOCKLOG_TZ}" date '+%F %T %Z' --date="${at}") [[ ${block} -eq 0 ]] && block="-" printf "| ${FG_LGRAY}%-${#leader_cnt}s${NC} | ${FG_LGRAY}%-${status_len}s${NC} | ${FG_LGRAY}%-${block_len}s${NC} | ${FG_LGRAY}%-${slot_len}s${NC} | ${FG_LGRAY}%-${slot_in_epoch_len}s${NC} | ${FG_LGRAY}%-${at_len}s${NC} |\n" "${block_cnt}" "${status}" "${block}" "${slot}" "${slot_in_epoch}" "${at}" ((block_cnt++)) done < <(sqlite3 "${BLOCKLOG_DB}" "SELECT status, block, slot, slot_in_epoch, at FROM blocklog WHERE epoch=${epoch_enter} ORDER BY slot;" 2>/dev/null) - printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+17))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+17))s" "" | tr " " "="; printf '|\n' elif [[ ${view} -eq 2 ]]; then - printf '|'; printf "%$((${#leader_cnt}+status_len+slot_len+size_len+hash_len+14))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+slot_len+size_len+hash_len+14))s" "" | tr " " "="; printf '|\n' printf "| %-${#leader_cnt}s | %-${status_len}s | %-${slot_len}s | %-${size_len}s | %-${hash_len}s |\n" "#" "Status" "Slot" "Size" "Hash" - printf '|'; printf "%$((${#leader_cnt}+status_len+slot_len+size_len+hash_len+14))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+slot_len+size_len+hash_len+14))s" "" | tr " " "="; printf '|\n' while IFS='|' read -r status slot size hash; do [[ ${size} -eq 0 ]] && size="-" [[ -z ${hash} ]] && hash="-" printf "| ${FG_LGRAY}%-${#leader_cnt}s${NC} | ${FG_LGRAY}%-${status_len}s${NC} | ${FG_LGRAY}%-${slot_len}s${NC} | ${FG_LGRAY}%-${size_len}s${NC} | ${FG_LGRAY}%-${hash_len}s${NC} |\n" "${block_cnt}" "${status}" "${slot}" "${size}" "${hash}" ((block_cnt++)) done < <(sqlite3 "${BLOCKLOG_DB}" "SELECT status, slot, size, hash FROM blocklog WHERE epoch=${epoch_enter} ORDER BY slot;" 2>/dev/null) - printf '|'; printf "%$((${#leader_cnt}+status_len+slot_len+size_len+hash_len+14))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+slot_len+size_len+hash_len+14))s" "" | tr " " "="; printf '|\n' elif [[ ${view} -eq 3 ]]; then - printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+size_len+hash_len+23))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+size_len+hash_len+23))s" "" | tr " " "="; printf '|\n' printf "| %-${#leader_cnt}s | %-${status_len}s | %-${block_len}s | %-${slot_len}s | %-${slot_in_epoch_len}s | %-${at_len}s | %-${size_len}s | %-${hash_len}s |\n" "#" "Status" "Block" "Slot" "SlotInEpoch" "Scheduled At" "Size" "Hash" - printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+size_len+hash_len+23))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+size_len+hash_len+23))s" "" | tr " " "="; printf '|\n' while IFS='|' read -r status block slot slot_in_epoch at size hash; do at=$(TZ="${BLOCKLOG_TZ}" date '+%F %T %Z' --date="${at}") [[ ${block} -eq 0 ]] && block="-" @@ -5478,7 +5478,7 @@ function main { printf "| ${FG_LGRAY}%-${#leader_cnt}s${NC} | ${FG_LGRAY}%-${status_len}s${NC} | ${FG_LGRAY}%-${block_len}s${NC} | ${FG_LGRAY}%-${slot_len}s${NC} | ${FG_LGRAY}%-${slot_in_epoch_len}s${NC} | ${FG_LGRAY}%-${at_len}s${NC} | ${FG_LGRAY}%-${size_len}s${NC} | ${FG_LGRAY}%-${hash_len}s${NC} |\n" "${block_cnt}" "${status}" "${block}" "${slot}" "${slot_in_epoch}" "${at}" "${size}" "${hash}" ((block_cnt++)) done < <(sqlite3 "${BLOCKLOG_DB}" "SELECT status, block, slot, slot_in_epoch, at, size, hash FROM blocklog WHERE epoch=${epoch_enter} ORDER BY slot;" 2>/dev/null) - printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+size_len+hash_len+23))s" | tr " " "="; printf '|\n' + printf '|'; printf "%$((${#leader_cnt}+status_len+block_len+slot_len+slot_in_epoch_len+at_len+size_len+hash_len+23))s" "" | tr " " "="; printf '|\n' elif [[ ${view} -eq 4 ]]; then println OFF "Block Status:\n" println OFF "Leader - Scheduled to make block at this slot"