Commit f94e04d5 authored by 张振华's avatar 张振华

Merge branch 'master' into dpos

parents c48b4c11 01f6506d
......@@ -150,3 +150,9 @@ chain33_QueryExecBalance() {
ok=$(jq '(.error|not) and (.result[0] | [has("balance", "frozen"), true] | unique | length == 1)' <<<"$resp")
[ "$ok" == true ]
}
chain33_GetAccounts() {
local MAIN_HTTP=$1
resp=$(curl -ksd '{"jsonrpc":"2.0","id":2,"method":"Chain33.GetAccounts","params":[{}]}' -H 'content-type:text/plain;' "${MAIN_HTTP}")
echo "$resp"
}
......@@ -98,6 +98,7 @@ function base_init() {
sed -i $sedfix 's/^minerdisable=.*/minerdisable=false/g' chain33.toml
sed -i $sedfix 's/^nodeGroupFrozenCoins=.*/nodeGroupFrozenCoins=20/g' chain33.toml
sed -i $sedfix 's/^paraConsensusStopBlocks=.*/paraConsensusStopBlocks=100/g' chain33.toml
# ticket
sed -i $sedfix 's/^ticketPrice =.*/ticketPrice = 10000/g' chain33.toml
......
......@@ -216,6 +216,7 @@ superManager=[
]
[exec.sub.paracross]
nodeGroupFrozenCoins=0
paraConsensusStopBlocks=100
#平行链共识停止后主链等待的高度
paraConsensusStopBlocks=30000
......@@ -40,6 +40,7 @@ func (client *commitMsgClient) handler() {
var isRollback bool
var notification []int64 //记录每次系统重启后 min and current height
var finishHeight int64
var consensHeight int64
var sendingHeight int64 //当前发送的最大高度
var sendingMsgs []*pt.ParacrossNodeStatus
var readTick <-chan time.Time
......@@ -155,7 +156,7 @@ out:
//获取正在共识的高度,同步有两层意思,一个是主链跟其他节点完成了同步,另一个是当前平行链节点的高度追赶上了共识高度
//一般来说高度增长从小到大: notifiy[0] -- selfConsensusHeight(mainHeight) -- finishHeight -- sendingHeight -- notify[1]
case rsp := <-consensusCh:
consensHeight := rsp.Height
consensHeight = rsp.Height
plog.Info("para consensus rcv", "notify", notification, "sending", len(sendingMsgs),
"consensHeigt", rsp.Height, "finished", finishHeight, "sync", isSync, "miner", readTick != nil, "consensBlockHash", common.ToHex(rsp.BlockHash))
......@@ -193,7 +194,6 @@ out:
finishHeight = consensHeight
sendingMsgs = nil
client.currentTx = nil
isSync = true
}
case miner := <-client.minerSwitch:
......@@ -212,6 +212,9 @@ out:
ticker = time.NewTicker(time.Second * time.Duration(minerInterval))
readTick = ticker.C
plog.Info("para consensus start mining")
//钱包开启后,从共识高度重新开始发送,在需要重发共识时候,不需要重启设备
finishHeight = consensHeight
}
case <-client.quit:
......
......@@ -2,21 +2,11 @@
# shellcheck disable=SC2128
set +e
set -o pipefail
set -x
MAIN_HTTP=""
CASE_ERR=""
# $2=0 means true, other false
echo_rst() {
if [ "$2" -eq 0 ]; then
echo "$1 ok"
else
echo "$1 err"
CASE_ERR="err"
fi
}
# shellcheck source=/dev/null
source ../dapp-test-common.sh
gID=""
gResp=""
......@@ -49,38 +39,6 @@ chain33_NewAccount() {
echo "$glAddr"
}
function block_wait() {
if [ "$#" -lt 1 ]; then
echo "wrong block_wait params"
exit 1
fi
cur_height=$(curl -ksd '{"jsonrpc":"2.0","id":2,"method":"Chain33.GetLastHeader","params":[{}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result.height")
expect=$((cur_height + ${1}))
local count=0
while true; do
new_height=$(curl -ksd '{"jsonrpc":"2.0","id":2,"method":"Chain33.GetLastHeader","params":[{}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result.height")
if [ "${new_height}" -ge "${expect}" ]; then
break
fi
count=$((count + 1))
sleep 1
done
echo "wait new block $count s, cur height=$expect,old=$cur_height"
}
chain33_SendToAddress() {
from=$1
to=$2
amount=$3
http=$4
note="test"
resp=$(curl -ksd '{"jsonrpc":"2.0","id":2,"method":"Chain33.SendToAddress","params":[{"from":"'"$from"'","to":"'"$to"'","amount":'"$amount"',"note":"'"$note"'"}]}' -H 'content-type:text/plain;' "${http}")
ok=$(jq '(.error|not)' <<<"$resp")
[ "$ok" == true ]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
chain33_SendTransaction() {
rawTx=$1
addr=$2
......@@ -98,8 +56,9 @@ chain33_SendTransaction() {
rst=$?
echo_rst "$FUNCNAME" "$rst"
#返回交易
gResp=$(echo "${resp}" | jq -r ".result")
gResp=$(jq -r ".result" <<<"$resp")
echo "tx hash is $gResp"
chain33_QueryTx "$gResp" "${MAIN_HTTP}"
}
blackwhite_BlackwhiteCreateTx() {
......@@ -211,6 +170,8 @@ function run_testcases() {
#给每个账户分别转帐
origAddr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
chain33_GetAccounts "${MAIN_HTTP}"
#主链中相应账户需要转帐
M_HTTP=${MAIN_HTTP//8901/8801}
chain33_SendToAddress "${origAddr}" "${gameAddr1}" 1000000000 "${M_HTTP}"
......@@ -222,29 +183,23 @@ function run_testcases() {
chain33_SendToAddress "${origAddr}" "${gameAddr2}" 1000000000 "${MAIN_HTTP}"
chain33_SendToAddress "${origAddr}" "${gameAddr3}" 1000000000 "${MAIN_HTTP}"
block_wait 1
#给游戏合约中转帐
chain33_SendToAddress "${gameAddr1}" "${bwExecAddr}" 500000000 "${MAIN_HTTP}"
chain33_SendToAddress "${gameAddr2}" "${bwExecAddr}" 500000000 "${MAIN_HTTP}"
chain33_SendToAddress "${gameAddr3}" "${bwExecAddr}" 500000000 "${MAIN_HTTP}"
block_wait 1
blackwhite_BlackwhiteCreateTx "${gameAddr1}"
block_wait 1
blackwhite_BlackwhitePlayTx "${gameAddr1}" "${white0}" "${white1}" "${black2}"
blackwhite_BlackwhitePlayTx "${gameAddr2}" "${white0}" "${black1}" "${black2}"
blackwhite_BlackwhitePlayTx "${gameAddr3}" "${white0}" "${black1}" "${black2}"
block_wait 1
blackwhite_BlackwhiteShowTx "${gameAddr1}" "${sect1}"
blackwhite_BlackwhiteShowTx "${gameAddr2}" "${sect1}"
blackwhite_BlackwhiteShowTx "${gameAddr3}" "${sect1}"
blackwhite_BlackwhiteTimeoutDoneTx "$gID"
#查询部分
block_wait 3
blackwhite_GetBlackwhiteRoundInfo "$gID"
blackwhite_GetBlackwhiteByStatusAndAddr "$gID" "${gameAddr1}"
blackwhite_GetBlackwhiteloopResult "$gID"
......@@ -256,6 +211,7 @@ function main() {
echo "main_ip=$MAIN_HTTP"
init
run_testcases
if [ -n "$CASE_ERR" ]; then
......@@ -264,4 +220,10 @@ function main() {
fi
}
main "$1"
function debug_function() {
set -x
eval "$@"
set +x
}
debug_function main "$1"
#!/usr/bin/env bash
# shellcheck disable=SC2128
MAIN_HTTP=""
CASE_ERR=""
#color
RED='\033[1;31m'
GRE='\033[1;32m'
NOC='\033[0m'
# base functions
# $2=0 means true, other false
function echo_rst() {
if [ "$2" -eq 0 ]; then
echo -e "${GRE}$1 ok${NOC}"
else
echo -e "${RED}$1 fail${NOC}"
CASE_ERR="err"
fi
}
function Chain33_SendToAddress() {
local from="$1"
local to="$2"
local amount=$3
local req='{"method":"Chain33.SendToAddress", "params":[{"from":"'"$from"'","to":"'"$to"'", "amount":'"$amount"', "note":"test\n"}]}'
# echo "#request: $req"
resp=$(curl -ksd "$req" "${MAIN_HTTP}")
# echo "#response: $resp"
ok=$(jq '(.error|not) and (.result.hash|length==66)' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
hash=$(jq '(.result.hash)' <<<"$resp")
echo "hash=$hash"
# query_tx "$hash"
}
function sign_raw_tx() {
txHex="$1"
priKey="$2"
req='{"method":"Chain33.SignRawTx","params":[{"privkey":"'"$priKey"'","txHex":"'"$txHex"'","expire":"120s"}]}'
# echo "#request SignRawTx: $req"
resp=$(curl -ksd "$req" ${MAIN_HTTP})
signedTx=$(jq -r ".result" <<<"$resp")
# echo "signedTx=$signedTx"
if [ "$signedTx" != null ]; then
send_tx "$signedTx"
else
echo "signedTx null error"
fi
}
function send_tx() {
signedTx=$1
req='{"method":"Chain33.SendTransaction","params":[{"token":"BTY","data":"'"$signedTx"'"}]}'
# echo "#request sendTx: $req"
# curl -ksd "$req" ${MAIN_HTTP}
resp=$(curl -ksd "$req" ${MAIN_HTTP})
err=$(jq '(.error)' <<<"$resp")
txhash=$(jq -r ".result" <<<"$resp")
if [ "$err" == null ]; then
# echo "tx hash: $txhash"
query_tx "$txhash"
else
echo "send tx error:$err"
fi
# shellcheck source=/dev/null
source ../dapp-test-common.sh
}
function block_wait() {
req='{"method":"Chain33.GetLastHeader","params":[{}]}'
cur_height=$(curl -ksd "$req" ${MAIN_HTTP} | jq ".result.height")
expect=$((cur_height + ${1}))
local count=0
while true; do
new_height=$(curl -ksd "$req" ${MAIN_HTTP} | jq ".result.height")
if [ "${new_height}" -ge "${expect}" ]; then
break
fi
count=$((count + 1))
sleep 1
done
echo "wait new block $count s, cur height=$expect,old=$cur_height"
}
function query_tx() {
block_wait 1
txhash="$1"
# echo "req=$req"
local times=10
while true; do
req='{"method":"Chain33.QueryTransaction","params":[{"hash":"'"$txhash"'"}]}'
ret=$(curl -ksd "$req" ${MAIN_HTTP})
tx=$(jq -r ".result.tx.hash" <<<"$ret")
echo "====query tx= ${1}, return=$ret "
if [ "${tx}" != "${1}" ]; then
block_wait 1
times=$((times - 1))
if [ $times -le 0 ]; then
echo "====query tx=$1 failed"
echo "req=$req"
curl -ksd "$req" ${MAIN_HTTP}
exit 1
fi
else
exec_ok=$(jq '(.result.receipt.tyName == "ExecOk")' <<<"$ret")
[ "$exec_ok" == true ]
echo_rst "query tx=$1" $?
break
fi
done
}
MAIN_HTTP=""
function init() {
ispara=$(echo '"'"${MAIN_HTTP}"'"' | jq '.|contains("8901")')
......@@ -149,7 +41,7 @@ function configJSCreator() {
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
sign_raw_tx "$rawtx" "${super_manager}"
chain33_SignRawTx "$rawtx" "${super_manager}" "${MAIN_HTTP}"
}
function createJSContract() {
......@@ -161,7 +53,7 @@ function createJSContract() {
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
sign_raw_tx "$rawtx" "${beneficiary_key}"
chain33_SignRawTx "$rawtx" "${beneficiary_key}" "${MAIN_HTTP}"
}
function callJS() {
......@@ -174,7 +66,7 @@ function callJS() {
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
sign_raw_tx "$rawtx" "${beneficiary_key}"
chain33_SignRawTx "$rawtx" "${beneficiary_key}" "${MAIN_HTTP}"
}
function queryJS() {
......
Title="user.p.para."
CoinSymbol="paracoin"
[log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
......
Title="user.p.guodun."
# TestNet=true
CoinSymbol="paracoin"
[log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
......
......@@ -496,7 +496,7 @@ function para_create_nodegroup() {
echo "=========== # para chain quit node group fail ============="
##quit fail
txhash=$(${PARA_CLI} send para nodegroup -o 3 -i "$id" -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b)
txhash=$(${PARA_CLI} send para nodegroup -o 3 -i "$id" -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
echo "tx=$txhash"
query_tx "${CLI}" "${txhash}"
status=$(${CLI} para nodegroup_status -t user.p.para. | jq -r ".status")
......@@ -513,17 +513,11 @@ function para_create_nodegroup() {
echo "=========== # para chain modify node group coin=5 ============="
txhash=$(${PARA_CLI} send para nodegroup -o 4 -c 5 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b)
echo "tx=$txhash"
query_tx "${CLI}" "${txhash}"
query_tx "${PARA_CLI}" "${txhash}"
modifyid=$(${PARA_CLI} para nodegroup_list -s 4 | jq -r ".ids[0].id")
if [ -z "$modifyid" ]; then
echo "query modify error "
${PARA_CLI} para nodegroup_list -s 4
modifyid=$(${PARA_CLI} tx query -s "${txhash}" | jq -r ".receipt.logs[0].log.current.id")
if [ -z "$modifyid" ]; then
${PARA_CLI} tx query -s "${txhash}"
echo "group id not getted"
exit 1
fi
fi
##approve
......@@ -547,21 +541,21 @@ function para_create_nodegroup() {
function para_nodegroup_behalf_quit_test() {
echo "=========== # para chain behalf node quit ============="
id=$(${PARA_CLI} para node_status -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -t user.p.para. | jq -r ".id")
if [ -z "${id}" ]; then
echo "wrong id "
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
status=$(${PARA_CLI} para node_addr_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" != "10" ]; then
echo "wrong 1E5 status"
${PARA_CLI} para node_addr_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
exit 1
fi
hash=$(${PARA_CLI} send para node -o 3 -i "$id" -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b)
hash=$(${PARA_CLI} send para node -o 3 -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
status=$(${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" != "3" ]; then
echo "wrong vote status"
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
id=$(${PARA_CLI} tx query -s "${hash}" | jq -r ".receipt.logs[0].log.current.id")
if [ -z "${id}" ]; then
echo "wrong id "
${PARA_CLI} tx query -s "${hash}"
exit 1
fi
......@@ -572,10 +566,10 @@ function para_nodegroup_behalf_quit_test() {
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
status=$(${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" != "4" ]; then
status=$(${PARA_CLI} para node_addr_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" != "11" ]; then
echo "wrong vote status"
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
${PARA_CLI} para node_addr_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
exit 1
fi
......@@ -594,7 +588,7 @@ function para_nodegroup_behalf_quit_test() {
}
function para_nodemanage_node_join() {
function para_nodemanage_cancel_test() {
echo "================# para node manage test ================="
balance=$(${CLI} account balance -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -e paracross | jq -r ".balance")
if [ "$balance" != "$PARA_COIN_FROZEN" ]; then
......@@ -613,174 +607,186 @@ function para_nodemanage_node_join() {
exit 1
fi
}
function para_nodemanage_node_behalf_join() {
echo "=========== # para chain new node join 1 ============="
hash=$(${PARA_CLI} send para node -o 1 -c 8 -a 1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
echo "=========== # para chain node cancel ============="
id=$(${PARA_CLI} tx query -s "${hash}" | jq -r ".receipt.logs[0].log.current.id")
if [ -z "$id" ]; then
echo "id not found"
${PARA_CLI} tx query -s "${hash}"
exit 1
fi
hash=$(${PARA_CLI} send para node -o 4 -i "$id" -k 0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "32.0000" ]; then
echo "1Ka frozen coinfrozen error balance=$balance"
balance=$(${CLI} account balance -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -e paracross | jq -r ".frozen")
if [ "$balance" == "$PARA_COIN_FROZEN" ]; then
echo "unfrozen coinfrozen error balance=$balance"
exit 1
fi
balance=$(${CLI} account balance -a 1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH -e paracross | jq -r ".frozen")
if [ "$balance" == "$PARA_COIN_FROZEN" ]; then
echo "1LU frozen coinfrozen error balance=$balance"
}
function para_nodemanage_test() {
echo "================# para node manage test ================="
balance=$(${CLI} account balance -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -e paracross | jq -r ".balance")
if [ "$balance" != "$PARA_COIN_FROZEN" ]; then
echo "balance coinfrozen error balance=$balance"
exit 1
fi
echo "=========== # para chain new node join 2============="
hash=$(${PARA_CLI} send para node -o 1 -c 9 -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
echo "=========== # para chain new node join reject============="
hash=$(${PARA_CLI} send para node -o 1 -c 5 -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -k 0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "41.0000" ]; then
balance=$(${CLI} account balance -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -e paracross | jq -r ".frozen")
if [ "$balance" != "$PARA_COIN_FROZEN" ]; then
echo "frozen coinfrozen error balance=$balance"
exit 1
fi
echo "=========== # para chain node 1 quit ============="
id=$(${PARA_CLI} para node_status -a 1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH -t user.p.para. | jq -r ".id")
if [ -z "${id}" ]; then
echo "wrong id "
${PARA_CLI} para node_status -t user.p.para. -a 1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH
id=$(${PARA_CLI} tx query -s "${hash}" | jq -r ".receipt.logs[0].log.current.id")
if [ -z "$id" ]; then
echo "id not found"
${PARA_CLI} tx query -s "${hash}"
exit 1
fi
hash=$(${PARA_CLI} send para node -o 3 -i "$id" -k 0xfdf2bbff853ecff2e7b86b2a8b45726c6538ca7d1403dc94e50131ef379bdca0)
echo "=========== # para chain node vote ============="
${PARA_CLI} send para node -o 2 -i "$id" -v 2 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
${PARA_CLI} send para node -o 2 -i "$id" -v 2 -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
hash=$(${PARA_CLI} send para node -o 2 -i "$id" -v 2 -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "33.0000" ]; then
echo "unfrozen coinfrozen error balance=$balance"
status=$(${PARA_CLI} para node_addr_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" == "10" ]; then
echo "wrong vote status"
${PARA_CLI} para node_addr_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
exit 1
fi
}
function para_nodemanage_quit_test() {
para_nodemanage_node_join
status=$(${PARA_CLI} para node_id_status -t user.p.para. -i "$id" | jq -r ".status")
if [ "${status}" != "3" ]; then
echo "wrong cancel status"
${PARA_CLI} para node_id_status -t user.p.para. -i "$id"
exit 1
fi
echo "=========== # para chain node quit ============="
id=$(${PARA_CLI} para node_status -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -t user.p.para. | jq -r ".id")
if [ -z "${id}" ]; then
echo "wrong id "
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
node=$(${PARA_CLI} para nodegroup_addrs -t user.p.para. | jq -r '.value|contains("1E5")')
if [ "${node}" == "true" ]; then
echo "wrong node group addr"
${PARA_CLI} para nodegroup_addrs -t user.p.para.
exit 1
fi
hash=$(${PARA_CLI} send para node -o 3 -i "$id" -k 0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
balance=$(${CLI} account balance -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -e paracross | jq -r ".frozen")
if [ "$balance" == "$PARA_COIN_FROZEN" ]; then
if [ "$balance" != "0.0000" ]; then
echo "unfrozen coinfrozen error balance=$balance"
exit 1
fi
echo "=========== # para chain node quit reject ============="
txhash=$(${PARA_CLI} send para node -o 3 -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -k 0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588)
echo "${txhash}"
query_tx "${PARA_CLI}" "${txhash}"
status=$(${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" != "4" ]; then
echo "wrong vote status"
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
id=$(${PARA_CLI} tx query -s "${txhash}" | jq -r ".receipt.logs[0].log.current.id")
if [ -z "$id" ]; then
echo "id not found"
${PARA_CLI} tx query -s "${txhash}"
exit 1
fi
}
function para_nodemanage_test() {
para_nodemanage_quit_test
para_nodemanage_node_join
echo "=========== # para chain node vote ============="
id=$(${PARA_CLI} para node_status -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -t user.p.para. | jq -r ".id")
if [ -z "${id}" ]; then
echo "wrong id "
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
exit 1
fi
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
hash=$(${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115)
echo "=========== # para chain node vote quit ============="
${PARA_CLI} send para node -o 2 -i "$id" -v 2 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
${PARA_CLI} send para node -o 2 -i "$id" -v 2 -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
hash=$(${PARA_CLI} send para node -o 2 -i "$id" -v 2 -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
status=$(${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" != "2" ]; then
status=$(${PARA_CLI} para node_addr_status -t user.p.para. -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 | jq -r ".status")
if [ "${status}" != "10" ]; then
echo "wrong vote status"
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
${PARA_CLI} para node_addr_status -t user.p.para. -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
exit 1
fi
node=$(${PARA_CLI} para nodegroup_addrs -t user.p.para. | jq -r '.value|contains("1E5")')
status=$(${PARA_CLI} para node_id_status -t user.p.para. -i "$id" | jq -r ".status")
if [ "${status}" != "3" ]; then
echo "wrong close status"
${PARA_CLI} para node_id_status -t user.p.para. -i "$id"
exit 1
fi
node=$(${PARA_CLI} para nodegroup_addrs -t user.p.para. | jq -r '.value|contains("1KS")')
if [ "${node}" != "true" ]; then
echo "wrong node group addr"
${PARA_CLI} para nodegroup_addrs -t user.p.para.
exit 1
fi
echo "=========== # para chain node quit ============="
hash=$(${PARA_CLI} send para node -o 3 -i "$id" -k 0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588)
}
function para_nodemanage_node_behalf_join() {
echo "=========== # para chain behalf node vote test ============="
echo "=========== # para chain new node join 1 ============="
hash=$(${PARA_CLI} send para node -o 1 -c 8 -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
status=$(${PARA_CLI} para node_list -t user.p.para. -s 3 | jq -r ".ids[0].targetAddr")
if [ "${status}" != "1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY" ]; then
echo "wrong join status"
${PARA_CLI} para node_list -t user.p.para. -s 3
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "32.0000" ]; then
echo "1Ka frozen coinfrozen error balance=$balance"
exit 1
fi
echo "=========== # para chain node vote quit ============="
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588
hash=$(${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
balance=$(${CLI} account balance -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY -e paracross | jq -r ".frozen")
if [ "$balance" != "0.0000" ]; then
echo "unfrozen coinfrozen error balance=$balance"
balance=$(${CLI} account balance -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -e paracross | jq -r ".frozen")
if [ "$balance" == "$PARA_COIN_FROZEN" ]; then
echo "1LU frozen coinfrozen error balance=$balance"
exit 1
fi
status=$(${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" != "4" ]; then
echo "wrong vote status"
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
node1_id=$(${PARA_CLI} tx query -s "${hash}" | jq -r ".receipt.logs[0].log.current.id")
if [ -z "$node1_id" ]; then
echo "id not found"
${PARA_CLI} tx query -s "${hash}"
exit 1
fi
node=$(${PARA_CLI} para nodegroup_addrs -t user.p.para. | jq -r '.value|contains("1E5")')
if [ "${node}" == "true" ]; then
echo "wrong node group addr"
${PARA_CLI} para nodegroup_addrs -t user.p.para.
echo "=========== # para chain new node join 2============="
hash=$(${PARA_CLI} send para node -o 1 -c 9 -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "41.0000" ]; then
echo "frozen coinfrozen error balance=$balance"
exit 1
fi
echo "=========== # para chain behalf node vote test ============="
para_nodemanage_node_behalf_join
id=$(${PARA_CLI} para node_status -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -t user.p.para. | jq -r ".id")
if [ -z "${id}" ]; then
echo "wrong id "
${PARA_CLI} para node_status -t user.p.para. -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB
id=$(${PARA_CLI} tx query -s "${hash}" | jq -r ".receipt.logs[0].log.current.id")
if [ -z "$id" ]; then
echo "id not found"
${PARA_CLI} tx query -s "${hash}"
exit 1
fi
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
hash=$(${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
status=$(${PARA_CLI} para node_status -t user.p.para. -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB | jq -r ".status")
if [ "${status}" != "2" ]; then
status=$(${PARA_CLI} para node_addr_status -t user.p.para. -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB | jq -r ".status")
if [ "${status}" != "10" ]; then
echo "wrong vote status"
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
${PARA_CLI} para node_addr_status -t user.p.para. -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB
exit 1
fi
status=$(${PARA_CLI} para node_id_status -t user.p.para. -i "$id" | jq -r ".status")
if [ "${status}" != "3" ]; then
echo "wrong close status"
${PARA_CLI} para node_id_status -t user.p.para. -i "$id"
exit 1
fi
......@@ -791,12 +797,50 @@ function para_nodemanage_test() {
exit 1
fi
echo "=========== # para chain node quit ============="
hash=$(${PARA_CLI} send para node -o 3 -i "$id" -k 0x794443611e7369a57b078881445b93b754cbc9b9b8f526535ab9c6d21d29203d)
echo "=========== # para chain same node vote again fail ============="
${PARA_CLI} send para node -o 2 -i "$node1_id" -v 1 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
${PARA_CLI} send para node -o 2 -i "$node1_id" -v 1 -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
hash=$(${PARA_CLI} send para node -o 2 -i "$node1_id" -v 1 -k 0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115)
echo "${hash}"
query_tx "${CLI}" "${hash}"
status=$(${CLI} para node_id_status -t user.p.para. -i "$node1_id" | jq -r ".status")
if [ "${status}" == "3" ]; then
echo "wrong vote status"
${CLI} para node_id_status -t user.p.para. -i "$node1_id"
exit 1
fi
echo "=========== # para chain node 1 cancel ============="
hash=$(${PARA_CLI} send para node -o 4 -i "$node1_id" -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
echo "=========== # para chain node vote quit ============="
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "33.0000" ]; then
echo "unfrozen coinfrozen error balance=$balance"
exit 1
fi
status=$(${PARA_CLI} para node_id_status -t user.p.para. -i "$node1_id" | jq -r ".status")
if [ "${status}" != "4" ]; then
echo "wrong cancel status"
${PARA_CLI} para node_id_status -t user.p.para. -i "$node1_id"
exit 1
fi
echo "=========== # para chain node 2 quit ============="
hash=$(${PARA_CLI} send para node -o 3 -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k 0x794443611e7369a57b078881445b93b754cbc9b9b8f526535ab9c6d21d29203d)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
id=$(${PARA_CLI} tx query -s "${hash}" | jq -r ".receipt.logs[0].log.current.id")
if [ -z "$id" ]; then
echo "id not found"
${PARA_CLI} tx query -s "${hash}"
exit 1
fi
echo "=========== # para chain node2 vote quit ============="
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
${PARA_CLI} send para node -o 2 -i "$id" -v 1 -k 0x794443611e7369a57b078881445b93b754cbc9b9b8f526535ab9c6d21d29203d
......@@ -810,26 +854,34 @@ function para_nodemanage_test() {
exit 1
fi
status=$(${PARA_CLI} para node_status -t user.p.para. -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB | jq -r ".status")
if [ "${status}" != "4" ]; then
status=$(${PARA_CLI} para node_addr_status -t user.p.para. -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB | jq -r ".status")
if [ "${status}" != "11" ]; then
echo "wrong vote status"
${PARA_CLI} para node_status -t user.p.para. -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY
${PARA_CLI} para node_addr_status -t user.p.para. -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB
exit 1
fi
status=$(${PARA_CLI} para node_id_status -t user.p.para. -i "$id" | jq -r ".status")
if [ "${status}" != "3" ]; then
echo "wrong cancel status"
${PARA_CLI} para node_id_status -t user.p.para. -i "$id"
exit 1
fi
node=$(${PARA_CLI} para nodegroup_addrs -t user.p.para. | jq -r '.value|contains("1NNa")')
if [ "${node}" == "true" ]; then
echo "wrong node group addr"
${PARA_CLI} para nodegroup_addrs -t user.p.para.
exit 1
fi
}
function para_test() {
echo "=========== # para chain test ============="
para_create_nodegroup
para_nodegroup_behalf_quit_test
para_nodemanage_cancel_test
para_nodemanage_test
para_nodemanage_node_behalf_join
token_create "${PARA_CLI}"
token_transfer "${PARA_CLI}"
para_cross_transfer_withdraw
......
......@@ -38,6 +38,7 @@ func ParcCmd() *cobra.Command {
GetParaListCmd(),
GetNodeGroupCmd(),
GetNodeInfoCmd(),
GetNodeIDInfoCmd(),
GetNodeListCmd(),
NodeGroupStatusCmd(),
NodeGroupListCmd(),
......@@ -251,12 +252,12 @@ func CreateRawNodeManageCmd() *cobra.Command {
}
func addNodeManageFlags(cmd *cobra.Command) {
cmd.Flags().Uint32P("operation", "o", 0, "operation:1:join,2:vote,3:quit")
cmd.Flags().Uint32P("operation", "o", 0, "operation:1:join,2:vote,3:quit,4:cancel")
cmd.MarkFlagRequired("operation")
cmd.Flags().StringP("addr", "a", "", "operating target addr")
cmd.Flags().StringP("addr", "a", "", "operating target addr[optional]")
cmd.Flags().StringP("id", "i", "", "operating target id")
cmd.Flags().StringP("id", "i", "", "operating target id[optional]")
cmd.Flags().Uint32P("value", "v", 1, "vote value: 1:yes,2:no")
cmd.Flags().Float64P("coins_frozen", "c", 0, "frozen coins amount, should not less nodegroup's")
......@@ -455,8 +456,8 @@ func paraList(cmd *cobra.Command, args []string) {
// GetNodeInfoCmd get node current status
func GetNodeInfoCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "node_status",
Short: "Get node current vote status",
Use: "node_addr_status",
Short: "Get node current status:10:joined,11:quited from nodegroup",
Run: nodeInfo,
}
addNodeBodyCmdFlags(cmd)
......@@ -468,7 +469,7 @@ func addNodeBodyCmdFlags(cmd *cobra.Command) {
cmd.MarkFlagRequired("title")
cmd.Flags().StringP("addr", "a", "", "addr apply for super user")
cmd.Flags().StringP("id", "i", "", "id apply for super user")
cmd.MarkFlagRequired("addr")
}
......@@ -476,15 +477,47 @@ func nodeInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
title, _ := cmd.Flags().GetString("title")
addr, _ := cmd.Flags().GetString("addr")
id, _ := cmd.Flags().GetString("id")
params := pt.ReqParacrossNodeInfo{
Title: title,
Addr: addr,
}
var res pt.ParaNodeAddrIdStatus
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetNodeAddrStatus", params, &res)
ctx.Run()
}
// GetNodeIDInfoCmd get node current status
func GetNodeIDInfoCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "node_id_status",
Short: "Get node id current vote status:0:all,1:joining,2:quiting,3:closed,4:canceled",
Run: nodeIDInfo,
}
addNodeIDBodyCmdFlags(cmd)
return cmd
}
func addNodeIDBodyCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("title", "t", "", "parallel chain's title")
cmd.MarkFlagRequired("title")
cmd.Flags().StringP("id", "i", "", "id apply for super user")
cmd.MarkFlagRequired("id")
}
func nodeIDInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
title, _ := cmd.Flags().GetString("title")
id, _ := cmd.Flags().GetString("id")
params := pt.ReqParacrossNodeInfo{
Title: title,
Id: id,
}
var res pt.ParaNodeIdStatus
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetNodeStatus", params, &res)
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetNodeIDStatus", params, &res)
ctx.Run()
}
......
......@@ -260,6 +260,19 @@ func (a *action) getNodesGroup(title string) (map[string]struct{}, error) {
return nodes, nil
}
//根据nodes过滤掉可能退出了的addrs
func updateCommitAddrs(stat *pt.ParacrossHeightStatus, nodes map[string]struct{}) {
details := &pt.ParacrossStatusDetails{}
for i, addr := range stat.Details.Addrs {
if _, ok := nodes[addr]; ok {
details.Addrs = append(details.Addrs, addr)
details.BlockHash = append(details.BlockHash, stat.Details.BlockHash[i])
}
}
stat.Details = details
}
func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error) {
err := checkCommitInfo(commit)
if err != nil {
......@@ -364,6 +377,11 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
}
receipt = makeCommitReceipt(a.fromaddr, commit, &copyStat, stat)
}
if types.IsDappFork(commit.Status.MainBlockHeight, pt.ParaX, pt.ForkCommitTx) {
updateCommitAddrs(stat, nodes)
}
clog.Info("paracross.Commit commit", "stat.title", stat.Title, "stat.height", stat.Height, "notes", len(nodes))
for i, v := range stat.Details.Addrs {
clog.Info("paracross.Commit commit detail", "addr", v, "hash", hex.EncodeToString(stat.Details.BlockHash[i]))
......
......@@ -100,6 +100,20 @@ func (e *Paracross) ExecDelLocal_NodeGroupConfig(payload *pt.ParaNodeGroupConfig
set.KV = append(set.KV, &types.KeyValue{
Key: calcLocalNodeGroupStatusTitle(g.Current.Status, g.Current.Title, g.Current.Id), Value: nil})
}
if log.Ty == pt.TyLogParaNodeConfig {
var g pt.ReceiptParaNodeConfig
err := types.Decode(log.Log, &g)
if err != nil {
return nil, err
}
if g.Prev != nil {
set.KV = append(set.KV, &types.KeyValue{
Key: calcLocalNodeTitleStatus(g.Current.Title, g.Prev.Status, g.Prev.Id), Value: types.Encode(g.Prev)})
}
set.KV = append(set.KV, &types.KeyValue{
Key: calcLocalNodeTitleStatus(g.Current.Title, g.Current.Status, g.Current.Id), Value: nil})
}
}
return &set, nil
}
......
......@@ -104,6 +104,21 @@ func (e *Paracross) ExecLocal_NodeGroupConfig(payload *pt.ParaNodeGroupConfig, t
set.KV = append(set.KV, &types.KeyValue{
Key: calcLocalNodeGroupStatusTitle(g.Current.Status, g.Current.Title, g.Current.Id), Value: types.Encode(g.Current)})
}
if log.Ty == pt.TyLogParaNodeConfig {
var g pt.ReceiptParaNodeConfig
err := types.Decode(log.Log, &g)
if err != nil {
return nil, err
}
if g.Prev != nil {
set.KV = append(set.KV, &types.KeyValue{
Key: calcLocalNodeTitleStatus(g.Current.Title, g.Prev.Status, g.Current.Id), Value: nil})
}
set.KV = append(set.KV, &types.KeyValue{
Key: calcLocalNodeTitleStatus(g.Current.Title, g.Current.Status, g.Current.Id),
Value: types.Encode(g.Current)})
}
}
return &set, nil
}
......
......@@ -85,19 +85,15 @@ func (p *Paracross) Query_GetNodeAddrInfo(in *pt.ReqParacrossNodeInfo) (types.Me
if in == nil || in.Title == "" || in.Addr == "" {
return nil, types.ErrInvalidParam
}
addrStat, err := getNodeAddr(p.GetStateDB(), in.Title, in.Addr)
if err != nil {
return nil, err
}
stat, err := getNodeID(p.GetStateDB(), addrStat.ProposalId)
stat, err := getNodeAddr(p.GetStateDB(), in.Title, in.Addr)
if err != nil {
return nil, err
}
return stat, nil
}
//Query_GetNodeIdInfo get specific node addr info
func (p *Paracross) Query_GetNodeIdInfo(in *pt.ReqParacrossNodeInfo) (types.Message, error) {
//Query_GetNodeIDInfo get specific node addr info
func (p *Paracross) Query_GetNodeIDInfo(in *pt.ReqParacrossNodeInfo) (types.Message, error) {
if in == nil || in.Title == "" || in.Id == "" {
return nil, types.ErrInvalidParam
}
......
......@@ -111,9 +111,28 @@ func makeVoteDoneReceipt(config *pt.ParaNodeIdStatus, totalCount, commitCount, m
}
}
func makeParaNodeStatusReceipt(fromAddr string, prev, current *pt.ParaNodeAddrIdStatus) *types.Receipt {
key := calcParaNodeAddrKey(current.Title, current.Addr)
log := &pt.ReceiptParaNodeAddrStatUpdate{
FromAddr: fromAddr,
Prev: prev,
Current: current,
}
return &types.Receipt{
Ty: types.ExecOk,
KV: []*types.KeyValue{
{Key: key, Value: types.Encode(current)},
},
Logs: []*types.ReceiptLog{
{
Ty: pt.TyLogParaNodeStatusUpdate,
Log: types.Encode(log),
},
},
}
}
func makeNodeConfigReceipt(fromAddr string, config *pt.ParaNodeAddrConfig, prev, current *pt.ParaNodeIdStatus) *types.Receipt {
key := calcParaNodeAddrKey(current.Title, current.TargetAddr)
val := &pt.ParaNodeAddrIdStatus{ProposalId: current.Id}
log := &pt.ReceiptParaNodeConfig{
Addr: fromAddr,
Config: config,
......@@ -124,7 +143,6 @@ func makeNodeConfigReceipt(fromAddr string, config *pt.ParaNodeAddrConfig, prev,
Ty: types.ExecOk,
KV: []*types.KeyValue{
{Key: []byte(current.Id), Value: types.Encode(current)},
{Key: key, Value: types.Encode(val)},
},
Logs: []*types.ReceiptLog{
{
......@@ -193,13 +211,24 @@ func makeParaNodeGroupReceipt(title string, prev, current *types.ConfigItem) *ty
}
}
func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
func (a *action) checkValidNode(config *pt.ParaNodeAddrConfig) (bool, error) {
nodes, _, err := getParacrossNodes(a.db, config.Title)
if err != nil {
return nil, errors.Wrapf(err, "getNodes for title:%s", config.Title)
return false, errors.Wrapf(err, "getNodes for title:%s", config.Title)
}
//有可能申请地址和配置地址不是同一个
if validNode(config.Addr, nodes) {
return true, nil
}
return false, nil
}
func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
addrExist, err := a.checkValidNode(config)
if err != nil {
return nil, err
}
if addrExist {
return nil, errors.Wrapf(pt.ErrParaNodeAddrExisted, "nodeAddr existed:%s", config.Addr)
}
......@@ -244,19 +273,8 @@ func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
return receipt, nil
}
stat, err := getNodeID(a.db, addrStat.ProposalId)
if err != nil {
clog.Error("nodeaccount.getNodeID fail", "err", err.Error())
return nil, err
}
var copyStat pt.ParaNodeIdStatus
err = deepCopy(&copyStat, stat)
if err != nil {
clog.Error("nodeaccount.nodeJoin deep copy fail", "copy", copyStat, "stat", stat)
return nil, err
}
if stat.Status == pt.ParacrossNodeQuited {
stat = &pt.ParaNodeIdStatus{
if addrStat.Status == pt.ParacrossNodeQuited {
stat := &pt.ParaNodeIdStatus{
Id: calcParaNodeIDKey(config.Title, common.ToHex(a.txhash)),
Status: pt.ParacrossNodeJoining,
Title: config.Title,
......@@ -265,73 +283,92 @@ func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
Votes: &pt.ParaNodeVoteDetail{},
CoinsFrozen: config.CoinsFrozen,
Height: a.height}
r := makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat)
r := makeNodeConfigReceipt(a.fromaddr, config, nil, stat)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
return nil, errors.Wrapf(pt.ErrParaNodeAddrExisted, "nodeAddr existed:%s,status:%d", config.Addr, stat.Status)
return nil, errors.Wrapf(pt.ErrParaNodeAddrExisted, "nodeAddr existed:%s,status:%d", config.Addr, addrStat.Status)
}
func (a *action) nodeQuit(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
addrExist, err := a.checkValidNode(config)
if err != nil {
return nil, err
}
if !addrExist {
return nil, errors.Wrapf(pt.ErrParaNodeAddrNotExisted, "nodeAddr not existed:%s", config.Addr)
}
addrStat, err := getNodeAddr(a.db, config.Title, config.Addr)
if err != nil {
return nil, errors.Wrapf(err, "nodeAddr:%s get error", config.Addr)
}
if addrStat.Status != pt.ParacrossNodeJoined {
return nil, errors.Wrapf(pt.ErrParaNodeAddrNotExisted, "nodeAddr:%s status:%d", config.Addr, addrStat.Status)
}
stat := &pt.ParaNodeIdStatus{
Id: calcParaNodeIDKey(config.Title, common.ToHex(a.txhash)),
Status: pt.ParacrossNodeQuiting,
Title: config.Title,
TargetAddr: config.Addr,
FromAddr: a.fromaddr,
Votes: &pt.ParaNodeVoteDetail{},
Height: a.height}
return makeNodeConfigReceipt(a.fromaddr, config, nil, stat), nil
}
func (a *action) nodeCancel(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
stat, err := getNodeID(a.db, config.Id)
if err != nil {
return nil, err
}
//只能提案发起人撤销
if a.fromaddr != stat.FromAddr {
return nil, errors.Wrapf(types.ErrNotAllow, "id create by:%s,not by:%s", stat.FromAddr, a.fromaddr)
}
if config.Title != stat.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, stat.Title)
}
if stat.Status != pt.ParacrossNodeJoining && stat.Status != pt.ParacrossNodeQuiting {
return nil, errors.Wrapf(pt.ErrParaNodeOpStatusWrong, "config id:%s,status:%d", config.Id, stat.Status)
}
var copyStat pt.ParaNodeIdStatus
err = deepCopy(&copyStat, stat)
if err != nil {
clog.Error("nodeaccount.nodeQuit deep copy fail", "copy", copyStat, "stat", stat)
return nil, err
}
if stat.Status == pt.ParacrossNodeJoined {
nodes, _, err := getParacrossNodes(a.db, config.Title)
if err != nil {
return nil, errors.Wrapf(err, "getNodes for title:%s", config.Title)
}
if !validNode(stat.TargetAddr, nodes) {
return nil, errors.Wrapf(pt.ErrParaNodeAddrNotExisted, "nodeAddr not existed:%s", stat.TargetAddr)
}
//不允许最后一个账户退出
if len(nodes) == 1 {
return nil, errors.Wrapf(pt.ErrParaNodeGroupLastAddr, "nodeAddr last one:%s", stat.TargetAddr)
}
stat.Status = pt.ParacrossNodeQuiting
stat.Height = a.height
stat.Votes = &pt.ParaNodeVoteDetail{}
return makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat), nil
}
if stat.Status == pt.ParacrossNodeJoining {
//still adding status, quit directly
receipt := &types.Receipt{Ty: types.ExecOk}
if !types.IsPara() {
r, err := a.nodeGroupCoinsActive(stat.FromAddr, stat.CoinsFrozen, 1)
if err != nil {
return nil, err
}
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
receipt = mergeReceipt(receipt, r)
}
stat.Status = pt.ParacrossNodeQuited
stat.Status = pt.ParacrossNodeCanceled
stat.Height = a.height
stat.Votes = &pt.ParaNodeVoteDetail{}
r := makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
receipt = mergeReceipt(receipt, r)
return receipt, nil
}
if stat.Status == pt.ParacrossNodeQuiting {
stat.Status = pt.ParacrossNodeCanceled
stat.Height = a.height
return makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat), nil
}
return nil, errors.Wrapf(pt.ErrParaUnSupportNodeOper, "nodeid %s was quit status:%d", config.Id, stat.Status)
}
......@@ -383,7 +420,7 @@ func (a *action) superManagerVoteProc(title string) error {
consensHeight := data.(*pt.ParacrossStatus).Height
//如果group建立后一直没有共识,则从approve时候开始算
if consensHeight == -1 {
consensMainHeight = status.MainHeight
consensMainHeight = status.Height
} else {
stat, err := a.exec.paracrossGetStateTitleHeight(title, consensHeight)
if err != nil {
......@@ -393,15 +430,71 @@ func (a *action) superManagerVoteProc(title string) error {
consensMainHeight = stat.(*pt.ParacrossHeightStatus).MainHeight
}
//return err to stop tx pass to para chain
if a.exec.GetMainHeight() <= consensMainHeight+confStopBlocks*int64(status.EmptyBlockInterval) {
clog.Error("superManagerVoteProc, super manager height not reach", "currHeight", a.exec.GetMainHeight(),
"consensHeight", consensHeight, "mainHeight", consensMainHeight, "confHeight", confStopBlocks, "interval", status.EmptyBlockInterval)
return pt.ErrParaConsensStopBlocksNotReach
if a.height <= consensMainHeight+confStopBlocks {
return errors.Wrapf(pt.ErrParaConsensStopBlocksNotReach,
"supermanager height not reach,current:%d less consens:%d plus confStopBlocks:%d", a.height, consensMainHeight, confStopBlocks)
}
return nil
}
func updateVotes(stat *pt.ParaNodeIdStatus, nodes map[string]struct{}) {
votes := &pt.ParaNodeVoteDetail{}
for i, addr := range stat.Votes.Addrs {
if _, ok := nodes[addr]; ok {
votes.Addrs = append(votes.Addrs, addr)
votes.Votes = append(votes.Votes, stat.Votes.Votes[i])
}
}
stat.Votes = votes
}
func (a *action) updateNodeAddrStatus(stat *pt.ParaNodeIdStatus) (*types.Receipt, error) {
addrStat, err := getNodeAddr(a.db, stat.Title, stat.TargetAddr)
if err != nil {
if !isNotFound(err) {
return nil, errors.Wrapf(err, "nodeAddr:%s get error", stat.TargetAddr)
}
addrStat = &pt.ParaNodeAddrIdStatus{}
addrStat.Title = stat.Title
addrStat.Addr = stat.TargetAddr
addrStat.Status = pt.ParacrossNodeJoined
addrStat.ProposalId = stat.Id
addrStat.QuitId = ""
return makeParaNodeStatusReceipt(a.fromaddr, nil, addrStat), nil
}
preStat := *addrStat
if stat.Status == pt.ParacrossNodeJoining {
addrStat.Status = pt.ParacrossNodeJoined
addrStat.ProposalId = stat.Id
addrStat.QuitId = ""
return makeParaNodeStatusReceipt(a.fromaddr, &preStat, addrStat), nil
}
if stat.Status == pt.ParacrossNodeQuiting {
proposalStat, err := getNodeID(a.db, addrStat.ProposalId)
if err != nil {
return nil, errors.Wrapf(err, "nodeAddr:%s quiting wrong proposeid:%s", stat.TargetAddr, addrStat.ProposalId)
}
addrStat.Status = pt.ParacrossNodeQuited
addrStat.QuitId = stat.Id
receipt := makeParaNodeStatusReceipt(a.fromaddr, &preStat, addrStat)
if !types.IsPara() {
r, err := a.nodeGroupCoinsActive(proposalStat.FromAddr, proposalStat.CoinsFrozen, 1)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
}
return receipt, nil
}
return nil, errors.Wrapf(pt.ErrParaNodeOpStatusWrong, "nodeAddr:%s get wrong status:%d", stat.TargetAddr, stat.Status)
}
func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
nodes, _, err := getParacrossNodes(a.db, config.Title)
if err != nil {
......@@ -415,10 +508,20 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
if err != nil {
return nil, err
}
if config.Title != stat.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, stat.Title)
}
if stat.Status != pt.ParacrossNodeJoining && stat.Status != pt.ParacrossNodeQuiting {
return nil, errors.Wrapf(pt.ErrParaNodeOpStatusWrong, "config id:%s,status:%d", config.Id, stat.Status)
}
//已经被其他id pass 场景
if stat.Status == pt.ParacrossNodeJoining && validNode(stat.TargetAddr, nodes) {
return nil, errors.Wrapf(pt.ErrParaNodeAddrExisted, "config id:%s,addr:%s", config.Id, stat.TargetAddr)
}
if stat.Status == pt.ParacrossNodeQuiting && !validNode(stat.TargetAddr, nodes) {
return nil, errors.Wrapf(pt.ErrParaNodeAddrNotExisted, "config id:%s,addr:%s", config.Id, stat.TargetAddr)
}
var copyStat pt.ParaNodeIdStatus
err = deepCopy(&copyStat, stat)
......@@ -437,6 +540,10 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
stat.Votes.Addrs = append(stat.Votes.Addrs, a.fromaddr)
stat.Votes.Votes = append(stat.Votes.Votes, pt.ParaNodeVoteStr[config.Value])
}
//剔除已退出nodegroup的addr的投票
updateVotes(stat, nodes)
most, vote := getMostVote(stat)
if !isCommitDone(stat, nodes, most) {
superManagerPass := false
......@@ -460,15 +567,10 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
receipt := &types.Receipt{Ty: types.ExecOk}
if vote == pt.ParaNodeVoteNo {
// 对已经在group里面的node,直接投票remove,对正在申请中的adding or quiting状态保持不变,对quited的保持不变
if stat.Status == pt.ParacrossNodeJoined {
r, err := unpdateNodeGroup(a.db, config.Title, stat.TargetAddr, false)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
stat.Status = pt.ParacrossNodeQuited
if stat.Status == pt.ParacrossNodeJoining {
stat.Status = pt.ParacrossNodeClosed
stat.Height = a.height
//active coins
if !types.IsPara() {
r, err := a.nodeGroupCoinsActive(stat.FromAddr, stat.CoinsFrozen, 1)
if err != nil {
......@@ -476,32 +578,42 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
}
receipt = mergeReceipt(receipt, r)
}
} else if stat.Status == pt.ParacrossNodeQuiting {
stat.Status = pt.ParacrossNodeClosed
stat.Height = a.height
}
} else {
if stat.Status == pt.ParacrossNodeJoining {
r, err := unpdateNodeGroup(a.db, config.Title, stat.TargetAddr, true)
if err != nil {
return nil, err
}
stat.Status = pt.ParacrossNodeJoined
stat.Height = a.height
receipt = mergeReceipt(receipt, r)
r, err = a.updateNodeAddrStatus(stat)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
stat.Status = pt.ParacrossNodeClosed
stat.Height = a.height
} else if stat.Status == pt.ParacrossNodeQuiting {
r, err := unpdateNodeGroup(a.db, config.Title, stat.TargetAddr, false)
if err != nil {
return nil, err
}
stat.Status = pt.ParacrossNodeQuited
stat.Height = a.height
receipt = mergeReceipt(receipt, r)
if !types.IsPara() {
r, err := a.nodeGroupCoinsActive(stat.FromAddr, stat.CoinsFrozen, 1)
r, err = a.updateNodeAddrStatus(stat)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
}
stat.Status = pt.ParacrossNodeClosed
stat.Height = a.height
}
}
r := makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat)
......@@ -669,8 +781,6 @@ func (a *action) nodeGroupApply(config *pt.ParaNodeGroupConfig) (*types.Receipt,
Title: config.Title,
TargetAddrs: strings.Join(addrs, ","),
CoinsFrozen: config.CoinsFrozen,
MainHeight: a.exec.GetMainHeight(),
EmptyBlockInterval: config.EmptyBlockInterval,
FromAddr: a.fromaddr,
Height: a.height}
r := makeNodeGroupIDReceipt(a.fromaddr, nil, stat)
......@@ -687,8 +797,6 @@ func (a *action) nodeGroupModify(config *pt.ParaNodeGroupConfig) (*types.Receipt
Status: pt.ParacrossNodeGroupModify,
Title: config.Title,
CoinsFrozen: config.CoinsFrozen,
MainHeight: a.exec.GetMainHeight(),
EmptyBlockInterval: config.EmptyBlockInterval,
Height: a.height}
r := makeNodeGroupIDReceipt(a.fromaddr, nil, stat)
receipt.KV = append(receipt.KV, r.KV...)
......@@ -703,13 +811,18 @@ func (a *action) nodeGroupQuit(config *pt.ParaNodeGroupConfig) (*types.Receipt,
return nil, err
}
//只能提案发起人撤销
if a.fromaddr != status.FromAddr {
return nil, errors.Wrapf(types.ErrNotAllow, "id create by:%s,not by:%s", status.FromAddr, a.fromaddr)
}
if config.Title != status.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, status.Title)
}
//approved or quited
if status.Status != pt.ParacrossNodeGroupApply {
return nil, errors.Wrapf(pt.ErrParaNodeGroupStatusWrong, "node group apply not apply:%d", status.Status)
return nil, errors.Wrapf(pt.ErrParaNodeOpStatusWrong, "node group apply not apply:%d", status.Status)
}
applyAddrs := strings.Split(status.TargetAddrs, ",")
......@@ -761,8 +874,6 @@ func (a *action) nodeGroupApproveModify(config *pt.ParaNodeGroupConfig, modify *
copyStat := *stat
stat.Id = modify.Id
stat.CoinsFrozen = modify.CoinsFrozen
stat.EmptyBlockInterval = modify.EmptyBlockInterval
stat.MainHeight = a.exec.GetMainHeight()
stat.Height = a.height
r = makeParaNodeGroupStatusReceipt(config.Title, a.fromaddr, &copyStat, stat)
......@@ -785,13 +896,15 @@ func (a *action) nodeGroupApproveApply(config *pt.ParaNodeGroupConfig, apply *pt
receipt := &types.Receipt{Ty: types.ExecOk}
//create the node group
r := a.nodeGroupCreate(apply)
r, err := a.nodeGroupCreate(apply)
if err != nil {
return nil, errors.Wrapf(err, "nodegroup create:title:%s,addrs:%s", config.Title, apply.TargetAddrs)
}
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
copyStat := *apply
apply.Status = pt.ParacrossNodeGroupApprove
apply.MainHeight = a.exec.GetMainHeight()
apply.Height = a.height
r = makeNodeGroupIDReceipt(a.fromaddr, &copyStat, apply)
......@@ -829,11 +942,11 @@ func (a *action) nodeGroupApprove(config *pt.ParaNodeGroupConfig) (*types.Receip
return a.nodeGroupApproveApply(config, id)
}
return nil, errors.Wrapf(pt.ErrParaNodeGroupStatusWrong, "nodeGroupApprove id wrong status:%d,id:%s", id.Status, config.Id)
return nil, errors.Wrapf(pt.ErrParaNodeOpStatusWrong, "nodeGroupApprove id wrong status:%d,id:%s", id.Status, config.Id)
}
func (a *action) nodeGroupCreate(status *pt.ParaNodeGroupStatus) *types.Receipt {
func (a *action) nodeGroupCreate(status *pt.ParaNodeGroupStatus) (*types.Receipt, error) {
nodes := strings.Split(status.TargetAddrs, ",")
var item types.ConfigItem
......@@ -851,7 +964,7 @@ func (a *action) nodeGroupCreate(status *pt.ParaNodeGroupStatus) *types.Receipt
for i, addr := range nodes {
stat := &pt.ParaNodeIdStatus{
Id: status.Id + "-" + strconv.Itoa(i),
Status: pt.ParacrossNodeJoined,
Status: pt.ParacrossNodeClosed,
Title: status.Title,
TargetAddr: addr,
Votes: &pt.ParaNodeVoteDetail{Addrs: []string{a.fromaddr}, Votes: []string{"yes"}},
......@@ -860,10 +973,15 @@ func (a *action) nodeGroupCreate(status *pt.ParaNodeGroupStatus) *types.Receipt
Height: a.height}
r := makeNodeConfigReceipt(a.fromaddr, nil, nil, stat)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
receipt = mergeReceipt(receipt, r)
r, err := a.updateNodeAddrStatus(stat)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
}
return receipt
return receipt, nil
}
//NodeGroupConfig support super node group config
......@@ -913,10 +1031,13 @@ func (a *action) NodeConfig(config *pt.ParaNodeAddrConfig) (*types.Receipt, erro
return a.nodeJoin(config)
} else if config.Op == pt.ParaNodeQuit {
return a.nodeQuit(config)
} else if config.Op == pt.ParaNodeCancel {
if config.Id == "" {
return nil, types.ErrInvalidParam
}
return a.nodeQuit(config)
return a.nodeCancel(config)
} else if config.Op == pt.ParaNodeVote {
if config.Id == "" || config.Value >= pt.ParaNodeVoteEnd {
......
......@@ -109,34 +109,17 @@ func checkGroupApplyReceipt(suite *NodeManageTestSuite, receipt *types.Receipt)
assert.Len(suite.T(), receipt.KV, 1)
assert.Len(suite.T(), receipt.Logs, 1)
var stat pt.ParaNodeIdStatus
err := types.Decode(receipt.KV[0].Value, &stat)
assert.Nil(suite.T(), err, "decode ParaNodeAddrStatus failed")
//suite.T().Log("titleHeight", titleHeight)
assert.Equal(suite.T(), int32(pt.TyLogParaNodeGroupConfig), receipt.Logs[0].Ty)
assert.Equal(suite.T(), int32(pt.ParacrossNodeGroupApply), stat.Status)
}
func checkGroupApproveReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 11)
assert.Len(suite.T(), receipt.Logs, 7)
len := len(receipt.KV)
var stat pt.ParaNodeIdStatus
err := types.Decode(receipt.KV[len-1].Value, &stat)
assert.Nil(suite.T(), err, "decode ParaNodeAddrStatus failed")
//suite.T().Log("ty len-1", receipt.Logs[lenLogs-1].Ty,"len",lenLogs)
assert.Equal(suite.T(), int32(pt.TyLogParaNodeGroupStatusUpdate), receipt.Logs[7-1].Ty)
assert.Equal(suite.T(), int32(pt.ParacrossNodeGroupApprove), stat.Status)
}
func checkJoinReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 2)
assert.Len(suite.T(), receipt.KV, 1)
assert.Len(suite.T(), receipt.Logs, 1)
var stat pt.ParaNodeIdStatus
......@@ -151,7 +134,7 @@ func checkJoinReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
func checkQuitReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 2)
assert.Len(suite.T(), receipt.KV, 1)
assert.Len(suite.T(), receipt.Logs, 1)
var stat pt.ParaNodeIdStatus
......@@ -299,13 +282,17 @@ func (suite *NodeManageTestSuite) testNodeConfig() {
//Quit test
config = &pt.ParaNodeAddrConfig{
Op: pt.ParaNodeQuit,
Id: g.Current.Id,
Addr: Account14K,
}
tx, err = pt.CreateRawNodeConfigTx(config)
suite.Nil(err)
receipt = nodeCommit(suite, PrivKeyD, tx)
checkQuitReceipt(suite, receipt)
suite.Equal(int32(pt.TyLogParaNodeConfig), receipt.Logs[0].Ty)
err = types.Decode(receipt.Logs[0].Log, &g)
suite.Nil(err)
//vote test
voteTest(suite, g.Current.Id, false)
}
......@@ -352,3 +339,18 @@ func TestGetAddrGroup(t *testing.T) {
assert.Equal(t, 0, len(ret))
}
func TestUpdateVotes(t *testing.T) {
stat := &pt.ParaNodeIdStatus{}
votes := &pt.ParaNodeVoteDetail{
Addrs: []string{"AA", "BB", "CC"},
Votes: []string{"yes", "no", "no"}}
stat.Votes = votes
nodes := make(map[string]struct{})
nodes["BB"] = struct{}{}
nodes["CC"] = struct{}{}
updateVotes(stat, nodes)
assert.Equal(t, []string{"BB", "CC"}, stat.Votes.Addrs)
assert.Equal(t, []string{"no", "no"}, stat.Votes.Votes)
}
......@@ -63,7 +63,11 @@ message ParaNodeVoteDetail {
}
message ParaNodeAddrIdStatus {
string proposalId = 1;
string addr = 1;
string proposalId = 2;
string quitId = 3;
int32 status = 4;
string title = 5;
}
message ParaNodeIdStatus {
......@@ -85,6 +89,11 @@ message ReceiptParaNodeConfig {
ParaNodeIdStatus current = 4;
}
message ReceiptParaNodeAddrStatUpdate {
string fromAddr = 1;
ParaNodeAddrIdStatus prev = 2;
ParaNodeAddrIdStatus current = 3;
}
message ReceiptParaNodeVoteDone {
string id = 1;
......@@ -104,7 +113,6 @@ message ParaNodeGroupConfig {
string id = 3;
string addrs = 4;
int64 coinsFrozen = 5;
uint32 emptyBlockInterval = 6;
}
......@@ -114,10 +122,8 @@ message ParaNodeGroupStatus {
string title = 3;
string targetAddrs = 4;
int64 coinsFrozen = 5;
uint32 emptyBlockInterval = 6;
int64 mainHeight = 7;
string fromAddr = 8;
int64 height = 9;
string fromAddr = 6;
int64 height = 7;
}
message ReceiptParaNodeGroupConfig {
......
......@@ -49,6 +49,9 @@ func (c *Jrpc) GetHeight(req *types.ReqString, result *interface{}) error {
}
data, err := c.cli.GetTitle(context.Background(), req)
if err != nil {
return err
}
*result = *data
return err
......@@ -68,6 +71,9 @@ func (c *channelClient) ListTitles(ctx context.Context, req *types.ReqNil) (*pt.
// ListTitles get paracross consensus titles list
func (c *Jrpc) ListTitles(req *types.ReqNil, result *interface{}) error {
data, err := c.cli.ListTitles(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
......@@ -89,6 +95,9 @@ func (c *Jrpc) GetTitleHeight(req *pt.ReqParacrossTitleHeight, result *interface
return types.ErrInvalidParam
}
data, err := c.cli.GetTitleHeight(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
......@@ -121,6 +130,9 @@ func (c *Jrpc) GetAssetTxResult(req *types.ReqHash, result *interface{}) error {
return types.ErrInvalidParam
}
data, err := c.cli.GetAssetTxResult(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
......@@ -175,27 +187,30 @@ func (c *Jrpc) GetBlock2MainInfo(req *types.ReqBlocks, result *interface{}) erro
}
ret, err := c.cli.GetBlock2MainInfo(context.Background(), req)
*result = *ret
if err != nil {
return err
}
*result = *ret
return nil
}
// GetNodeStatus get super node status
func (c *channelClient) GetNodeStatus(ctx context.Context, req *pt.ReqParacrossNodeInfo) (*pt.ParaNodeIdStatus, error) {
// GetNodeAddrStatus get super node status
func (c *channelClient) GetNodeAddrStatus(ctx context.Context, req *pt.ReqParacrossNodeInfo) (*pt.ParaNodeAddrIdStatus, error) {
r := *req
data, err := c.Query(pt.GetExecName(), "GetNodeAddrInfo", &r)
if err != nil {
return nil, err
}
if resp, ok := data.(*pt.ParaNodeIdStatus); ok {
if resp, ok := data.(*pt.ParaNodeAddrIdStatus); ok {
return resp, nil
}
return nil, types.ErrDecode
}
// GetNodeStatus get super node status
// GetNodeIDStatus get super node status
func (c *channelClient) GetNodeIDStatus(ctx context.Context, req *pt.ReqParacrossNodeInfo) (*pt.ParaNodeIdStatus, error) {
r := *req
data, err := c.Query(pt.GetExecName(), "GetNodeIdInfo", &r)
data, err := c.Query(pt.GetExecName(), "GetNodeIDInfo", &r)
if err != nil {
return nil, err
}
......@@ -205,22 +220,30 @@ func (c *channelClient) GetNodeIDStatus(ctx context.Context, req *pt.ReqParacros
return nil, types.ErrDecode
}
// GetNodeStatus get super node status
func (c *Jrpc) GetNodeStatus(req *pt.ReqParacrossNodeInfo, result *interface{}) error {
if req == nil || (req.Addr == "" && req.Id == "") {
// GetNodeAddrStatus get super node status
func (c *Jrpc) GetNodeAddrStatus(req *pt.ReqParacrossNodeInfo, result *interface{}) error {
if req == nil || req.Addr == "" {
return types.ErrInvalidParam
}
var data *pt.ParaNodeIdStatus
var err error
if req.Addr != "" {
data, err = c.cli.GetNodeStatus(context.Background(), req)
data, err := c.cli.GetNodeAddrStatus(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
if req.Id != "" {
data, err = c.cli.GetNodeIDStatus(context.Background(), req)
// GetNodeIDStatus get super node status
func (c *Jrpc) GetNodeIDStatus(req *pt.ReqParacrossNodeInfo, result *interface{}) error {
if req == nil || req.Id == "" {
return types.ErrInvalidParam
}
data, err := c.cli.GetNodeIDStatus(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
......@@ -241,6 +264,9 @@ func (c *channelClient) ListNodeStatus(ctx context.Context, req *pt.ReqParacross
//ListNodeStatus list super node by status
func (c *Jrpc) ListNodeStatus(req *pt.ReqParacrossNodeInfo, result *interface{}) error {
data, err := c.cli.ListNodeStatus(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
......@@ -261,6 +287,9 @@ func (c *channelClient) GetNodeGroupAddrs(ctx context.Context, req *pt.ReqParacr
// GetNodeGroupAddrs get super node group addrs
func (c *Jrpc) GetNodeGroupAddrs(req *pt.ReqParacrossNodeInfo, result *interface{}) error {
data, err := c.cli.GetNodeGroupAddrs(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
......@@ -281,6 +310,9 @@ func (c *channelClient) GetNodeGroupStatus(ctx context.Context, req *pt.ReqParac
// GetNodeGroupStatus get super node group status
func (c *Jrpc) GetNodeGroupStatus(req *pt.ReqParacrossNodeInfo, result *interface{}) error {
data, err := c.cli.GetNodeGroupStatus(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
......@@ -301,6 +333,9 @@ func (c *channelClient) ListNodeGroupStatus(ctx context.Context, req *pt.ReqPara
//ListNodeGroupStatus list super node group by status
func (c *Jrpc) ListNodeGroupStatus(req *pt.ReqParacrossNodeInfo, result *interface{}) error {
data, err := c.cli.ListNodeGroupStatus(context.Background(), req)
if err != nil {
return err
}
*result = data
return err
}
......@@ -3,6 +3,7 @@ package testnode
//DefaultConfig default config for testnode
var DefaultConfig = `
Title="user.p.guodun."
CoinSymbol="bty"
# TestNet=true
[log]
......
......@@ -45,8 +45,8 @@ var (
ErrParaNodeVoteSelf = errors.New("ErrParaNodeVoteSelf")
//ErrParaNodeGroupFrozenCoinsNotEnough node group coins in tx less than conf's minimum coins
ErrParaNodeGroupFrozenCoinsNotEnough = errors.New("ErrParaNodeGroupFrozenCoinsNotEnough")
//ErrParaNodeGroupStatusWrong node group process wrong status
ErrParaNodeGroupStatusWrong = errors.New("ErrParaNodeGroupStatusWrong")
//ErrParaNodeOpStatusWrong node process wrong status
ErrParaNodeOpStatusWrong = errors.New("ErrParaNodeOpStatusWrong")
//ErrParaConsensStopBlocksNotReach consensus stop blocks not reach
ErrParaConsensStopBlocksNotReach = errors.New("ErrParaConsensStopBlocksNotReach")
)
......@@ -41,6 +41,7 @@ const (
TyLogParaNodeVoteDone = 658
TyLogParaNodeGroupAddrsUpdate = 659
TyLogParaNodeGroupConfig = 660
TyLogParaNodeStatusUpdate = 661
TyLogParaNodeGroupStatusUpdate = 664
)
......@@ -92,6 +93,7 @@ const (
ParaNodeJoin = iota + 1
ParaNodeVote
ParaNodeQuit
ParaNodeCancel
)
// node vote op
......@@ -106,16 +108,24 @@ const (
var ParaNodeVoteStr = []string{"invalid", "yes", "no"}
const (
// ParacrossNodeJoining apply for adding group
ParacrossNodeJoining = iota + 1
// ParacrossNodeJoined pass to add by votes
ParacrossNodeJoined
// ParacrossNodeQuiting apply for quiting
ParacrossNodeQuiting
ParacrossNodeJoined = iota + 10
// ParacrossNodeQuited pass to quite by votes
ParacrossNodeQuited
)
//voting status
const (
// ParacrossNodeIDJoining apply for join group
ParacrossNodeJoining = iota + 1
// ParacrossNodeIDQuiting apply for quiting group
ParacrossNodeQuiting
// ParacrossNodeIDClosed id voting closed
ParacrossNodeClosed
// ParacrossNodeCanceled to cancel apply of joining or quiting
ParacrossNodeCanceled
)
const (
//ParacrossNodeGroupApply apply for para chain node group initially
ParacrossNodeGroupApply = iota + 1
......@@ -204,12 +214,7 @@ func CreateRawNodeConfigTx(config *ParaNodeAddrConfig) (*types.Transaction, erro
//CreateRawNodeGroupApplyTx create raw tx for node group
func CreateRawNodeGroupApplyTx(apply *ParaNodeGroupConfig) (*types.Transaction, error) {
apply.Title = types.GetTitle()
apply.EmptyBlockInterval = 4
apply.Id = strings.Trim(apply.Id, " ")
interval := types.Conf("config.consensus.sub.para").GInt("emptyBlockInterval")
if interval > 0 {
apply.EmptyBlockInterval = uint32(interval)
}
action := &ParacrossAction{
Ty: ParacrossActionNodeGroupApply,
......
......@@ -484,7 +484,11 @@ func (m *ParaNodeVoteDetail) GetVotes() []string {
}
type ParaNodeAddrIdStatus struct {
ProposalId string `protobuf:"bytes,1,opt,name=proposalId,proto3" json:"proposalId,omitempty"`
Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
ProposalId string `protobuf:"bytes,2,opt,name=proposalId,proto3" json:"proposalId,omitempty"`
QuitId string `protobuf:"bytes,3,opt,name=quitId,proto3" json:"quitId,omitempty"`
Status int32 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"`
Title string `protobuf:"bytes,5,opt,name=title,proto3" json:"title,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -515,6 +519,13 @@ func (m *ParaNodeAddrIdStatus) XXX_DiscardUnknown() {
var xxx_messageInfo_ParaNodeAddrIdStatus proto.InternalMessageInfo
func (m *ParaNodeAddrIdStatus) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
func (m *ParaNodeAddrIdStatus) GetProposalId() string {
if m != nil {
return m.ProposalId
......@@ -522,6 +533,27 @@ func (m *ParaNodeAddrIdStatus) GetProposalId() string {
return ""
}
func (m *ParaNodeAddrIdStatus) GetQuitId() string {
if m != nil {
return m.QuitId
}
return ""
}
func (m *ParaNodeAddrIdStatus) GetStatus() int32 {
if m != nil {
return m.Status
}
return 0
}
func (m *ParaNodeAddrIdStatus) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
type ParaNodeIdStatus struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
......@@ -680,6 +712,61 @@ func (m *ReceiptParaNodeConfig) GetCurrent() *ParaNodeIdStatus {
return nil
}
type ReceiptParaNodeAddrStatUpdate struct {
FromAddr string `protobuf:"bytes,1,opt,name=fromAddr,proto3" json:"fromAddr,omitempty"`
Prev *ParaNodeAddrIdStatus `protobuf:"bytes,2,opt,name=prev,proto3" json:"prev,omitempty"`
Current *ParaNodeAddrIdStatus `protobuf:"bytes,3,opt,name=current,proto3" json:"current,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReceiptParaNodeAddrStatUpdate) Reset() { *m = ReceiptParaNodeAddrStatUpdate{} }
func (m *ReceiptParaNodeAddrStatUpdate) String() string { return proto.CompactTextString(m) }
func (*ReceiptParaNodeAddrStatUpdate) ProtoMessage() {}
func (*ReceiptParaNodeAddrStatUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{10}
}
func (m *ReceiptParaNodeAddrStatUpdate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReceiptParaNodeAddrStatUpdate.Unmarshal(m, b)
}
func (m *ReceiptParaNodeAddrStatUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReceiptParaNodeAddrStatUpdate.Marshal(b, m, deterministic)
}
func (m *ReceiptParaNodeAddrStatUpdate) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReceiptParaNodeAddrStatUpdate.Merge(m, src)
}
func (m *ReceiptParaNodeAddrStatUpdate) XXX_Size() int {
return xxx_messageInfo_ReceiptParaNodeAddrStatUpdate.Size(m)
}
func (m *ReceiptParaNodeAddrStatUpdate) XXX_DiscardUnknown() {
xxx_messageInfo_ReceiptParaNodeAddrStatUpdate.DiscardUnknown(m)
}
var xxx_messageInfo_ReceiptParaNodeAddrStatUpdate proto.InternalMessageInfo
func (m *ReceiptParaNodeAddrStatUpdate) GetFromAddr() string {
if m != nil {
return m.FromAddr
}
return ""
}
func (m *ReceiptParaNodeAddrStatUpdate) GetPrev() *ParaNodeAddrIdStatus {
if m != nil {
return m.Prev
}
return nil
}
func (m *ReceiptParaNodeAddrStatUpdate) GetCurrent() *ParaNodeAddrIdStatus {
if m != nil {
return m.Current
}
return nil
}
type ReceiptParaNodeVoteDone struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
......@@ -698,7 +785,7 @@ func (m *ReceiptParaNodeVoteDone) Reset() { *m = ReceiptParaNodeVoteDone
func (m *ReceiptParaNodeVoteDone) String() string { return proto.CompactTextString(m) }
func (*ReceiptParaNodeVoteDone) ProtoMessage() {}
func (*ReceiptParaNodeVoteDone) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{10}
return fileDescriptor_6a397e38c9ea6747, []int{11}
}
func (m *ReceiptParaNodeVoteDone) XXX_Unmarshal(b []byte) error {
......@@ -781,7 +868,6 @@ type ParaNodeGroupConfig struct {
Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`
Addrs string `protobuf:"bytes,4,opt,name=addrs,proto3" json:"addrs,omitempty"`
CoinsFrozen int64 `protobuf:"varint,5,opt,name=coinsFrozen,proto3" json:"coinsFrozen,omitempty"`
EmptyBlockInterval uint32 `protobuf:"varint,6,opt,name=emptyBlockInterval,proto3" json:"emptyBlockInterval,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -791,7 +877,7 @@ func (m *ParaNodeGroupConfig) Reset() { *m = ParaNodeGroupConfig{} }
func (m *ParaNodeGroupConfig) String() string { return proto.CompactTextString(m) }
func (*ParaNodeGroupConfig) ProtoMessage() {}
func (*ParaNodeGroupConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{11}
return fileDescriptor_6a397e38c9ea6747, []int{12}
}
func (m *ParaNodeGroupConfig) XXX_Unmarshal(b []byte) error {
......@@ -847,23 +933,14 @@ func (m *ParaNodeGroupConfig) GetCoinsFrozen() int64 {
return 0
}
func (m *ParaNodeGroupConfig) GetEmptyBlockInterval() uint32 {
if m != nil {
return m.EmptyBlockInterval
}
return 0
}
type ParaNodeGroupStatus struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
TargetAddrs string `protobuf:"bytes,4,opt,name=targetAddrs,proto3" json:"targetAddrs,omitempty"`
CoinsFrozen int64 `protobuf:"varint,5,opt,name=coinsFrozen,proto3" json:"coinsFrozen,omitempty"`
EmptyBlockInterval uint32 `protobuf:"varint,6,opt,name=emptyBlockInterval,proto3" json:"emptyBlockInterval,omitempty"`
MainHeight int64 `protobuf:"varint,7,opt,name=mainHeight,proto3" json:"mainHeight,omitempty"`
FromAddr string `protobuf:"bytes,8,opt,name=fromAddr,proto3" json:"fromAddr,omitempty"`
Height int64 `protobuf:"varint,9,opt,name=height,proto3" json:"height,omitempty"`
FromAddr string `protobuf:"bytes,6,opt,name=fromAddr,proto3" json:"fromAddr,omitempty"`
Height int64 `protobuf:"varint,7,opt,name=height,proto3" json:"height,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -873,7 +950,7 @@ func (m *ParaNodeGroupStatus) Reset() { *m = ParaNodeGroupStatus{} }
func (m *ParaNodeGroupStatus) String() string { return proto.CompactTextString(m) }
func (*ParaNodeGroupStatus) ProtoMessage() {}
func (*ParaNodeGroupStatus) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{12}
return fileDescriptor_6a397e38c9ea6747, []int{13}
}
func (m *ParaNodeGroupStatus) XXX_Unmarshal(b []byte) error {
......@@ -929,20 +1006,6 @@ func (m *ParaNodeGroupStatus) GetCoinsFrozen() int64 {
return 0
}
func (m *ParaNodeGroupStatus) GetEmptyBlockInterval() uint32 {
if m != nil {
return m.EmptyBlockInterval
}
return 0
}
func (m *ParaNodeGroupStatus) GetMainHeight() int64 {
if m != nil {
return m.MainHeight
}
return 0
}
func (m *ParaNodeGroupStatus) GetFromAddr() string {
if m != nil {
return m.FromAddr
......@@ -971,7 +1034,7 @@ func (m *ReceiptParaNodeGroupConfig) Reset() { *m = ReceiptParaNodeGroup
func (m *ReceiptParaNodeGroupConfig) String() string { return proto.CompactTextString(m) }
func (*ReceiptParaNodeGroupConfig) ProtoMessage() {}
func (*ReceiptParaNodeGroupConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{13}
return fileDescriptor_6a397e38c9ea6747, []int{14}
}
func (m *ReceiptParaNodeGroupConfig) XXX_Unmarshal(b []byte) error {
......@@ -1035,7 +1098,7 @@ func (m *ReqParacrossNodeInfo) Reset() { *m = ReqParacrossNodeInfo{} }
func (m *ReqParacrossNodeInfo) String() string { return proto.CompactTextString(m) }
func (*ReqParacrossNodeInfo) ProtoMessage() {}
func (*ReqParacrossNodeInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{14}
return fileDescriptor_6a397e38c9ea6747, []int{15}
}
func (m *ReqParacrossNodeInfo) XXX_Unmarshal(b []byte) error {
......@@ -1095,7 +1158,7 @@ func (m *RespParacrossNodeAddrs) Reset() { *m = RespParacrossNodeAddrs{}
func (m *RespParacrossNodeAddrs) String() string { return proto.CompactTextString(m) }
func (*RespParacrossNodeAddrs) ProtoMessage() {}
func (*RespParacrossNodeAddrs) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{15}
return fileDescriptor_6a397e38c9ea6747, []int{16}
}
func (m *RespParacrossNodeAddrs) XXX_Unmarshal(b []byte) error {
......@@ -1134,7 +1197,7 @@ func (m *RespParacrossNodeGroups) Reset() { *m = RespParacrossNodeGroups
func (m *RespParacrossNodeGroups) String() string { return proto.CompactTextString(m) }
func (*RespParacrossNodeGroups) ProtoMessage() {}
func (*RespParacrossNodeGroups) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{16}
return fileDescriptor_6a397e38c9ea6747, []int{17}
}
func (m *RespParacrossNodeGroups) XXX_Unmarshal(b []byte) error {
......@@ -1176,7 +1239,7 @@ func (m *ParaBlock2MainMap) Reset() { *m = ParaBlock2MainMap{} }
func (m *ParaBlock2MainMap) String() string { return proto.CompactTextString(m) }
func (*ParaBlock2MainMap) ProtoMessage() {}
func (*ParaBlock2MainMap) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{17}
return fileDescriptor_6a397e38c9ea6747, []int{18}
}
func (m *ParaBlock2MainMap) XXX_Unmarshal(b []byte) error {
......@@ -1236,7 +1299,7 @@ func (m *ParaBlock2MainInfo) Reset() { *m = ParaBlock2MainInfo{} }
func (m *ParaBlock2MainInfo) String() string { return proto.CompactTextString(m) }
func (*ParaBlock2MainInfo) ProtoMessage() {}
func (*ParaBlock2MainInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{18}
return fileDescriptor_6a397e38c9ea6747, []int{19}
}
func (m *ParaBlock2MainInfo) XXX_Unmarshal(b []byte) error {
......@@ -1289,7 +1352,7 @@ func (m *ParacrossNodeStatus) Reset() { *m = ParacrossNodeStatus{} }
func (m *ParacrossNodeStatus) String() string { return proto.CompactTextString(m) }
func (*ParacrossNodeStatus) ProtoMessage() {}
func (*ParacrossNodeStatus) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{19}
return fileDescriptor_6a397e38c9ea6747, []int{20}
}
func (m *ParacrossNodeStatus) XXX_Unmarshal(b []byte) error {
......@@ -1419,7 +1482,7 @@ func (m *ParacrossCommitAction) Reset() { *m = ParacrossCommitAction{} }
func (m *ParacrossCommitAction) String() string { return proto.CompactTextString(m) }
func (*ParacrossCommitAction) ProtoMessage() {}
func (*ParacrossCommitAction) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{20}
return fileDescriptor_6a397e38c9ea6747, []int{21}
}
func (m *ParacrossCommitAction) XXX_Unmarshal(b []byte) error {
......@@ -1459,7 +1522,7 @@ func (m *ParacrossMinerAction) Reset() { *m = ParacrossMinerAction{} }
func (m *ParacrossMinerAction) String() string { return proto.CompactTextString(m) }
func (*ParacrossMinerAction) ProtoMessage() {}
func (*ParacrossMinerAction) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{21}
return fileDescriptor_6a397e38c9ea6747, []int{22}
}
func (m *ParacrossMinerAction) XXX_Unmarshal(b []byte) error {
......@@ -1516,7 +1579,7 @@ func (m *ParacrossAction) Reset() { *m = ParacrossAction{} }
func (m *ParacrossAction) String() string { return proto.CompactTextString(m) }
func (*ParacrossAction) ProtoMessage() {}
func (*ParacrossAction) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{22}
return fileDescriptor_6a397e38c9ea6747, []int{23}
}
func (m *ParacrossAction) XXX_Unmarshal(b []byte) error {
......@@ -1894,7 +1957,7 @@ func (m *ReceiptParacrossCommit) Reset() { *m = ReceiptParacrossCommit{}
func (m *ReceiptParacrossCommit) String() string { return proto.CompactTextString(m) }
func (*ReceiptParacrossCommit) ProtoMessage() {}
func (*ReceiptParacrossCommit) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{23}
return fileDescriptor_6a397e38c9ea6747, []int{24}
}
func (m *ReceiptParacrossCommit) XXX_Unmarshal(b []byte) error {
......@@ -1954,7 +2017,7 @@ func (m *ReceiptParacrossMiner) Reset() { *m = ReceiptParacrossMiner{} }
func (m *ReceiptParacrossMiner) String() string { return proto.CompactTextString(m) }
func (*ReceiptParacrossMiner) ProtoMessage() {}
func (*ReceiptParacrossMiner) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{24}
return fileDescriptor_6a397e38c9ea6747, []int{25}
}
func (m *ReceiptParacrossMiner) XXX_Unmarshal(b []byte) error {
......@@ -2000,7 +2063,7 @@ func (m *ReceiptParacrossDone) Reset() { *m = ReceiptParacrossDone{} }
func (m *ReceiptParacrossDone) String() string { return proto.CompactTextString(m) }
func (*ReceiptParacrossDone) ProtoMessage() {}
func (*ReceiptParacrossDone) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{25}
return fileDescriptor_6a397e38c9ea6747, []int{26}
}
func (m *ReceiptParacrossDone) XXX_Unmarshal(b []byte) error {
......@@ -2089,7 +2152,7 @@ func (m *ReceiptParacrossRecord) Reset() { *m = ReceiptParacrossRecord{}
func (m *ReceiptParacrossRecord) String() string { return proto.CompactTextString(m) }
func (*ReceiptParacrossRecord) ProtoMessage() {}
func (*ReceiptParacrossRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{26}
return fileDescriptor_6a397e38c9ea6747, []int{27}
}
func (m *ReceiptParacrossRecord) XXX_Unmarshal(b []byte) error {
......@@ -2137,7 +2200,7 @@ func (m *ParacrossTx) Reset() { *m = ParacrossTx{} }
func (m *ParacrossTx) String() string { return proto.CompactTextString(m) }
func (*ParacrossTx) ProtoMessage() {}
func (*ParacrossTx) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{27}
return fileDescriptor_6a397e38c9ea6747, []int{28}
}
func (m *ParacrossTx) XXX_Unmarshal(b []byte) error {
......@@ -2178,7 +2241,7 @@ func (m *ReqParacrossTitleHeight) Reset() { *m = ReqParacrossTitleHeight
func (m *ReqParacrossTitleHeight) String() string { return proto.CompactTextString(m) }
func (*ReqParacrossTitleHeight) ProtoMessage() {}
func (*ReqParacrossTitleHeight) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{28}
return fileDescriptor_6a397e38c9ea6747, []int{29}
}
func (m *ReqParacrossTitleHeight) XXX_Unmarshal(b []byte) error {
......@@ -2231,7 +2294,7 @@ func (m *RespParacrossDone) Reset() { *m = RespParacrossDone{} }
func (m *RespParacrossDone) String() string { return proto.CompactTextString(m) }
func (*RespParacrossDone) ProtoMessage() {}
func (*RespParacrossDone) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{29}
return fileDescriptor_6a397e38c9ea6747, []int{30}
}
func (m *RespParacrossDone) XXX_Unmarshal(b []byte) error {
......@@ -2319,7 +2382,7 @@ func (m *RespParacrossTitles) Reset() { *m = RespParacrossTitles{} }
func (m *RespParacrossTitles) String() string { return proto.CompactTextString(m) }
func (*RespParacrossTitles) ProtoMessage() {}
func (*RespParacrossTitles) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{30}
return fileDescriptor_6a397e38c9ea6747, []int{31}
}
func (m *RespParacrossTitles) XXX_Unmarshal(b []byte) error {
......@@ -2359,7 +2422,7 @@ func (m *ReqParacrossTitleHash) Reset() { *m = ReqParacrossTitleHash{} }
func (m *ReqParacrossTitleHash) String() string { return proto.CompactTextString(m) }
func (*ReqParacrossTitleHash) ProtoMessage() {}
func (*ReqParacrossTitleHash) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{31}
return fileDescriptor_6a397e38c9ea6747, []int{32}
}
func (m *ReqParacrossTitleHash) XXX_Unmarshal(b []byte) error {
......@@ -2419,7 +2482,7 @@ func (m *ParacrossAsset) Reset() { *m = ParacrossAsset{} }
func (m *ParacrossAsset) String() string { return proto.CompactTextString(m) }
func (*ParacrossAsset) ProtoMessage() {}
func (*ParacrossAsset) Descriptor() ([]byte, []int) {
return fileDescriptor_6a397e38c9ea6747, []int{32}
return fileDescriptor_6a397e38c9ea6747, []int{33}
}
func (m *ParacrossAsset) XXX_Unmarshal(b []byte) error {
......@@ -2528,6 +2591,7 @@ func init() {
proto.RegisterType((*ParaNodeAddrIdStatus)(nil), "types.ParaNodeAddrIdStatus")
proto.RegisterType((*ParaNodeIdStatus)(nil), "types.ParaNodeIdStatus")
proto.RegisterType((*ReceiptParaNodeConfig)(nil), "types.ReceiptParaNodeConfig")
proto.RegisterType((*ReceiptParaNodeAddrStatUpdate)(nil), "types.ReceiptParaNodeAddrStatUpdate")
proto.RegisterType((*ReceiptParaNodeVoteDone)(nil), "types.ReceiptParaNodeVoteDone")
proto.RegisterType((*ParaNodeGroupConfig)(nil), "types.ParaNodeGroupConfig")
proto.RegisterType((*ParaNodeGroupStatus)(nil), "types.ParaNodeGroupStatus")
......@@ -2556,119 +2620,121 @@ func init() {
func init() { proto.RegisterFile("paracross.proto", fileDescriptor_6a397e38c9ea6747) }
var fileDescriptor_6a397e38c9ea6747 = []byte{
// 1788 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0xcd, 0x6f, 0x23, 0x4b,
0x11, 0xf7, 0xf8, 0xdb, 0x95, 0xd8, 0x49, 0xfa, 0x6d, 0xb2, 0xc6, 0x3c, 0xf2, 0xac, 0xd1, 0x03,
0x05, 0x58, 0x05, 0x5e, 0x16, 0x2d, 0x42, 0x4f, 0x08, 0xf6, 0xe5, 0xed, 0xc6, 0xd1, 0x7e, 0x68,
0xd5, 0x09, 0x70, 0x42, 0x62, 0xd6, 0xee, 0xc4, 0x23, 0xec, 0x99, 0xd9, 0xe9, 0xf6, 0x6e, 0xc2,
0x0d, 0x09, 0xfe, 0x05, 0x24, 0xc4, 0x95, 0x33, 0x17, 0xee, 0xfc, 0x01, 0x70, 0xe3, 0x3f, 0xe0,
0xc6, 0x9d, 0x03, 0x57, 0x54, 0xd5, 0x3d, 0x33, 0xdd, 0xe3, 0x0f, 0x56, 0x4b, 0x2e, 0xdc, 0x5c,
0xd5, 0xd5, 0x55, 0x5d, 0xbf, 0xfa, 0x1c, 0xc3, 0x4e, 0x12, 0xa4, 0xc1, 0x38, 0x8d, 0xa5, 0x3c,
0x4e, 0xd2, 0x58, 0xc5, 0xac, 0xa1, 0x6e, 0x13, 0x21, 0x07, 0x7b, 0x2a, 0x0d, 0x22, 0x19, 0x8c,
0x55, 0x18, 0x47, 0xfa, 0x64, 0xb0, 0x3d, 0x8e, 0xe7, 0xf3, 0x9c, 0xda, 0x7d, 0x3d, 0x8b, 0xc7,
0xbf, 0x1c, 0x4f, 0x83, 0x30, 0xe3, 0xf4, 0xc4, 0x8d, 0x18, 0x2f, 0x54, 0x9c, 0x6a, 0xda, 0x7f,
0x0e, 0x07, 0xaf, 0x32, 0xe5, 0x17, 0x2a, 0x50, 0x0b, 0xf9, 0xa5, 0x50, 0x41, 0x38, 0x93, 0xec,
0x1e, 0x34, 0x82, 0xc9, 0x24, 0x95, 0x7d, 0x6f, 0x58, 0x3b, 0xea, 0x70, 0x4d, 0xb0, 0x8f, 0xa1,
0x43, 0x3a, 0x47, 0x81, 0x9c, 0xf6, 0xab, 0xc3, 0xda, 0xd1, 0x36, 0x2f, 0x18, 0xfe, 0xdf, 0x3d,
0xd8, 0xcf, 0xd5, 0x8d, 0x44, 0x78, 0x3d, 0x55, 0x5a, 0x29, 0x3b, 0x80, 0xa6, 0xa4, 0x5f, 0x7d,
0x6f, 0xe8, 0x1d, 0x35, 0xb8, 0xa1, 0xd0, 0x8a, 0x0a, 0xd5, 0x4c, 0xf4, 0xab, 0x43, 0x0f, 0xad,
0x10, 0x81, 0xd2, 0x53, 0xba, 0xdd, 0xaf, 0x0d, 0xbd, 0xa3, 0x1a, 0x37, 0x14, 0xfb, 0x3e, 0xb4,
0x26, 0xfa, 0x79, 0xfd, 0xfa, 0xd0, 0x3b, 0xda, 0x3a, 0xf9, 0xda, 0x31, 0x21, 0x71, 0xbc, 0xda,
0x07, 0x9e, 0x49, 0xb3, 0x43, 0x80, 0x79, 0x10, 0x46, 0xfa, 0x49, 0xfd, 0x06, 0x29, 0xb5, 0x38,
0x6c, 0x00, 0x6d, 0xa2, 0xd0, 0xab, 0xe6, 0xd0, 0x3b, 0xda, 0xe6, 0x39, 0xed, 0xff, 0xd3, 0x83,
0xfe, 0x4a, 0xa7, 0xb8, 0x4c, 0xee, 0xc8, 0x2f, 0xf7, 0x79, 0xf5, 0x8d, 0xcf, 0x6b, 0x90, 0xc2,
0x9c, 0x66, 0x43, 0xd8, 0xc2, 0x98, 0x87, 0xea, 0x31, 0x45, 0xab, 0x49, 0xd1, 0xb2, 0x59, 0xec,
0x08, 0x76, 0x34, 0xf9, 0x45, 0x1e, 0xb9, 0x16, 0x49, 0x95, 0xd9, 0xfe, 0xcf, 0x61, 0xa7, 0x84,
0x64, 0xe1, 0x88, 0xb7, 0xda, 0x91, 0xaa, 0xe3, 0x88, 0x93, 0x1e, 0x35, 0x02, 0xd2, 0x4a, 0x8f,
0x3f, 0xda, 0x48, 0x9e, 0xc6, 0x91, 0x14, 0x91, 0x5c, 0x6c, 0x36, 0x84, 0xde, 0x4d, 0x0b, 0x68,
0xb4, 0x35, 0x9b, 0xc5, 0x3e, 0x85, 0xee, 0x58, 0xab, 0x1a, 0xd9, 0xd0, 0xba, 0x4c, 0xf6, 0x2d,
0xd8, 0x35, 0x8c, 0x02, 0x84, 0x3a, 0x19, 0x5a, 0xe2, 0xfb, 0xbf, 0xf3, 0x80, 0xe1, 0x33, 0x5f,
0xc6, 0x13, 0x81, 0x08, 0x9e, 0xc6, 0xd1, 0x55, 0x78, 0xbd, 0xe6, 0x81, 0x3d, 0xa8, 0xc6, 0x09,
0xbd, 0xab, 0xcb, 0xab, 0x71, 0x82, 0x74, 0x38, 0xa1, 0x37, 0x74, 0x78, 0x35, 0x9c, 0x30, 0x06,
0x75, 0xac, 0x1c, 0x63, 0x8c, 0x7e, 0xa3, 0xa6, 0xb7, 0xc1, 0x6c, 0x21, 0x28, 0x96, 0x5d, 0xae,
0x09, 0x1d, 0xc8, 0x30, 0x92, 0x4f, 0xd3, 0xf8, 0x57, 0x22, 0xa2, 0x34, 0x44, 0x57, 0x0b, 0x96,
0xff, 0xe3, 0xe2, 0x5d, 0x3f, 0x8d, 0x95, 0xd0, 0x59, 0xbe, 0xa6, 0x50, 0xd1, 0x46, 0xac, 0x84,
0xa4, 0x22, 0xed, 0x70, 0x4d, 0xf8, 0x8f, 0xe0, 0x9e, 0xed, 0xd9, 0xf9, 0xc4, 0x80, 0x7f, 0x08,
0x90, 0xa4, 0x71, 0x12, 0xcb, 0x60, 0x76, 0x3e, 0x31, 0x0e, 0x5a, 0x1c, 0xff, 0xdf, 0x1e, 0xec,
0x66, 0x17, 0xf3, 0x4b, 0xda, 0x55, 0x2f, 0x77, 0xb5, 0xa8, 0x85, 0xea, 0xea, 0x5a, 0xa8, 0xd9,
0xc0, 0x1d, 0x02, 0xa8, 0x20, 0xbd, 0x16, 0x94, 0xa4, 0x06, 0x1e, 0x8b, 0x53, 0x86, 0xa3, 0xb1,
0x04, 0x07, 0xfb, 0x4e, 0xe6, 0x62, 0x93, 0x7a, 0xc1, 0x57, 0xac, 0x5e, 0xe0, 0x42, 0x64, 0xbc,
0xc7, 0x32, 0xba, 0x4a, 0xe3, 0x39, 0x19, 0x6c, 0xe9, 0x32, 0xca, 0x68, 0x2b, 0xa3, 0xdb, 0x76,
0x46, 0xfb, 0x7f, 0xf1, 0x60, 0x9f, 0x8b, 0xb1, 0x08, 0x13, 0x95, 0x29, 0x36, 0xf9, 0x90, 0x45,
0xd6, 0xb3, 0x22, 0xfb, 0x19, 0x34, 0xc7, 0x74, 0x4a, 0x10, 0x2c, 0xbf, 0xa9, 0x48, 0x27, 0x6e,
0x04, 0xd9, 0xb7, 0xa1, 0x9e, 0xa4, 0xe2, 0x2d, 0x81, 0xb3, 0x75, 0x72, 0xbf, 0x74, 0x21, 0x03,
0x9b, 0x93, 0x10, 0xfb, 0x0c, 0x5a, 0xe3, 0x45, 0x9a, 0x8a, 0x48, 0x99, 0x06, 0xb8, 0x56, 0x3e,
0x93, 0xf3, 0xff, 0xe5, 0xc1, 0xfd, 0x92, 0x03, 0x84, 0x4c, 0x1c, 0x89, 0xa5, 0x08, 0xae, 0xee,
0x5a, 0x6e, 0xa4, 0x6a, 0x4b, 0x91, 0xc2, 0xf3, 0x58, 0x05, 0x33, 0x54, 0xad, 0x1b, 0x73, 0x83,
0x5b, 0x1c, 0x6c, 0x0a, 0x44, 0xa1, 0x59, 0x8a, 0x63, 0x83, 0x17, 0x0c, 0xea, 0x6d, 0xb1, 0x54,
0x74, 0xd8, 0xa4, 0xc3, 0x9c, 0x66, 0x7d, 0x68, 0x61, 0xe4, 0xb8, 0x54, 0x26, 0x5e, 0x19, 0x89,
0x36, 0x27, 0x71, 0x24, 0xb4, 0xb3, 0x14, 0xb2, 0x06, 0xb7, 0x38, 0xfe, 0x9f, 0x3d, 0xf8, 0x28,
0x73, 0xf7, 0x2c, 0x8d, 0x17, 0xc9, 0xff, 0x54, 0xc4, 0x79, 0x89, 0xe9, 0x34, 0x35, 0x25, 0xf6,
0xdf, 0x33, 0xf4, 0x18, 0x98, 0x98, 0x27, 0xea, 0x96, 0x7a, 0xcb, 0x79, 0xa4, 0x44, 0xfa, 0x36,
0x98, 0x91, 0x97, 0x5d, 0xbe, 0xe2, 0xc4, 0xff, 0x43, 0xb5, 0xf4, 0xea, 0x3b, 0xa9, 0xb4, 0x21,
0x6c, 0x15, 0xd1, 0xca, 0x7c, 0xb0, 0x59, 0x77, 0xef, 0x49, 0x69, 0xa2, 0xb5, 0x56, 0x4d, 0xb4,
0xbc, 0x14, 0xdb, 0x6b, 0x4b, 0xb1, 0xe3, 0x94, 0xe2, 0x5f, 0x3d, 0x18, 0x94, 0x32, 0xd9, 0x0e,
0xed, 0xaa, 0x7a, 0x3c, 0x29, 0xd5, 0xe3, 0xa0, 0x54, 0x2e, 0xd6, 0xfd, 0xbc, 0x20, 0x8f, 0x9d,
0x82, 0x5c, 0x79, 0xc3, 0xa9, 0xc9, 0xef, 0x95, 0x6b, 0x72, 0xd3, 0x95, 0xbc, 0x2c, 0xa7, 0x70,
0x8f, 0x8b, 0x37, 0xf9, 0x34, 0xa4, 0xda, 0x8d, 0xae, 0xe2, 0xf5, 0x09, 0x1a, 0x4e, 0x4c, 0x55,
0xda, 0x53, 0xa5, 0x66, 0xf9, 0x5a, 0x24, 0x45, 0xdd, 0x4e, 0x0a, 0xff, 0x14, 0x0e, 0xb8, 0x90,
0x89, 0x63, 0x4a, 0x87, 0xfd, 0x9b, 0x50, 0x0b, 0x27, 0x7a, 0x6e, 0x6c, 0xe8, 0x24, 0x28, 0xe3,
0x9f, 0x61, 0x13, 0x29, 0x29, 0x21, 0xbf, 0x24, 0x7b, 0x60, 0x6b, 0xd9, 0xe4, 0x3b, 0x29, 0xfa,
0xad, 0x07, 0x7b, 0x78, 0x48, 0xe9, 0x72, 0xf2, 0x22, 0x08, 0xa3, 0x17, 0x41, 0x62, 0x85, 0xdc,
0x5b, 0xbf, 0x4f, 0x68, 0xf7, 0x0b, 0x46, 0x29, 0xc9, 0x6a, 0x1b, 0xd7, 0xa6, 0xba, 0xbb, 0x36,
0xf9, 0x5f, 0xea, 0x59, 0x5a, 0x3c, 0x83, 0xd0, 0x3f, 0x86, 0x46, 0xa8, 0xc4, 0x3c, 0xf3, 0xa6,
0x6f, 0x79, 0xe3, 0x3c, 0x98, 0x6b, 0x31, 0xff, 0x1f, 0x35, 0x5d, 0xb0, 0x39, 0x26, 0xa6, 0x60,
0x3f, 0x85, 0x2e, 0x5a, 0x2a, 0x76, 0x0d, 0x8f, 0x76, 0x21, 0x97, 0x89, 0x8b, 0x59, 0xc1, 0xb0,
0x17, 0x9c, 0x32, 0x7b, 0x4d, 0x61, 0x17, 0xa8, 0xd5, 0x1d, 0xd4, 0x7c, 0xd8, 0x4e, 0x52, 0x51,
0x18, 0x6f, 0x90, 0x71, 0x87, 0xe7, 0x22, 0xdb, 0x2c, 0x6d, 0x6a, 0x46, 0x03, 0x3a, 0x23, 0xcc,
0xbe, 0x98, 0x69, 0xc8, 0x79, 0xa8, 0x41, 0xe6, 0x02, 0x6d, 0xad, 0x21, 0x67, 0x20, 0xf6, 0xea,
0xe6, 0x34, 0x5e, 0x44, 0x4a, 0x52, 0x19, 0x77, 0x79, 0x4e, 0xeb, 0x33, 0x2e, 0xe4, 0x62, 0xa6,
0xfa, 0xa0, 0xb7, 0xed, 0x8c, 0xc6, 0x96, 0xaf, 0x6e, 0x50, 0x83, 0xec, 0x6f, 0xd1, 0xe7, 0x45,
0x46, 0xd2, 0xa2, 0x87, 0x30, 0x5f, 0x66, 0x57, 0xb7, 0x35, 0xa6, 0x0e, 0x13, 0x5f, 0x6e, 0x18,
0x5a, 0x49, 0x97, 0x94, 0x38, 0x3c, 0xf6, 0x00, 0xf6, 0xa2, 0x38, 0x3a, 0xa5, 0xe5, 0xf7, 0x32,
0x7b, 0x64, 0x8f, 0x1e, 0xb9, 0x7c, 0xe0, 0x3f, 0xb3, 0xbe, 0x69, 0xf4, 0xd1, 0x63, 0xfa, 0xe2,
0xc2, 0xe6, 0x62, 0xed, 0xfe, 0x6e, 0xee, 0x97, 0x12, 0x22, 0x2f, 0x46, 0xa5, 0x17, 0x30, 0x3a,
0x7e, 0x11, 0x46, 0x22, 0xfd, 0x70, 0x5d, 0x98, 0x3e, 0xa1, 0xbc, 0x10, 0xb3, 0xab, 0x7c, 0x95,
0xa6, 0xf4, 0x69, 0xf3, 0x32, 0xdb, 0xff, 0x5b, 0xdd, 0x5a, 0xec, 0x8d, 0xc5, 0x47, 0xd8, 0x1a,
0xd1, 0x1b, 0x63, 0xf1, 0xe3, 0xb2, 0x45, 0xdb, 0xd7, 0x51, 0x85, 0x1b, 0x69, 0xf6, 0x10, 0x1a,
0x73, 0x7c, 0xb8, 0xe9, 0x8f, 0x5f, 0x2d, 0x5f, 0xb3, 0xbc, 0x1a, 0x55, 0xb8, 0x96, 0x65, 0x3f,
0x84, 0x6e, 0x20, 0xa5, 0x50, 0x97, 0xf8, 0xc1, 0x7a, 0x25, 0x52, 0xd3, 0x29, 0xf7, 0xcd, 0xe5,
0xc7, 0x78, 0x26, 0xb3, 0xc3, 0x51, 0x85, 0xbb, 0xd2, 0xf9, 0xf5, 0x9f, 0x85, 0x6a, 0x3a, 0x49,
0x83, 0x77, 0x94, 0xd1, 0xe5, 0xeb, 0xd9, 0x61, 0x7e, 0x3d, 0x63, 0xb0, 0x87, 0xd0, 0x56, 0x99,
0xe1, 0xe6, 0x66, 0xc3, 0xb9, 0x20, 0x5e, 0x7a, 0x97, 0x99, 0x6b, 0x6d, 0x36, 0x97, 0x0b, 0xb2,
0x27, 0xd0, 0xcb, 0x14, 0x5c, 0xc6, 0x4f, 0x6e, 0xc4, 0x98, 0x0a, 0xa3, 0x40, 0xc9, 0xb5, 0xa7,
0x45, 0x46, 0x15, 0x5e, 0xba, 0xc4, 0x3e, 0x07, 0x88, 0xf2, 0x45, 0x93, 0xca, 0x67, 0xd3, 0x2a,
0x39, 0xaa, 0x70, 0x4b, 0x9c, 0x3d, 0x85, 0x9d, 0xc8, 0x1d, 0x6d, 0x54, 0x64, 0x1b, 0x87, 0xdf,
0xa8, 0xc2, 0xcb, 0x97, 0x70, 0xe6, 0xa8, 0x5b, 0xb3, 0x60, 0x54, 0xd5, 0xed, 0x17, 0x2d, 0xf3,
0xd5, 0x82, 0x73, 0xf8, 0xc0, 0x9a, 0xc3, 0x56, 0xb2, 0xac, 0x9b, 0xc1, 0xd6, 0xb2, 0xf2, 0x7e,
0xa9, 0xfd, 0x5d, 0x67, 0x06, 0x2f, 0xa5, 0xa6, 0xf3, 0x15, 0xae, 0xa7, 0xf0, 0xa3, 0xf2, 0x14,
0xde, 0x7c, 0x29, 0x9f, 0xc3, 0xcf, 0x9c, 0xf5, 0xbe, 0xc8, 0xe0, 0x0f, 0xaa, 0xee, 0xdf, 0x54,
0x71, 0xaa, 0xbb, 0xda, 0x68, 0xd1, 0x76, 0x57, 0x64, 0x6f, 0x69, 0x45, 0xc6, 0x15, 0x0d, 0x29,
0x0d, 0xa3, 0x01, 0xdd, 0x66, 0xb1, 0x6f, 0x40, 0x0f, 0xd7, 0xe2, 0x8b, 0x60, 0x2e, 0x8c, 0x50,
0x8d, 0x84, 0x4a, 0xdc, 0x62, 0x52, 0xd4, 0x57, 0x4f, 0x8a, 0x46, 0x79, 0xbe, 0x16, 0x3d, 0xbc,
0xb9, 0xa9, 0x87, 0xb7, 0x36, 0xf4, 0xf0, 0xb6, 0xdb, 0xc3, 0xfd, 0x5f, 0x2c, 0xe7, 0x07, 0x17,
0xe3, 0x38, 0x9d, 0xdc, 0x55, 0x7e, 0xf8, 0x5f, 0x87, 0xad, 0xfc, 0xf8, 0xf2, 0x06, 0xdd, 0xd3,
0x53, 0xc2, 0x28, 0x36, 0x94, 0xde, 0x5a, 0x8a, 0x25, 0xeb, 0x12, 0xb1, 0x28, 0x4f, 0xd4, 0xf7,
0xf9, 0x5f, 0xc3, 0xff, 0x75, 0x15, 0xf6, 0x9c, 0xfd, 0xe7, 0xff, 0x2b, 0xaa, 0x9d, 0x0f, 0x8d,
0x6a, 0xc7, 0x8a, 0xea, 0x19, 0x7c, 0xe4, 0x40, 0x40, 0x68, 0x62, 0xa9, 0x36, 0xe9, 0x35, 0xe5,
0x9d, 0x69, 0x09, 0x2e, 0x6e, 0xe4, 0x74, 0xc9, 0x95, 0xa3, 0x82, 0x2f, 0x5b, 0x1d, 0x93, 0xa5,
0x1d, 0xd0, 0xf9, 0x4f, 0xe9, 0x4f, 0x55, 0xe8, 0x15, 0xa3, 0x0d, 0xdb, 0x2b, 0x26, 0x19, 0x7e,
0x4b, 0x64, 0x49, 0x86, 0xbf, 0xa9, 0x99, 0xc5, 0xd9, 0x02, 0xad, 0x62, 0x0c, 0x5d, 0x98, 0xb7,
0x70, 0x02, 0xbd, 0xcd, 0x2d, 0x8e, 0x95, 0x51, 0x75, 0xb2, 0x68, 0x28, 0xe4, 0x07, 0x73, 0xc4,
0x2a, 0x83, 0x5c, 0x53, 0x68, 0x53, 0x60, 0xbb, 0xd7, 0x68, 0xd3, 0x6f, 0x5a, 0xc8, 0x6f, 0xe7,
0xaf, 0xe3, 0x99, 0xf9, 0x78, 0x35, 0x94, 0x15, 0x36, 0x70, 0xc2, 0x46, 0xff, 0x51, 0x61, 0xb8,
0x11, 0x2d, 0xb3, 0x0f, 0xee, 0x93, 0xc4, 0x12, 0x9f, 0xfe, 0xb0, 0x09, 0xd2, 0xc0, 0x48, 0x1d,
0xe8, 0xd5, 0xb7, 0xe0, 0xe0, 0x1a, 0x25, 0x17, 0xe3, 0xb1, 0x90, 0xb2, 0x7f, 0x9f, 0x9c, 0xcb,
0xc8, 0x93, 0xdf, 0xd7, 0xa0, 0x93, 0xff, 0x9f, 0xcc, 0x7e, 0x04, 0xed, 0x33, 0xa1, 0x28, 0x04,
0x6c, 0x37, 0x8f, 0xdc, 0x9b, 0x0b, 0x95, 0x86, 0xd1, 0xf5, 0xe0, 0x93, 0xe5, 0x9d, 0xc0, 0xf9,
0xd3, 0xce, 0xaf, 0xb0, 0x1f, 0x00, 0x3c, 0x0f, 0xa5, 0x32, 0xc9, 0xd0, 0x2d, 0x54, 0xbc, 0x0c,
0x67, 0x83, 0xc1, 0xaa, 0x5c, 0xd0, 0xa2, 0x7e, 0x85, 0xbd, 0x02, 0x76, 0x26, 0xc8, 0x29, 0xbb,
0x30, 0x0f, 0x0b, 0x15, 0xab, 0x0a, 0x77, 0xb0, 0x36, 0xbf, 0xfc, 0x0a, 0xbb, 0x80, 0x5e, 0xe6,
0xcd, 0x7b, 0x6a, 0xfb, 0x64, 0xe3, 0x94, 0x90, 0x89, 0x5f, 0x61, 0x9f, 0xc3, 0xee, 0x99, 0x50,
0x94, 0x5a, 0xf9, 0x96, 0xd9, 0x2b, 0xd4, 0x62, 0x5a, 0x0c, 0xf6, 0xcb, 0x6a, 0x48, 0xdc, 0xaf,
0xb0, 0x07, 0xd0, 0x3c, 0x97, 0x17, 0xb7, 0xd1, 0xb8, 0x0c, 0xcd, 0x9e, 0x21, 0xcf, 0xe5, 0x69,
0xb0, 0xb8, 0x9e, 0xaa, 0x9f, 0x24, 0x7e, 0xe5, 0x75, 0x93, 0xfe, 0x94, 0x7f, 0xf8, 0x9f, 0x00,
0x00, 0x00, 0xff, 0xff, 0xd3, 0xee, 0x12, 0x0b, 0xf1, 0x17, 0x00, 0x00,
// 1819 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xcd, 0x6f, 0x24, 0x47,
0x15, 0x9f, 0x9e, 0x4f, 0xcf, 0xb3, 0x3d, 0x6b, 0x57, 0xd6, 0xde, 0x61, 0x48, 0x36, 0xa3, 0x56,
0x40, 0x06, 0x56, 0x0e, 0xf1, 0x42, 0x10, 0x8a, 0x10, 0x6c, 0x9c, 0xc4, 0x63, 0x25, 0x1b, 0x45,
0x6d, 0x07, 0x4e, 0x48, 0xf4, 0xce, 0x94, 0x3d, 0x2d, 0x66, 0xba, 0x7b, 0xbb, 0x6a, 0x12, 0x9b,
0x1b, 0x02, 0xee, 0x9c, 0x90, 0x38, 0xc3, 0x99, 0x3f, 0x81, 0x3f, 0x80, 0xdc, 0xf8, 0x0f, 0xb8,
0x71, 0xe7, 0xc0, 0x15, 0xbd, 0x57, 0x55, 0xdd, 0x55, 0x35, 0x1f, 0x6b, 0x2d, 0x7b, 0xc9, 0xcd,
0xef, 0xd5, 0xab, 0xf7, 0xf1, 0xab, 0xf7, 0xd5, 0x63, 0xb8, 0x97, 0xc7, 0x45, 0x3c, 0x2e, 0x32,
0x21, 0x8e, 0xf3, 0x22, 0x93, 0x19, 0x6b, 0xc9, 0xdb, 0x9c, 0x8b, 0xc1, 0xbe, 0x2c, 0xe2, 0x54,
0xc4, 0x63, 0x99, 0x64, 0xa9, 0x3a, 0x19, 0xec, 0x8c, 0xb3, 0xf9, 0xbc, 0xa4, 0xf6, 0x9e, 0xcd,
0xb2, 0xf1, 0xaf, 0xc7, 0xd3, 0x38, 0x31, 0x9c, 0x1e, 0xbf, 0xe1, 0xe3, 0x85, 0xcc, 0x0a, 0x45,
0x87, 0x9f, 0xc0, 0xe1, 0x67, 0x46, 0xf9, 0x85, 0x8c, 0xe5, 0x42, 0x7c, 0xc0, 0x65, 0x9c, 0xcc,
0x04, 0xbb, 0x0f, 0xad, 0x78, 0x32, 0x29, 0x44, 0x3f, 0x18, 0x36, 0x8e, 0xba, 0x91, 0x22, 0xd8,
0xeb, 0xd0, 0x25, 0x9d, 0xa3, 0x58, 0x4c, 0xfb, 0xf5, 0x61, 0xe3, 0x68, 0x27, 0xaa, 0x18, 0xe1,
0x3f, 0x03, 0x38, 0x28, 0xd5, 0x8d, 0x78, 0x72, 0x3d, 0x95, 0x4a, 0x29, 0x3b, 0x84, 0xb6, 0xa0,
0xbf, 0xfa, 0xc1, 0x30, 0x38, 0x6a, 0x45, 0x9a, 0x42, 0x2b, 0x32, 0x91, 0x33, 0xde, 0xaf, 0x0f,
0x03, 0xb4, 0x42, 0x04, 0x4a, 0x4f, 0xe9, 0x76, 0xbf, 0x31, 0x0c, 0x8e, 0x1a, 0x91, 0xa6, 0xd8,
0x8f, 0xa0, 0x33, 0x51, 0xee, 0xf5, 0x9b, 0xc3, 0xe0, 0x68, 0xfb, 0xe4, 0x8d, 0x63, 0x42, 0xe2,
0x78, 0x75, 0x0c, 0x91, 0x91, 0x66, 0x0f, 0x01, 0xe6, 0x71, 0x92, 0x2a, 0x97, 0xfa, 0x2d, 0x52,
0x6a, 0x71, 0xd8, 0x00, 0xb6, 0x88, 0xc2, 0xa8, 0xda, 0xc3, 0xe0, 0x68, 0x27, 0x2a, 0xe9, 0xf0,
0xdf, 0x01, 0xf4, 0x57, 0x06, 0x15, 0x89, 0xfc, 0x15, 0xc5, 0xe5, 0xba, 0xd7, 0xdc, 0xe8, 0x5e,
0x8b, 0x14, 0x96, 0x34, 0x1b, 0xc2, 0x36, 0xbe, 0x79, 0x22, 0x9f, 0xd0, 0x6b, 0xb5, 0xe9, 0xb5,
0x6c, 0x16, 0x3b, 0x82, 0x7b, 0x8a, 0x7c, 0xbf, 0x7c, 0xb9, 0x0e, 0x49, 0xf9, 0xec, 0xf0, 0x97,
0x70, 0xcf, 0x43, 0xb2, 0x0a, 0x24, 0x58, 0x1d, 0x48, 0xdd, 0x09, 0xc4, 0x49, 0x8f, 0x06, 0x01,
0x69, 0xa5, 0xc7, 0x5f, 0x6d, 0x24, 0x4f, 0xb3, 0x54, 0xf0, 0x54, 0x2c, 0x36, 0x1b, 0xc2, 0xe8,
0xa6, 0x15, 0x34, 0xca, 0x9a, 0xcd, 0x62, 0x6f, 0xc1, 0xee, 0x58, 0xa9, 0x1a, 0xd9, 0xd0, 0xba,
0x4c, 0xf6, 0x5d, 0xd8, 0xd3, 0x8c, 0x0a, 0x84, 0x26, 0x19, 0x5a, 0xe2, 0x87, 0x7f, 0x0a, 0x80,
0xa1, 0x9b, 0x9f, 0x66, 0x13, 0x8e, 0x08, 0x9e, 0x66, 0xe9, 0x55, 0x72, 0xbd, 0xc6, 0xc1, 0x1e,
0xd4, 0xb3, 0x9c, 0xfc, 0xda, 0x8d, 0xea, 0x59, 0x8e, 0x74, 0x32, 0x21, 0x1f, 0xba, 0x51, 0x3d,
0x99, 0x30, 0x06, 0x4d, 0xac, 0x1c, 0x6d, 0x8c, 0xfe, 0x46, 0x4d, 0x5f, 0xc4, 0xb3, 0x05, 0xa7,
0xb7, 0xdc, 0x8d, 0x14, 0xa1, 0x1e, 0x32, 0x49, 0xc5, 0x47, 0x45, 0xf6, 0x1b, 0x9e, 0x52, 0x1a,
0x62, 0xa8, 0x15, 0x2b, 0xfc, 0x59, 0xe5, 0xd7, 0xcf, 0x33, 0xc9, 0x55, 0x96, 0xaf, 0x29, 0x54,
0xb4, 0x91, 0x49, 0x2e, 0xa8, 0x48, 0xbb, 0x91, 0x22, 0xc2, 0x3f, 0x06, 0x70, 0xdf, 0x0e, 0xed,
0x7c, 0xa2, 0xd1, 0x37, 0x6e, 0x06, 0x96, 0x9b, 0x0f, 0x01, 0xf2, 0x22, 0xcb, 0x33, 0x11, 0xcf,
0xce, 0x27, 0x3a, 0x91, 0x2d, 0x0e, 0x26, 0xc1, 0xf3, 0x45, 0x22, 0xcf, 0x4d, 0xb8, 0x9a, 0xb2,
0x6a, 0xa2, 0xb9, 0xba, 0x26, 0x5a, 0x16, 0x80, 0xe1, 0x7f, 0x03, 0xd8, 0x33, 0x2e, 0x95, 0xee,
0x28, 0x14, 0x83, 0x12, 0xc5, 0x4a, 0x65, 0x7d, 0xb5, 0xca, 0x86, 0xfd, 0x26, 0x0f, 0x01, 0x64,
0x5c, 0x5c, 0x73, 0xca, 0x7f, 0x8d, 0xbc, 0xc5, 0xf1, 0x91, 0x6e, 0x2d, 0x21, 0xcd, 0xde, 0x36,
0xe8, 0xb5, 0xa9, 0xcd, 0x7c, 0xc3, 0x6a, 0x33, 0x2e, 0xfa, 0x1a, 0x58, 0xac, 0xd0, 0xab, 0x22,
0x9b, 0x93, 0xc1, 0x8e, 0xaa, 0x50, 0x43, 0x5b, 0xc5, 0xb2, 0x65, 0x17, 0x4b, 0xf8, 0xf7, 0x00,
0x0e, 0x22, 0x3e, 0xe6, 0x49, 0x2e, 0x8d, 0x62, 0x9d, 0x6a, 0xab, 0x5e, 0xe3, 0x1d, 0x68, 0x8f,
0xe9, 0x94, 0x20, 0x58, 0xf6, 0xa9, 0xca, 0xd4, 0x48, 0x0b, 0xb2, 0xef, 0x41, 0x33, 0x2f, 0xf8,
0x17, 0x04, 0xce, 0xf6, 0xc9, 0x03, 0xef, 0x82, 0x01, 0x3b, 0x22, 0x21, 0xf6, 0x0e, 0x74, 0xc6,
0x8b, 0xa2, 0xe0, 0xa9, 0xd4, 0xbd, 0x75, 0xad, 0xbc, 0x91, 0x0b, 0xff, 0x12, 0xc0, 0x1b, 0x5e,
0x00, 0xe8, 0x05, 0x8a, 0x7d, 0x9e, 0x4f, 0x62, 0xc9, 0x1d, 0x58, 0x02, 0x0f, 0x96, 0xb7, 0xb5,
0x77, 0x2a, 0x9c, 0x6f, 0xae, 0x08, 0xc7, 0xf3, 0xf0, 0x87, 0x95, 0x87, 0x8d, 0x17, 0xdf, 0x29,
0xbd, 0xfc, 0x4f, 0x00, 0x0f, 0x3c, 0x2f, 0xe9, 0xfd, 0xb2, 0x94, 0x2f, 0xe5, 0xd9, 0xea, 0xb6,
0xed, 0xe6, 0x53, 0x63, 0x29, 0x9f, 0xf0, 0x3c, 0x93, 0xf1, 0x0c, 0x55, 0x9b, 0xa4, 0xb7, 0x38,
0xd8, 0x15, 0x89, 0x42, 0xb3, 0x94, 0x6d, 0xad, 0xa8, 0x62, 0x50, 0x73, 0xcf, 0x84, 0xa4, 0xc3,
0x36, 0x1d, 0x96, 0x34, 0xeb, 0x43, 0x07, 0xf3, 0x2b, 0x12, 0x52, 0x67, 0x95, 0x21, 0xd1, 0xe6,
0x24, 0x4b, 0xb9, 0x0a, 0x96, 0x12, 0xab, 0x15, 0x59, 0x9c, 0xf0, 0x77, 0x01, 0xbc, 0x66, 0xc2,
0x3d, 0x2b, 0xb2, 0x45, 0xfe, 0x7f, 0x75, 0xb1, 0xb2, 0xc7, 0xa8, 0x62, 0xd2, 0x3d, 0xe6, 0x85,
0x75, 0x14, 0x7e, 0xe5, 0x7b, 0xf1, 0x4a, 0xea, 0x7b, 0x08, 0xdb, 0x15, 0xfa, 0xc6, 0x27, 0x9b,
0x75, 0x87, 0x0a, 0xb7, 0x33, 0xb3, 0xbd, 0xb6, 0x60, 0x3b, 0x4e, 0xc1, 0xfe, 0x23, 0x80, 0x81,
0x97, 0x49, 0x36, 0xb4, 0xab, 0xaa, 0xf6, 0xc4, 0xab, 0xda, 0x81, 0x97, 0xb2, 0xd6, 0xfd, 0xb2,
0x6c, 0x8f, 0x9d, 0xb2, 0x5d, 0x79, 0xc3, 0xa9, 0x8b, 0x1f, 0xf8, 0x95, 0xbb, 0xe9, 0x4a, 0x59,
0x16, 0x53, 0xb8, 0x1f, 0xf1, 0xe7, 0xe5, 0x38, 0xa6, 0x0a, 0x4f, 0xaf, 0xb2, 0xf5, 0x09, 0x92,
0x98, 0x19, 0x60, 0x8f, 0xb5, 0x86, 0x15, 0xeb, 0x9a, 0xbe, 0x1f, 0x9e, 0xc2, 0x61, 0xc4, 0x45,
0xee, 0x98, 0x52, 0xcf, 0xf4, 0x1d, 0x68, 0x24, 0x13, 0x35, 0xb8, 0x36, 0xf4, 0x1b, 0x94, 0x09,
0xcf, 0xb0, 0x88, 0x3d, 0x25, 0x14, 0x97, 0x60, 0x8f, 0x6c, 0x2d, 0x9b, 0x62, 0x27, 0x45, 0x7f,
0x08, 0x60, 0x1f, 0x0f, 0x69, 0xde, 0x9f, 0x3c, 0x8d, 0x93, 0xf4, 0x69, 0x9c, 0x5b, 0x4f, 0x1e,
0xac, 0x5f, 0x68, 0x54, 0xf8, 0x15, 0xc3, 0xdb, 0xdb, 0x1a, 0x1b, 0xf7, 0xb6, 0xa6, 0xbb, 0xb7,
0x85, 0x1f, 0xa8, 0x61, 0x5e, 0xb9, 0x41, 0xe8, 0x1f, 0x43, 0x2b, 0x91, 0x7c, 0x6e, 0xa2, 0xe9,
0x5b, 0xd1, 0x38, 0x0e, 0x47, 0x4a, 0x2c, 0xfc, 0x57, 0x43, 0x15, 0x58, 0x89, 0x89, 0x2e, 0xb0,
0xb7, 0x60, 0x17, 0x2d, 0x55, 0xcb, 0x4e, 0x40, 0xcb, 0x98, 0xcb, 0xc4, 0xcd, 0xb0, 0x62, 0xd8,
0x1b, 0x96, 0xcf, 0x5e, 0x53, 0x88, 0x15, 0x6a, 0x4d, 0x07, 0xb5, 0x10, 0x76, 0xf2, 0x82, 0x57,
0xc6, 0x5b, 0x64, 0xdc, 0xe1, 0xb9, 0xc8, 0xb6, 0xbd, 0x55, 0x51, 0x6b, 0xc0, 0x60, 0xb8, 0x5e,
0x58, 0x8d, 0x86, 0x92, 0x87, 0x1a, 0x44, 0x29, 0xb0, 0xa5, 0x34, 0x94, 0x0c, 0xc4, 0x5e, 0xde,
0x9c, 0x66, 0x8b, 0x54, 0x8a, 0x7e, 0x97, 0x1a, 0x5b, 0x49, 0xab, 0xb3, 0x88, 0x8b, 0xc5, 0x4c,
0xf6, 0x41, 0xad, 0xfb, 0x86, 0xc6, 0x96, 0x2b, 0x6f, 0x50, 0x83, 0xe8, 0x6f, 0xd3, 0xf7, 0x8d,
0x21, 0x69, 0xd3, 0x44, 0x98, 0x2f, 0xcd, 0xd5, 0x1d, 0x85, 0xa9, 0xc3, 0x44, 0xcf, 0x35, 0x43,
0x29, 0xd9, 0x25, 0x25, 0x0e, 0x8f, 0x3d, 0x82, 0xfd, 0x34, 0x4b, 0x4f, 0x69, 0xfb, 0xbe, 0x34,
0x4e, 0xf6, 0xc8, 0xc9, 0xe5, 0x83, 0xf0, 0x63, 0xeb, 0xa3, 0x4a, 0x1d, 0x3d, 0xa1, 0x4f, 0x3e,
0x6c, 0x2e, 0xd6, 0xc7, 0x87, 0x9b, 0xfb, 0x5e, 0x42, 0x94, 0xc5, 0x28, 0xd5, 0x02, 0x48, 0xc7,
0x4f, 0x93, 0x94, 0x17, 0x2f, 0xaf, 0x0b, 0xd3, 0x27, 0x11, 0x17, 0x7c, 0x76, 0x55, 0xee, 0xf2,
0x94, 0x3e, 0x5b, 0x91, 0xcf, 0x0e, 0xbf, 0x6a, 0x5a, 0x5f, 0x16, 0xda, 0xe2, 0xbb, 0xd8, 0x1a,
0x31, 0x1a, 0x6d, 0xf1, 0x75, 0xdf, 0xa2, 0x1d, 0xeb, 0xa8, 0x16, 0x69, 0x69, 0xf6, 0x18, 0x5a,
0x73, 0x74, 0x7c, 0xc5, 0x12, 0xe0, 0x47, 0x35, 0xaa, 0x45, 0x4a, 0x96, 0xfd, 0x04, 0x76, 0x63,
0x21, 0xb8, 0xbc, 0xc4, 0x2f, 0xe6, 0x2b, 0x5e, 0xe8, 0x4e, 0x79, 0xa0, 0x2f, 0x3f, 0xc1, 0x33,
0x61, 0x0e, 0x47, 0xb5, 0xc8, 0x95, 0x2e, 0xaf, 0xff, 0x22, 0x91, 0xd3, 0x49, 0x11, 0x7f, 0x49,
0x19, 0xed, 0x5f, 0x37, 0x87, 0xe5, 0x75, 0xc3, 0x60, 0x8f, 0x61, 0x4b, 0x1a, 0xc3, 0xed, 0xcd,
0x86, 0x4b, 0x41, 0xbc, 0xf4, 0xa5, 0x31, 0xd7, 0xd9, 0x6c, 0xae, 0x14, 0x64, 0x1f, 0x42, 0xcf,
0x28, 0xb8, 0xcc, 0x3e, 0xbc, 0xe1, 0x63, 0x2a, 0x8c, 0x0a, 0x25, 0xd7, 0x9e, 0x12, 0x19, 0xd5,
0x22, 0xef, 0x12, 0x7b, 0x0f, 0x20, 0x2d, 0xd7, 0x51, 0x2a, 0x9f, 0x4d, 0x0b, 0xe7, 0xa8, 0x16,
0x59, 0xe2, 0xec, 0x23, 0xb8, 0x97, 0xba, 0xa3, 0x8d, 0x8a, 0x6c, 0xe3, 0xf0, 0x1b, 0xd5, 0x22,
0xff, 0x12, 0xce, 0x1c, 0x79, 0xab, 0x17, 0x82, 0xba, 0xbc, 0x7d, 0xbf, 0xa3, 0x3f, 0x9b, 0x70,
0x0e, 0x1f, 0x5a, 0x73, 0xd8, 0x4a, 0x96, 0x75, 0x33, 0xd8, 0x5a, 0x2e, 0xee, 0x96, 0xda, 0xdf,
0x77, 0x66, 0xf0, 0x52, 0x6a, 0x3a, 0x3f, 0x03, 0xa8, 0x29, 0xfc, 0xae, 0x3f, 0x85, 0x37, 0x5f,
0x2a, 0xe7, 0xf0, 0xc7, 0xce, 0x47, 0x40, 0x95, 0xc1, 0x2f, 0x55, 0xdd, 0xbf, 0xaf, 0xe3, 0x54,
0x77, 0xb5, 0xd1, 0xa2, 0xeb, 0xae, 0xa8, 0xc1, 0xd2, 0x8a, 0x8a, 0x2b, 0x15, 0x52, 0x0a, 0x46,
0x0d, 0xba, 0xcd, 0x62, 0xdf, 0x86, 0x1e, 0xae, 0xa5, 0x17, 0xf1, 0x9c, 0x6b, 0xa1, 0x06, 0x09,
0x79, 0xdc, 0x6a, 0x52, 0x34, 0x57, 0x4f, 0x8a, 0x96, 0x3f, 0x5f, 0xab, 0x1e, 0xde, 0xde, 0xd4,
0xc3, 0x3b, 0x1b, 0x7a, 0xf8, 0x96, 0xdb, 0xc3, 0xc3, 0x5f, 0x2d, 0xe7, 0x47, 0xc4, 0xc7, 0x59,
0x31, 0x79, 0x55, 0xf9, 0x11, 0x7e, 0x0b, 0xb6, 0xcb, 0xe3, 0xcb, 0x1b, 0x0c, 0x4f, 0x4d, 0x09,
0xad, 0x58, 0x53, 0x6a, 0x6b, 0xa9, 0x96, 0xac, 0x4b, 0xc4, 0xc2, 0x9f, 0xa8, 0x77, 0xf9, 0x61,
0x25, 0xfc, 0x6d, 0x1d, 0xf6, 0x9d, 0xfd, 0xe7, 0xeb, 0xf5, 0xaa, 0xdd, 0x97, 0x7d, 0xd5, 0xae,
0xf5, 0xaa, 0x67, 0xf0, 0x9a, 0x03, 0x01, 0xa1, 0x89, 0xa5, 0xda, 0x26, 0x6f, 0xfc, 0x9d, 0x69,
0x09, 0xae, 0x48, 0xcb, 0xa9, 0x92, 0xf3, 0x5f, 0x05, 0x3d, 0x5b, 0xfd, 0x26, 0x4b, 0x3b, 0xa0,
0xf3, 0xa3, 0xd6, 0xdf, 0xea, 0xd0, 0xab, 0x46, 0x1b, 0xb6, 0x57, 0x4c, 0x32, 0xfc, 0x96, 0x30,
0x49, 0x86, 0x7f, 0x53, 0x33, 0xcb, 0xcc, 0x02, 0x2d, 0x33, 0x7c, 0xba, 0xa4, 0x6c, 0xe1, 0x04,
0xfa, 0x56, 0x64, 0x71, 0xac, 0x8c, 0x6a, 0x92, 0x45, 0x4d, 0x21, 0x3f, 0x9e, 0x23, 0x56, 0x06,
0x72, 0x45, 0xa1, 0x4d, 0x8e, 0xed, 0x5e, 0xa1, 0x4d, 0x7f, 0xd3, 0x42, 0x7e, 0x3b, 0x7f, 0x96,
0xcd, 0xf4, 0xc7, 0xa3, 0xa6, 0xac, 0x67, 0x03, 0xe7, 0xd9, 0xe8, 0x47, 0x32, 0x7c, 0x6e, 0x44,
0x4b, 0xef, 0x83, 0x07, 0x24, 0xb1, 0xc4, 0xa7, 0x1f, 0x87, 0xe2, 0x22, 0xd6, 0x52, 0x87, 0x6a,
0xf5, 0xad, 0x38, 0xb8, 0x46, 0x89, 0xc5, 0x78, 0xcc, 0x85, 0xe8, 0x3f, 0xa0, 0xe0, 0x0c, 0x79,
0xf2, 0xe7, 0x06, 0x74, 0xcb, 0x1f, 0xb4, 0xd9, 0x4f, 0x61, 0xeb, 0x8c, 0x4b, 0x7a, 0x02, 0xb6,
0x57, 0xbe, 0xdc, 0xf3, 0x0b, 0x59, 0x24, 0xe9, 0xf5, 0xe0, 0xcd, 0xe5, 0x9d, 0xc0, 0xf9, 0xd5,
0x30, 0xac, 0xb1, 0x1f, 0x03, 0x7c, 0x92, 0x08, 0xa9, 0x93, 0x61, 0xb7, 0x52, 0xf1, 0x69, 0x32,
0x1b, 0x0c, 0x56, 0xe5, 0x82, 0x12, 0x0d, 0x6b, 0xec, 0x33, 0x60, 0x67, 0x9c, 0x82, 0xb2, 0x0b,
0xf3, 0x61, 0xa5, 0x62, 0x55, 0xe1, 0x0e, 0xd6, 0xe6, 0x57, 0x58, 0x63, 0x17, 0xd0, 0x33, 0xd1,
0xdc, 0x51, 0xdb, 0x9b, 0x1b, 0xa7, 0x84, 0xc8, 0xc3, 0x1a, 0x7b, 0x0f, 0xf6, 0xce, 0xb8, 0xa4,
0xd4, 0x2a, 0xb7, 0xcc, 0x5e, 0xa5, 0x16, 0xd3, 0x62, 0x70, 0xe0, 0xab, 0x21, 0xf1, 0xb0, 0xc6,
0x1e, 0x41, 0xfb, 0x5c, 0x5c, 0xdc, 0xa6, 0x63, 0x1f, 0x9a, 0x7d, 0x4d, 0x9e, 0x8b, 0xd3, 0x78,
0x71, 0x3d, 0x95, 0x9f, 0xe7, 0x61, 0xed, 0x59, 0x9b, 0xfe, 0x2b, 0xf0, 0xf8, 0x7f, 0x01, 0x00,
0x00, 0xff, 0xff, 0xed, 0xd7, 0xdd, 0x61, 0x72, 0x18, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
......
......@@ -62,6 +62,7 @@ func (p *ParacrossType) GetLogMap() map[int64]*types.LogInfo {
TyLogParaAssetDeposit: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetDeposit"},
TyLogParacrossMiner: {Ty: reflect.TypeOf(ReceiptParacrossMiner{}), Name: "LogParacrossMiner"},
TyLogParaNodeConfig: {Ty: reflect.TypeOf(ReceiptParaNodeConfig{}), Name: "LogParaNodeConfig"},
TyLogParaNodeStatusUpdate: {Ty: reflect.TypeOf(ReceiptParaNodeAddrStatUpdate{}), Name: "LogParaNodeAddrStatUpdate"},
TyLogParaNodeGroupAddrsUpdate: {Ty: reflect.TypeOf(types.ReceiptConfig{}), Name: "LogParaNodeGroupAddrsUpdate"},
TyLogParaNodeVoteDone: {Ty: reflect.TypeOf(ReceiptParaNodeVoteDone{}), Name: "LogParaNodeVoteDone"},
TyLogParaNodeGroupConfig: {Ty: reflect.TypeOf(ReceiptParaNodeGroupConfig{}), Name: "LogParaNodeGroupConfig"},
......
#!/usr/bin/env bash
# shellcheck disable=SC2128
MAIN_HTTP=""
CASE_ERR=""
#color
RED='\033[1;31m'
GRE='\033[1;32m'
NOC='\033[0m'
# base functions
# $2=0 means true, other false
function echo_rst() {
if [ "$2" -eq 0 ]; then
echo -e "${GRE}$1 ok${NOC}"
else
echo -e "${RED}$1 fail${NOC}"
CASE_ERR="err"
fi
}
function Chain33_SendToAddress() {
local from="$1"
local to="$2"
local amount=$3
local req='{"method":"Chain33.SendToAddress", "params":[{"from":"'"$from"'","to":"'"$to"'", "amount":'"$amount"', "note":"test\n"}]}'
# echo "#request: $req"
resp=$(curl -ksd "$req" "${MAIN_HTTP}")
# echo "#response: $resp"
ok=$(jq '(.error|not) and (.result.hash|length==66)' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
hash=$(jq '(.result.hash)' <<<"$resp")
echo "hash=$hash"
# query_tx "$hash"
}
# shellcheck source=/dev/null
source ../dapp-test-common.sh
function sign_raw_tx() {
txHex="$1"
priKey="$2"
req='{"method":"Chain33.SignRawTx","params":[{"privkey":"'"$priKey"'","txHex":"'"$txHex"'","expire":"120s"}]}'
# echo "#request SignRawTx: $req"
signedTx=$(curl -ksd "$req" ${MAIN_HTTP} | jq -r ".result")
# echo "signedTx=$signedTx"
if [ "$signedTx" != null ]; then
send_tx "$signedTx"
else
echo "signedTx null error"
fi
}
function send_tx() {
signedTx=$1
req='{"method":"Chain33.SendTransaction","params":[{"token":"BTY","data":"'"$signedTx"'"}]}'
# echo "#request sendTx: $req"
# curl -ksd "$req" ${MAIN_HTTP}
resp=$(curl -ksd "$req" ${MAIN_HTTP})
err=$(jq '(.error)' <<<"$resp")
txhash=$(jq -r ".result" <<<"$resp")
if [ "$err" == null ]; then
# echo "tx hash: $txhash"
query_tx "$txhash"
else
echo "send tx error:$err"
fi
}
function block_wait() {
req='{"method":"Chain33.GetLastHeader","params":[{}]}'
cur_height=$(curl -ksd "$req" ${MAIN_HTTP} | jq ".result.height")
expect=$((cur_height + ${1}))
local count=0
while true; do
new_height=$(curl -ksd "$req" ${MAIN_HTTP} | jq ".result.height")
if [ "${new_height}" -ge "${expect}" ]; then
break
fi
count=$((count + 1))
sleep 1
done
echo "wait new block $count s, cur height=$expect,old=$cur_height"
}
function query_tx() {
block_wait 1
txhash="$1"
# echo "req=$req"
local times=10
while true; do
req='{"method":"Chain33.QueryTransaction","params":[{"hash":"'"$txhash"'"}]}'
ret=$(curl -ksd "$req" ${MAIN_HTTP})
tx=$(jq -r ".result.tx.hash" <<<"$ret")
echo "====query tx= ${1}, return=$ret "
if [ "${tx}" != "${1}" ]; then
block_wait 1
times=$((times - 1))
if [ $times -le 0 ]; then
echo "====query tx=$1 failed"
echo "req=$req"
curl -ksd "$req" ${MAIN_HTTP}
exit 1
fi
else
exec_err=$(jq '(.result.receipt.logs[0].tyName == "LogErr")' <<<"$ret")
[ "$exec_err" != true ]
echo "====query tx=$1 success"
break
fi
done
}
MAIN_HTTP=""
txhash=""
function query_unfreezeID() {
block_wait 1
chain33_BlockWait 1 "$MAIN_HTTP"
# echo "req=$req"
local times=10
......@@ -161,8 +55,8 @@ function init() {
owner_key=CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944
#unfreeze_exec_addr=15YsqAuXeEXVHgm6RVx4oJaAAnhtwqnu3H
Chain33_SendToAddress "$owner" "$exec_addr" 500000000
Chain33_SendToAddress "$beneficiary" "$exec_addr" 500000000
Chain33_SendToAddress "$owner" "$exec_addr" 500000000 "${MAIN_HTTP}"
Chain33_SendToAddress "$beneficiary" "$exec_addr" 500000000 "${MAIN_HTTP}"
block_wait 1
}
......@@ -175,7 +69,7 @@ function CreateRawUnfreezeCreate() {
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
sign_raw_tx "$rawtx" "$owner_key"
chain33_SignRawTx "$rawtx" "$owner_key" "${MAIN_HTTP}"
query_unfreezeID
}
......@@ -189,8 +83,9 @@ function CreateRawUnfreezeWithdraw() {
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
sign_raw_tx "$rawtx" "${beneficiary_key}"
chain33_SignRawTx "$rawtx" "${beneficiary_key}" "${MAIN_HTTP}"
}
function CreateRawUnfreezeTerminate() {
req='{"method":"unfreeze.CreateRawUnfreezeTerminate","params":[{"unfreezeID":"'${uid}'"}]}'
# echo "#request: $req"
......@@ -200,7 +95,7 @@ function CreateRawUnfreezeTerminate() {
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
sign_raw_tx "$rawtx" "$owner_key"
chain33_SignRawTx "$rawtx" "$owner_key" "${MAIN_HTTP}"
block_wait 2
}
......
......@@ -58,6 +58,6 @@ matrix:
- sudo mv docker-compose /usr/local/bin
script:
- make build_ci
- make autotest_ci
- make autotest dapp=all
- make docker-compose && make docker-compose-down
......@@ -49,14 +49,6 @@ function config_chain33() {
else
sed -i $sedfix '/^Title/a TestNet=true' ${chain33Config}
fi
#update fee
sed -i $sedfix 's/Fee=.*/Fee=100000/' ${chain33Config}
#update block time
#update wallet store driver
sed -i $sedfix '/^\[wallet\]/,/^\[wallet./ s/^driver.*/driver="leveldb"/' ${chain33Config}
}
function config_autotest() {
......
......@@ -40,12 +40,10 @@ function config_chain33() {
fi
#update fee
sed -i $sedfix 's/Fee=.*/Fee=100000/' ${chain33Config}
#update block time
# sed -i $sedfix 's/Fee=.*/Fee=100000/' ${chain33Config}
#update wallet store driver
sed -i $sedfix '/^\[wallet\]/,/^\[wallet./ s/^driver.*/driver="leveldb"/' ${chain33Config}
# sed -i $sedfix '/^\[wallet\]/,/^\[wallet./ s/^driver.*/driver="leveldb"/' ${chain33Config}
}
autotestConfig="autotest.toml"
......
......@@ -138,13 +138,17 @@ chain33_GetHeaders() {
chain33_GetLastMemPool() {
if [ "$IS_PARA" == true ]; then
echo_rst "$FUNCNAME" 2
else
req='"method":"Chain33.GetLastMemPool", "params":[{}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "$1")
# echo "#response: $resp"
#echo "#response: $resp"
ok=$(jq '(.error|not) and (.result.txs|length >= 0)' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
fi
}
chain33_GetProperFee() {
......@@ -394,11 +398,16 @@ chain33_GetTxByHashes() {
}
chain33_GetMempool() {
if [ "$IS_PARA" == true ]; then
echo_rst "$FUNCNAME" 2
else
resp=$(curl -ksd '{"jsonrpc":"2.0","id":2,"method":"Chain33.GetMempool","params":[{}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.txs|length >= 0)' <<<"$resp")
[ "$ok" == true ]
rst=$?
echo_rst "$FUNCNAME" "$rst"
fi
}
chain33_GetAccountsV2() {
......
......@@ -54,6 +54,8 @@ dbPath="datadir/addrbook"
dbCache=4
# GRPC请求日志文件
grpcLogFile="grpc33.log"
#waitPid 等待seed导入
waitPid=false
[rpc]
# jrpc绑定地址
......
......@@ -53,6 +53,8 @@ grpcLogFile="grpc33.log"
version=216
verMix=216
verMax=217
#waitPid 等待seed导入
waitPid=false
[rpc]
jrpcBindAddr="localhost:8801"
......@@ -69,6 +71,7 @@ name="timeline"
poolCacheSize=10240
minTxFee=100000
maxTxNumPerAccount=100
isLevelFee=false
[mempool.sub.timeline]
poolCacheSize=10240
......@@ -163,6 +166,7 @@ minerwhitelist=["*"]
[exec]
isFree=false
minExecFee=100000
maxExecFee=1000000000
enableStat=false
enableMVCC=false
......
Title="chain33"
TestNet=true
FixTime=false
# 配置主币的名称: 比特元链bty, 部分未配置的平行链需要配置为 bty, 新的平行链配置 para或其他, 不配置panic
CoinSymbol="bty"
[log]
......@@ -77,6 +78,8 @@ dbPath="datadir/addrbook"
dbCache=4
# GRPC请求日志文件
grpcLogFile="grpc33.log"
#waitPid 等待seed导入
waitPid=false
[rpc]
# jrpc绑定地址
......@@ -105,7 +108,10 @@ poolCacheSize=10240
minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=100
# 最大得交易手续费用,这个没有默认值,必填,一般是100000
maxTxFee=1000000000
# 是否开启阶梯手续费
isLevelFee=false
[mempool.sub.timeline]
# mempool缓存容量大小,默认10240
......
......@@ -243,15 +243,7 @@ func (a *AddrBook) genPubkey(privkey string) string {
func (a *AddrBook) loadDb() bool {
a.bookDb = db.NewDB("addrbook", a.cfg.Driver, a.cfg.DbPath, a.cfg.DbCache)
privkey, err := a.bookDb.Get([]byte(privKeyTag))
if len(privkey) == 0 || err != nil {
a.initKey()
privkey, _ := a.GetPrivPubKey()
err := a.bookDb.Set([]byte(privKeyTag), []byte(privkey))
if err != nil {
panic(err)
}
} else {
if len(privkey) != 0 && err == nil {
a.setKey(string(privkey), a.genPubkey(string(privkey)))
}
......@@ -393,10 +385,12 @@ func (a *AddrBook) setKey(privkey, pubkey string) {
//ResetPeerkey reset priv,pub key
func (a *AddrBook) ResetPeerkey(privkey, pubkey string) {
a.keymtx.Lock()
defer a.keymtx.Unlock()
a.privkey = privkey
a.pubkey = pubkey
if privkey == "" || pubkey == "" {
a.initKey()
privkey, pubkey = a.GetPrivPubKey()
}
a.setKey(privkey, pubkey)
err := a.bookDb.Set([]byte(privKeyTag), []byte(privkey))
if err != nil {
panic(err)
......
......@@ -34,12 +34,6 @@ const (
maxSamIPNum = 20
)
var (
// LocalAddr local address
LocalAddr string
//defaultPort = 13802
)
const (
defalutNatPort = 23802
maxOutBoundNum = 25
......
......@@ -147,6 +147,7 @@ func (d *DownloadJob) GetFreePeer(blockHeight int64) *Peer {
var jobNum int32 = 10
var bestPeer *Peer
for _, peer := range d.downloadPeers {
pbpeer, ok := infos[peer.Addr()]
if ok {
if len(peer.GetPeerName()) == 0 {
......@@ -194,6 +195,7 @@ func (d *DownloadJob) DownloadBlock(invs []*pb.Inventory,
REGET:
freePeer := d.GetFreePeer(inv.GetHeight()) //获取当前任务数最少的节点,相当于 下载速度最快的节点
if freePeer == nil {
log.Debug("no free peer")
time.Sleep(time.Millisecond * 100)
goto REGET
}
......
......@@ -123,7 +123,8 @@ func (n *Node) flushNodePort(localport, export uint16) {
n.nodeInfo.SetExternalAddr(exaddr)
n.nodeInfo.addrBook.AddOurAddress(exaddr)
}
if listenAddr, err := NewNetAddressString(fmt.Sprintf("%v:%v", LocalAddr, localport)); err == nil {
if listenAddr, err := NewNetAddressString(fmt.Sprintf("%v:%v", n.nodeInfo.GetListenAddr().IP.String(), localport)); err == nil {
n.nodeInfo.SetListenAddr(listenAddr)
n.nodeInfo.addrBook.AddOurAddress(listenAddr)
}
......@@ -354,9 +355,9 @@ func (n *Node) detectNodeAddr() {
for {
cfg := n.nodeInfo.cfg
laddr := P2pComm.GetLocalAddr()
LocalAddr = laddr
//LocalAddr = laddr
log.Info("DetectNodeAddr", "addr:", laddr)
if len(LocalAddr) == 0 {
if laddr == "" {
log.Error("DetectNodeAddr", "NetWork Disable p2p Disable", "Retry until Network enable")
time.Sleep(time.Second * 5)
continue
......
......@@ -34,6 +34,7 @@ type P2p struct {
txFactory chan struct{}
otherFactory chan struct{}
waitRestart chan struct{}
closed int32
restart int32
cfg *types.P2P
......@@ -96,15 +97,15 @@ func (network *P2p) isRestart() bool {
// Close network client
func (network *P2p) Close() {
log.Info("p2p network start shutdown")
atomic.StoreInt32(&network.closed, 1)
log.Debug("close", "network", "ShowTaskCapcity done")
network.node.Close()
log.Debug("close", "node", "done")
if network.client != nil {
if !network.isRestart() {
network.client.Close()
}
}
network.node.pubsub.Shutdown()
......@@ -126,25 +127,74 @@ func (network *P2p) SetQueueClient(cli queue.Client) {
go func(p2p *P2p) {
p2p.node.Start()
if p2p.isRestart() {
//reset
p2p.node.Start()
atomic.StoreInt32(&p2p.closed, 0)
atomic.StoreInt32(&p2p.restart, 0)
network.waitRestart <- struct{}{}
} else {
return
}
p2p.subP2pMsg()
go p2p.loadP2PPrivKeyToWallet()
key, pub := p2p.node.nodeInfo.addrBook.GetPrivPubKey()
log.Debug("key pub:", pub, "")
if key == "" {
if p2p.cfg.WaitPid { //key为空,则为初始钱包,阻塞模式,一直等到钱包导入助记词,解锁
if p2p.genAirDropKeyFromWallet() != nil {
return
}
} else {
//创建随机Pid,会同时出现node award ,airdropaddr
p2p.node.nodeInfo.addrBook.ResetPeerkey(key, pub)
go p2p.genAirDropKeyFromWallet()
}
} else {
//key 有两种可能,老版本的随机key,也有可能是seed的key, 非阻塞模式
go p2p.genAirDropKeyFromWallet()
}
p2p.node.Start()
log.Debug("SetQueueClient gorountine ret")
}(network)
}
func (network *P2p) loadP2PPrivKeyToWallet() error {
var parm types.ReqWalletImportPrivkey
parm.Privkey, _ = network.node.nodeInfo.addrBook.GetPrivPubKey()
parm.Label = "node award"
ReTry:
msg := network.client.NewMessage("wallet", types.EventWalletImportPrivkey, &parm)
err := network.client.SendTimeout(msg, true, time.Minute)
if err != nil {
log.Error("ImportPrivkey", "Error", err.Error())
return err
}
resp, err := network.client.WaitTimeout(msg, time.Minute)
if err != nil {
if err == types.ErrPrivkeyExist {
return nil
}
if err == types.ErrLabelHasUsed {
//切换随机lable
parm.Label = fmt.Sprintf("node award %v", P2pComm.RandStr(3))
time.Sleep(time.Second)
goto ReTry
}
log.Error("loadP2PPrivKeyToWallet", "err", err.Error())
return err
}
log.Debug("loadP2PPrivKeyToWallet", "resp", resp.GetData())
return nil
}
func (network *P2p) showTaskCapcity() {
ticker := time.NewTicker(time.Second * 5)
log.Info("ShowTaskCapcity", "Capcity", atomic.LoadInt32(&network.txCapcity))
......@@ -160,10 +210,11 @@ func (network *P2p) showTaskCapcity() {
}
func (network *P2p) genAirDropKeyFromWallet() error {
_, savePub := network.node.nodeInfo.addrBook.GetPrivPubKey()
for {
if network.isClose() {
return nil
log.Error("genAirDropKeyFromWallet", "p2p closed", "")
return fmt.Errorf("p2p closed")
}
msg := network.client.NewMessage("wallet", types.EventGetWalletStatus, nil)
err := network.client.SendTimeout(msg, true, time.Minute)
......@@ -179,12 +230,20 @@ func (network *P2p) genAirDropKeyFromWallet() error {
continue
}
if resp.GetData().(*types.WalletStatus).GetIsWalletLock() { //上锁
if savePub == "" {
log.Warn("P2P Stuck ! Wallet must be unlock and save with mnemonics")
}
time.Sleep(time.Second)
continue
}
if !resp.GetData().(*types.WalletStatus).GetIsHasSeed() { //无种子
time.Sleep(time.Second)
if savePub == "" {
log.Warn("P2P Stuck ! Wallet must be imported with mnemonics")
}
time.Sleep(time.Second * 5)
continue
}
......@@ -208,7 +267,6 @@ func (network *P2p) genAirDropKeyFromWallet() error {
} else {
hexPrivkey = reply.GetData()
}
log.Info("genAirDropKeyFromWallet", "hexprivkey", hexPrivkey)
if hexPrivkey[:2] == "0x" {
hexPrivkey = hexPrivkey[2:]
}
......@@ -221,19 +279,30 @@ func (network *P2p) genAirDropKeyFromWallet() error {
log.Info("genAirDropKeyFromWallet", "pubkey", hexPubkey)
_, pub := network.node.nodeInfo.addrBook.GetPrivPubKey()
if pub == hexPubkey {
if savePub == hexPubkey {
return nil
}
//覆盖addrbook 中的公私钥对
if savePub != "" {
//priv,pub是随机公私钥对,兼容老版本,先对其进行导入钱包处理
err = network.loadP2PPrivKeyToWallet()
if err != nil {
log.Error("genAirDropKeyFromWallet", "loadP2PPrivKeyToWallet error", err)
panic(err)
}
network.node.nodeInfo.addrBook.ResetPeerkey(hexPrivkey, hexPubkey)
//重启p2p模块
log.Info("genAirDropKeyFromWallet", "p2p will Restart....")
network.ReStart()
return nil
}
//覆盖addrbook 中的公私钥对
network.node.nodeInfo.addrBook.ResetPeerkey(hexPrivkey, hexPubkey)
return nil
}
// ReStart p2p
//ReStart p2p
func (network *P2p) ReStart() {
atomic.StoreInt32(&network.restart, 1)
network.Close()
......@@ -246,67 +315,6 @@ func (network *P2p) ReStart() {
network.SetQueueClient(network.client)
}
func (network *P2p) loadP2PPrivKeyToWallet() error {
for {
if network.isClose() {
return nil
}
msg := network.client.NewMessage("wallet", types.EventGetWalletStatus, nil)
err := network.client.SendTimeout(msg, true, time.Minute)
if err != nil {
log.Error("GetWalletStatus", "Error", err.Error())
time.Sleep(time.Second)
continue
}
resp, err := network.client.WaitTimeout(msg, time.Minute)
if err != nil {
time.Sleep(time.Second)
continue
}
if resp.GetData().(*types.WalletStatus).GetIsWalletLock() { //上锁
time.Sleep(time.Second)
continue
}
if !resp.GetData().(*types.WalletStatus).GetIsHasSeed() { //无种子
time.Sleep(time.Second)
continue
}
break
}
var parm types.ReqWalletImportPrivkey
parm.Privkey, _ = network.node.nodeInfo.addrBook.GetPrivPubKey()
parm.Label = "node award"
ReTry:
msg := network.client.NewMessage("wallet", types.EventWalletImportPrivkey, &parm)
err := network.client.SendTimeout(msg, true, time.Minute)
if err != nil {
log.Error("ImportPrivkey", "Error", err.Error())
return err
}
resp, err := network.client.WaitTimeout(msg, time.Minute)
if err != nil {
if err == types.ErrPrivkeyExist {
return nil
}
if err == types.ErrLabelHasUsed {
//切换随机lable
parm.Label = fmt.Sprintf("node award %v", P2pComm.RandStr(3))
time.Sleep(time.Second)
goto ReTry
}
log.Error("loadP2PPrivKeyToWallet", "err", err.Error())
return err
}
log.Debug("loadP2PPrivKeyToWallet", "resp", resp.GetData())
return nil
}
func (network *P2p) subP2pMsg() {
if network.client == nil {
......
......@@ -2,6 +2,7 @@ package p2p
import (
"encoding/hex"
//"fmt"
"net"
"os"
"sort"
......@@ -31,8 +32,6 @@ func init() {
q = queue.New("channel")
go q.Start()
p2pModule = initP2p(33802, dataDir)
p2pModule.Wait()
go func() {
cfg, sub := types.InitCfg("../cmd/chain33/chain33.test.toml")
......@@ -115,6 +114,9 @@ func init() {
}
}
}()
time.Sleep(time.Second)
p2pModule = initP2p(53802, dataDir)
p2pModule.Wait()
}
......@@ -128,9 +130,14 @@ func initP2p(port int32, dbpath string) *P2p {
cfg.Version = 119
cfg.ServerStart = true
cfg.Driver = "leveldb"
p2pcli := New(cfg)
p2pcli.SetQueueClient(q.Client())
p2pcli.node.nodeInfo.addrBook.initKey()
privkey, _ := p2pcli.node.nodeInfo.addrBook.GetPrivPubKey()
p2pcli.node.nodeInfo.addrBook.bookDb.Set([]byte(privKeyTag), []byte(privkey))
p2pcli.node.nodeInfo.SetServiceTy(7)
p2pcli.SetQueueClient(q.Client())
return p2pcli
}
......@@ -162,17 +169,19 @@ func TestNetInfo(t *testing.T) {
p2pModule.node.nodeInfo.SetNatDone()
p2pModule.node.nodeInfo.Get()
p2pModule.node.nodeInfo.Set(p2pModule.node.nodeInfo)
assert.NotNil(t, p2pModule.node.nodeInfo.GetListenAddr())
assert.NotNil(t, p2pModule.node.nodeInfo.GetExternalAddr())
}
//测试Peer
func TestPeer(t *testing.T) {
conn, err := grpc.Dial("localhost:33802", grpc.WithInsecure(),
conn, err := grpc.Dial("localhost:53802", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
assert.Nil(t, err)
defer conn.Close()
remote, err := NewNetAddressString("127.0.0.1:33802")
remote, err := NewNetAddressString("127.0.0.1:53802")
assert.Nil(t, err)
localP2P := initP2p(43802, "testdata2")
......@@ -219,7 +228,7 @@ func TestPeer(t *testing.T) {
_, err = p2pcli.SendVersion(peer, localP2P.node.nodeInfo)
assert.Nil(t, err)
t.Log(p2pcli.CheckPeerNatOk("localhost:33802"))
t.Log(p2pcli.CheckPeerNatOk("localhost:53802"))
t.Log("checkself:", p2pcli.CheckSelf("loadhost:43803", localP2P.node.nodeInfo))
_, err = p2pcli.GetAddr(peer)
assert.Nil(t, err)
......@@ -230,7 +239,7 @@ func TestPeer(t *testing.T) {
height, err := p2pcli.GetBlockHeight(localP2P.node.nodeInfo)
assert.Nil(t, err)
assert.Equal(t, int(height), 2019)
assert.Equal(t, false, p2pcli.CheckSelf("localhost:33802", localP2P.node.nodeInfo))
assert.Equal(t, false, p2pcli.CheckSelf("localhost:53802", localP2P.node.nodeInfo))
//测试下载
job := NewDownloadJob(NewP2PCli(localP2P).(*Cli), []*Peer{peer})
......@@ -271,7 +280,7 @@ func TestGrpcConns(t *testing.T) {
var conns []*grpc.ClientConn
for i := 0; i < maxSamIPNum; i++ {
conn, err := grpc.Dial("localhost:33802", grpc.WithInsecure(),
conn, err := grpc.Dial("localhost:53802", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
assert.Nil(t, err)
......@@ -282,7 +291,7 @@ func TestGrpcConns(t *testing.T) {
conns = append(conns, conn)
}
conn, err := grpc.Dial("localhost:33802", grpc.WithInsecure(),
conn, err := grpc.Dial("localhost:53802", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
assert.Nil(t, err)
cli := types.NewP2PgserviceClient(conn)
......@@ -300,7 +309,7 @@ func TestGrpcConns(t *testing.T) {
//测试grpc 流多连接
func TestGrpcStreamConns(t *testing.T) {
conn, err := grpc.Dial("localhost:33802", grpc.WithInsecure(),
conn, err := grpc.Dial("localhost:53802", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
assert.Nil(t, err)
cli := types.NewP2PgserviceClient(conn)
......@@ -329,7 +338,7 @@ func TestGrpcStreamConns(t *testing.T) {
func TestP2pComm(t *testing.T) {
addrs := P2pComm.AddrRouteble([]string{"localhost:33802"})
addrs := P2pComm.AddrRouteble([]string{"localhost:53802"})
t.Log(addrs)
i32 := P2pComm.BytesToInt32([]byte{0xff})
......@@ -398,7 +407,13 @@ func TestAddrBook(t *testing.T) {
assert.Equal(t, addrBook.genPubkey(hex.EncodeToString(prv)), pubstr)
addrBook.Save()
addrBook.GetAddrs()
addrBook.ResetPeerkey("", "")
privkey, _ := addrBook.GetPrivPubKey()
assert.NotEmpty(t, privkey)
addrBook.ResetPeerkey(hex.EncodeToString(prv), pubstr)
resetkey, _ := addrBook.GetPrivPubKey()
assert.NotEqual(t, resetkey, privkey)
}
func TestBytesToInt32(t *testing.T) {
......
......@@ -630,8 +630,8 @@ func (m *Cli) getLocalPeerInfo() (*pb.P2PPeerInfo, error) {
localpeerinfo.Name = pub
localpeerinfo.MempoolSize = int32(meminfo.GetSize())
if m.network.node.nodeInfo.GetExternalAddr().IP == nil {
localpeerinfo.Addr = LocalAddr
localpeerinfo.Port = int32(m.network.node.listenPort)
localpeerinfo.Addr = m.network.node.nodeInfo.GetListenAddr().IP.String()
localpeerinfo.Port = int32(m.network.node.nodeInfo.GetListenAddr().Port)
} else {
localpeerinfo.Addr = m.network.node.nodeInfo.GetExternalAddr().IP.String()
localpeerinfo.Port = int32(m.network.node.nodeInfo.GetExternalAddr().Port)
......
......@@ -574,7 +574,7 @@ func (s *P2pserver) ServerStreamRead(stream pb.P2Pgservice_ServerStreamReadServe
if s.node.Size() > 0 {
if remoteIP != LocalAddr && remoteIP != s.node.nodeInfo.GetExternalAddr().IP.String() {
if remoteIP != s.node.nodeInfo.GetListenAddr().IP.String() && remoteIP != s.node.nodeInfo.GetExternalAddr().IP.String() {
s.node.nodeInfo.SetServiceTy(Service)
}
}
......
......@@ -281,6 +281,35 @@ func (mem *Mempool) RemoveTxsOfBlock(block *types.Block) bool {
return true
}
// GetProperFeeRate 获取合适的手续费率
func (mem *Mempool) GetProperFeeRate() int64 {
baseFeeRate := mem.cache.GetProperFee()
if mem.cfg.IsLevelFee {
return mem.getLevelFeeRate(baseFeeRate)
}
return baseFeeRate
}
// getLevelFeeRate 获取合适的阶梯手续费率
func (mem *Mempool) getLevelFeeRate(baseFeeRate int64) int64 {
var feeRate int64
sumByte := mem.cache.TotalByte()
maxTxNumber := types.GetP(mem.Height()).MaxTxNumber
switch {
case (sumByte > int64(types.MaxBlockSize/100) && sumByte < int64(types.MaxBlockSize/20)) ||
(int64(mem.Size()) >= maxTxNumber/10 && int64(mem.Size()) < maxTxNumber/2):
feeRate = 10 * baseFeeRate
case sumByte >= int64(types.MaxBlockSize/20) || int64(mem.Size()) >= maxTxNumber/2:
feeRate = 100 * baseFeeRate
default:
return baseFeeRate
}
if feeRate > 10000000 {
feeRate = 10000000
}
return feeRate
}
// Mempool.DelBlock将回退的区块内的交易重新加入mempool中
func (mem *Mempool) delBlock(block *types.Block) {
if len(block.Txs) <= 0 {
......
......@@ -6,6 +6,7 @@ package mempool
import (
"github.com/33cn/chain33/types"
"github.com/golang/protobuf/proto"
)
//QueueCache 排队交易处理
......@@ -31,6 +32,8 @@ type txCache struct {
*AccountTxIndex
*LastTxCache
qcache QueueCache
totalFee int64
totalByte int64
}
//NewTxCache init accountIndex and last cache
......@@ -59,6 +62,8 @@ func (cache *txCache) Remove(hash string) {
}
cache.AccountTxIndex.Remove(tx)
cache.LastTxCache.Remove(tx)
cache.totalFee -= tx.Fee
cache.totalByte -= int64(proto.Size(tx))
}
//Exist 是否存在
......@@ -69,6 +74,14 @@ func (cache *txCache) Exist(hash string) bool {
return cache.qcache.Exist(hash)
}
//GetProperFee 获取合适手续费
func (cache *txCache) GetProperFee() int64 {
if cache.qcache == nil {
return 0
}
return cache.qcache.GetProperFee()
}
//Size cache tx num
func (cache *txCache) Size() int {
if cache.qcache == nil {
......@@ -77,6 +90,16 @@ func (cache *txCache) Size() int {
return cache.qcache.Size()
}
//TotalFee 手续费总和
func (cache *txCache) TotalFee() int64 {
return cache.totalFee
}
//TotalByte 交易字节数总和
func (cache *txCache) TotalByte() int64 {
return cache.totalByte
}
//Walk iter all txs
func (cache *txCache) Walk(count int, cb func(tx *Item) bool) {
if cache.qcache == nil {
......@@ -107,6 +130,8 @@ func (cache *txCache) Push(tx *types.Transaction) error {
return err
}
cache.LastTxCache.Push(tx)
cache.totalFee += tx.Fee
cache.totalByte += int64(proto.Size(tx))
return nil
}
......
......@@ -92,6 +92,13 @@ func (mem *Mempool) checkTxs(msg *queue.Message) *queue.Message {
msg.Data = err
return msg
}
if mem.cfg.IsLevelFee {
err = mem.checkLevelFee(tx)
if err != nil {
msg.Data = err
return msg
}
}
//检查txgroup 中的每个交易
txs, err := tx.GetTxGroup()
if err != nil {
......@@ -114,7 +121,21 @@ func (mem *Mempool) checkTxs(msg *queue.Message) *queue.Message {
return msg
}
//checkTxList 检查账户余额是否足够,并加入到Mempool,成功则传入goodChan,若加入Mempool失败则传入badChan
// checkLevelFee 检查阶梯手续费
func (mem *Mempool) checkLevelFee(tx *types.TransactionCache) error {
//获取mempool里所有交易手续费总和
feeRate := mem.GetProperFeeRate()
totalfee, err := tx.GetTotalFee(feeRate)
if err != nil {
return err
}
if tx.Fee < totalfee {
return types.ErrTxFeeTooLow
}
return nil
}
//checkTxRemote 检查账户余额是否足够,并加入到Mempool,成功则传入goodChan,若加入Mempool失败则传入badChan
func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message {
tx := msg.GetData().(types.TxGroup)
lastheader := mem.GetHeader()
......
......@@ -189,9 +189,9 @@ func (mem *Mempool) eventGetAddrTxs(msg *queue.Message) {
msg.Reply(mem.client.NewMessage("", types.EventReplyAddrTxs, txlist))
}
// eventGetProperFee 获取排队策略中合适的手续费
// eventGetProperFee 获取排队策略中合适的手续费
func (mem *Mempool) eventGetProperFee(msg *queue.Message) {
properFee := mem.cache.qcache.GetProperFee()
properFee := mem.GetProperFeeRate()
msg.Reply(mem.client.NewMessage("rpc", types.EventReplyProperFee,
&types.ReplyProperFee{ProperFee: properFee}))
}
......
......@@ -9,6 +9,8 @@ import (
"math/rand"
"testing"
"github.com/golang/protobuf/proto"
"github.com/33cn/chain33/blockchain"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
......@@ -38,6 +40,7 @@ var (
toAddr = address.PubKeyToAddress(privKey.PubKey().Bytes()).String()
amount = int64(1e8)
v = &cty.CoinsAction_Transfer{Transfer: &types.AssetsTransfer{Amount: amount}}
bigByte = make([]byte, 99510)
transfer = &cty.CoinsAction{Value: v, Ty: cty.CoinsActionTransfer}
tx1 = &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(transfer), Fee: 1000000, Expire: 2, To: toAddr}
tx2 = &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(transfer), Fee: 100000000, Expire: 0, To: toAddr}
......@@ -54,6 +57,21 @@ var (
tx13 = &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(transfer), Fee: 100, Expire: 0, To: toAddr}
tx14 = &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(transfer), Fee: 100000000, Expire: 0, To: "notaddress"}
tx15 = &types.Transaction{Execer: []byte("user.write"), Payload: types.Encode(transfer), Fee: 100000000, Expire: 0, To: toAddr}
tx16 = &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(transfer), Fee: 100000, Expire: 3, To: toAddr}
tx17 = &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(transfer), Fee: 100000, Expire: 4, To: toAddr}
tx18 = &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(transfer), Fee: 4000000, Expire: 4, To: toAddr}
bigTx1 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 100100000, Expire: 0, To: toAddr}
bigTx2 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 100100000, Expire: 11, To: toAddr}
bigTx3 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 11, To: toAddr}
bigTx4 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 12, To: toAddr}
bigTx5 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 13, To: toAddr}
bigTx6 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 14, To: toAddr}
bigTx7 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 15, To: toAddr}
bigTx8 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 16, To: toAddr}
bigTx9 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 17, To: toAddr}
bigTx10 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 18, To: toAddr}
bigTx11 = &types.Transaction{Execer: []byte("user.write"), Payload: bigByte, Fee: 1001000000, Expire: 19, To: toAddr}
)
//var privTo, _ = c.GenKey()
......@@ -92,6 +110,21 @@ func init() {
tx13.Sign(types.SECP256K1, privKey)
tx14.Sign(types.SECP256K1, privKey)
tx15.Sign(types.SECP256K1, privKey)
tx16.Sign(types.SECP256K1, privKey)
tx17.Sign(types.SECP256K1, privKey)
tx18.Sign(types.SECP256K1, privKey)
bigTx1.Sign(types.SECP256K1, privKey)
bigTx2.Sign(types.SECP256K1, privKey)
bigTx3.Sign(types.SECP256K1, privKey)
bigTx4.Sign(types.SECP256K1, privKey)
bigTx5.Sign(types.SECP256K1, privKey)
bigTx6.Sign(types.SECP256K1, privKey)
bigTx7.Sign(types.SECP256K1, privKey)
bigTx8.Sign(types.SECP256K1, privKey)
bigTx9.Sign(types.SECP256K1, privKey)
bigTx10.Sign(types.SECP256K1, privKey)
bigTx11.Sign(types.SECP256K1, privKey)
}
func getprivkey(key string) crypto.PrivKey {
......@@ -169,6 +202,27 @@ func initEnv(size int) (queue.Queue, *Mempool) {
return q, mem
}
func initEnv4(size int) (queue.Queue, *Mempool) {
if size == 0 {
size = 100
}
var q = queue.New("channel")
cfg, _ := types.InitCfg("testdata/chain33.test.toml")
types.Init(cfg.Title, cfg)
blockchainProcess(q)
execProcess(q)
cfg.Mempool.PoolCacheSize = int64(size)
subConfig := SubConfig{cfg.Mempool.PoolCacheSize, cfg.Mempool.MinTxFee}
mem := NewMempool(cfg.Mempool)
mem.SetQueueCache(NewSimpleQueue(subConfig))
mem.SetQueueClient(q.Client())
mem.setSync(true)
mem.SetMinFee(types.GInt("MinFee"))
mem.Wait()
return q, mem
}
func createTx(priv crypto.PrivKey, to string, amount int64) *types.Transaction {
v := &cty.CoinsAction_Transfer{Transfer: &types.AssetsTransfer{Amount: amount}}
transfer := &cty.CoinsAction{Value: v, Ty: cty.CoinsActionTransfer}
......@@ -821,6 +875,211 @@ func TestAddTxGroup(t *testing.T) {
}
}
func TestLevelFeeBigByte(t *testing.T) {
q, mem := initEnv(0)
defer q.Close()
defer mem.Close()
defer func() {
mem.cfg.IsLevelFee = false
}()
mem.cfg.IsLevelFee = true
mem.SetMinFee(100000)
msg0 := mem.client.NewMessage("mempool", types.EventTx, tx1)
mem.client.Send(msg0, true)
resp0, _ := mem.client.Wait(msg0)
if string(resp0.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(resp0.GetData().(*types.Reply).GetMsg()))
}
msg00 := mem.client.NewMessage("mempool", types.EventTx, tx17)
mem.client.Send(msg00, true)
resp00, _ := mem.client.Wait(msg00)
if string(resp00.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(resp00.GetData().(*types.Reply).GetMsg()))
}
msgBig1 := mem.client.NewMessage("mempool", types.EventTx, bigTx1)
mem.client.Send(msgBig1, true)
respBig1, _ := mem.client.Wait(msgBig1)
if string(respBig1.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(respBig1.GetData().(*types.Reply).GetMsg()))
}
msgBig2 := mem.client.NewMessage("mempool", types.EventTx, bigTx2)
mem.client.Send(msgBig2, true)
respBig2, _ := mem.client.Wait(msgBig2)
if string(respBig2.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(respBig2.GetData().(*types.Reply).GetMsg()))
}
msgBig3 := mem.client.NewMessage("mempool", types.EventTx, bigTx3)
mem.client.Send(msgBig3, true)
respBig3, _ := mem.client.Wait(msgBig3)
if string(respBig3.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(respBig3.GetData().(*types.Reply).GetMsg()))
}
//test low fee , feeRate = 10 * minfee
msg2 := mem.client.NewMessage("mempool", types.EventTx, tx16)
mem.client.Send(msg2, true)
resp2, _ := mem.client.Wait(msg2)
if string(resp2.GetData().(*types.Reply).GetMsg()) != types.ErrTxFeeTooLow.Error() {
t.Error(string(resp2.GetData().(*types.Reply).GetMsg()))
}
//test high fee , feeRate = 10 * minfee
msg3 := mem.client.NewMessage("mempool", types.EventTx, tx6)
mem.client.Send(msg3, true)
resp3, _ := mem.client.Wait(msg3)
if string(resp3.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(resp3.GetData().(*types.Reply).GetMsg()))
}
//test group high fee , feeRate = 10 * minfee
txGroup, err := types.CreateTxGroup([]*types.Transaction{bigTx4, bigTx5, bigTx6, bigTx7, bigTx8, bigTx9, bigTx10, bigTx11})
if err != nil {
t.Error("CreateTxGroup err ", err.Error())
}
for i := range txGroup.Txs {
err := txGroup.SignN(i, types.SECP256K1, mainPriv)
if err != nil {
t.Error("TestAddTxGroup SignNfailed ", err.Error())
}
}
bigtxGroup := txGroup.Tx()
msgBigG := mem.client.NewMessage("mempool", types.EventTx, bigtxGroup)
mem.client.Send(msgBigG, true)
respBigG, _ := mem.client.Wait(msgBigG)
if string(respBigG.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(respBigG.GetData().(*types.Reply).GetMsg()))
}
//test low fee , feeRate = 100 * minfee
msg4 := mem.client.NewMessage("mempool", types.EventTx, tx18)
mem.client.Send(msg4, true)
resp4, _ := mem.client.Wait(msg4)
if string(resp4.GetData().(*types.Reply).GetMsg()) != types.ErrTxFeeTooLow.Error() {
t.Error(string(resp4.GetData().(*types.Reply).GetMsg()))
}
//test high fee , feeRate = 100 * minfee
msg5 := mem.client.NewMessage("mempool", types.EventTx, tx8)
mem.client.Send(msg5, true)
resp5, _ := mem.client.Wait(msg5)
if string(resp5.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(resp5.GetData().(*types.Reply).GetMsg()))
}
}
func TestLevelFeeTxNum(t *testing.T) {
q, mem := initEnv4(0)
defer q.Close()
defer mem.Close()
defer func() {
mem.cfg.IsLevelFee = false
}()
mem.cfg.IsLevelFee = true
mem.SetMinFee(100000)
//test low fee , feeRate = 10 * minfee
msg1 := mem.client.NewMessage("mempool", types.EventTx, tx16)
mem.client.Send(msg1, true)
resp1, _ := mem.client.Wait(msg1)
if string(resp1.GetData().(*types.Reply).GetMsg()) != types.ErrTxFeeTooLow.Error() {
t.Error(string(resp1.GetData().(*types.Reply).GetMsg()))
}
//test high fee , feeRate = 10 * minfee
msg2 := mem.client.NewMessage("mempool", types.EventTx, tx6)
mem.client.Send(msg2, true)
resp2, _ := mem.client.Wait(msg2)
if string(resp2.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(resp2.GetData().(*types.Reply).GetMsg()))
}
//test high fee , feeRate = 10 * minfee
msg3 := mem.client.NewMessage("mempool", types.EventTx, tx7)
mem.client.Send(msg3, true)
resp3, _ := mem.client.Wait(msg3)
if string(resp3.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(resp3.GetData().(*types.Reply).GetMsg()))
}
//test low fee , feeRate = 100 * minfee
msg4 := mem.client.NewMessage("mempool", types.EventTx, tx18)
mem.client.Send(msg4, true)
resp4, _ := mem.client.Wait(msg4)
if string(resp4.GetData().(*types.Reply).GetMsg()) != types.ErrTxFeeTooLow.Error() {
t.Error(string(resp4.GetData().(*types.Reply).GetMsg()))
}
//test high fee , feeRate = 100 * minfee
msg5 := mem.client.NewMessage("mempool", types.EventTx, tx8)
mem.client.Send(msg5, true)
resp5, _ := mem.client.Wait(msg5)
if string(resp5.GetData().(*types.Reply).GetMsg()) != "" {
t.Error(string(resp5.GetData().(*types.Reply).GetMsg()))
}
}
func TestSimpleQueue_TotalFee(t *testing.T) {
q, mem := initEnv(0)
defer q.Close()
defer mem.Close()
txa := &types.Transaction{Payload: []byte("123"), Fee: 100000}
mem.cache.Push(txa)
txb := &types.Transaction{Payload: []byte("1234"), Fee: 100000}
mem.cache.Push(txb)
var sumFee int64
mem.cache.Walk(mem.cache.Size(), func(it *Item) bool {
sumFee += it.Value.Fee
return true
})
assert.Equal(t, sumFee, mem.cache.TotalFee())
assert.Equal(t, sumFee, int64(200000))
mem.cache.Remove(string(txb.Hash()))
var sumFee2 int64
mem.cache.Walk(mem.cache.Size(), func(it *Item) bool {
sumFee2 += it.Value.Fee
return true
})
assert.Equal(t, sumFee2, mem.cache.TotalFee())
assert.Equal(t, sumFee2, int64(100000))
}
func TestSimpleQueue_TotalByte(t *testing.T) {
q, mem := initEnv(0)
defer q.Close()
defer mem.Close()
txa := &types.Transaction{Payload: []byte("123"), Fee: 100000}
mem.cache.Push(txa)
txb := &types.Transaction{Payload: []byte("1234"), Fee: 100000}
mem.cache.Push(txb)
var sumByte int64
mem.cache.Walk(mem.cache.Size(), func(it *Item) bool {
sumByte += int64(proto.Size(it.Value))
return true
})
assert.Equal(t, sumByte, mem.cache.TotalByte())
assert.Equal(t, sumByte, int64(19))
mem.cache.Remove(string(txb.Hash()))
var sumByte2 int64
mem.cache.Walk(mem.cache.Size(), func(it *Item) bool {
sumByte2 += int64(proto.Size(it.Value))
return true
})
assert.Equal(t, sumByte2, mem.cache.TotalByte())
assert.Equal(t, sumByte2, int64(9))
}
func BenchmarkMempool(b *testing.B) {
q, mem := initEnv(10240)
defer q.Close()
......
......@@ -58,6 +58,10 @@ func (cache *SimpleQueue) Push(tx *Item) error {
// Remove 删除数据
func (cache *SimpleQueue) Remove(hash string) error {
_, err := cache.GetItem(hash)
if err != nil {
return err
}
cache.txList.Remove(hash)
return nil
}
......
Title="chain33"
TestNet=true
CoinSymbol="bty"
[log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
loglevel = "debug"
logConsoleLevel = "info"
# 日志文件名,可带目录,所有生成的日志文件都放到此目录下
logFile = "logs/chain33.log"
# 单个日志文件的最大值(单位:兆)
maxFileSize = 20
# 最多保存的历史日志文件个数
maxBackups = 20
# 最多保存的历史日志消息(单位:天)
maxAge = 28
# 日志文件名是否使用本地事件(否则使用UTC时间)
localTime = true
# 历史日志文件是否压缩(压缩格式为gz)
compress = false
# 是否打印调用源文件和行号
callerFile = true
# 是否打印调用方法
callerFunction = true
[blockchain]
defCacheSize=128
maxFetchBlockNum=128
timeoutSeconds=5
batchBlockNum=128
driver="memdb"
dbPath="datadir"
dbCache=64
isStrongConsistency=true
singleMode=true
batchsync=false
isRecordBlockSequence=true
isParaChain=false
enableTxQuickIndex=false
[p2p]
port=13802
seeds=["47.104.125.151:13802","47.104.125.97:13802","47.104.125.177:13802"]
enable=true
isSeed=true
serverStart=true
msgCacheSize=10240
driver="memdb"
dbPath="datadir/addrbook"
dbCache=4
grpcLogFile="grpc33.log"
version=216
verMix=216
verMax=217
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
enableTLS=false
certFile="cert.pem"
keyFile="key.pem"
[mempool]
name="timeline"
poolCacheSize=10240
minTxFee=100000
maxTxNumPerAccount=100
isLevelFee=false
[mempool.sub.timeline]
poolCacheSize=10240
[mempool.sub.score]
poolCacheSize=10240
timeParam=1 #时间占价格比例
priceConstant=1544 #手续费相对于时间的一个合适的常量,取当前unxi时间戳前四位数,排序时手续费高1e-5~=快1s
pricePower=1 #常量比例
[mempool.sub.price]
poolCacheSize=10240
[consensus]
name="solo"
minerstart=true
genesisBlockTime=1514533394
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 4 #160
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[consensus.sub.solo]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
hotkeyAddr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
waitTxMs=10
[consensus.sub.ticket]
genesisBlockTime=1514533394
[[consensus.sub.ticket.genesis]]
minerAddr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
returnAddr="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
count=10000
[[consensus.sub.ticket.genesis]]
minerAddr="1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"
returnAddr="1EbDHAXpoiewjPLX9uqoz38HsKqMXayZrF"
count=10000
[[consensus.sub.ticket.genesis]]
minerAddr="1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX"
returnAddr="1KcCVZLSQYRUwE5EXTsAoQs9LuJW6xwfQa"
count=10000
[store]
name="mavl"
driver="memdb"
dbPath="datadir/mavltree"
dbCache=128
[store.sub.mavl]
enableMavlPrefix=false
enableMVCC=false
enableMavlPrune=false
pruneHeight=10000
# 是否使能mavl数据载入内存
enableMemTree=false
# 是否使能mavl叶子节点数据载入内存
enableMemVal=false
[wallet]
minFee=1000000
driver="memdb"
dbPath="datadir/wallet"
dbCache=16
signType="secp256k1"
[wallet.sub.ticket]
minerwhitelist=["*"]
[exec]
isFree=false
minExecFee=100000
maxExecFee=1000000000
enableStat=false
enableMVCC=false
[exec.sub.token]
saveTokenTxList=true
tokenApprs = [
"1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK",
"1LY8GFia5EiyoTodMLfkB5PHNNpXRqxhyB",
"1GCzJDS6HbgTQ2emade7mEJGGWFfA15pS9",
"1JYB8sxi4He5pZWHCd3Zi2nypQ4JMB6AxN",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
]
[exec.sub.relay]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
[exec.sub.cert]
# 是否启用证书验证和签名
enable=false
# 加密文件路径
cryptoPath="authdir/crypto"
# 带证书签名类型,支持"auth_ecdsa", "auth_sm2"
signType="auth_ecdsa"
[exec.sub.manage]
superManager=[
"1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
]
[health]
listenAddr="localhost:8805"
checkInterval=1
unSyncMaxTimes=2
......@@ -68,6 +68,7 @@ type Mempool struct {
// 每个账户在mempool中得最大交易数量,默认100
MaxTxNumPerAccount int64 `protobuf:"varint,5,opt,name=maxTxNumPerAccount" json:"maxTxNumPerAccount,omitempty"`
MaxTxLast int64 `protobuf:"varint,6,opt,name=maxTxLast" json:"maxTxLast,omitempty"`
IsLevelFee bool `protobuf:"varint,7,opt,name=isLevelFee" json:"isLevelFee,omitempty"`
}
// Consensus 配置
......@@ -176,6 +177,8 @@ type P2P struct {
InnerBounds int32 `protobuf:"varint,15,opt,name=innerBounds" json:"innerBounds,omitempty"`
// 是否使用Github获取种子节点
UseGithub bool `protobuf:"varint,16,opt,name=useGithub" json:"useGithub,omitempty"`
//是否等待Pid
WaitPid bool `protobuf:"varint,17,opt,name=waitPid" json:"waitPid,omitempty"`
}
// RPC 配置
......
......@@ -286,6 +286,12 @@ func Init(t string, cfg *Config) {
panic("config CoinSymbol must without '-'")
}
coinSymbol = cfg.CoinSymbol
} else {
if isPara() {
panic("must config CoinSymbol in para chain")
} else {
coinSymbol = DefaultCoinsSymbol
}
}
}
//local 只用于单元测试
......
......@@ -33,6 +33,11 @@ const (
NoneX = "none"
)
//DefaultCoinsSymbol 默认的主币名称
const (
DefaultCoinsSymbol = "bty"
)
//UserKeyX 用户自定义执行器前缀byte类型
var (
UserKey = []byte(UserKeyX)
......
......@@ -2,6 +2,7 @@ Title="user.p.guodun."
TestNet=false
FixTime=false
EnableParaFork=true
CoinSymbol="gd"
[log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
......
......@@ -2,6 +2,7 @@ Title="user.p.guodun2."
TestNet=false
FixTime=false
EnableParaFork=false
CoinSymbol="gd2"
[log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
......
......@@ -348,6 +348,28 @@ func (tx *TransactionCache) Check(height, minfee, maxFee int64) error {
return tx.checkok
}
//GetTotalFee 获取交易真实费用
func (tx *TransactionCache) GetTotalFee(minFee int64) (int64, error) {
txgroup, err := tx.GetTxGroup()
if err != nil {
tx.checkok = err
return 0, err
}
var totalfee int64
if txgroup == nil {
return tx.GetRealFee(minFee)
}
txs := txgroup.Txs
for i := 0; i < len(txs); i++ {
fee, err := txs[i].GetRealFee(minFee)
if err != nil {
return 0, err
}
totalfee += fee
}
return totalfee, nil
}
//GetTxGroup 获取交易组
func (tx *TransactionCache) GetTxGroup() (*Transactions, error) {
var err error
......
......@@ -49,6 +49,7 @@ var (
datadir = flag.String("datadir", "", "data dir of chain33, include logs and datas")
versionCmd = flag.Bool("v", false, "version")
fixtime = flag.Bool("fixtime", false, "fix time")
waitPid = flag.Bool("waitpid", false, "p2p stuck until seed save info wallet & wallet unlock")
)
//RunChain33 : run Chain33
......@@ -91,6 +92,9 @@ func RunChain33(name string) {
if *fixtime {
cfg.FixTime = *fixtime
}
if *waitPid {
cfg.P2P.WaitPid = *waitPid
}
//set test net flag
types.Init(cfg.Title, cfg)
if cfg.FixTime {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment