Unverified Commit acb8402d authored by 33cn's avatar 33cn Committed by GitHub

Merge pull request #1059 from YingQm/issues898_para_add_supervision_0923

#898 平行链增加监督节点角色管理
parents c81872d0 cbbce049
......@@ -31,6 +31,15 @@ NODE4="${1}_chain30_1"
NODE5="${1}_chain29_1"
CLI5="docker exec ${NODE5} /root/chain33-cli"
# shellcheck disable=SC2034
NODE6="${1}_chain28_1"
# shellcheck disable=SC2034
NODE7="${1}_chain27_1"
# shellcheck disable=SC2034
NODE8="${1}_chain26_1"
# shellcheck disable=SC2034
NODE9="${1}_chain25_1"
containers=("${NODE1}" "${NODE2}" "${NODE3}" "${NODE4}")
export COMPOSE_PROJECT_NAME="$1"
## global config ###
......
......@@ -24,3 +24,15 @@ services:
chain28:
build:
context: .
chain27:
build:
context: .
chain26:
build:
context: .
chain25:
build:
context: .
......@@ -23,8 +23,15 @@ CLI5="docker exec ${NODE5} /root/chain33-cli"
NODE6="${1}_chain28_1"
CLI6="docker exec ${NODE6} /root/chain33-cli"
containers=("${NODE1}" "${NODE2}" "${NODE3}" "${NODE4}" "${NODE5}" "${NODE6}")
forkContainers=("${CLI3}" "${CLI2}" "${CLI}" "${CLI4}" "${CLI5}" "${CLI6}")
NODE7="${1}_chain27_1"
CLI7="docker exec ${NODE7} /root/chain33-cli"
NODE8="${1}_chain26_1"
CLI8="docker exec ${NODE8} /root/chain33-cli"
NODE9="${1}_chain25_1"
CLI9="docker exec ${NODE9} /root/chain33-cli"
containers=("${NODE1}" "${NODE2}" "${NODE3}" "${NODE4}" "${NODE5}" "${NODE6}" "${NODE7}" "${NODE8}" "${NODE9}")
forkContainers=("${CLI3}" "${CLI2}" "${CLI}" "${CLI4}" "${CLI5}" "${CLI6}" "${CLI7}" "${CLI8}" "${CLI9}")
export COMPOSE_PROJECT_NAME="$1"
......
......@@ -127,6 +127,7 @@ mainForkParacrossCommitTx=2270000
#主链开启循环检查共识交易done的fork高度,需要和主链保持严格一致,不可修改,4320000是bityuan主链对应高度, ycc或其他按实际修改
#不可为0,主链Local时候需特殊配置
mainLoopCheckCommitTxDoneForkHeight=4320000
#mainForkParaSupervision=10400000
#无平行链交易的主链区块间隔,平行链产生一个空块,从高度0开始,配置[blockHeight:interval],比如["0:50","1000:100"]
emptyBlockInterval=["0:50"]
......@@ -289,6 +290,7 @@ ForkLoopCheckCommitTxDone=0
#仅平行链适用,自共识分阶段开启,缺省是0,若对应主链高度7200000之前开启过自共识,需要重新配置此分叉,并为之前自共识设置selfConsensEnablePreContract配置项
ForkParaSelfConsStages=0
ForkParaAssetTransferRbk=0
ForkParaSupervision=0
#仅平行链适用,开启挖矿交易的高度,已有代码版本可能未在0高度开启挖矿,需要设置这个高度,新版本默认从0开启挖矿,通过交易配置分阶段奖励
ForkParaFullMinerHeight=0
......
......@@ -12,13 +12,11 @@ import (
"sync/atomic"
"time"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/pkg/errors"
)
......@@ -45,6 +43,7 @@ type blsClient struct {
feedDog uint32
quit chan struct{}
mutex sync.Mutex
typeNode uint32
}
func newBlsClient(para *client, cfg *subConfig) *blsClient {
......@@ -60,6 +59,7 @@ func newBlsClient(para *client, cfg *subConfig) *blsClient {
b.rcvCommitTxCh = make(chan []*pt.ParacrossCommitAction, maxRcvTxCount)
b.quit = make(chan struct{})
b.leaderSwitchInt = defLeaderSwitchInt
b.typeNode = pt.ParaCommitNode
if cfg.BlsLeaderSwitchIntval > 0 {
b.leaderSwitchInt = cfg.BlsLeaderSwitchIntval
}
......@@ -170,15 +170,57 @@ func (b *blsClient) getLeaderInfo() ([]string, int32, int32, int32, bool) {
offIdx := atomic.LoadInt32(&b.leaderOffset)
leaderIdx := (baseIdx + offIdx) % int32(len(nodes))
return nodes, leaderIdx, baseIdx, offIdx, nodes[leaderIdx] == b.selfID
}
func (b *blsClient) getSuperNodes() ([]string, string) {
func (b *blsClient) getSuperGroupNodes() ([]string, string) {
// 获取授权节点
nodeStr, err := b.paraClient.commitMsgClient.getNodeGroupAddrs()
if err != nil {
return nil, ""
}
return strings.Split(nodeStr, ","), nodeStr
if strings.Contains(nodeStr, b.selfID) {
b.typeNode = pt.ParaCommitSuperNode
return strings.Split(nodeStr, ","), nodeStr
} else {
b.typeNode = pt.ParaCommitNode
}
return nil, ""
}
func (b *blsClient) getSupervisionGroupNodes() ([]string, string) {
// 获取监督节点
nodeStr, err := b.paraClient.commitMsgClient.getSupervisionNodeGroupAddrs()
if err != nil {
return nil, ""
}
if strings.Contains(nodeStr, b.selfID) {
b.typeNode = pt.ParaCommitSupervisionNode
return strings.Split(nodeStr, ","), nodeStr
} else {
b.typeNode = pt.ParaCommitNode
}
return nil, ""
}
func (b *blsClient) getSuperNodes() ([]string, string) {
if b.typeNode == pt.ParaCommitNode {
// 获取授权节点
nodes, nodeStr := b.getSuperGroupNodes()
if len(nodes) > 0 {
return nodes, nodeStr
}
return b.getSupervisionGroupNodes()
} else if b.typeNode == pt.ParaCommitSuperNode {
return b.getSuperGroupNodes()
} else if b.typeNode == pt.ParaCommitSupervisionNode {
return b.getSupervisionGroupNodes()
}
return nil, ""
}
func (b *blsClient) isValidNodes(id string) bool {
......@@ -209,7 +251,7 @@ out:
//自己是Leader,则聚合并发送交易
_, _, _, _, isLeader := b.getLeaderInfo()
if isLeader {
b.sendAggregateTx(nodes)
_ = b.sendAggregateTx(nodes)
}
//聚合签名总共消耗大约1.5ms
//清空txsBuff,重新收集
......@@ -239,7 +281,7 @@ func (b *blsClient) sendAggregateTx(nodes []string) error {
func (b *blsClient) rcvCommitTx(tx *types.Transaction) error {
if !b.isValidNodes(tx.From()) {
plog.Error("rcvCommitTx is not valid node", "addr", tx.From())
plog.Error("rcvCommitTx is not valid node", "addr", tx.From(), "typeNode", b.typeNode)
return pt.ErrParaNodeAddrNotExisted
}
......@@ -265,7 +307,6 @@ func (b *blsClient) rcvCommitTx(tx *types.Transaction) error {
b.rcvCommitTxCh <- commits
return nil
}
func (b *blsClient) checkCommitTx(txs []*types.Transaction) ([]*pt.ParacrossCommitAction, error) {
......@@ -291,7 +332,7 @@ func (b *blsClient) checkCommitTx(txs []*types.Transaction) ([]*pt.ParacrossComm
//验证bls 签名
err = b.verifyBlsSign(tx.From(), commit)
if err != nil {
return nil, errors.Wrapf(pt.ErrBlsSignVerify, "from=%s", tx.From())
return nil, errors.Wrapf(err, "from=%s", tx.From())
}
commits = append(commits, commit)
}
......@@ -392,7 +433,7 @@ func (b *blsClient) aggregateCommit2Action(nodes []string, commits []*pt.ParaBls
for _, v := range commits {
a := &pt.ParacrossCommitAction{Bls: &pt.ParacrossCommitBlsInfo{}}
s := &pt.ParacrossNodeStatus{}
types.Decode(v.Msgs[0], s)
_ = types.Decode(v.Msgs[0], s)
a.Status = s
sign, err := b.aggregateSigns(v.Signs)
......@@ -511,7 +552,7 @@ func (b *blsClient) getBlsPubKey(addr string) (crypto.PubKey, error) {
plog.Error("verifyBlsSign.DeserializePublicKey", "key", addr)
return nil, err
}
plog.Info("getBlsPubKey", "addr", addr, "pub", resp.BlsPubKey, "serial", pubKey.Bytes())
plog.Info("getBlsPubKey", "addr", addr, "pub", resp.BlsPubKey, "serial", common.ToHex(pubKey.Bytes()))
b.peersBlsPubKey[addr] = pubKey
return pubKey, nil
......
......@@ -34,7 +34,6 @@ func TestIntegrateCommits(t *testing.T) {
assert.Equal(t, len(pool[0].Signs), 2)
assert.Equal(t, pool[0].Addrs[0], "aa")
assert.Equal(t, pool[0].Addrs[1], "bb")
}
func TestBlsSignMain(t *testing.T) {
......@@ -126,7 +125,7 @@ func testVerifyBlsSign(t *testing.T, cryptCli crypto.Crypto) {
data := "0x1a0c757365722e702e706172612e"
msg, err := common.FromHex(data)
assert.NoError(t, err)
types.Decode(msg, status)
_ = types.Decode(msg, status)
commit.Status = status
commit.Bls = blsInfo
err = client.verifyBlsSign(KS, commit)
......
......@@ -341,10 +341,14 @@ func (client *commitMsgClient) checkConsensusStop(checks *commitCheckParams) {
func (client *commitMsgClient) checkAuthAccountIn() {
nodeStr, err := client.getNodeGroupAddrs()
if err != nil {
nodeSupervisionStr, errSupervision := client.getSupervisionNodeGroupAddrs() // 判断是否是监督节点
if err != nil && errSupervision != nil {
return
}
authExist := strings.Contains(nodeStr, client.authAccount)
authExist1 := strings.Contains(nodeStr, client.authAccount)
authExist2 := strings.Contains(nodeSupervisionStr, client.authAccount)
authExist := authExist1 || authExist2
//如果授权节点重新加入,需要从当前共识高度重新发送
if !client.authAccountIn && authExist {
......@@ -403,7 +407,6 @@ func (client *commitMsgClient) isSync() bool {
}
return true
}
func (client *commitMsgClient) getSendingTx(startHeight, endHeight int64) (*types.Transaction, int64) {
......@@ -933,6 +936,27 @@ func (client *commitMsgClient) getNodeGroupAddrs() (string, error) {
return resp.Value, nil
}
//Supervision node group会在主链和平行链都同时配置,只本地查询就可以
func (client *commitMsgClient) getSupervisionNodeGroupAddrs() (string, error) {
cfg := client.paraClient.GetAPI().GetConfig()
ret, err := client.paraClient.GetAPI().QueryChain(&types.ChainExecutor{
Driver: "paracross",
FuncName: "GetSupervisionNodeGroupAddrs",
Param: types.Encode(&pt.ReqParacrossNodeInfo{Title: cfg.GetTitle()}),
})
if err != nil {
plog.Error("commitmsg.getSupervisionNodeGroupAddrs ", "err", err.Error())
return "", err
}
resp, ok := ret.(*types.ReplyConfig)
if !ok {
plog.Error("commitmsg.getSupervisionNodeGroupAddrs rsp nok")
return "", err
}
return resp.Value, nil
}
func (client *commitMsgClient) onWalletStatus(status *types.WalletStatus) {
if status == nil || client.authAccount == "" {
plog.Info("para onWalletStatus", "status", status == nil, "auth", client.authAccount == "")
......
......@@ -30,6 +30,26 @@ services:
environment:
PARAFILE: "/root/chain33.para29.toml"
chain28:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para28.toml"
chain27:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para27.toml"
chain26:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para26.toml"
chain25:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para25.toml"
nginx:
image: nginx:latest
depends_on:
......
#!/usr/bin/env bash
set -x
# shellcheck source=/dev/null
source testcase.sh
......
#!/usr/bin/env bash
# shellcheck disable=SC2128
set -x
PARA_CLI="docker exec ${NODE3} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI2="docker exec ${NODE2} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI1="docker exec ${NODE1} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI4="docker exec ${NODE4} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI5="docker exec ${NODE5} /root/chain33-cli --paraName user.p.game. --rpc_laddr http://localhost:8901"
PARA_CLI6="docker exec ${NODE6} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI7="docker exec ${NODE7} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI8="docker exec ${NODE8} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
PARA_CLI9="docker exec ${NODE9} /root/chain33-cli --paraName user.p.para. --rpc_laddr http://localhost:8901"
MAIN_CLI="docker exec ${NODE3} /root/chain33-cli"
PARANAME="para"
......@@ -18,6 +25,22 @@ BLSPUB_JR="81307df1fdde8f0e846ed1542c859c1e9daba2553e62e48db0877329c5c63fb86e70b
BLSPUB_NL="ad1d9ff67d790581fa3659c1817985eeec7c65206e8a873147cd5b6bfe1356d5cd4ed1089462bd11e51705e100c95a6b"
BLSPUB_MC="980287e26d4d44f8c57944ffc096f7d98a460c97dadbffaed14ff0de901fa7f8afc59fcb1805a0b031e5eae5601df1c2"
# 监督节点
ADDR_28="15HmJz2abkExxgcmSRt2Q5D4hZg6zJUD1h"
ADDR_27="13Q5qkhpAMKSQkcZLdrW2watv6A1zYau8U"
ADDR_26="1bVrfkMkr67nppZcoZNNbhpvHVB3FJdnb"
ADDR_25="1P5fmCYpzZ5hbKbjmSGYVKxbrtzJ9Pyu1V"
BLSPUB_28="80e713aae96a44607ba6e0f1acfe88641ac72b789e81696cb646b1e1ae5335bd92011593eee303f9e909fd752c762db3"
BLSPUB_27="a007c19e2ffb9e6e555c1d3b6599c9e62394153aa36920bbe12c90bde796972b8de72d74da98c65b51b767ccf0f44ca3"
BLSPUB_26="95af65564ac8f159d456940926726a266956281929004d5aad89a680830a8eda5dad527f9aa22d2b110367347c1bc3c5"
BLSPUB_25="80fd0544816faea8d973d11e57ce28bdd9aa70551f7e77ca2543aa5daa8675aaa9936e5d1cda5ad93cec7cae1fd34278"
# 超级节点私钥
SUPER_KEY="0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc"
#1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj
ADDR_1KA_KEY="0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5"
xsedfix=""
if [ "$(uname)" == "Darwin" ]; then
xsedfix=".bak"
......@@ -39,6 +62,16 @@ function para_init() {
para_set_toml chain33.para29.toml "$PARANAME_GAME" "$1"
sed -i $xsedfix 's/^authAccount=.*/authAccount="1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"/g' chain33.para29.toml
# 监督节点
para_set_toml chain33.para28.toml "$PARANAME" "$1"
para_set_toml chain33.para27.toml "$PARANAME" "$1"
para_set_toml chain33.para26.toml "$PARANAME" "$1"
para_set_toml chain33.para25.toml "$PARANAME" "$1"
sed -i $xsedfix 's/^authAccount=.*/authAccount="'"$ADDR_28"'"/g' chain33.para28.toml # 0x3a35610ba6e1e72d7878f4c819e6a6768668cb5481f423ef04b6a11e0e16e44f
sed -i $xsedfix 's/^authAccount=.*/authAccount="'"$ADDR_27"'"/g' chain33.para27.toml # 0xb9548ee4d37a4dcbfa0b21cbfe1ac95121e2850225cf7d8eb1e50c52996b1b83
sed -i $xsedfix 's/^authAccount=.*/authAccount="'"$ADDR_26"'"/g' chain33.para26.toml # 0x515c1d4aa106bee952437247aa9907c6ef1322485cf36f312fdca988464e0871
sed -i $xsedfix 's/^authAccount=.*/authAccount="'"$ADDR_25"'"/g' chain33.para25.toml # 0xdd11ba1060534f07e0353b302ff4a3a9210dc55782aca1b30b56d7fa63df8c66
}
function para_set_toml() {
......@@ -103,6 +136,10 @@ function para_set_wallet() {
para_import_wallet "${PARA_CLI1}" "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" "paraAuthAccount"
#1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
para_import_wallet "${PARA_CLI4}" "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" "paraAuthAccount"
para_import_wallet "${PARA_CLI6}" "0x3a35610ba6e1e72d7878f4c819e6a6768668cb5481f423ef04b6a11e0e16e44f" "paraAuthAccount"
para_import_wallet "${PARA_CLI7}" "0xb9548ee4d37a4dcbfa0b21cbfe1ac95121e2850225cf7d8eb1e50c52996b1b83" "paraAuthAccount"
para_import_wallet "${PARA_CLI8}" "0x515c1d4aa106bee952437247aa9907c6ef1322485cf36f312fdca988464e0871" "paraAuthAccount"
para_import_wallet "${PARA_CLI9}" "0xdd11ba1060534f07e0353b302ff4a3a9210dc55782aca1b30b56d7fa63df8c66" "paraAuthAccount"
#14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
para_import_key "${PARA_CLI}" "0xCC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944" "genesis"
......@@ -119,7 +156,7 @@ function para_set_wallet() {
#super node behalf test
#1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj
para_import_key "${PARA_CLI}" "0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5" "behalfnode"
para_import_key "${PARA_CLI}" "${ADDR_1KA_KEY}" "behalfnode"
#1Luh4AziYyaC5zP3hUXtXFZS873xAxm6rH
para_import_key "${PARA_CLI}" "0xfdf2bbff853ecff2e7b86b2a8b45726c6538ca7d1403dc94e50131ef379bdca0" "othernode1"
#1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB
......@@ -130,7 +167,6 @@ function para_set_wallet() {
para_import_wallet "${PARA_CLI5}" "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" "paraAuthAccount"
#1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu
para_import_key "${PARA_CLI5}" "0x128de4afa7c061c00d854a1bca51b58e80a2c292583739e5aebf4c0f778959e1" "cross_transfer"
}
function para_import_wallet() {
......@@ -182,6 +218,11 @@ function para_transfer() {
main_transfer2account "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
main_transfer2account "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
main_transfer2account "1BM2xhBk95qoae8zKNDWwAVGgBERhb7DQu"
# superversion node
main_transfer2account "$ADDR_28"
main_transfer2account "$ADDR_27"
main_transfer2account "$ADDR_26"
main_transfer2account "$ADDR_25"
# super node test
main_transfer2account "1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY"
main_transfer2account "1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj"
......@@ -207,7 +248,7 @@ function para_transfer() {
#1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY test
main_transfer2paracross "0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588"
#1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj
main_transfer2paracross "0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5" 100
main_transfer2paracross "${ADDR_1KA_KEY}" 100
block_wait "${CLI}" 2
......@@ -216,7 +257,6 @@ function para_transfer() {
txhash=$(para_configkey "${PARA_CLI}" "token-blacklist" "BTY")
echo "txhash=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
}
function main_transfer2account() {
......@@ -251,7 +291,7 @@ function main_transfer2paracross() {
function para_configkey() {
tx=$(${1} config config_tx -o add -c "${2}" -v "${3}")
sign=$(${CLI} wallet sign -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc -d "${tx}")
sign=$(${CLI} wallet sign -k "${SUPER_KEY}" -d "${tx}")
send=$(${CLI} wallet send -d "${sign}")
echo "${send}"
}
......@@ -297,7 +337,7 @@ function token_create() {
fi
echo "=========== # 2.token finish ============="
hash=$(${1} send token finish -f 0.001 -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -s GD -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
hash=$(${1} send token finish -f 0.001 -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -s GD -k "${SUPER_KEY}")
echo "${hash}"
query_tx "${1}" "${hash}"
......@@ -384,6 +424,8 @@ function para_cross_transfer_withdraw() {
query_tx "${PARA_CLI}" "${hash}"
hash2=$(${CLI} send para asset_withdraw --paraName user.p.para. -a 0.7 -n test -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01)
echo "${hash2}"
query_tx "${PARA_CLI}" "${hash2}"
local times=200
while true; do
......@@ -427,7 +469,7 @@ function para_cross_transfer_withdraw() {
function token_create_on_mainChain() {
echo "=========== # main chain token test ============="
echo "=========== # 0.config token-blacklist ============="
hash=$(${CLI} send config config_tx -c token-blacklist -o add -v BTY -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
hash=$(${CLI} send config config_tx -c token-blacklist -o add -v BTY -k "${SUPER_KEY}")
echo "${hash}"
query_tx "${MAIN_CLI}" "${hash}"
......@@ -455,7 +497,7 @@ function token_create_on_mainChain() {
fi
echo "=========== # 2.token finish ============="
hash=$(${CLI} send token finish -f 0.001 -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -s FZM -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
hash=$(${CLI} send token finish -f 0.001 -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -s FZM -k "${SUPER_KEY}")
echo "${hash}"
query_tx "${MAIN_CLI}" "${hash}"
......@@ -516,14 +558,14 @@ function para_cross_transfer_withdraw_for_token() {
function para_create_nodegroup_gamechain() {
echo "=========== # game para chain create node group test ============="
##apply
txhash=$(${CLI} --paraName user.p.game. send para nodegroup apply -a "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" -p "$BLSPUB_KS" -c 5 -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
txhash=$(${CLI} --paraName user.p.game. send para nodegroup apply -a "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" -p "$BLSPUB_KS" -c 5 -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI5}" "${txhash}"
id=$txhash
echo "=========== # game para chain approve node group ============="
##approve
txhash=$(${CLI} --paraName user.p.game. send para nodegroup approve -i "$id" -c 5 -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
txhash=$(${CLI} --paraName user.p.game. send para nodegroup approve -i "$id" -c 5 -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI5}" "${txhash}"
......@@ -534,7 +576,6 @@ function para_create_nodegroup_gamechain() {
fi
${PARA_CLI5} para nodegroup addrs
}
function para_cross_transfer_from_parachain() {
......@@ -632,26 +673,44 @@ function check_cross_transfer_game_balance() {
break
fi
done
}
function check_number() {
if [[ $# -lt 2 ]]; then
echo -e "${RED}wrong check number parameters${NOC}"
exit 1
fi
if [ "$(echo "$1 < $2" | bc)" -eq 1 ] || [ "$(echo "$1 > $2" | bc)" -eq 1 ]; then
echo -e "${RED}error number, expect ${1}, get ${2}${NOC}"
exit 1
fi
}
function check_balance_1ka() {
balancePre=$1
coins=$2
balanceNow=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
local diff=0
diff=$(echo "$balanceNow - $balancePre" | bc)
check_number "${diff}" "$coins"
}
function para_create_nodegroup_test() {
echo "=========== # para chain create node group test ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##apply
txhash=$(${PARA_CLI} send para nodegroup apply -a "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4,1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR,1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" -c 5 -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
txhash=$(${PARA_CLI} send para nodegroup apply -a "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4,1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR,1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" -c 5 -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "20.0000" ]; then
echo "apply coinfrozen error balance=$balance"
exit 1
fi
check_balance_1ka "$balancePre" 20
echo "=========== # para chain quit node group ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##quit
txhash=$(${PARA_CLI} send para nodegroup quit -i "$id" -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
txhash=$(${PARA_CLI} send para nodegroup quit -i "$id" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
newid=$(${PARA_CLI} para nodegroup list -s 3 | jq -r ".ids[0].id")
......@@ -660,34 +719,27 @@ function para_create_nodegroup_test() {
echo "quit status error "
exit 1
fi
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".balance")
if [ "$balance" != "100.0000" ]; then
echo "quit coinfrozen error balance=$balance"
exit 1
fi
check_balance_1ka "$balancePre" -20
}
function para_create_nodegroup() {
para_create_nodegroup_test
echo "=========== # para chain create node group again ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##apply
local blspubs=$BLSPUB_E5,$BLSPUB_KS,$BLSPUB_JR,$BLSPUB_NL,$BLSPUB_MC
txhash=$(${PARA_CLI} send para nodegroup apply -a "1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY,1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4,1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR,1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" -p "$blspubs" -c 6 -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
txhash=$(${PARA_CLI} send para nodegroup apply -a "1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY,1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4,1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR,1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" -p "$blspubs" -c 6 -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "30.0000" ]; then
echo "apply coinfrozen error balance=$balance"
exit 1
fi
check_balance_1ka "$balancePre" 30
echo "=========== # para chain approve node group ============="
##approve
txhash=$(${PARA_CLI} send para nodegroup approve -i "$id" -c 6 -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
txhash=$(${PARA_CLI} send para nodegroup approve -i "$id" -c 6 -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
......@@ -701,7 +753,7 @@ function para_create_nodegroup() {
echo "=========== # para chain quit node group fail ============="
##quit fail
txhash=$(${PARA_CLI} send para nodegroup quit -i "$id" -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
txhash=$(${PARA_CLI} send para nodegroup quit -i "$id" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${CLI}" "${txhash}"
status=$(${PARA_CLI} para nodegroup status | jq -r ".status")
......@@ -709,6 +761,7 @@ function para_create_nodegroup() {
echo "status quit not approve status=$status"
exit 1
fi
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "30.0000" ]; then
echo "quit fail coinfrozen error balance=$balance"
......@@ -726,7 +779,7 @@ function para_create_nodegroup() {
fi
##approve
txhash=$(${PARA_CLI} send para nodegroup approve -i "$modifyid" -c 5 -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
txhash=$(${PARA_CLI} send para nodegroup approve -i "$modifyid" -c 5 -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
......@@ -744,8 +797,188 @@ function para_create_nodegroup() {
fi
}
# $1 status, $2 hash
function check_supervision_node_group_list() {
newid=$(${PARA_CLI} para supervision_node id_list -s "$1" | jq -r ".ids[0].id")
if [ "$newid" != "$2" ]; then
${PARA_CLI} para supervision_node id_list -s "$1"
echo "cancel status error "
exit 1
fi
}
# $1 status $2 addr
function check_supervision_node_addr_status() {
status=$(${PARA_CLI} para supervision_node addr_status -a "$2" | jq -r ".status")
if [ "$status" != "$1" ]; then
${PARA_CLI} para supervision_node addr_status -a "$2"
echo "addr_status $status not eq target status $1"
exit 1
fi
}
# $1 addrs
function check_supervision_node_addrs() {
addrs=$(${PARA_CLI} para supervision_node addrs | jq -r ".value")
if [ "$addrs" != "$1" ]; then
${PARA_CLI} para supervision_node addrs
echo "supervision group addrs $addrs, not $1"
exit 1
fi
}
function para_create_supervision_nodegroup_cancel() {
echo "=========== # ${FUNCNAME} begin ============="
echo "=========== # supervision node group apply ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##apply
txhash=$(${PARA_CLI} send para supervision_node apply -a "$ADDR_28" -c 6 -p "$BLSPUB_28" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
check_balance_1ka "$balancePre" 6
echo "=========== # supervision node group cancel ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##cancel
txhash=$(${PARA_CLI} send para supervision_node cancel -i "$id" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
check_balance_1ka "$balancePre" -6
echo "=========== # ${FUNCNAME} end ============="
}
function para_create_supervision_nodegroup_quit() {
echo "=========== # ${FUNCNAME} begin ============="
echo "=========== # para chain apply supervision node group 25 ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##apply
txhash=$(${PARA_CLI} send para supervision_node apply -a "$ADDR_25" -c 6 -p "$BLSPUB_25" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
check_balance_1ka "$balancePre" 6
echo "=========== # para chain approve supervision node group 25 ============="
##approve
txhash=$(${PARA_CLI} send para supervision_node approve -i "$id" -c 6 -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
check_supervision_node_addr_status 2 "$ADDR_25"
check_supervision_node_group_list 2 "$id"
check_supervision_node_addrs "$ADDR_25"
echo "=========== # para chain quit supervision node group 25 ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
txhash=$(${PARA_CLI} send para supervision_node quit -a "$ADDR_25" -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
check_balance_1ka "$balancePre" -6
check_supervision_node_group_list 3 "$id"
check_supervision_node_addr_status 3 "$ADDR_25"
check_supervision_node_addrs null
echo "=========== # ${FUNCNAME} end ============="
}
function para_create_supervision_nodegroup_approve() {
echo "=========== # ${FUNCNAME} begin ============="
echo "=========== # para chain apply supervision node group 28 ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##apply
txhash=$(${PARA_CLI} send para supervision_node apply -a "$ADDR_28" -c 6 -p "$BLSPUB_28" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
check_balance_1ka "$balancePre" 6
echo "=========== # para chain approve supervision node group 28 ============="
##approve
txhash=$(${PARA_CLI} send para supervision_node approve -i "$id" -c 6 -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
check_supervision_node_group_list 2 "$id"
check_supervision_node_addr_status 2 "$ADDR_28"
check_supervision_node_addrs "$ADDR_28"
echo "=========== # para chain apply supervision node group 27 ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##apply
txhash=$(${PARA_CLI} send para supervision_node apply -a "$ADDR_27" -c 6 -p "$BLSPUB_27" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
check_balance_1ka "$balancePre" 6
echo "=========== # para chain approve supervision node group 27 ============="
##approve
txhash=$(${PARA_CLI} send para supervision_node approve -i "$id" -c 6 -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
check_supervision_node_addr_status 2 "$ADDR_27"
check_supervision_node_addrs "$ADDR_28,$ADDR_27"
echo "=========== # para chain apply supervision node group 26 ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##apply
txhash=$(${PARA_CLI} send para supervision_node apply -a "$ADDR_26" -c 6 -p "$BLSPUB_26" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
check_balance_1ka "$balancePre" 6
echo "=========== # para chain approve supervision node group 26 ============="
##approve
txhash=$(${PARA_CLI} send para supervision_node approve -i "$id" -c 6 -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
check_supervision_node_addr_status 2 "$ADDR_26"
check_supervision_node_addrs "$ADDR_28,$ADDR_27,$ADDR_26"
echo "=========== # para chain apply supervision node group 25 again ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
##apply
txhash=$(${PARA_CLI} send para supervision_node apply -a "$ADDR_25" -c 6 -p "$BLSPUB_25" -k "${ADDR_1KA_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
id=$txhash
check_balance_1ka "$balancePre" 6
echo "=========== # para chain approve supervision node group 25 again ============="
##approve
txhash=$(${PARA_CLI} send para supervision_node approve -i "$id" -c 6 -k "${SUPER_KEY}")
echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}"
check_supervision_node_addr_status 2 "$ADDR_25"
check_supervision_node_addrs "$ADDR_28,$ADDR_27,$ADDR_26,$ADDR_25"
echo "=========== # ${FUNCNAME} end ============="
}
function para_create_supervision_nodegroup() {
echo "=========== # ${FUNCNAME} begin ============="
para_create_supervision_nodegroup_cancel
para_create_supervision_nodegroup_quit
para_create_supervision_nodegroup_approve
docker stop "${NODE9}"
echo "=========== # ${FUNCNAME} end ============="
}
function para_nodegroup_behalf_quit_test() {
echo "=========== # para chain behalf node quit ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
status=$(${PARA_CLI} para node addr_status -a 1E5saiXVb9mW8wcWUUZjsHJPZs5GmdzuSY | jq -r ".status")
if [ "${status}" != "10" ]; then
echo "wrong 1E5 status"
......@@ -779,12 +1012,7 @@ function para_nodegroup_behalf_quit_test() {
exit 1
fi
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "24.0000" ]; then
echo "unfrozen coinfrozen error balance=$balance"
exit 1
fi
check_balance_1ka "$balancePre" -6
}
function para_nodemanage_cancel_test() {
......@@ -816,11 +1044,9 @@ function para_nodemanage_cancel_test() {
echo "unfrozen coinfrozen error balance=$balance"
exit 1
fi
}
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
......@@ -873,6 +1099,7 @@ function para_nodemanage_test() {
echo "unfrozen coinfrozen error balance=$balance"
exit 1
fi
echo "=========== # para chain node quit reject ============="
txhash=$(${PARA_CLI} send para node quit -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -k 0x9c451df9e5cb05b88b28729aeaaeb3169a2414097401fcb4c79c1971df734588)
echo "${txhash}"
......@@ -905,22 +1132,19 @@ function para_nodemanage_test() {
${PARA_CLI} para nodegroup addrs
exit 1
fi
}
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 join -c 8 -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
hash=$(${PARA_CLI} send para node join -c 8 -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k "${ADDR_1KA_KEY}")
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
node1_id=$hash
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "37.0000" ]; then
echo "1Ka frozen coinfrozen error balance=$balance"
exit 1
fi
# 37
check_balance_1ka "$balancePre" 8
balance=$(${CLI} account balance -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -e paracross | jq -r ".frozen")
if [ "$balance" == "$PARA_COIN_FROZEN" ]; then
......@@ -929,16 +1153,14 @@ function para_nodemanage_node_behalf_join() {
fi
echo "=========== # para chain new node join 2============="
hash=$(${PARA_CLI} send para node join -c 9 -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
hash=$(${PARA_CLI} send para node join -c 9 -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k "${ADDR_1KA_KEY}")
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
id=$hash
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "46.0000" ]; then
echo "frozen coinfrozen error balance=$balance"
exit 1
fi
# 46
check_balance_1ka "$balancePre" 9
${PARA_CLI} send para node vote -i "$id" -v 1 -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b
${PARA_CLI} send para node vote -i "$id" -v 1 -k 0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4
......@@ -981,15 +1203,14 @@ function para_nodemanage_node_behalf_join() {
fi
echo "=========== # para chain node 1 cancel ============="
hash=$(${PARA_CLI} send para node cancel -i "$node1_id" -k 0xd165c84ed37c2a427fea487470ee671b7a0495d68d82607cafbc6348bf23bec5)
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
hash=$(${PARA_CLI} send para node cancel -i "$node1_id" -k "${ADDR_1KA_KEY}")
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "38.0000" ]; then
echo "unfrozen coinfrozen error balance=$balance"
exit 1
fi
# 38
check_balance_1ka "$balancePre" -8
status=$(${PARA_CLI} para node id_status -i "$node1_id" | jq -r ".status")
if [ "${status}" != "4" ]; then
echo "wrong cancel status"
......@@ -998,6 +1219,7 @@ function para_nodemanage_node_behalf_join() {
fi
echo "=========== # para chain node 2 quit ============="
balancePre=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
hash=$(${PARA_CLI} send para node quit -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB -k 0x794443611e7369a57b078881445b93b754cbc9b9b8f526535ab9c6d21d29203d)
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
......@@ -1011,11 +1233,8 @@ function para_nodemanage_node_behalf_join() {
echo "${hash}"
query_tx "${PARA_CLI}" "${hash}"
balance=$(${CLI} account balance -a 1Ka7EPFRqs3v9yreXG6qA4RQbNmbPJCZPj -e paracross | jq -r ".frozen")
if [ "$balance" != "29.0000" ]; then
echo "unfrozen coinfrozen error balance=$balance"
exit 1
fi
# 29
check_balance_1ka "$balancePre" -9
status=$(${PARA_CLI} para node addr_status -a 1NNaYHkscJaLJ2wUrFNeh6cQXBS4TrFYeB | jq -r ".status")
if [ "${status}" != "11" ]; then
......@@ -1035,7 +1254,6 @@ function para_nodemanage_node_behalf_join() {
${PARA_CLI} para nodegroup addrs
exit 1
fi
}
function check_privacy_utxo() {
......@@ -1057,6 +1275,7 @@ function check_privacy_utxo() {
fi
done
}
function privacy_transfer_test() {
echo "========= # para privacy test ============="
echo "#enable privacy"
......@@ -1093,10 +1312,8 @@ function para_test() {
echo "=========== # para chain test ============="
para_create_nodegroup
para_nodegroup_behalf_quit_test
para_create_supervision_nodegroup
para_create_nodegroup_gamechain
# para_nodemanage_cancel_test
# para_nodemanage_test
# para_nodemanage_node_behalf_join
token_create "${PARA_CLI}"
token_transfer "${PARA_CLI}"
para_cross_transfer_withdraw
......@@ -1106,12 +1323,12 @@ function para_test() {
}
function paracross() {
set -x
if [ "${2}" == "init" ]; then
para_init "${3}"
elif [ "${2}" == "config" ]; then
para_set_wallet
para_transfer
elif [ "${2}" == "test" ]; then
para_test "${1}"
fi
......@@ -1133,5 +1350,4 @@ function paracross() {
elif [ "${2}" == "fork2CheckRst" ]; then
checkParaBlockHashfun 30
fi
}
......@@ -233,6 +233,11 @@ function paracross_ListNodeStatus() {
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"ListNodeStatusInfo","payload":{"title":"user.p.para.","status":3}}]}' ${UNIT_HTTP} '(.error|not) and (.result| [has("status"),true])' "$FUNCNAME"
}
function paracross_GetSupervisionInfo() {
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetSupervisionNodeGroupAddrs","payload":{"title":"user.p.para."}}]}' ${UNIT_HTTP} '(.error|not) and (.result| [has("key","value"),true])' "GetSupervisionNodeGroupAddrs"
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"ListSupervisionNodeStatusInfo","payload":{"title":"user.p.para.","status":0}}]}' ${UNIT_HTTP} '(.error|not) and (.result| [has("status"),true])' "ListSupervisionNodeStatusInfo status:0"
}
para_test_addr="1MAuE8QSbbech3bVKK2JPJJxYxNtT95oSU"
para_test_prikey="0x24d1fad138be98eebee31440f144aa38c404533f40862995282162bc538e91c8"
......@@ -585,7 +590,6 @@ function apply_coins() {
para_exec_addr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"user.p.para.paracross"}]}' ${para_ip} | jq -r ".result")
chain33_SendToAddress "$addr1q9" "${para_exec_addr}" 900000000 "${para_ip}"
chain33_QueryExecBalance "${addr1q9}" "user.p.para.paracross" "$para_ip"
}
function run_testcases() {
......@@ -597,12 +601,12 @@ function run_testcases() {
paracross_GetNodeGroupStatus
paracross_ListNodeGroupStatus
paracross_ListNodeStatus
paracross_GetSupervisionInfo
paracross_Transfer_Withdraw
paracross_testBindMiner "$UNIT_HTTP"
paracross_testTxGroup "$UNIT_HTTP"
paracross_testTxGroupFail "$UNIT_HTTP"
#paracross_testParaAssetWithdrawFail "$UNIT_HTTP"
paracross_testSelfConsensStages "$UNIT_HTTP"
}
......
......@@ -7,17 +7,17 @@ package commands
import (
"encoding/hex"
"fmt"
"math"
"os"
"strings"
cmdtypes "github.com/33cn/chain33/system/dapp/commands/types"
"github.com/pkg/errors"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/system/dapp/commands"
cmdtypes "github.com/33cn/chain33/system/dapp/commands/types"
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
......@@ -37,6 +37,7 @@ func ParcCmd() *cobra.Command {
CreateRawCrossAssetTransferCmd(),
superNodeCmd(),
nodeGroupCmd(),
supervisionNodeCmd(),
paraConfigCmd(),
GetParaInfoCmd(),
GetParaListCmd(),
......@@ -64,10 +65,10 @@ func CreateRawAssetTransferCmd() *cobra.Command {
func addCreateAssetTransferFlags(cmd *cobra.Command) {
cmd.Flags().StringP("to", "t", "", "receiver account address")
cmd.MarkFlagRequired("to")
_ = cmd.MarkFlagRequired("to")
cmd.Flags().Float64P("amount", "a", 0, "transaction amount")
cmd.MarkFlagRequired("amount")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
......@@ -77,7 +78,7 @@ func addCreateAssetTransferFlags(cmd *cobra.Command) {
func createAssetTransfer(cmd *cobra.Command, args []string) {
txHex, err := createAssetTx(cmd, false)
if err != nil {
fmt.Fprintln(os.Stderr, err)
_, _ = fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(txHex)
......@@ -96,12 +97,12 @@ func CreateRawAssetWithdrawCmd() *cobra.Command {
func addCreateAssetWithdrawFlags(cmd *cobra.Command) {
cmd.Flags().Float64P("amount", "a", 0, "withdraw amount")
cmd.MarkFlagRequired("amount")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("to", "t", "", "receiver account address")
cmd.MarkFlagRequired("to")
_ = cmd.MarkFlagRequired("to")
cmd.Flags().StringP("symbol", "s", "", "default for bty, symbol for token")
}
......@@ -109,7 +110,7 @@ func addCreateAssetWithdrawFlags(cmd *cobra.Command) {
func createAssetWithdraw(cmd *cobra.Command, args []string) {
txHex, err := createAssetTx(cmd, true)
if err != nil {
fmt.Fprintln(os.Stderr, err)
_, _ = fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(txHex)
......@@ -138,7 +139,7 @@ func createAssetTx(cmd *cobra.Command, isWithdraw bool) (string, error) {
paraName, _ := cmd.Flags().GetString("paraName")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "title is not right, title format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "title is not right, title format like `user.p.guodun.`")
return "", types.ErrInvalidParam
}
......@@ -174,15 +175,15 @@ func CreateRawTransferCmd() *cobra.Command {
func addCreateTransferFlags(cmd *cobra.Command) {
cmd.Flags().StringP("to", "t", "", "receiver account address")
cmd.MarkFlagRequired("to")
_ = cmd.MarkFlagRequired("to")
cmd.Flags().Float64P("amount", "a", 0, "transaction amount")
cmd.MarkFlagRequired("amount")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("symbol", "s", "", "default for bty, symbol for token")
cmd.MarkFlagRequired("symbol")
_ = cmd.MarkFlagRequired("symbol")
}
func createTransfer(cmd *cobra.Command, args []string) {
......@@ -202,15 +203,15 @@ func CreateRawTransferToExecCmd() *cobra.Command {
func addCreateTransferToExecFlags(cmd *cobra.Command) {
cmd.Flags().Float64P("amount", "a", 0, "transaction amount")
cmd.MarkFlagRequired("amount")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("symbol", "s", "coins.bty", "default for bty, symbol for token")
cmd.MarkFlagRequired("symbol")
_ = cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("exec", "e", "", "asset deposit exec")
cmd.MarkFlagRequired("exec")
_ = cmd.MarkFlagRequired("exec")
}
func createTransferToExec(cmd *cobra.Command, args []string) {
......@@ -230,15 +231,15 @@ func CreateRawWithdrawCmd() *cobra.Command {
func addCreateWithdrawFlags(cmd *cobra.Command) {
cmd.Flags().Float64P("amount", "a", 0, "withdraw amount")
cmd.MarkFlagRequired("amount")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("symbol", "s", "", "default for bty, symbol for token")
cmd.MarkFlagRequired("symbol")
_ = cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("exec", "e", "", "asset deposit exec")
cmd.MarkFlagRequired("exec")
_ = cmd.MarkFlagRequired("exec")
}
func createWithdraw(cmd *cobra.Command, args []string) {
......@@ -258,16 +259,16 @@ func CreateRawCrossAssetTransferCmd() *cobra.Command {
func addCreateCrossAssetTransferFlags(cmd *cobra.Command) {
cmd.Flags().StringP("exec", "e", "", "exec of asset resident")
cmd.MarkFlagRequired("exec")
_ = cmd.MarkFlagRequired("exec")
cmd.Flags().StringP("symbol", "s", "", "asset symbol like bty")
cmd.MarkFlagRequired("symbol")
_ = cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("to", "t", "", "transfer to account")
cmd.MarkFlagRequired("to")
_ = cmd.MarkFlagRequired("to")
cmd.Flags().Float64P("amount", "a", 0, "transaction amount")
cmd.MarkFlagRequired("amount")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
......@@ -287,7 +288,7 @@ func createCrossAssetTransfer(cmd *cobra.Command, args []string) {
}
if amount < 0 {
fmt.Fprintln(os.Stderr, "amount < 0")
_, _ = fmt.Fprintln(os.Stderr, "amount < 0")
return
}
amountInt64, err := types.FormatFloatDisplay2Value(amount, cfg.CoinPrecision)
......@@ -298,7 +299,7 @@ func createCrossAssetTransfer(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
execName := paraName + pt.ParaX
......@@ -359,10 +360,10 @@ func nodeJoinCmd() *cobra.Command {
func addNodeJoinFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "target join addr")
cmd.MarkFlagRequired("addr")
_ = cmd.MarkFlagRequired("addr")
cmd.Flags().Float64P("coins", "c", 0, "frozen coins amount, should not less nodegroup's setting")
cmd.MarkFlagRequired("coins")
_ = cmd.MarkFlagRequired("coins")
}
......@@ -371,7 +372,7 @@ func createNodeJoinTx(cmd *cobra.Command, args []string) {
coins, _ := cmd.Flags().GetFloat64("coins")
paraName, _ := cmd.Flags().GetString("paraName")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
......@@ -409,10 +410,10 @@ func nodeVoteCmd() *cobra.Command {
func addNodeVoteFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "operating target apply id")
cmd.MarkFlagRequired("id")
_ = cmd.MarkFlagRequired("id")
cmd.Flags().Uint32P("value", "v", 1, "vote value: 1:yes,2:no")
cmd.MarkFlagRequired("value")
_ = cmd.MarkFlagRequired("value")
}
func createNodeVoteTx(cmd *cobra.Command, args []string) {
......@@ -420,7 +421,7 @@ func createNodeVoteTx(cmd *cobra.Command, args []string) {
id, _ := cmd.Flags().GetString("id")
val, _ := cmd.Flags().GetUint32("value")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: 2, Id: id, Value: val}
......@@ -448,7 +449,7 @@ func nodeQuitCmd() *cobra.Command {
func addNodeQuitFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "target quit addr")
cmd.MarkFlagRequired("addr")
_ = cmd.MarkFlagRequired("addr")
}
......@@ -456,7 +457,7 @@ func createNodeQuitTx(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
opAddr, _ := cmd.Flags().GetString("addr")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: 3, Addr: opAddr}
......@@ -484,7 +485,7 @@ func nodeCancelCmd() *cobra.Command {
func addNodeCancelFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "operating target apply id")
cmd.MarkFlagRequired("id")
_ = cmd.MarkFlagRequired("id")
}
......@@ -492,7 +493,7 @@ func createNodeCancelTx(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
id, _ := cmd.Flags().GetString("id")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: 4, Id: id}
......@@ -520,9 +521,9 @@ func nodeModifyCmd() *cobra.Command {
func addNodeModifyFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "operating target apply id")
cmd.MarkFlagRequired("addr")
_ = cmd.MarkFlagRequired("addr")
cmd.Flags().StringP("pubkey", "p", "", "operating target apply id")
cmd.MarkFlagRequired("pubkey")
_ = cmd.MarkFlagRequired("pubkey")
}
......@@ -531,7 +532,7 @@ func createNodeModifyTx(cmd *cobra.Command, args []string) {
addr, _ := cmd.Flags().GetString("addr")
pubkey, _ := cmd.Flags().GetString("pubkey")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: pt.ParaOpModify, Addr: addr, BlsPubKey: pubkey}
......@@ -559,12 +560,12 @@ func nodeBindCmd() *cobra.Command {
func addNodeBindFlags(cmd *cobra.Command) {
cmd.Flags().Uint32P("action", "a", 1, "action bind:1 or unbind:2")
cmd.MarkFlagRequired("action")
_ = cmd.MarkFlagRequired("action")
cmd.Flags().Uint64P("coins", "c", 0, "bind coins, unbind not needed")
cmd.Flags().StringP("node", "n", "", "target node to bind/unbind miner")
cmd.MarkFlagRequired("node")
_ = cmd.MarkFlagRequired("node")
}
......@@ -575,12 +576,12 @@ func createNodeBindTx(cmd *cobra.Command, args []string) {
coins, _ := cmd.Flags().GetUint64("coins")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
if action == 1 && coins == 0 {
fmt.Fprintln(os.Stderr, "coins should bigger than 0")
_, _ = fmt.Fprintln(os.Stderr, "coins should bigger than 0")
}
payload := &pt.ParaBindMinerCmd{BindAction: int32(action), BindCoins: int64(coins), TargetNode: node}
......@@ -609,7 +610,6 @@ func getNodeBindListCmd() *cobra.Command {
func addNodeBindCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("node", "n", "", "super node addr to bind miner")
cmd.Flags().StringP("miner", "m", "", "bind miner addr")
}
func nodeBindInfo(cmd *cobra.Command, args []string) {
......@@ -641,7 +641,7 @@ func getNodeInfoCmd() *cobra.Command {
func addNodeBodyCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "addr apply for super user")
cmd.MarkFlagRequired("addr")
_ = cmd.MarkFlagRequired("addr")
}
......@@ -677,7 +677,7 @@ func getNodeIDInfoCmd() *cobra.Command {
func addNodeIDBodyCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "id apply for super user")
cmd.MarkFlagRequired("id")
_ = cmd.MarkFlagRequired("id")
}
......@@ -713,7 +713,7 @@ func getNodeListCmd() *cobra.Command {
func addNodeListCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int32P("status", "s", 0, "status:0:all,1:joining,2:quiting,3:closed,4:canceled")
cmd.MarkFlagRequired("status")
_ = cmd.MarkFlagRequired("status")
}
......@@ -738,10 +738,10 @@ func nodeList(cmd *cobra.Command, args []string) {
func addSelfConsStageCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int64P("height", "g", 0, "height apply for self consensus enable or not ")
cmd.MarkFlagRequired("height")
_ = cmd.MarkFlagRequired("height")
cmd.Flags().Uint32P("enable", "e", 0, "if self consensus enable at height,1:enable,2:disable")
cmd.MarkFlagRequired("enable")
_ = cmd.MarkFlagRequired("enable")
}
......@@ -778,10 +778,10 @@ func selfConsStageCmd() *cobra.Command {
func addVoteFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "operating target apply id")
cmd.MarkFlagRequired("id")
_ = cmd.MarkFlagRequired("id")
cmd.Flags().Uint32P("value", "v", 1, "vote value: 1:yes,2:no")
cmd.MarkFlagRequired("value")
_ = cmd.MarkFlagRequired("value")
}
func createVoteTx(cmd *cobra.Command, args []string) {
......@@ -844,7 +844,7 @@ func configCancelCmd() *cobra.Command {
Run: stageCancelTx,
}
cmd.Flags().StringP("id", "i", "", "operating target apply id")
cmd.MarkFlagRequired("id")
_ = cmd.MarkFlagRequired("id")
return cmd
}
......@@ -903,12 +903,12 @@ func nodeGroupApplyCmd() *cobra.Command {
func addNodeGroupApplyCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addrs", "a", "", "addrs apply for super node,split by ',' ")
cmd.MarkFlagRequired("addrs")
_ = cmd.MarkFlagRequired("addrs")
cmd.Flags().StringP("blspubs", "p", "", "bls sign pub key for addr's private key,split by ',' (optional)")
cmd.Flags().Float64P("coins", "c", 0, "coins amount to frozen, not less config")
cmd.MarkFlagRequired("coins")
_ = cmd.MarkFlagRequired("coins")
}
......@@ -919,7 +919,7 @@ func nodeGroupApply(cmd *cobra.Command, args []string) {
coins, _ := cmd.Flags().GetFloat64("coins")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
......@@ -948,10 +948,10 @@ func nodeGroupApply(cmd *cobra.Command, args []string) {
func addNodeGroupApproveCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "apply id for nodegroup ")
cmd.MarkFlagRequired("id")
_ = cmd.MarkFlagRequired("id")
cmd.Flags().Float64P("coins", "c", 0, "coins amount to frozen, not less config")
cmd.MarkFlagRequired("coins")
_ = cmd.MarkFlagRequired("coins")
}
......@@ -961,7 +961,7 @@ func nodeGroupApprove(cmd *cobra.Command, args []string) {
coins, _ := cmd.Flags().GetFloat64("coins")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
......@@ -998,7 +998,7 @@ func nodeGroupApproveCmd() *cobra.Command {
func addNodeGroupQuitCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "apply quit id for nodegroup ")
cmd.MarkFlagRequired("id")
_ = cmd.MarkFlagRequired("id")
}
......@@ -1006,7 +1006,7 @@ func nodeGroupQuit(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
id, _ := cmd.Flags().GetString("id")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeGroupConfig{Title: paraName, Op: 3, Id: id}
......@@ -1033,7 +1033,7 @@ func nodeGroupQuitCmd() *cobra.Command {
func addNodeGroupModifyCmdFlags(cmd *cobra.Command) {
cmd.Flags().Float64P("coins", "c", 0, "modify coins amount to frozen, not less config")
cmd.MarkFlagRequired("coins")
_ = cmd.MarkFlagRequired("coins")
}
......@@ -1041,7 +1041,7 @@ func nodeGroupModify(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
coins, _ := cmd.Flags().GetFloat64("coins")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
......@@ -1186,10 +1186,10 @@ func GetHeightCmd() *cobra.Command {
func addBlockBodyCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int64P("start", "s", 0, "block start height")
cmd.MarkFlagRequired("start")
_ = cmd.MarkFlagRequired("start")
cmd.Flags().Int64P("end", "e", 0, "block end height")
cmd.MarkFlagRequired("end")
_ = cmd.MarkFlagRequired("end")
}
func blockInfo(cmd *cobra.Command, args []string) {
......@@ -1224,8 +1224,7 @@ func GetBlockInfoCmd() *cobra.Command {
func addLocalBlockBodyCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int64P("start", "t", 0, "block height,-1:latest height")
cmd.MarkFlagRequired("start")
_ = cmd.MarkFlagRequired("start")
}
func localBlockInfo(cmd *cobra.Command, args []string) {
......@@ -1254,8 +1253,7 @@ func GetLocalBlockInfoCmd() *cobra.Command {
func addParaBodyCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int64P("height", "g", 0, "height to para chain")
cmd.MarkFlagRequired("height")
_ = cmd.MarkFlagRequired("height")
}
func paraInfo(cmd *cobra.Command, args []string) {
......@@ -1325,7 +1323,7 @@ func getNodeGroupAddrsCmd() *cobra.Command {
func addParaAssetTranCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("hash", "s", "", "asset transfer tx hash")
cmd.MarkFlagRequired("hash")
_ = cmd.MarkFlagRequired("hash")
}
......@@ -1412,7 +1410,7 @@ func nodeGroupListCmd() *cobra.Command {
func getNodeGroupListCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int32P("status", "s", 0, "status:1:apply,2:approve,3:quit")
cmd.MarkFlagRequired("status")
_ = cmd.MarkFlagRequired("status")
}
func nodeGroupList(cmd *cobra.Command, args []string) {
......@@ -1480,7 +1478,7 @@ func GetSelfConsOneStageCmd() *cobra.Command {
Run: stageOneInfo,
}
cmd.Flags().Int64P("height", "g", 0, "height to para chain")
cmd.MarkFlagRequired("height")
_ = cmd.MarkFlagRequired("height")
return cmd
}
......@@ -1514,7 +1512,7 @@ func showSelfStages(cmd *cobra.Command, args []string) {
index, _ := cmd.Flags().GetInt32("index")
if id == "" && status == 0 {
fmt.Fprintln(os.Stderr, "should fill id or status in")
_, _ = fmt.Fprintln(os.Stderr, "should fill id or status in")
return
}
......@@ -1538,7 +1536,7 @@ func showSelfStages(cmd *cobra.Command, args []string) {
func addConsensDoneCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int64P("height", "g", 0, "height to para chain")
cmd.MarkFlagRequired("height")
_ = cmd.MarkFlagRequired("height")
}
......@@ -1585,7 +1583,6 @@ func issueCoinsCmd() *cobra.Command {
func addIssueCoinsFlags(cmd *cobra.Command) {
cmd.Flags().Uint64P("amount", "a", 0, "new issue amount")
cmd.MarkFlagRequired("amount")
}
func createIssueCoinsTx(cmd *cobra.Command, args []string) {
......@@ -1611,5 +1608,306 @@ func createIssueCoinsTx(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
func supervisionNodeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "supervision_node",
Short: "supervision node manage cmd",
}
cmd.AddCommand(supervisionNodeApplyCmd())
cmd.AddCommand(supervisionNodeApproveCmd())
cmd.AddCommand(supervisionNodeQuitCmd())
cmd.AddCommand(supervisionNodeCancelCmd())
cmd.AddCommand(getSupervisionNodeGroupAddrsCmd())
cmd.AddCommand(supervisionNodeListInfoCmd())
cmd.AddCommand(getSupervisionNodeInfoCmd())
cmd.AddCommand(supervisionNodeModifyCmd())
return cmd
}
func supervisionNodeApplyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "apply",
Short: "apply for para chain's supervision node",
Run: supervisionNodeApply,
}
addSupervisionNodeApplyCmdFlags(cmd)
return cmd
}
func addSupervisionNodeApplyCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "addr apply for supervision node")
_ = cmd.MarkFlagRequired("addr")
cmd.Flags().StringP("blspub", "p", "", "bls sign pub key for addr's private key")
cmd.Flags().Float64P("coins", "c", 0, "coins amount to frozen, not less config")
_ = cmd.MarkFlagRequired("coins")
}
func supervisionNodeApply(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
addr, _ := cmd.Flags().GetString("addr")
blspub, _ := cmd.Flags().GetString("blspub")
coins, _ := cmd.Flags().GetFloat64("coins")
if !strings.HasPrefix(paraName, "user.p") {
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: 1, Addr: addr, BlsPubKey: blspub, CoinsFrozen: int64(math.Trunc((coins+0.0000001)*1e4)) * 1e4}
params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, pt.ParaX),
ActionName: "SupervisionNodeConfig",
Payload: types.MustPBToJSON(payload),
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
func supervisionNodeApproveCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "approve",
Short: "approve for para chain's supervision node application",
Run: supervisionNodeApprove,
}
addSupervisionNodeApproveCmdFlags(cmd)
return cmd
}
func addSupervisionNodeApproveCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "apply id for supervision node ")
_ = cmd.MarkFlagRequired("id")
cmd.Flags().Float64P("coins", "c", 0, "coins amount to frozen, not less config")
_ = cmd.MarkFlagRequired("coins")
}
func supervisionNodeApprove(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
id, _ := cmd.Flags().GetString("id")
coins, _ := cmd.Flags().GetFloat64("coins")
if !strings.HasPrefix(paraName, "user.p") {
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: 2, Id: id, CoinsFrozen: int64(math.Trunc((coins+0.0000001)*1e4)) * 1e4}
params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, pt.ParaX),
ActionName: "SupervisionNodeConfig",
Payload: types.MustPBToJSON(payload),
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
func supervisionNodeQuitCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "quit",
Short: "quit for para chain's supervision node application",
Run: supervisionNodeQuit,
}
addSupervisionNodeQuitCmdFlags(cmd)
return cmd
}
func addSupervisionNodeQuitCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "apply quit id for supervision node")
_ = cmd.MarkFlagRequired("addr")
}
func supervisionNodeQuit(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
opAddr, _ := cmd.Flags().GetString("addr")
if !strings.HasPrefix(paraName, "user.p") {
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: 3, Addr: opAddr}
params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, pt.ParaX),
ActionName: "SupervisionNodeConfig",
Payload: types.MustPBToJSON(payload),
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
func supervisionNodeCancelCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "cancel",
Short: "cancel for para chain's supervision node application",
Run: supervisionNodeCancel,
}
addSupervisionNodeCancelCmdFlags(cmd)
return cmd
}
func addSupervisionNodeCancelCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "apply cancel id for supervision node")
_ = cmd.MarkFlagRequired("id")
}
func supervisionNodeCancel(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
id, _ := cmd.Flags().GetString("id")
if !strings.HasPrefix(paraName, "user.p") {
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: 4, Id: id}
params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, pt.ParaX),
ActionName: "SupervisionNodeConfig",
Payload: types.MustPBToJSON(payload),
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
func getSupervisionNodeGroupAddrsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "addrs",
Short: "Query supervision node group's current addrs by title",
Run: supervisionNodeGroup,
}
return cmd
}
func supervisionNodeGroup(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
var params rpctypes.Query4Jrpc
params.Execer = pt.ParaX
params.FuncName = "GetSupervisionNodeGroupAddrs"
req := pt.ReqParacrossNodeInfo{Title: paraName}
params.Payload = types.MustPBToJSON(&req)
var res types.ReplyConfig
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
}
// supervisionNodeListInfoCmd get node list by status
func supervisionNodeListInfoCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "id_list",
Short: "Get supervision node apply id list info by status",
Run: supervisionNodeListInfo,
}
getSupervisionNodeListInfoCmdFlags(cmd)
return cmd
}
func getSupervisionNodeListInfoCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int32P("status", "s", 0, "status:0:all,1:joining,2:quiting,3:closed,4:canceled")
_ = cmd.MarkFlagRequired("status")
}
func supervisionNodeListInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
status, _ := cmd.Flags().GetInt32("status")
var params rpctypes.Query4Jrpc
params.Execer = pt.ParaX
params.FuncName = "ListSupervisionNodeStatusInfo"
req := pt.ReqParacrossNodeInfo{
Title: paraName,
Status: status,
}
params.Payload = types.MustPBToJSON(&req)
var res pt.RespParacrossNodeAddrs
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
}
// getNodeInfoCmd get node current status
func getSupervisionNodeInfoCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "addr_status",
Short: "Get node current status:2:approve, 3:quit from supervision group",
Run: supervisionNodeInfo,
}
addSupervisionNodeInfoCmdFlags(cmd)
return cmd
}
func addSupervisionNodeInfoCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "addr apply for super user")
_ = cmd.MarkFlagRequired("addr")
}
func supervisionNodeInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
addr, _ := cmd.Flags().GetString("addr")
var params rpctypes.Query4Jrpc
params.Execer = pt.ParaX
params.FuncName = "GetNodeAddrInfo"
req := pt.ReqParacrossNodeInfo{
Title: paraName,
Addr: addr,
}
params.Payload = types.MustPBToJSON(&req)
var res pt.ParaNodeAddrIdStatus
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
}
func supervisionNodeModifyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "modify",
Short: "supervision node modify parameters",
Run: createSupervisionNodeModifyTx,
}
addSupervisionNodeModifyFlags(cmd)
return cmd
}
func addSupervisionNodeModifyFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "operating target apply id")
_ = cmd.MarkFlagRequired("addr")
cmd.Flags().StringP("pubkey", "p", "", "operating target apply id")
_ = cmd.MarkFlagRequired("pubkey")
}
func createSupervisionNodeModifyTx(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
addr, _ := cmd.Flags().GetString("addr")
pubkey, _ := cmd.Flags().GetString("pubkey")
if !strings.HasPrefix(paraName, "user.p") {
_, _ = fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: pt.ParacrossSupervisionNodeModify, Addr: addr, BlsPubKey: pubkey}
params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, pt.ParaX),
ActionName: "SupervisionNodeConfig",
Payload: types.MustPBToJSON(payload),
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
......@@ -76,6 +76,7 @@ func getNodes(db dbm.KV, key []byte) (map[string]struct{}, []string, error) {
return nodesMap, nodesArray, nil
}
// manager 合约 分叉前写入 现在不用了
func getConfigManageNodes(db dbm.KV, title string) (map[string]struct{}, []string, error) {
key := calcManageConfigNodesKey(title)
return getNodes(db, key)
......@@ -190,19 +191,22 @@ func makeRecordReceipt(addr string, commit *pt.ParacrossNodeStatus) *types.Recei
}
func makeDoneReceipt(cfg *types.Chain33Config, execMainHeight, execHeight int64, commit *pt.ParacrossNodeStatus,
most, commitCount, totalCount int32) *types.Receipt {
most, commitCount, totalCount, mostSupervisionCount, totalSupervisionCommit, totalSupervisionNodes int32) *types.Receipt {
log := &pt.ReceiptParacrossDone{
TotalNodes: totalCount,
TotalCommit: commitCount,
MostSameCommit: most,
Title: commit.Title,
Height: commit.Height,
BlockHash: commit.BlockHash,
TxResult: commit.TxResult,
MainBlockHeight: commit.MainBlockHeight,
MainBlockHash: commit.MainBlockHash,
ChainExecHeight: execHeight,
TotalNodes: totalCount,
TotalCommit: commitCount,
MostSameCommit: most,
Title: commit.Title,
Height: commit.Height,
BlockHash: commit.BlockHash,
TxResult: commit.TxResult,
MainBlockHeight: commit.MainBlockHeight,
MainBlockHash: commit.MainBlockHash,
ChainExecHeight: execHeight,
TotalSupervisionNodes: totalSupervisionNodes,
TotalSupervisionCommit: totalSupervisionCommit,
MostSupervisionCommit: mostSupervisionCount,
}
key := calcTitleKey(commit.Title)
status := &pt.ParacrossStatus{
......@@ -276,8 +280,7 @@ func getConfigNodes(db dbm.KV, title string) (map[string]struct{}, []string, []b
if errors.Cause(err) != pt.ErrTitleNotExist {
return nil, nil, nil, errors.Wrapf(err, "getNodes para for title:%s", title)
}
key = calcManageConfigNodesKey(title)
nodes, nodesArray, err = getNodes(db, key)
nodes, nodesArray, err = getConfigManageNodes(db, title)
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "getNodes manager for title:%s", title)
}
......@@ -288,6 +291,7 @@ func getConfigNodes(db dbm.KV, title string) (map[string]struct{}, []string, []b
func (a *action) getNodesGroup(title string) (map[string]struct{}, []string, error) {
cfg := a.api.GetConfig()
// 如果高度是分叉前,获取老的Nodes
if a.exec.GetMainHeight() < pt.GetDappForkHeight(cfg, pt.ForkCommitTx) {
nodes, nodesArray, err := getConfigManageNodes(a.db, title)
if err != nil {
......@@ -298,7 +302,18 @@ func (a *action) getNodesGroup(title string) (map[string]struct{}, []string, err
nodes, nodesArray, _, err := getConfigNodes(a.db, title)
return nodes, nodesArray, err
}
func getSupervisionNodeGroupAddrs(db dbm.KV, title string) (map[string]struct{}, []string, []byte, error) {
key := calcParaSupervisionNodeGroupAddrsKey(title)
nodes, nodesArray, err := getNodes(db, key)
if err != nil {
if errors.Cause(err) != pt.ErrTitleNotExist {
return nil, nil, nil, errors.Wrapf(err, "getSupervisionNodeGroupAddrs para for title:%s", title)
}
}
return nodes, nodesArray, key, nil
}
func (a *action) isValidSuperNode(addr string) error {
......@@ -325,7 +340,6 @@ func updateCommitBlockHashs(stat *pt.ParacrossHeightStatus, commit *pt.Paracross
}
stat.BlockDetails.BlockHashs = append(stat.BlockDetails.BlockHashs, commit.BlockHash)
stat.BlockDetails.TxResults = append(stat.BlockDetails.TxResults, commit.TxResult)
}
//根据nodes过滤掉可能退出了的addrs
......@@ -338,7 +352,17 @@ func updateCommitAddrs(stat *pt.ParacrossHeightStatus, nodes map[string]struct{}
}
}
stat.Details = details
}
func updateSupervisionDetailsCommitAddrs(stat *pt.ParacrossHeightStatus, nodes map[string]struct{}) {
supervisionDetailsDetails := &pt.ParacrossStatusDetails{}
for i, addr := range stat.SupervisionDetails.Addrs {
if _, ok := nodes[addr]; ok {
supervisionDetailsDetails.Addrs = append(supervisionDetailsDetails.Addrs, addr)
supervisionDetailsDetails.BlockHash = append(supervisionDetailsDetails.BlockHash, stat.SupervisionDetails.BlockHash[i])
}
}
stat.SupervisionDetails = supervisionDetailsDetails
}
//自共识分阶段使能,综合考虑挖矿奖励和共识分配奖励,判断是否自共识使能需要采用共识的高度,而不能采用当前区块高度a.height
......@@ -426,12 +450,21 @@ func getValidAddrs(nodes map[string]struct{}, addrs []string) []string {
return ret
}
//get secp256 addr's bls pubkey
func getAddrBlsPubKey(db dbm.KV, title, addr string) (string, error) {
addrStat, err := getNodeAddr(db, title, addr)
if err != nil {
return "", errors.Wrapf(err, "nodeAddr:%s-%s get error", title, addr)
}
return addrStat.BlsPubKey, nil
}
//bls签名共识交易验证 大约平均耗时3ms (2~4ms)
func (a *action) procBlsSign(nodesArry []string, commit *pt.ParacrossCommitAction) ([]string, error) {
signAddrs := util.GetAddrsByBitMap(nodesArry, commit.Bls.AddrsMap)
var pubs []string
for _, addr := range signAddrs {
pub, err := getAddrBlsPubKey(a.db, commit.Status.Title, addr)
pub, err := getAddrBlsPubKey(a.db, commit.Status.Title, addr /*, commitNodeType*/)
if err != nil {
return nil, errors.Wrapf(err, "pubkey not exist to addr=%s", addr)
}
......@@ -485,6 +518,25 @@ func verifyBlsSign(cryptoCli crypto.Crypto, pubs []string, commit *pt.ParacrossC
return nil
}
func (a *action) getValidCommitAddrs(commit *pt.ParacrossCommitAction, nodesMap map[string]struct{}, nodesArry []string) ([]string, error) {
//获取commitAddrs, bls sign 包含多个账户的聚合签名
commitAddrs := []string{a.fromaddr}
if commit.Bls != nil {
addrs, err := a.procBlsSign(nodesArry, commit)
if err != nil {
return nil, errors.Wrap(err, "procBlsSign")
}
commitAddrs = addrs
}
validAddrs := getValidAddrs(nodesMap, commitAddrs)
if len(validAddrs) <= 0 {
return nil, errors.Wrapf(errors.New("getValidAddrs error"), "getValidAddrs nil commitAddrs=%s ", strings.Join(commitAddrs, ","))
}
return validAddrs, nil
}
//共识commit msg 处理
func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
......@@ -501,28 +553,51 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
return nil, errors.Wrap(err, "getNodesGroup")
}
//获取commitAddrs, bls sign 包含多个账户的聚合签名
commitAddrs := []string{a.fromaddr}
if commit.Bls != nil {
addrs, err := a.procBlsSign(nodesArry, commit)
var validAddrs, supervisionValidAddrs []string
bIsCommitSuperNode := false
bIsCommitSupervisionNode := false
if _, exist := nodesMap[a.fromaddr]; exist {
validAddrs, err = a.getValidCommitAddrs(commit, nodesMap, nodesArry)
if err != nil {
return nil, errors.Wrap(err, "procBlsSign")
return nil, errors.Wrap(err, "getValidCommitAddrs")
}
commitAddrs = addrs
bIsCommitSuperNode = true
}
validAddrs := getValidAddrs(nodesMap, commitAddrs)
if len(validAddrs) <= 0 {
return nil, errors.Wrapf(err, "getValidAddrs nil commitAddrs=%s", strings.Join(commitAddrs, ","))
// 获取监督节点的数据
supervisionNodesMap, supervisionNodesArry, _, err := getSupervisionNodeGroupAddrs(a.db, commit.Status.Title)
if err != nil && errors.Cause(err) != pt.ErrTitleNotExist {
return nil, errors.Wrap(err, "getSupervisionNodeGroupAddrs")
}
if !bIsCommitSuperNode {
if _, exist := supervisionNodesMap[a.fromaddr]; exist {
supervisionValidAddrs, err = a.getValidCommitAddrs(commit, supervisionNodesMap, supervisionNodesArry)
if err != nil {
return nil, errors.Wrap(err, "getValidCommitAddrs")
}
bIsCommitSupervisionNode = true
}
}
if !bIsCommitSuperNode && !bIsCommitSupervisionNode {
return nil, errors.Wrapf(errors.New("from addr error"), "form addr %s not in SuperNodesGroup, not in SupervisionNodesGroup", a.fromaddr)
}
return a.proCommitMsg(commit.Status, nodesMap, validAddrs)
return a.proCommitMsg(commit.Status, nodesMap, validAddrs, supervisionNodesMap, supervisionValidAddrs)
}
func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]struct{}, commitAddrs []string) (*types.Receipt, error) {
func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]struct{}, commitAddrs []string, supervisionNodes map[string]struct{}, supervisionValidAddrs []string) (*types.Receipt, error) {
cfg := a.api.GetConfig()
err := a.preCheckCommitInfo(commit, commitAddrs)
var err error
if len(commitAddrs) > 0 {
err = a.preCheckCommitInfo(commit, commitAddrs)
} else {
err = a.preCheckCommitInfo(commit, supervisionValidAddrs)
}
if err != nil {
return nil, err
}
......@@ -535,7 +610,8 @@ func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]s
// 在完成共识之后来的, 增加 record log, 只记录不修改已经达成的共识
if commit.Height <= titleStatus.Height {
clog.Debug("paracross.Commit record", "node", commitAddrs, "titile", commit.Title, "height", commit.Height)
return makeRecordReceipt(strings.Join(commitAddrs, ","), commit), nil
addr := strings.Join(commitAddrs, ",") + strings.Join(supervisionValidAddrs, ",")
return makeRecordReceipt(addr, commit), nil
}
// 未共识处理, 接受当前高度以及后续高度
......@@ -573,6 +649,20 @@ func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]s
}
}
for _, addr := range supervisionValidAddrs {
if stat.SupervisionDetails == nil {
stat.SupervisionDetails = &pt.ParacrossStatusDetails{}
}
// 如有分叉, 同一个节点可能再次提交commit交易
found, index := hasCommited(stat.SupervisionDetails.Addrs, addr)
if found {
stat.SupervisionDetails.BlockHash[index] = commit.BlockHash
} else {
stat.SupervisionDetails.Addrs = append(stat.SupervisionDetails.Addrs, addr)
stat.SupervisionDetails.BlockHash = append(stat.SupervisionDetails.BlockHash, commit.BlockHash)
}
}
//用commit.MainBlockHeight 判断更准确,如果用a.exec.MainHeight也可以,但是可能收到MainHeight之前的高度共识tx,
// 后面loopCommitTxDone时候也是用当前共识高度大于分叉高度判断
if pt.IsParaForkHeight(cfg, commit.MainBlockHeight, pt.ForkLoopCheckCommitTxDone) {
......@@ -584,7 +674,11 @@ func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]s
if cfg.IsDappFork(commit.MainBlockHeight, pt.ParaX, pt.ForkCommitTx) {
updateCommitAddrs(stat, nodes)
}
saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
if stat.SupervisionDetails != nil {
updateSupervisionDetailsCommitAddrs(stat, supervisionNodes)
}
_ = saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
//fork之前记录的stat 没有根据nodes更新而更新
if pt.IsParaForkHeight(cfg, stat.MainHeight, pt.ForkLoopCheckCommitTxDone) {
r := makeCommitStatReceipt(stat)
......@@ -592,7 +686,7 @@ func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]s
}
if commit.Height > titleStatus.Height+1 {
saveTitleHeight(a.db, calcTitleHeightKey(commit.Title, commit.Height), stat)
_ = saveTitleHeight(a.db, calcTitleHeightKey(commit.Title, commit.Height), stat)
//平行链由主链共识无缝切换,即接收第一个收到的高度,可以不从0开始
allow, err := a.isAllowConsensJump(commit, titleStatus)
if err != nil {
......@@ -603,7 +697,7 @@ func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]s
return receipt, nil
}
}
r, err := a.commitTxDone(commit, stat, titleStatus, nodes)
r, err := a.commitTxDone(commit, stat, titleStatus, nodes, supervisionNodes)
if err != nil {
return nil, err
}
......@@ -613,7 +707,7 @@ func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]s
//分叉以前stat里面只记录了blockhash的信息,没有crossTxHash等信息,无法通过stat直接重构出mostCommitStatus
func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHeightStatus, titleStatus *pt.ParacrossStatus,
nodes map[string]struct{}) (*types.Receipt, error) {
nodes map[string]struct{}, supervisionNodes map[string]struct{}) (*types.Receipt, error) {
receipt := &types.Receipt{}
clog.Debug("paracross.Commit commit", "stat.title", stat.Title, "stat.height", stat.Height, "notes", len(nodes))
......@@ -625,9 +719,28 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac
if !isCommitDone(len(nodes), mostCount) {
return receipt, nil
}
clog.Debug("paracross.Commit commit ----pass", "most", mostCount, "mostHash", common.ToHex([]byte(mostHash)))
// 如果已经有监督节点
mostSupervisionCount := 0
if len(supervisionNodes) > 0 && stat.SupervisionDetails != nil {
for i, v := range stat.SupervisionDetails.Addrs {
clog.Debug("paracross.Commit commit SupervisionDetails", "addr", v, "hash", common.ToHex(stat.SupervisionDetails.BlockHash[i]))
}
mostSupervisionCount, mostSupervisionHash := GetMostCommit(stat.SupervisionDetails.BlockHash)
if !isCommitDone(len(supervisionNodes), mostSupervisionCount) {
return receipt, nil
}
clog.Debug("paracross.Commit commit SupervisionDetails ----pass", "mostSupervisionCount", mostSupervisionCount, "mostSupervisionHash", common.ToHex([]byte(mostSupervisionHash)))
if mostHash != mostSupervisionHash {
clog.Error("paracross.Commit commit mostSupervisionHash mostHash not equal", "mostHash: ", common.ToHex([]byte(mostHash)), "mostSupervisionHash: ", common.ToHex([]byte(mostSupervisionHash)))
return receipt, nil
}
}
stat.Status = pt.ParacrossStatusCommitDone
saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
_ = saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
//之前记录的stat 状态没更新
cfg := a.api.GetConfig()
......@@ -636,8 +749,15 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac
receipt = mergeReceipt(receipt, r)
}
supervisionDetailsAddrsLen := 0
if stat.SupervisionDetails != nil {
supervisionDetailsAddrsLen = len(stat.SupervisionDetails.Addrs)
}
//add commit done receipt
receiptDone := makeDoneReceipt(cfg, a.exec.GetMainHeight(), a.height, nodeStatus, int32(mostCount), int32(len(stat.Details.Addrs)), int32(len(nodes)))
receiptDone := makeDoneReceipt(cfg, a.exec.GetMainHeight(), a.height, nodeStatus,
int32(mostCount), int32(len(stat.Details.Addrs)), int32(len(nodes)),
int32(mostSupervisionCount), int32(supervisionDetailsAddrsLen), int32(len(supervisionNodes)))
receipt = mergeReceipt(receipt, receiptDone)
r, err := a.commitTxDoneStep2(nodeStatus, stat, titleStatus)
......@@ -650,7 +770,6 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac
func (a *action) commitTxDoneStep2(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHeightStatus, titleStatus *pt.ParacrossStatus) (*types.Receipt, error) {
receipt := &types.Receipt{}
titleStatus.Title = nodeStatus.Title
titleStatus.Height = nodeStatus.Height
titleStatus.BlockHash = nodeStatus.BlockHash
......@@ -659,7 +778,7 @@ func (a *action) commitTxDoneStep2(nodeStatus *pt.ParacrossNodeStatus, stat *pt.
titleStatus.MainHeight = nodeStatus.MainBlockHeight
titleStatus.MainHash = nodeStatus.MainBlockHash
}
saveTitle(a.db, calcTitleKey(titleStatus.Title), titleStatus)
_ = saveTitle(a.db, calcTitleKey(titleStatus.Title), titleStatus)
clog.Debug("paracross.Commit commit done", "height", nodeStatus.Height, "statusBlockHash", common.ToHex(nodeStatus.BlockHash))
......@@ -735,6 +854,11 @@ func (a *action) loopCommitTxDone(title string) (*types.Receipt, error) {
if err != nil {
return nil, errors.Wrapf(err, "getNodes for title:%s", title)
}
// 获取监督节点的数据
supervisionNodes, _, _, err := getSupervisionNodeGroupAddrs(a.db, title)
if err != nil && errors.Cause(err) != pt.ErrTitleNotExist {
return nil, errors.Wrap(err, "getSupervisionNodeGroupAddrs loopCommitTxDone")
}
//从当前共识高度开始遍历
titleStatus, err := getTitle(a.db, calcTitleKey(title))
if err != nil {
......@@ -762,23 +886,22 @@ func (a *action) loopCommitTxDone(title string) (*types.Receipt, error) {
return receipt, nil
}
r, err := a.checkCommitTxDone(title, stat, nodes)
r, err := a.checkCommitTxDone(stat, nodes, supervisionNodes)
if err != nil {
clog.Error("paracross.loopCommitTxDone checkExecCommitTxDone", "para title", title, "height", stat.Height, "error", err)
clog.Error("paracropara_cross_transfer main chain and game chain failedss.loopCommitTxDone checkExecCommitTxDone", "para title", title, "height", stat.Height, "error", err)
return receipt, nil
}
if r == nil {
return receipt, nil
}
receipt = mergeReceipt(receipt, r)
}
}
func (a *action) checkCommitTxDone(title string, stat *pt.ParacrossHeightStatus, nodes map[string]struct{}) (*types.Receipt, error) {
status, err := getTitle(a.db, calcTitleKey(title))
func (a *action) checkCommitTxDone(stat *pt.ParacrossHeightStatus, nodes, supervisionNodes map[string]struct{}) (*types.Receipt, error) {
status, err := getTitle(a.db, calcTitleKey(stat.Title))
if err != nil {
return nil, errors.Wrapf(err, "getTitle:%s", title)
return nil, errors.Wrapf(err, "getTitle:%s", stat.Title)
}
//待共识的stat的高度大于当前status高度+1,说明共识不连续,退出,如果是平行链自共识首次切换场景,可以在正常流程里面再触发
......@@ -786,28 +909,46 @@ func (a *action) checkCommitTxDone(title string, stat *pt.ParacrossHeightStatus,
return nil, nil
}
return a.commitTxDoneByStat(stat, status, nodes)
return a.commitTxDoneByStat(stat, status, nodes, supervisionNodes)
}
//只根据stat的信息在commitDone之后重构一个commitMostStatus做后续处理
func (a *action) commitTxDoneByStat(stat *pt.ParacrossHeightStatus, titleStatus *pt.ParacrossStatus, nodes map[string]struct{}) (*types.Receipt, error) {
receipt := &types.Receipt{}
func (a *action) commitTxDoneByStat(stat *pt.ParacrossHeightStatus, titleStatus *pt.ParacrossStatus, nodes, supervisionNodes map[string]struct{}) (*types.Receipt, error) {
clog.Debug("paracross.commitTxDoneByStat", "stat.title", stat.Title, "stat.height", stat.Height, "notes", len(nodes))
for i, v := range stat.Details.Addrs {
clog.Debug("paracross.commitTxDoneByStat detail", "addr", v, "hash", common.ToHex(stat.Details.BlockHash[i]))
}
updateCommitAddrs(stat, nodes)
commitCount := len(stat.Details.Addrs)
most, mostHash := GetMostCommit(stat.Details.BlockHash)
if !isCommitDone(len(nodes), most) {
return nil, nil
}
clog.Debug("paracross.commitTxDoneByStat ----pass", "most", most, "mostHash", common.ToHex([]byte(mostHash)))
mostSupervisionCount := 0
if len(supervisionNodes) > 0 {
for i, v := range stat.SupervisionDetails.Addrs {
clog.Debug("paracross.commitTxDoneByStat SupervisionDetails", "addr", v, "hash", common.ToHex(stat.SupervisionDetails.BlockHash[i]))
}
updateSupervisionDetailsCommitAddrs(stat, supervisionNodes)
mostSupervisionCount, mostSupervisionHash := GetMostCommit(stat.SupervisionDetails.BlockHash)
if !isCommitDone(len(supervisionNodes), mostSupervisionCount) {
return nil, nil
}
clog.Debug("paracross.commitTxDoneByStat SupervisionDetails ----pass", "mostSupervisionCount", mostSupervisionCount, "mostSupervisionHash", common.ToHex([]byte(mostSupervisionHash)))
if mostHash != mostSupervisionHash {
clog.Error("paracross.commitTxDoneByStat mostSupervisionHash mostHash not equal", "mostHash: ", common.ToHex([]byte(mostHash)), "mostSupervisionHash: ", common.ToHex([]byte(mostSupervisionHash)))
return nil, nil
}
}
stat.Status = pt.ParacrossStatusCommitDone
saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
_ = saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
r := makeCommitStatReceipt(stat)
receipt := &types.Receipt{}
receipt = mergeReceipt(receipt, r)
txRst := getMostResults([]byte(mostHash), stat)
......@@ -820,9 +961,16 @@ func (a *action) commitTxDoneByStat(stat *pt.ParacrossHeightStatus, titleStatus
TxResult: txRst,
}
supervisionDetailsAddrsLen := 0
if stat.SupervisionDetails != nil {
supervisionDetailsAddrsLen = len(stat.SupervisionDetails.Addrs)
}
//add commit done receipt
cfg := a.api.GetConfig()
receiptDone := makeDoneReceipt(cfg, a.exec.GetMainHeight(), a.height, mostStatus, int32(most), int32(commitCount), int32(len(nodes)))
receiptDone := makeDoneReceipt(cfg, a.exec.GetMainHeight(), a.height, mostStatus,
int32(most), int32(len(stat.Details.Addrs)), int32(len(nodes)),
int32(mostSupervisionCount), int32(supervisionDetailsAddrsLen), int32(len(supervisionNodes)))
receipt = mergeReceipt(receipt, receiptDone)
r, err := a.commitTxDoneStep2(mostStatus, stat, titleStatus)
......@@ -871,7 +1019,6 @@ func (a *action) isAllowConsensJump(commit *pt.ParacrossNodeStatus, titleStatus
return a.isAllowParaConsensJump(commit, titleStatus)
}
return a.isAllowMainConsensJump(commit, titleStatus), nil
}
func execCrossTx(a *action, cross *types.TransactionDetail, crossTxHash []byte) (*types.Receipt, error) {
......@@ -915,7 +1062,6 @@ func execCrossTx(a *action, cross *types.TransactionDetail, crossTxHash []byte)
return receiptWithdraw, nil
}
return nil, nil
}
func rollbackCrossTx(a *action, cross *types.TransactionDetail, crossTxHash []byte) (*types.Receipt, error) {
......@@ -1432,29 +1578,6 @@ func (a *action) isAllowTransfer() error {
return nil
}
/*
func (a *Paracross) CrossLimits(tx *types.Transaction, index int) bool {
if tx.GroupCount < 2 {
return true
}
txs, err := a.GetTxGroup(index)
if err != nil {
clog.Error("crossLimits", "get tx group failed", err, "hash", common.ToHex(tx.Hash()))
return false
}
titles := make(map[string] struct{})
for _, txTmp := range txs {
title, err := getTitleFrom(txTmp.Execer)
if err == nil {
titles[string(title)] = struct{}{}
}
}
return len(titles) <= 1
}
*/
func (a *action) Transfer(transfer *types.AssetsTransfer, tx *types.Transaction, index int) (*types.Receipt, error) {
clog.Debug("Paracross.Exec Transfer", "symbol", transfer.Cointoken, "amount",
transfer.Amount, "to", tx.To)
......
......@@ -125,3 +125,9 @@ func (e *Paracross) Exec_ParaBindMiner(payload *pt.ParaBindMinerCmd, tx *types.T
a := newAction(e, tx)
return a.bindMiner(payload)
}
//Exec_SupervisionNodeConfig exec Supervision node config
func (e *Paracross) Exec_SupervisionNodeConfig(payload *pt.ParaNodeAddrConfig, tx *types.Transaction, index int) (*types.Receipt, error) {
a := newAction(e, tx)
return a.SupervisionNodeConfig(payload)
}
......@@ -97,7 +97,6 @@ func (e *Paracross) ExecDelLocal_NodeConfig(payload *pt.ParaNodeAddrConfig, tx *
}
set.KV = append(set.KV, r.KV...)
}
}
}
return &set, nil
......@@ -120,8 +119,7 @@ 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 {
} else if log.Ty == pt.TyLogParaNodeConfig {
var g pt.ReceiptParaNodeConfig
err := types.Decode(log.Log, &g)
if err != nil {
......@@ -139,6 +137,27 @@ func (e *Paracross) ExecDelLocal_NodeGroupConfig(payload *pt.ParaNodeGroupConfig
return &set, nil
}
func (e *Paracross) ExecDelLocal_SupervisionNodeConfig(payload *pt.ParaNodeAddrConfig, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
var set types.LocalDBSet
for _, log := range receiptData.Logs {
if log.Ty == pt.TyLogParaSupervisionNodeConfig {
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: calcLocalSupervisionNodeStatusTitle(g.Current.Title, g.Prev.Status, g.Current.TargetAddr, g.Current.Id), Value: types.Encode(g.Prev)})
}
set.KV = append(set.KV, &types.KeyValue{
Key: calcLocalSupervisionNodeStatusTitle(g.Current.Title, g.Current.Status, g.Current.TargetAddr, g.Current.Id), Value: nil})
}
}
return &set, nil
}
//ExecDelLocal_AssetTransfer asset transfer del local db process
func (e *Paracross) ExecDelLocal_AssetTransfer(payload *types.AssetsTransfer, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
var set types.LocalDBSet
......
......@@ -6,9 +6,8 @@ package executor
import (
"bytes"
"math/big"
"encoding/hex"
"math/big"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
......@@ -123,8 +122,7 @@ 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 {
} else if log.Ty == pt.TyLogParaNodeConfig {
var g pt.ReceiptParaNodeConfig
err := types.Decode(log.Log, &g)
if err != nil {
......@@ -143,6 +141,27 @@ func (e *Paracross) ExecLocal_NodeGroupConfig(payload *pt.ParaNodeGroupConfig, t
return &set, nil
}
func (e *Paracross) ExecLocal_SupervisionNodeConfig(payload *pt.ParaNodeAddrConfig, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
var set types.LocalDBSet
for _, log := range receiptData.Logs {
if log.Ty == pt.TyLogParaSupervisionNodeConfig {
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: calcLocalSupervisionNodeStatusTitle(g.Current.Title, g.Prev.Status, g.Current.TargetAddr, g.Current.Id), Value: nil})
}
set.KV = append(set.KV, &types.KeyValue{
Key: calcLocalSupervisionNodeStatusTitle(g.Current.Title, g.Current.Status, g.Current.TargetAddr, g.Current.Id), Value: types.Encode(g.Current)})
}
}
return &set, nil
}
//ExecLocal_AssetTransfer asset transfer local proc
func (e *Paracross) ExecLocal_AssetTransfer(payload *types.AssetsTransfer, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
var set types.LocalDBSet
......
......@@ -38,6 +38,11 @@ var (
paraBindMinderAddr string
paraBindMinderNode string
//监督节点
paraSupervisionNodes string
paraSupervisionNodeIDPrefix string
localSupervisionNodeStatusTitle string
)
func setPrefix() {
......@@ -67,6 +72,9 @@ func setPrefix() {
localNodeGroupStatusTitle = "LODB-paracross-nodegroupStatusTitle-"
paraSupervisionNodes = "mavl-paracross-supervision-nodes-title-"
paraSupervisionNodeIDPrefix = "mavl-paracross-title-nodeid-supervision-"
localSupervisionNodeStatusTitle = "LODB-paracross-supervision-nodeStatusTitle-"
}
func calcTitleKey(t string) []byte {
......@@ -195,3 +203,23 @@ func calcParaBindMinerAddr(node, bind string) []byte {
func calcParaBindMinerNode() []byte {
return []byte(paraBindMinderNode)
}
func calcParaSupervisionNodeGroupAddrsKey(title string) []byte {
return []byte(fmt.Sprintf(paraSupervisionNodes+"%s", title))
}
func calcParaSupervisionNodeIDKey(title, hash string) string {
return fmt.Sprintf(paraSupervisionNodeIDPrefix+"%s-%s", title, hash)
}
func calcLocalSupervisionNodeStatusTitle(title string, status int32, addr, id string) []byte {
return []byte(fmt.Sprintf(localSupervisionNodeStatusTitle+"%s-%02d-%s-%s-%s", title, status, addr, id))
}
func calcLocalSupervisionNodeStatusTitlePrefix(title string, status int32) []byte {
return []byte(fmt.Sprintf(localSupervisionNodeStatusTitle+"%s-%02d", title, status))
}
func calcLocalSupervisionNodeStatusTitleAllPrefix(title string) []byte {
return []byte(fmt.Sprintf(localSupervisionNodeStatusTitle+"%s-", title))
}
......@@ -355,6 +355,11 @@ func (c *Paracross) allow(tx *types.Transaction, index int) error {
return nil
}
}
if cfg.IsDappFork(c.GetHeight(), pt.ParaX, pt.ForkParaSupervision) {
if payload.Ty == pt.ParacrossActionSupervisionNodeConfig {
return nil
}
}
}
return types.ErrNotAllow
}
......
......@@ -26,21 +26,14 @@ import (
"github.com/stretchr/testify/suite"
)
// 构造一个4个节点的平行链数据, 进行测试
const (
SignedType = types.SECP256K1
)
var (
MainBlockHash10 = []byte("main block hash 10")
MainBlockHeight = int64(10)
CurHeight = int64(10)
Title = string("user.p.test.")
Title = "user.p.test."
TitleHeight = int64(10)
PerBlock = []byte("block-hash-9")
CurBlock = []byte("block-hash-10")
PerState = []byte("state-hash-9")
CurState = []byte("state-hash-10")
PrivKeyA = "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" // 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
PrivKeyB = "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" // 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
......@@ -53,10 +46,15 @@ var (
[]byte("1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"),
}
TokenSymbol = "X"
MainBlockHeightForTransfer = int64(9)
chain33TestCfg = types.NewChain33Config(testnode.DefaultConfig)
chain33TestMainCfg = types.NewChain33Config(strings.Replace(types.GetDefaultCfgstring(), "Title=\"local\"", "Title=\"test\"", 1))
PrivKeyE = "0x3a35610ba6e1e72d7878f4c819e6a6768668cb5481f423ef04b6a11e0e16e44f" // 15HmJz2abkExxgcmSRt2Q5D4hZg6zJUD1h
PrivKeyF = "0xaffa90b6a897c798e63890312b2ec9fb5a3c156dac290479ccb67c25c78e9413" // 1JQjqDChawMYfG3yyxByrhJ467HorPVfFZ
SupervisionNodes = [][]byte{
[]byte("15HmJz2abkExxgcmSRt2Q5D4hZg6zJUD1h"),
[]byte("1JQjqDChawMYfG3yyxByrhJ467HorPVfFZ"),
}
chain33TestCfg = types.NewChain33Config(testnode.DefaultConfig)
chain33TestMainCfg = types.NewChain33Config(strings.Replace(types.GetDefaultCfgstring(), "Title=\"local\"", "Title=\"test\"", 1))
)
type CommitTestSuite struct {
......@@ -85,6 +83,28 @@ func makeNodeInfo(key, addr string, cnt int) *types.ConfigItem {
return &item
}
func makeSupervisionNodeInfo(suite *CommitTestSuite) {
SupervisionNodeKey := calcParaSupervisionNodeGroupAddrsKey(Title)
var item types.ConfigItem
item.Key = Title
item.Addr = Title
item.Ty = mty.ConfigItemArrayConfig
emptyValue := &types.ArrayConfig{Value: make([]string, 0)}
arr := types.ConfigItem_Arr{Arr: emptyValue}
item.Value = &arr
for _, n := range SupervisionNodes {
item.GetArr().Value = append(item.GetArr().Value, string(n))
}
_ = suite.stateDB.Set(SupervisionNodeKey, types.Encode(&item))
value, err := suite.stateDB.Get(SupervisionNodeKey)
if err != nil {
suite.T().Error("get setup title failed", err)
return
}
assert.Equal(suite.T(), value, types.Encode(&item))
}
func init() {
log.SetFileLog(nil)
log.SetLogLevel("debug")
......@@ -92,7 +112,6 @@ func init() {
}
func (suite *CommitTestSuite) SetupSuite() {
suite.stateDB, _ = dbm.NewGoMemDB("state", "state", 1024)
// memdb 不支持KVDB接口, 等测试完Exec , 再扩展 memdb
//suite.localDB, _ = dbm.NewGoMemDB("local", "local", 1024)
......@@ -118,7 +137,7 @@ func (suite *CommitTestSuite) SetupSuite() {
// setup title nodes : len = 4
nodeConfigKey := calcManageConfigNodesKey(Title)
nodeValue := makeNodeInfo(Title, Title, 4)
suite.stateDB.Set(nodeConfigKey, types.Encode(nodeValue))
_ = suite.stateDB.Set(nodeConfigKey, types.Encode(nodeValue))
value, err := suite.stateDB.Get(nodeConfigKey)
if err != nil {
suite.T().Error("get setup title failed", err)
......@@ -126,10 +145,12 @@ func (suite *CommitTestSuite) SetupSuite() {
}
assert.Equal(suite.T(), value, types.Encode(nodeValue))
makeSupervisionNodeInfo(suite)
stageKey := calcParaSelfConsStagesKey()
stage := &pt.SelfConsensStage{StartHeight: 0, Enable: pt.ParaConfigYes}
stages := &pt.SelfConsensStages{Items: []*pt.SelfConsensStage{stage}}
suite.stateDB.Set(stageKey, types.Encode(stages))
_ = suite.stateDB.Set(stageKey, types.Encode(stages))
value, err = suite.stateDB.Get(stageKey)
if err != nil {
suite.T().Error("get setup stages failed", err)
......@@ -142,7 +163,7 @@ func (suite *CommitTestSuite) SetupSuite() {
titleStatus.Title = Title
titleStatus.Height = CurHeight - 1
titleStatus.BlockHash = PerBlock
saveTitle(suite.stateDB, calcTitleKey(Title), &titleStatus)
_ = saveTitle(suite.stateDB, calcTitleKey(Title), &titleStatus)
// setup api
hashes := &types.ReqHashes{Hashes: [][]byte{MainBlockHash10}}
......@@ -200,13 +221,13 @@ func signTx(s suite.Suite, tx *types.Transaction, hexPrivKey string) (*types.Tra
return tx, err
}
bytes, err := common.FromHex(hexPrivKey[:])
bytesData, err := common.FromHex(hexPrivKey[:])
if err != nil {
s.T().Error("TestExec", "Hex2Bytes privkey faiiled", err)
return tx, err
}
privKey, err := c.PrivKeyFromBytes(bytes)
privKey, err := c.PrivKeyFromBytes(bytesData)
if err != nil {
s.T().Error("TestExec", "PrivKeyFromBytes failed", err)
return tx, err
......@@ -224,13 +245,13 @@ func getPrivKey(s suite.Suite, hexPrivKey string) (crypto.PrivKey, error) {
return nil, err
}
bytes, err := common.FromHex(hexPrivKey[:])
bytesData, err := common.FromHex(hexPrivKey[:])
if err != nil {
s.T().Error("TestExec", "Hex2Bytes privkey faiiled", err)
return nil, err
}
privKey, err := c.PrivKeyFromBytes(bytes)
privKey, err := c.PrivKeyFromBytes(bytesData)
if err != nil {
s.T().Error("TestExec", "PrivKeyFromBytes failed", err)
return nil, err
......@@ -256,7 +277,7 @@ func commitOnceImpl(suite suite.Suite, exec *Paracross, privkeyStr string) (rece
return
}
func checkCommitReceipt(suite *CommitTestSuite, receipt *types.Receipt, commitCnt int) {
func checkCommitReceipt(suite *CommitTestSuite, receipt *types.Receipt, commitCnt int, commitSupervisionCnt int) {
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 1)
assert.Len(suite.T(), receipt.Logs, 1)
......@@ -274,12 +295,15 @@ func checkCommitReceipt(suite *CommitTestSuite, receipt *types.Receipt, commitCn
assert.Equal(suite.T(), int32(pt.ParacrossStatusCommiting), titleHeight.Status)
assert.Equal(suite.T(), Title, titleHeight.Title)
assert.Equal(suite.T(), commitCnt, len(titleHeight.Details.Addrs))
if commitSupervisionCnt > 0 {
assert.Equal(suite.T(), commitSupervisionCnt, len(titleHeight.SupervisionDetails.Addrs))
}
}
func checkDoneReceipt(suite suite.Suite, receipt *types.Receipt, commitCnt int) {
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 6)
assert.Len(suite.T(), receipt.Logs, 6)
assert.Len(suite.T(), receipt.KV, 8)
assert.Len(suite.T(), receipt.Logs, 8)
key := calcTitleHeightKey(Title, TitleHeight)
suite.T().Log("title height key", string(key))
......@@ -311,6 +335,7 @@ func checkDoneReceipt(suite suite.Suite, receipt *types.Receipt, commitCnt int)
}
func checkRecordReceipt(suite *CommitTestSuite, receipt *types.Receipt, commitCnt int) {
_ = commitCnt
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 0)
assert.Len(suite.T(), receipt.Logs, 1)
......@@ -327,16 +352,22 @@ func checkRecordReceipt(suite *CommitTestSuite, receipt *types.Receipt, commitCn
func (suite *CommitTestSuite) TestExec() {
receipt := commitOnce(suite, PrivKeyA)
checkCommitReceipt(suite, receipt, 1)
checkCommitReceipt(suite, receipt, 1, 0)
receipt = commitOnce(suite, PrivKeyA)
checkCommitReceipt(suite, receipt, 1)
checkCommitReceipt(suite, receipt, 1, 0)
receipt = commitOnce(suite, PrivKeyB)
checkCommitReceipt(suite, receipt, 2)
checkCommitReceipt(suite, receipt, 2, 0)
receipt = commitOnce(suite, PrivKeyA)
checkCommitReceipt(suite, receipt, 2)
checkCommitReceipt(suite, receipt, 2, 0)
receipt = commitOnce(suite, PrivKeyE)
checkCommitReceipt(suite, receipt, 2, 1)
receipt = commitOnce(suite, PrivKeyF)
checkCommitReceipt(suite, receipt, 2, 2)
receipt = commitOnce(suite, PrivKeyC)
checkDoneReceipt(suite.Suite, receipt, 3)
......@@ -363,105 +394,6 @@ func TestGetTitle(t *testing.T) {
assert.Equal(t, titleExpect, title)
}
/*
func TestCrossLimits(t *testing.T) {
stateDB, _ := dbm.NewGoMemDB("state", "state", 1024)
localDB := new(dbmock.KVDB)
api := new(apimock.QueueProtocolAPI)
exec := newParacross().(*Paracross)
exec.SetLocalDB(localDB)
exec.SetStateDB(stateDB)
exec.SetEnv(0, 0, 0)
exec.SetAPI(api)
func (s *VoteTestSuite) TestFilterTxsForPara() {
tx1, err := createAssetTransferTx(s.Suite, PrivKeyA, nil)
s.Nil(err)
tx2, err := createParaNormalTx(s.Suite, PrivKeyB, nil)
s.Nil(err)
tx3, err := createParaNormalTx(s.Suite,PrivKeyA,[]byte("toA"))
s.Nil(err)
tx4, err := createCrossParaTx(s.Suite, []byte("toB"))
s.Nil(err)
tx5, err := createParaNormalTx(s.Suite,PrivKeyA,[]byte("toB"))
s.Nil(err)
tx345 := []*types.Transaction{tx3, tx4,tx5}
txGroup345, err := createTxsGroup(s.Suite, tx345)
s.Nil(err)
tx6, err := createCrossParaTx(s.Suite, nil)
s.Nil(err)
tx7, err := createCrossParaTx(s.Suite, nil)
s.Nil(err)
tx67 := []*types.Transaction{tx6, tx7}
txGroup67, err := createTxsGroup(s.Suite, tx67)
s.Nil(err)
tx71, err := createParaNormalTx(s.Suite,PrivKeyA,[]byte("toA"))
s.Nil(err)
tx72, err := createCrossParaTx(s.Suite, []byte("toB"))
s.Nil(err)
tx73, err := createParaNormalTx(s.Suite,PrivKeyA,[]byte("toB"))
s.Nil(err)
tx777 := []*types.Transaction{tx71, tx72,tx73}
txGroup777, err := createTxsGroup(s.Suite, tx777)
s.Nil(err)
tx8, err := createAssetTransferTx(s.Suite, PrivKeyA, nil)
s.Nil(err)
tx9, err := createAssetTransferTx(s.Suite, PrivKeyC, nil)
s.Nil(err)
txs := []*types.Transaction{tx1, tx2}
txs = append(txs, txGroup345...)
txs = append(txs, txGroup67...)
txs = append(txs, txGroup777...)
txs = append(txs, tx8)
txs = append(txs, tx9)
errlog := &types.ReceiptLog{Ty: types.TyLogErr, Log: []byte("")}
feelog := &types.Receipt{}
feelog.Logs = append(feelog.Logs, errlog)
recpt1 := &types.ReceiptData{Ty: types.ExecPack,Logs:feelog.Logs}
recpt2 := &types.ReceiptData{Ty: types.ExecPack}
recpt3 := &types.ReceiptData{Ty: types.ExecOk}
recpt4 := &types.ReceiptData{Ty: types.ExecOk}
recpt5 := &types.ReceiptData{Ty: types.ExecOk}
recpt6 := &types.ReceiptData{Ty: types.ExecPack,Logs:feelog.Logs}
recpt7 := &types.ReceiptData{Ty: types.ExecPack}
recpt71 := &types.ReceiptData{Ty: types.ExecPack}
recpt72 := &types.ReceiptData{Ty: types.ExecPack}
recpt73 := &types.ReceiptData{Ty: types.ExecPack}
recpt8 := &types.ReceiptData{Ty: types.ExecPack,Logs:feelog.Logs}
recpt9 := &types.ReceiptData{Ty: types.ExecOk}
receipts := []*types.ReceiptData{recpt1, recpt2, recpt3, recpt4, recpt5, recpt6, recpt7, recpt71,recpt72, recpt73, recpt8,recpt9}
block := &types.Block{Txs: txs}
detail := &types.BlockDetail{
Block: block,
Receipts: receipts,
}
rst := FilterTxsForPara(Title, detail)
filterTxs := []*types.Transaction{ tx2,tx3, tx4, tx5,tx71,tx72,tx73,tx9}
s.Equal( filterTxs, rst)
}
tx := &types.Transaction{Execer: []byte("p.user.test.paracross")}
res := exec.CrossLimits(tx, 1)
assert.True(t, res)
}
*/
type VoteTestSuite struct {
suite.Suite
stateDB dbm.KV
......@@ -489,7 +421,7 @@ func (s *VoteTestSuite) SetupSuite() {
stageKey := calcParaSelfConsStagesKey()
stage := &pt.SelfConsensStage{StartHeight: 0, Enable: pt.ParaConfigYes}
stages := &pt.SelfConsensStages{Items: []*pt.SelfConsensStage{stage}}
s.stateDB.Set(stageKey, types.Encode(stages))
_ = s.stateDB.Set(stageKey, types.Encode(stages))
value, err := s.stateDB.Get(stageKey)
if err != nil {
s.T().Error("get setup stages failed", err)
......@@ -565,7 +497,7 @@ func (s *VoteTestSuite) TestVoteTx() {
//s.T().Log(string(kv.GetKey()))
if bytes.Equal(key, kv.Key) {
var rst pt.ParacrossNodeStatus
types.Decode(kv.GetValue(), &rst)
_ = types.Decode(kv.GetValue(), &rst)
s.Equal([]byte{0x4d}, rst.TxResult)
s.Equal([]byte{0x25}, rst.CrossTxResult)
s.Equal(7, len(rst.TxHashs))
......@@ -662,7 +594,7 @@ func (s *VoteTestSuite) TestVoteTxFork() {
//s.T().Log(string(kv.GetKey()))
if bytes.Equal(key, kv.Key) {
var rst pt.ParacrossNodeStatus
types.Decode(kv.GetValue(), &rst)
_ = types.Decode(kv.GetValue(), &rst)
s.Equal([]byte("8e"), rst.TxResult)
s.Equal([]byte("22"), rst.CrossTxResult)
s.Equal(1, len(rst.TxHashs))
......@@ -739,7 +671,7 @@ func createTxsGroup(s suite.Suite, txs []*types.Transaction) ([]*types.Transacti
}
privKey, _ := getPrivKey(s, PrivKeyA)
for i := range group.Txs {
group.SignN(i, int32(types.SECP256K1), privKey)
_ = group.SignN(i, int32(types.SECP256K1), privKey)
}
return group.Txs, nil
}
......@@ -794,11 +726,11 @@ func TestUpdateCommitBlockHashs(t *testing.T) {
}
updateCommitBlockHashs(stat, commit)
assert.Equal(t, int(1), len(stat.BlockDetails.BlockHashs))
assert.Equal(t, 1, len(stat.BlockDetails.BlockHashs))
assert.Equal(t, commit.BlockHash, stat.BlockDetails.BlockHashs[0])
updateCommitBlockHashs(stat, commit)
assert.Equal(t, int(1), len(stat.BlockDetails.BlockHashs))
assert.Equal(t, 1, len(stat.BlockDetails.BlockHashs))
assert.Equal(t, commit.BlockHash, stat.BlockDetails.BlockHashs[0])
commit2 := &pt.ParacrossNodeStatus{
......@@ -812,7 +744,7 @@ func TestUpdateCommitBlockHashs(t *testing.T) {
CrossTxHashs: [][]byte{[]byte("hash2")},
}
updateCommitBlockHashs(stat, commit2)
assert.Equal(t, int(2), len(stat.BlockDetails.BlockHashs))
assert.Equal(t, 2, len(stat.BlockDetails.BlockHashs))
assert.Equal(t, commit2.BlockHash, stat.BlockDetails.BlockHashs[1])
}
......
......@@ -33,7 +33,7 @@ func (p *Paracross) Query_GetTitleHeight(in *pt.ReqParacrossTitleHeight) (types.
}
stat, err := p.paracrossGetStateTitleHeight(in.Title, in.Height)
if err != nil {
clog.Error("paracross.GetTitleHeight", "title", title, "height", in.Height, "err", err.Error())
clog.Error("paracross.GetTitleHeight", "title", in.Title, "height", in.Height, "err", err.Error())
return nil, err
}
status := stat.(*pt.ParacrossHeightStatus)
......@@ -48,6 +48,10 @@ func (p *Paracross) Query_GetTitleHeight(in *pt.ReqParacrossTitleHeight) (types.
res.CommitAddrs = append(res.CommitAddrs, addr)
res.CommitBlockHash = append(res.CommitBlockHash, common.ToHex(status.Details.BlockHash[i]))
}
for i, addr := range status.SupervisionDetails.Addrs {
res.CommitSupervisionAddrs = append(res.CommitSupervisionAddrs, addr)
res.CommitSupervisionBlockHash = append(res.CommitSupervisionBlockHash, common.ToHex(status.SupervisionDetails.BlockHash[i]))
}
return res, nil
}
......@@ -95,6 +99,37 @@ func (p *Paracross) Query_GetNodeGroupAddrs(in *pt.ReqParacrossNodeInfo) (types.
return &reply, nil
}
//Query_GetNodeGroupAddrs get node group addrs
func (p *Paracross) Query_GetSupervisionNodeGroupAddrs(in *pt.ReqParacrossNodeInfo) (types.Message, error) {
if in == nil {
return nil, types.ErrInvalidParam
}
cfg := p.GetAPI().GetConfig()
if cfg.IsPara() {
in.Title = cfg.GetTitle()
} else if in.Title == "" {
return nil, errors.Wrap(types.ErrInvalidParam, "title is null")
}
_, nodesArry, key, err := getSupervisionNodeGroupAddrs(p.GetStateDB(), in.GetTitle())
if err != nil {
return nil, err
}
var nodes string
for _, k := range nodesArry {
if len(nodes) == 0 {
nodes = k
continue
}
nodes = nodes + "," + k
}
var reply types.ReplyConfig
reply.Key = string(key)
reply.Value = nodes
return &reply, nil
}
//Query_GetNodeAddrInfo get specific node addr info
func (p *Paracross) Query_GetNodeAddrInfo(in *pt.ReqParacrossNodeInfo) (types.Message, error) {
if in == nil || in.Addr == "" {
......@@ -213,6 +248,7 @@ func (p *Paracross) Query_ListNodeGroupStatus(in *pt.ReqParacrossNodeInfo) (type
if in == nil {
return nil, types.ErrInvalidParam
}
resp, err := listLocalNodeGroupStatus(p.GetLocalDB(), in.Status)
if err != nil {
return resp, err
......@@ -232,6 +268,31 @@ func (p *Paracross) Query_ListNodeGroupStatus(in *pt.ReqParacrossNodeInfo) (type
return resp, nil
}
//Query_ListSupervisionNodeStatusInfo list node info by status
func (p *Paracross) Query_ListSupervisionNodeStatusInfo(in *pt.ReqParacrossNodeInfo) (types.Message, error) {
if in == nil || in.Title == "" {
return nil, types.ErrInvalidParam
}
var prefix []byte
if in.Status == 0 {
prefix = calcLocalSupervisionNodeStatusTitleAllPrefix(in.Title)
} else {
prefix = calcLocalSupervisionNodeStatusTitlePrefix(in.Title, in.Status)
}
resp, err := listNodeStatus(p.GetLocalDB(), prefix)
if err != nil {
return resp, err
}
addrs := resp.(*pt.RespParacrossNodeAddrs)
for _, id := range addrs.Ids {
id.Id = getParaNodeIDSuffix(id.Id)
}
return resp, nil
}
//Query_ListTitles query paracross titles list
func (p *Paracross) Query_ListTitles(in *types.ReqNil) (types.Message, error) {
return p.paracrossListTitles()
......@@ -504,9 +565,12 @@ func (p *Paracross) Query_GetHeight(req *types.ReqString) (*pt.ParacrossConsensu
return nil, errors.Wrap(types.ErrInvalidParam, "req invalid")
}
}
reqTitle := req.Data
var reqTitle string
if cfg.IsPara() {
reqTitle = cfg.GetTitle()
} else if req != nil {
reqTitle = req.Data
}
res, err := p.paracrossGetHeight(reqTitle)
if err != nil {
......
......@@ -137,6 +137,12 @@ func (a *action) reward(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHe
return nil, err
}
// 监督节点地址
supervisionAddrs := make([]string, 0)
if stat.SupervisionDetails != nil {
supervisionAddrs = getSuperNodes(stat.SupervisionDetails, nodeStatus.BlockHash)
}
//奖励超级节点
minderRewards := coinReward
//如果有委托挖矿地址,则超级节点分baseReward部分,否则全部
......@@ -144,7 +150,12 @@ func (a *action) reward(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHe
minderRewards = coinBaseReward
}
receipt := &types.Receipt{Ty: types.ExecOk}
r, change, err := a.rewardSuperNode(minderRewards, nodeAddrs, nodeStatus.Height)
miners := nodeAddrs
for _, addr := range supervisionAddrs {
miners = append(miners, addr)
}
r, change, err := a.rewardSuperNode(minderRewards, miners, nodeStatus.Height)
if err != nil {
return nil, err
}
......
......@@ -208,15 +208,6 @@ func makeParaNodeGroupReceipt(title string, prev, current *types.ConfigItem) *ty
}
}
//get secp256 addr's bls pubkey
func getAddrBlsPubKey(db dbm.KV, title, addr string) (string, error) {
addrStat, err := getNodeAddr(db, title, addr)
if err != nil {
return "", errors.Wrapf(err, "nodeAddr:%s-%s get error", title, addr)
}
return addrStat.BlsPubKey, nil
}
func (a *action) checkValidNode(config *pt.ParaNodeAddrConfig) (bool, error) {
nodes, _, err := getParacrossNodes(a.db, config.Title)
if err != nil {
......@@ -280,7 +271,6 @@ func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
func (a *action) nodeQuit(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
......@@ -309,7 +299,6 @@ func (a *action) nodeQuit(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
Votes: &pt.ParaNodeVoteDetail{},
Height: a.height}
return makeNodeConfigReceipt(a.fromaddr, config, nil, stat), nil
}
func (a *action) nodeCancel(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
......@@ -357,7 +346,6 @@ func (a *action) nodeCancel(config *pt.ParaNodeAddrConfig) (*types.Receipt, erro
}
return nil, errors.Wrapf(pt.ErrParaUnSupportNodeOper, "nodeid %s was quit status:%d", config.Id, stat.Status)
}
func (a *action) nodeModify(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
......@@ -457,7 +445,6 @@ func updateVotes(in *pt.ParaNodeVoteDetail, nodes map[string]struct{}) *pt.ParaN
//由于propasal id 和quit id分开,quit id不知道对应addr proposal id的coinfrozen信息,需要维护一个围绕addr的数据库结构信息
func (a *action) updateNodeAddrStatus(stat *pt.ParaNodeIdStatus) (*types.Receipt, error) {
cfg := a.api.GetConfig()
addrStat, err := getNodeAddr(a.db, stat.Title, stat.TargetAddr)
if err != nil {
if !isNotFound(err) {
......@@ -491,6 +478,7 @@ func (a *action) updateNodeAddrStatus(stat *pt.ParaNodeIdStatus) (*types.Receipt
addrStat.QuitId = stat.Id
receipt := makeParaNodeStatusReceipt(a.fromaddr, &preStat, addrStat)
cfg := a.api.GetConfig()
if !cfg.IsPara() {
r, err := a.nodeGroupCoinsActive(proposalStat.FromAddr, proposalStat.CoinsFrozen, 1)
if err != nil {
......@@ -602,10 +590,9 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
stat.Status = pt.ParaApplyClosed
stat.Height = a.height
}
} else {
if stat.Status == pt.ParaApplyJoining {
r, err := unpdateNodeGroup(a.db, config.Title, stat.TargetAddr, true)
r, err := updateNodeGroup(a.db, config.Title, stat.TargetAddr, true)
if err != nil {
return nil, err
}
......@@ -620,7 +607,7 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
stat.Status = pt.ParaApplyClosed
stat.Height = a.height
} else if stat.Status == pt.ParaApplyQuiting {
r, err := unpdateNodeGroup(a.db, config.Title, stat.TargetAddr, false)
r, err := updateNodeGroup(a.db, config.Title, stat.TargetAddr, false)
if err != nil {
return nil, err
}
......@@ -636,7 +623,7 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
//node quit后,如果committx满足2/3目标,自动触发commitDone
r, err = a.loopCommitTxDone(config.Title)
if err != nil {
clog.Error("unpdateNodeGroup.loopCommitTxDone", "title", title, "err", err.Error())
clog.Error("updateNodeGroup.loopCommitTxDone", "title", cfg.GetTitle(), "err", err.Error())
}
receipt = mergeReceipt(receipt, r)
}
......@@ -651,10 +638,9 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
receiptDone := makeVoteDoneReceipt(stat, len(nodes), len(stat.Votes.Addrs), most, pt.ParaNodeVoteStr[vote], stat.Status)
receipt = mergeReceipt(receipt, receiptDone)
return receipt, nil
}
func unpdateNodeGroup(db dbm.KV, title, addr string, add bool) (*types.Receipt, error) {
func updateNodeGroup(db dbm.KV, title, addr string, add bool) (*types.Receipt, error) {
var item types.ConfigItem
key := calcParaNodeGroupAddrsKey(title)
......@@ -665,7 +651,7 @@ func unpdateNodeGroup(db dbm.KV, title, addr string, add bool) (*types.Receipt,
if value != nil {
err = types.Decode(value, &item)
if err != nil {
clog.Error("unpdateNodeGroup", "decode db key", key)
clog.Error("updateNodeGroup", "decode db key", key)
return nil, err // types.ErrBadConfigValue
}
}
......@@ -677,8 +663,7 @@ func unpdateNodeGroup(db dbm.KV, title, addr string, add bool) (*types.Receipt,
if add {
item.GetArr().Value = append(item.GetArr().Value, addr)
item.Addr = addr
clog.Info("unpdateNodeGroup add", "addr", addr, "from", copyItem.GetArr().Value, "to", item.GetArr().Value)
clog.Info("updateNodeGroup add", "addr", addr, "from", copyItem.GetArr().Value, "to", item.GetArr().Value)
} else {
//必须保留至少1个授权账户
if len(item.GetArr().Value) <= 1 {
......@@ -691,11 +676,11 @@ func unpdateNodeGroup(db dbm.KV, title, addr string, add bool) (*types.Receipt,
item.GetArr().Value = append(item.GetArr().Value, value)
}
}
clog.Info("unpdateNodeGroup delete", "addr", addr)
clog.Info("updateNodeGroup delete", "addr", addr)
}
err = db.Set(key, types.Encode(&item))
if err != nil {
return nil, errors.Wrapf(err, "unpdateNodeGroup set dbkey=%s", key)
return nil, errors.Wrapf(err, "updateNodeGroup set dbkey=%s", key)
}
return makeParaNodeGroupReceipt(title, &copyItem, &item), nil
}
......@@ -929,7 +914,6 @@ func (a *action) nodeGroupApproveModify(config *pt.ParaNodeGroupConfig, modify *
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
func (a *action) nodeGroupApproveApply(config *pt.ParaNodeGroupConfig, apply *pt.ParaNodeGroupStatus) (*types.Receipt, error) {
......@@ -971,7 +955,6 @@ func (a *action) nodeGroupApproveApply(config *pt.ParaNodeGroupConfig, apply *pt
}
return receipt, nil
}
// NodeGroupApprove super addr approve the node group apply
......@@ -1068,13 +1051,11 @@ func (a *action) NodeGroupConfig(config *pt.ParaNodeGroupConfig) (*types.Receipt
return nil, err
}
return a.nodeGroupApply(config)
} else if config.Op == pt.ParacrossNodeGroupApprove {
if config.Id == "" {
return nil, types.ErrInvalidParam
}
return a.nodeGroupApprove(config)
} else if config.Op == pt.ParacrossNodeGroupQuit {
if config.Id == "" {
return nil, types.ErrInvalidParam
......@@ -1122,5 +1103,4 @@ func (a *action) NodeConfig(config *pt.ParaNodeAddrConfig) (*types.Receipt, erro
default:
return nil, pt.ErrParaUnSupportNodeOper
}
}
......@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/suite"
//"github.com/stretchr/testify/mock"
"strings"
"testing"
apimock "github.com/33cn/chain33/client/mocks"
......@@ -16,8 +17,6 @@ import (
dbmock "github.com/33cn/chain33/common/db/mocks"
"github.com/33cn/chain33/types"
"strings"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/stretchr/testify/mock"
)
......@@ -25,11 +24,15 @@ import (
var (
PrivKey14K = "CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944" // 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
Account14K = "14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
Account1MC = "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
applyAddrs = "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4, 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR, 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
Bls14K = "80e713aae96a44607ba6e0f1acfe88641ac72b789e81696cb646b1e1ae5335bd92011593eee303f9e909fd752c762db3"
applyAddrs = "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4,1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR,1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k,1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
PrivKey1KS = "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
Account12Q = "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
PrivKey12Q = "4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
PrivKey1Ku = "0xb1474387fe5beda4d6a9d999226bab561c708e07da15d74d575dad890e24cef0"
Account1Ku = "1KufZaLTKVAy37AsXNd9bsva5WZvP8w5uG"
PrivKey1M3 = "0xa4ebb30bd017f3d8e60532dd4f7059704d7897071fc07482aa0681c57c88f874"
Account1M3 = "1M3XCbWVxAPBH5AR8VmLky4ZtDdGgC6ugD"
)
// createRawNodeConfigTx create raw tx for node config
......@@ -60,7 +63,6 @@ func createRawNodeGroupApplyTx(apply *pt.ParaNodeGroupConfig) (*types.Transactio
}
return tx, nil
}
type NodeManageTestSuite struct {
......@@ -68,13 +70,10 @@ type NodeManageTestSuite struct {
stateDB dbm.KV
localDB *dbmock.KVDB
api *apimock.QueueProtocolAPI
exec *Paracross
//title string
exec *Paracross
}
func (suite *NodeManageTestSuite) SetupSuite() {
suite.stateDB, _ = dbm.NewGoMemDB("state", "state", 1024)
// memdb 不支持KVDB接口, 等测试完Exec , 再扩展 memdb
//suite.localDB, _ = dbm.NewGoMemDB("local", "local", 1024)
......@@ -82,6 +81,14 @@ func (suite *NodeManageTestSuite) SetupSuite() {
suite.api = new(apimock.QueueProtocolAPI)
suite.api.On("GetConfig", mock.Anything).Return(chain33TestCfg, nil)
block := &types.Block{
Height: 1,
MainHeight: 10,
}
detail := &types.BlockDetail{Block: block}
details := &types.BlockDetails{Items: []*types.BlockDetail{detail}}
suite.api.On("GetBlocks", mock.Anything).Return(details, nil)
suite.exec = newParacross().(*Paracross)
suite.exec.SetAPI(suite.api)
suite.exec.SetLocalDB(suite.localDB)
......@@ -90,12 +97,6 @@ func (suite *NodeManageTestSuite) SetupSuite() {
suite.exec.SetBlockInfo([]byte(""), []byte(""), 3)
enableParacrossTransfer = false
//forkHeight := types.GetDappFork(pt.ParaX, pt.ForkCommitTx)
//if forkHeight == types.MaxHeight {
// types.ReplaceDappFork(MainTitle, pt.ParaX, pt.ForkCommitTx, 0)
//
//}
chain33TestCfg.S("config.consensus.sub.para.MainForkParacrossCommitTx", int64(1))
chain33TestCfg.S("config.exec.sub.manage.superManager", []interface{}{Account12Q})
......@@ -105,7 +106,6 @@ func (suite *NodeManageTestSuite) SetupSuite() {
Block: &types.Block{},
}
MainBlockHash10 = blockDetail.Block.Hash(chain33TestCfg)
}
func (suite *NodeManageTestSuite) TestSetup() {
......@@ -143,9 +143,7 @@ func checkGroupApplyReceipt(suite *NodeManageTestSuite, receipt *types.Receipt)
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 1)
assert.Len(suite.T(), receipt.Logs, 1)
assert.Equal(suite.T(), int32(pt.TyLogParaNodeGroupConfig), receipt.Logs[0].Ty)
}
func checkGroupApproveReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
......@@ -160,11 +158,9 @@ func checkJoinReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
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.TyLogParaNodeConfig), receipt.Logs[0].Ty)
assert.Equal(suite.T(), int32(pt.ParaApplyJoining), stat.Status)
assert.NotNil(suite.T(), stat.Votes)
}
func checkQuitReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
......@@ -179,7 +175,6 @@ func checkQuitReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
assert.Equal(suite.T(), int32(pt.TyLogParaNodeConfig), receipt.Logs[0].Ty)
assert.Equal(suite.T(), int32(pt.ParaApplyQuiting), stat.Status)
assert.NotNil(suite.T(), stat.Votes)
}
func checkVoteReceipt(suite *NodeManageTestSuite, receipt *types.Receipt, count int) {
......@@ -189,15 +184,14 @@ func checkVoteReceipt(suite *NodeManageTestSuite, receipt *types.Receipt, count
err := types.Decode(receipt.KV[0].Value, &stat)
assert.Nil(suite.T(), err, "decode ParaNodeAddrStatus failed")
assert.Len(suite.T(), stat.Votes.Votes, count)
}
func checkVoteDoneReceipt(suite *NodeManageTestSuite, receipt *types.Receipt, count int, join bool) {
_ = count
suite.NotNil(receipt)
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
suite.T().Log("checkVoteDoneReceipt", "kvlen", len(receipt.KV))
_, arry, err := getParacrossNodes(suite.stateDB, Title)
suite.Suite.Nil(err)
if join {
......@@ -249,7 +243,6 @@ func (suite *NodeManageTestSuite) testNodeGroupConfigQuit() {
receipt := nodeCommit(suite, PrivKeyB, tx)
checkGroupApplyReceipt(suite, receipt)
suite.Equal(int32(pt.TyLogParaNodeGroupConfig), receipt.Logs[0].Ty)
var g pt.ReceiptParaNodeGroupConfig
err = types.Decode(receipt.Logs[0].Log, &g)
suite.Nil(err)
......@@ -263,8 +256,6 @@ func (suite *NodeManageTestSuite) testNodeGroupConfigQuit() {
suite.Nil(err)
nodeCommit(suite, PrivKeyB, tx)
//checkGroupApproveReceipt(suite, receipt)
}
func (suite *NodeManageTestSuite) testNodeGroupConfig() {
......@@ -281,7 +272,6 @@ func (suite *NodeManageTestSuite) testNodeGroupConfig() {
receipt := nodeCommit(suite, PrivKeyB, tx)
checkGroupApplyReceipt(suite, receipt)
suite.Equal(int32(pt.TyLogParaNodeGroupConfig), receipt.Logs[0].Ty)
var g pt.ReceiptParaNodeGroupConfig
err = types.Decode(receipt.Logs[0].Log, &g)
suite.Nil(err)
......@@ -296,7 +286,6 @@ func (suite *NodeManageTestSuite) testNodeGroupConfig() {
receipt = nodeCommit(suite, PrivKey12Q, tx)
checkGroupApproveReceipt(suite, receipt)
}
func (suite *NodeManageTestSuite) testNodeConfig() {
......@@ -340,9 +329,14 @@ func (suite *NodeManageTestSuite) testNodeConfig() {
}
func (suite *NodeManageTestSuite) TestExec() {
suite.testSuperExec()
suite.testSupervisionExec()
}
func (suite *NodeManageTestSuite) testSuperExec() {
suite.testNodeGroupConfig()
suite.testNodeConfig()
suite.testSuperQuery()
}
func TestNodeManageSuite(t *testing.T) {
......@@ -350,7 +344,6 @@ func TestNodeManageSuite(t *testing.T) {
}
func (suite *NodeManageTestSuite) TearDownSuite() {
}
func TestGetAddrGroup(t *testing.T) {
......@@ -374,7 +367,6 @@ func TestGetAddrGroup(t *testing.T) {
ret = getConfigAddrs(addrs)
assert.Equal(t, []string(nil), ret)
assert.Equal(t, 0, len(ret))
}
func TestUpdateVotes(t *testing.T) {
......@@ -402,5 +394,30 @@ func TestGetNodeIdSuffix(t *testing.T) {
id = "mavl-paracross-title-nodegroupid-user.p.para.-0xb6cd0274aa5f839fa2291ecfbfc626b494aacac7587a61e444e9f848a4c02d7b-1"
rtID = getParaNodeIDSuffix(id)
assert.Equal(t, txID, rtID)
}
func (suite *NodeManageTestSuite) testSuperQuery() {
ret, err := suite.exec.Query_GetNodeGroupAddrs(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle()})
suite.Nil(err)
resp, ok := ret.(*types.ReplyConfig)
assert.Equal(suite.T(), ok, true)
assert.Equal(suite.T(), resp.Value, applyAddrs)
ret, err = suite.exec.Query_GetNodeAddrInfo(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle(), Addr: "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"})
suite.Nil(err)
resp2, ok := ret.(*pt.ParaNodeAddrIdStatus)
assert.Equal(suite.T(), ok, true)
assert.NotNil(suite.T(), resp2)
_, err = suite.exec.Query_GetNodeAddrInfo(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle(), Addr: "1FbS6G4CRYAYeSEPGg7uKP9MukUo6crEE5"})
suite.NotNil(err)
ret, err = suite.exec.Query_GetNodeGroupStatus(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle()})
suite.Nil(err)
resp3, ok := ret.(*pt.ParaNodeGroupStatus)
assert.Equal(suite.T(), ok, true)
assert.Equal(suite.T(), resp3.Status, int32(pt.ParacrossNodeGroupApprove))
_, err = suite.exec.Query_GetNodeIDInfo(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle(), Id: "mavl-paracross-title-nodeid-user.p.test.-0x8cf0e600667b8e6cf66516369acd4e1b5f6c93b3ae1c0b5edf458dfbe01f1607"})
suite.Nil(err)
}
package executor
import (
"github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
)
func makeParaSupervisionNodeGroupReceipt(title string, prev, current *types.ConfigItem) *types.Receipt {
key := calcParaSupervisionNodeGroupAddrsKey(title)
log := &types.ReceiptConfig{Prev: prev, Current: current}
return &types.Receipt{
Ty: types.ExecOk,
KV: []*types.KeyValue{
{Key: key, Value: types.Encode(current)},
},
Logs: []*types.ReceiptLog{
{
Ty: pt.TyLogParaSupervisionNodeGroupAddrsUpdate,
Log: types.Encode(log),
},
},
}
}
func makeSupervisionNodeConfigReceipt(fromAddr string, config *pt.ParaNodeAddrConfig, prev, current *pt.ParaNodeIdStatus) *types.Receipt {
log := &pt.ReceiptParaNodeConfig{
Addr: fromAddr,
Config: config,
Prev: prev,
Current: current,
}
return &types.Receipt{
Ty: types.ExecOk,
KV: []*types.KeyValue{
{Key: []byte(current.Id), Value: types.Encode(current)},
},
Logs: []*types.ReceiptLog{
{
Ty: pt.TyLogParaSupervisionNodeConfig,
Log: types.Encode(log),
},
},
}
}
func makeParaSupervisionNodeStatusReceipt(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.TyLogParaSupervisionNodeStatusUpdate,
Log: types.Encode(log),
},
},
}
}
func getSupervisionNodeID(db dbm.KV, title string, id string) (*pt.ParaNodeIdStatus, error) {
id = calcParaSupervisionNodeIDKey(title, id)
val, err := getDb(db, []byte(id))
if err != nil {
return nil, err
}
var status pt.ParaNodeIdStatus
err = types.Decode(val, &status)
return &status, err
}
func (a *action) updateSupervisionNodeGroup(title, addr string, add bool) (*types.Receipt, error) {
var item types.ConfigItem
key := calcParaSupervisionNodeGroupAddrsKey(title)
value, err := a.db.Get(key)
if err != nil {
return nil, err
}
if value != nil {
err = types.Decode(value, &item)
if err != nil {
clog.Error("updateSupervisionNodeGroup", "decode db key", key)
return nil, err
}
}
copyValue := *item.GetArr()
copyItem := item
copyItem.Value = &types.ConfigItem_Arr{Arr: &copyValue}
receipt := &types.Receipt{Ty: types.ExecOk}
item.Addr = addr
if add {
item.GetArr().Value = append(item.GetArr().Value, addr)
clog.Info("updateSupervisionNodeGroup add", "addr", addr)
} else {
item.GetArr().Value = make([]string, 0)
for _, value := range copyItem.GetArr().Value {
if value != addr {
item.GetArr().Value = append(item.GetArr().Value, value)
}
}
clog.Info("updateSupervisionNodeGroup delete", "addr", addr)
}
err = a.db.Set(key, types.Encode(&item))
if err != nil {
return nil, errors.Wrapf(err, "updateNodeGroup set dbkey=%s", key)
}
r := makeParaSupervisionNodeGroupReceipt(title, &copyItem, &item)
receipt = mergeReceipt(receipt, r)
return receipt, nil
}
func (a *action) checkValidSupervisionNode(config *pt.ParaNodeAddrConfig) (bool, error) {
key := calcParaSupervisionNodeGroupAddrsKey(config.Title)
nodes, _, err := getNodes(a.db, key)
if err != nil && !(isNotFound(err) || errors.Cause(err) == pt.ErrTitleNotExist) {
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) checkSupervisionNodeGroupExist(title string) (bool, error) {
key := calcParaSupervisionNodeGroupAddrsKey(title)
value, err := a.db.Get(key)
if err != nil && !isNotFound(err) {
return false, err
}
if value != nil {
var item types.ConfigItem
err = types.Decode(value, &item)
if err != nil {
clog.Error("updateSupervisionNodeGroup", "decode db key", key)
return false, err
}
return true, nil
}
return false, nil
}
func (a *action) supervisionNodeGroupCreate(title, targetAddrs string) (*types.Receipt, error) {
var item types.ConfigItem
key := calcParaSupervisionNodeGroupAddrsKey(title)
item.Key = string(key)
emptyValue := &types.ArrayConfig{Value: make([]string, 0)}
arr := types.ConfigItem_Arr{Arr: emptyValue}
item.Value = &arr
item.GetArr().Value = append(item.GetArr().Value, targetAddrs)
item.Addr = a.fromaddr
receipt := makeParaSupervisionNodeGroupReceipt(title, nil, &item)
return receipt, nil
}
//由于propasal id 和quit id分开,quit id不知道对应addr proposal id的coinfrozen信息,需要维护一个围绕addr的数据库结构信息
func (a *action) updateSupervisionNodeAddrStatus(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.BlsPubKey = stat.BlsPubKey
addrStat.Status = pt.ParacrossSupervisionNodeApprove
addrStat.ProposalId = stat.Id
addrStat.QuitId = ""
return makeParaSupervisionNodeStatusReceipt(a.fromaddr, nil, addrStat), nil
}
preStat := *addrStat
if stat.Status == pt.ParacrossSupervisionNodeQuit {
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 = stat.Status
addrStat.QuitId = stat.Id
receipt := makeParaSupervisionNodeStatusReceipt(a.fromaddr, &preStat, addrStat)
cfg := a.api.GetConfig()
if !cfg.IsPara() {
r, err := a.nodeGroupCoinsActive(proposalStat.FromAddr, proposalStat.CoinsFrozen, 1)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
}
return receipt, nil
} else {
addrStat.Status = stat.Status
addrStat.ProposalId = stat.Id
addrStat.QuitId = ""
return makeParaSupervisionNodeStatusReceipt(a.fromaddr, &preStat, addrStat), nil
}
}
func (a *action) supervisionNodeApply(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, "supervisionNodeGroup Apply Addr existed:%s in super group", config.Addr)
}
// 判断 node 是否已经申请
addrExist, err = a.checkValidSupervisionNode(config)
if err != nil {
return nil, err
}
if addrExist {
return nil, errors.Wrapf(pt.ErrParaSupervisionNodeAddrExisted, "supervisionNodeGroup Apply Addr existed:%s", config.Addr)
}
// 在主链上冻结金额
receipt := &types.Receipt{Ty: types.ExecOk}
cfg := a.api.GetConfig()
if !cfg.IsPara() {
r, err := a.nodeGroupCoinsFrozen(a.fromaddr, config.CoinsFrozen, 1)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
}
stat := &pt.ParaNodeIdStatus{
Id: calcParaSupervisionNodeIDKey(config.Title, common.ToHex(a.txhash)),
Status: pt.ParacrossSupervisionNodeApply,
Title: config.Title,
TargetAddr: config.Addr,
BlsPubKey: config.BlsPubKey,
CoinsFrozen: config.CoinsFrozen,
FromAddr: a.fromaddr,
Height: a.height,
}
r := makeSupervisionNodeConfigReceipt(a.fromaddr, config, nil, stat)
receipt = mergeReceipt(receipt, r)
return receipt, nil
}
func (a *action) supervisionNodeApprove(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
cfg := a.api.GetConfig()
//只在主链检查
if !cfg.IsPara() && !isSuperManager(cfg, a.fromaddr) {
return nil, errors.Wrapf(types.ErrNotAllow, "node group approve not supervision manager:%s", a.fromaddr)
}
apply, err := getSupervisionNodeID(a.db, config.Title, config.Id)
if err != nil {
return nil, err
}
if config.Title != apply.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, apply.Title)
}
if apply.CoinsFrozen < config.CoinsFrozen {
return nil, errors.Wrapf(pt.ErrParaNodeGroupFrozenCoinsNotEnough, "id not enough coins apply:%d,config:%d", apply.CoinsFrozen, config.CoinsFrozen)
}
// 判断监督账户组是否已经存在
exist, err := a.checkSupervisionNodeGroupExist(config.Title)
if err != nil {
return nil, err
}
receipt := &types.Receipt{Ty: types.ExecOk}
if !exist {
// 监督账户组不存在
r, err := a.supervisionNodeGroupCreate(apply.Title, apply.TargetAddr)
if err != nil {
return nil, errors.Wrapf(err, "nodegroup create:title:%s,addrs:%s", config.Title, apply.TargetAddr)
}
receipt = mergeReceipt(receipt, r)
} else {
// 监督账户组已经存在
r, err := a.updateSupervisionNodeGroup(config.Title, apply.TargetAddr, true)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
}
copyStat := proto.Clone(apply).(*pt.ParaNodeIdStatus)
apply.Status = pt.ParacrossSupervisionNodeApprove
apply.Height = a.height
r, err := a.updateSupervisionNodeAddrStatus(apply)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
r = makeSupervisionNodeConfigReceipt(a.fromaddr, config, copyStat, apply)
receipt = mergeReceipt(receipt, r)
return receipt, nil
}
func (a *action) supervisionNodeQuit(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
addrExist, err := a.checkValidSupervisionNode(config)
if err != nil {
return nil, err
}
if !addrExist {
return nil, errors.Wrapf(pt.ErrParaSupervisionNodeAddrNotExisted, "nodeAddr not existed:%s", config.Addr)
}
status, err := getNodeAddr(a.db, config.Title, config.Addr)
if err != nil {
return nil, errors.Wrapf(err, "nodeAddr:%s get error", config.Addr)
}
if status.Status != pt.ParacrossSupervisionNodeApprove {
return nil, errors.Wrapf(pt.ErrParaSupervisionNodeAddrNotExisted, "nodeAddr:%s status:%d", config.Addr, status.Status)
}
cfg := a.api.GetConfig()
stat := &pt.ParaNodeIdStatus{
Id: status.ProposalId,
Status: pt.ParacrossSupervisionNodeQuit,
Title: config.Title,
TargetAddr: config.Addr,
FromAddr: a.fromaddr,
Height: a.height,
}
//只能提案发起人或超级节点可以撤销
if a.fromaddr != status.Addr && !cfg.IsPara() && !isSuperManager(cfg, a.fromaddr) {
return nil, errors.Wrapf(types.ErrNotAllow, "id create by:%s,not by:%s", status.Addr, a.fromaddr)
}
if config.Title != status.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, status.Title)
}
receipt := &types.Receipt{Ty: types.ExecOk}
// node quit后,如果committx满足2/3目标,自动触发commitDone 后期增加
r, err := a.loopCommitTxDone(config.Title)
if err != nil {
clog.Error("updateSupervisionNodeGroup.loopCommitTxDone", "title", config.Title, "err", err.Error())
}
receipt = mergeReceipt(receipt, r)
r, err = a.updateSupervisionNodeGroup(config.Title, stat.TargetAddr, false)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
r, err = a.updateSupervisionNodeAddrStatus(stat)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
r = makeSupervisionNodeConfigReceipt(a.fromaddr, config, nil, stat)
receipt = mergeReceipt(receipt, r)
return receipt, nil
}
func (a *action) supervisionNodeCancel(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
cfg := a.api.GetConfig()
status, err := getSupervisionNodeID(a.db, config.Title, config.Id)
if err != nil {
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)
}
if status.Status != pt.ParacrossSupervisionNodeApply {
return nil, errors.Wrapf(pt.ErrParaNodeOpStatusWrong, "config id:%s,status:%d", config.Id, status.Status)
}
receipt := &types.Receipt{Ty: types.ExecOk}
//main chain
if !cfg.IsPara() {
r, err := a.nodeGroupCoinsActive(status.FromAddr, status.CoinsFrozen, 1)
if err != nil {
return nil, err
}
receipt = mergeReceipt(receipt, r)
}
copyStat := proto.Clone(status).(*pt.ParaNodeIdStatus)
status.Status = pt.ParacrossSupervisionNodeCancel
status.Height = a.height
r := makeSupervisionNodeConfigReceipt(a.fromaddr, config, copyStat, status)
receipt = mergeReceipt(receipt, r)
return receipt, nil
}
func (a *action) supervisionNodeModify(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
addrStat, err := getNodeAddr(a.db, config.Title, config.Addr)
if err != nil {
return nil, errors.Wrapf(err, "nodeAddr:%s get error", config.Addr)
}
// 只能提案发起人
if a.fromaddr != config.Addr {
return nil, errors.Wrapf(types.ErrNotAllow, "addr create by:%s,not by:%s", config.Addr, a.fromaddr)
}
preStat := *addrStat
addrStat.BlsPubKey = config.BlsPubKey
return makeParaSupervisionNodeStatusReceipt(a.fromaddr, &preStat, addrStat), nil
}
func (a *action) SupervisionNodeConfig(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
cfg := a.api.GetConfig()
if !validTitle(cfg, config.Title) {
return nil, pt.ErrInvalidTitle
}
if !types.IsParaExecName(string(a.tx.Execer)) {
return nil, errors.Wrapf(types.ErrInvalidParam, "exec=%s,should prefix with user.p.", string(a.tx.Execer))
}
if (config.Op == pt.ParacrossSupervisionNodeApprove || config.Op == pt.ParacrossSupervisionNodeCancel) && config.Id == "" {
return nil, types.ErrInvalidParam
}
if config.Op == pt.ParacrossSupervisionNodeApply {
return a.supervisionNodeApply(config)
} else if config.Op == pt.ParacrossSupervisionNodeApprove {
return a.supervisionNodeApprove(config)
} else if config.Op == pt.ParacrossSupervisionNodeQuit {
// 退出 group
return a.supervisionNodeQuit(config)
} else if config.Op == pt.ParacrossSupervisionNodeCancel {
// 撤销未批准的申请
return a.supervisionNodeCancel(config)
} else if config.Op == pt.ParacrossSupervisionNodeModify {
return a.supervisionNodeModify(config)
}
return nil, pt.ErrParaUnSupportNodeOper
}
平行链目前有超级节点和普通节点两个角色,对超级节点账户组没有制衡的角色
波卡有钓鱼节点的概念,可以监督验证节点。chain33 也可以增加一个监督节点
基本功能如下:
1. 监督节点可以是一个节点也可以是监督节点账户组。
1. 监督节点账户组和超级节点账户组共识逻辑一样,都是超过2/3节点的共识结果,否则认为没有达成共识
1. 如果监督节点或超级节点账户组任何一方没有达成共识,认为暂时没有达成共识
1. 如果监督节点和超级节点的共识结果不一致,则暂时搁置共识,等待修正共识。不做处罚处理
1. 所有参与共识的监督节点和超级节点 前2/3节点平分挖矿奖励。
\ No newline at end of file
package executor
import (
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/stretchr/testify/assert"
)
// createRawSupervisionNodeConfigTx create raw tx for node config
func createRawSupervisionNodeConfigTx(config *pt.ParaNodeAddrConfig) *types.Transaction {
action := &pt.ParacrossAction{
Ty: pt.ParacrossActionSupervisionNodeConfig,
Value: &pt.ParacrossAction_SupervisionNodeConfig{SupervisionNodeConfig: config},
}
tx := &types.Transaction{
Payload: types.Encode(action),
Execer: []byte(config.Title + pt.ParaX),
}
return tx
}
func (suite *NodeManageTestSuite) testSupervisionExec() {
suite.testSupervisionNodeConfigCancel(Account14K, PrivKey14K)
suite.testSupervisionNodeConfigApprove(Account14K, PrivKey14K)
suite.testSupervisionNodeConfigApprove(Account1Ku, PrivKey1Ku)
suite.testSupervisionNodeConfigApprove(Account1M3, PrivKey1M3)
suite.testSupervisionNodeError()
suite.testSupervisionQuery()
suite.testSupervisionNodeQuit()
suite.testSupervisionNodeModify()
}
func (suite *NodeManageTestSuite) testSupervisionNodeConfigCancel(addr, privKey string) {
// Apply
config := &pt.ParaNodeAddrConfig{
Title: chain33TestCfg.GetTitle(),
Op: pt.ParacrossSupervisionNodeApply,
Addr: addr,
}
tx := createRawSupervisionNodeConfigTx(config)
receipt := nodeCommit(suite, privKey, tx)
checkSupervisionGroupApplyReceipt(suite, receipt)
var g pt.ReceiptParaNodeGroupConfig
err := types.Decode(receipt.Logs[0].Log, &g)
suite.Nil(err)
// cancel
config = &pt.ParaNodeAddrConfig{
Title: chain33TestCfg.GetTitle(),
Op: pt.ParacrossSupervisionNodeCancel,
Id: getParaNodeIDSuffix(g.Current.Id),
}
tx = createRawSupervisionNodeConfigTx(config)
receipt = nodeCommit(suite, privKey, tx)
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
}
func (suite *NodeManageTestSuite) testSupervisionNodeConfigApprove(addr, privKey string) {
config := &pt.ParaNodeAddrConfig{
Title: chain33TestCfg.GetTitle(),
Op: pt.ParacrossSupervisionNodeApply,
Addr: addr,
}
tx := createRawSupervisionNodeConfigTx(config)
receipt := nodeCommit(suite, privKey, tx)
checkSupervisionGroupApplyReceipt(suite, receipt)
var g pt.ReceiptParaNodeGroupConfig
err := types.Decode(receipt.Logs[0].Log, &g)
suite.Nil(err)
config = &pt.ParaNodeAddrConfig{
Title: chain33TestCfg.GetTitle(),
Id: getParaNodeIDSuffix(g.Current.Id),
Op: pt.ParacrossSupervisionNodeApprove,
}
tx = createRawSupervisionNodeConfigTx(config)
receipt = nodeCommit(suite, privKey, tx)
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
}
func (suite *NodeManageTestSuite) testSupervisionNodeError() {
config := &pt.ParaNodeAddrConfig{
Title: chain33TestCfg.GetTitle(),
Op: pt.ParacrossSupervisionNodeApply,
Addr: Account1M3,
}
tx := createRawSupervisionNodeConfigTx(config)
tx, _ = signTx(suite.Suite, tx, PrivKey1M3)
_, err := suite.exec.Exec(tx, 0)
suite.NotNil(err)
config = &pt.ParaNodeAddrConfig{
Title: chain33TestCfg.GetTitle(),
Op: pt.ParacrossSupervisionNodeApply,
Addr: "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4",
}
tx = createRawSupervisionNodeConfigTx(config)
tx, _ = signTx(suite.Suite, tx, PrivKey1KS)
_, err = suite.exec.Exec(tx, 0)
suite.NotNil(err)
}
func (suite *NodeManageTestSuite) testSupervisionNodeQuit() {
config := &pt.ParaNodeAddrConfig{
Title: chain33TestCfg.GetTitle(),
Op: pt.ParacrossSupervisionNodeQuit,
Addr: Account1Ku,
}
tx := createRawSupervisionNodeConfigTx(config)
receipt := nodeCommit(suite, PrivKey1Ku, tx)
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 3)
assert.Len(suite.T(), receipt.Logs, 3)
assert.Equal(suite.T(), int32(pt.TyLogParaSupervisionNodeGroupAddrsUpdate), receipt.Logs[0].Ty)
ret, err := suite.exec.Query_GetSupervisionNodeGroupAddrs(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle()})
suite.Nil(err)
resp, ok := ret.(*types.ReplyConfig)
assert.Equal(suite.T(), ok, true)
assert.Equal(suite.T(), resp.Value, "14KEKbYtKKQm4wMthSK9J4La4nAiidGozt,1M3XCbWVxAPBH5AR8VmLky4ZtDdGgC6ugD")
}
func (suite *NodeManageTestSuite) testSupervisionNodeModify() {
config := &pt.ParaNodeAddrConfig{
Title: chain33TestCfg.GetTitle(),
Op: pt.ParacrossSupervisionNodeModify,
Addr: Account14K,
BlsPubKey: Bls14K,
}
tx := createRawSupervisionNodeConfigTx(config)
receipt := nodeCommit(suite, PrivKey14K, tx)
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 1)
assert.Len(suite.T(), receipt.Logs, 1)
assert.Equal(suite.T(), int32(pt.TyLogParaSupervisionNodeStatusUpdate), receipt.Logs[0].Ty)
ret, err := suite.exec.Query_GetNodeAddrInfo(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle(), Addr: Account14K})
suite.Nil(err)
resp, ok := ret.(*pt.ParaNodeAddrIdStatus)
assert.Equal(suite.T(), ok, true)
assert.NotNil(suite.T(), resp)
assert.Equal(suite.T(), resp.BlsPubKey, Bls14K)
}
func checkSupervisionGroupApplyReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
assert.Equal(suite.T(), receipt.Ty, int32(types.ExecOk))
assert.Len(suite.T(), receipt.KV, 1)
assert.Len(suite.T(), receipt.Logs, 1)
assert.Equal(suite.T(), int32(pt.TyLogParaSupervisionNodeConfig), receipt.Logs[0].Ty)
}
func (suite *NodeManageTestSuite) testSupervisionQuery() {
ret, err := suite.exec.Query_GetSupervisionNodeGroupAddrs(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle()})
suite.Nil(err)
resp, ok := ret.(*types.ReplyConfig)
assert.Equal(suite.T(), ok, true)
assert.Equal(suite.T(), resp.Value, "14KEKbYtKKQm4wMthSK9J4La4nAiidGozt,1KufZaLTKVAy37AsXNd9bsva5WZvP8w5uG,1M3XCbWVxAPBH5AR8VmLky4ZtDdGgC6ugD")
ret, err = suite.exec.Query_GetNodeAddrInfo(&pt.ReqParacrossNodeInfo{Title: chain33TestCfg.GetTitle(), Addr: Account14K})
suite.Nil(err)
resp2, ok := ret.(*pt.ParaNodeAddrIdStatus)
assert.Equal(suite.T(), ok, true)
assert.NotNil(suite.T(), resp2)
}
......@@ -21,23 +21,26 @@ message ParacrossStatusBlockDetails {
message ParacrossHeightStatus {
// ing, done
int32 status = 1;
string title = 2;
int64 height = 3;
ParacrossStatusDetails details = 4;
int64 mainHeight = 5;
bytes mainHash = 6;
ParacrossStatusBlockDetails blockDetails = 7;
int32 status = 1;
string title = 2;
int64 height = 3;
ParacrossStatusDetails details = 4;
int64 mainHeight = 5;
bytes mainHash = 6;
ParacrossStatusBlockDetails blockDetails = 7;
ParacrossStatusDetails supervisionDetails = 8;
}
message ParacrossHeightStatusRsp {
int32 status = 1;
string title = 2;
int64 height = 3;
int64 mainHeight = 4;
string mainHash = 5;
repeated string commitAddrs = 6;
repeated string commitBlockHash = 7;
int32 status = 1;
string title = 2;
int64 height = 3;
int64 mainHeight = 4;
string mainHash = 5;
repeated string commitAddrs = 6;
repeated string commitBlockHash = 7;
repeated string commitSupervisionAddrs = 8;
repeated string commitSupervisionBlockHash = 9;
}
message ParacrossStatus {
......@@ -351,8 +354,9 @@ message ParacrossAction {
ParaNodeAddrConfig nodeConfig = 9;
ParaNodeGroupConfig nodeGroupConfig = 10;
ParaStageConfig selfStageConfig = 11;
CrossAssetTransfer crossAssetTransfer = 12;
ParaBindMinerCmd paraBindMiner = 13;
CrossAssetTransfer crossAssetTransfer = 12;
ParaBindMinerCmd paraBindMiner = 13;
ParaNodeAddrConfig supervisionNodeConfig = 14;
}
int32 ty = 2;
}
......@@ -385,6 +389,9 @@ message ReceiptParacrossDone {
bytes mainBlockHash = 13;
int64 mainBlockHeight = 14;
int64 chainExecHeight = 15;
int32 totalSupervisionNodes = 16;
int32 totalSupervisionCommit = 17;
int32 mostSupervisionCommit = 18;
}
message ReceiptParacrossRecord {
......
......@@ -59,4 +59,12 @@ var (
ErrConsensClosed = errors.New("ErrConsensClosed")
//ErrBlsSignVerify bls12-381 aggregate sign verify
ErrBlsSignVerify = errors.New("ErrBlsSignVerify")
//ErrParaSupervisionNodeAddrExisted node addr exist in group
ErrParaSupervisionNodeAddrExisted = errors.New("ErrParaSupervisionNodeAddrExisted")
//ErrParaSupervisionNodeGroupNotSet para config node group not set by take over
ErrParaSupervisionNodeGroupNotSet = errors.New("ErrParaSupervisionNodeGroupNotSet")
//ErrParaSupervisionNodeGroupExisted para config group taked over alreay
ErrParaSupervisionNodeGroupExisted = errors.New("ErrParaSupervisionNodesExisted")
//ErrParaSupervisionNodeAddrNotExisted node addr not exist in supervision group
ErrParaSupervisionNodeAddrNotExisted = errors.New("ErrParaSupervisionNodeAddrNotExisted")
)
......@@ -49,6 +49,10 @@ const (
TyLogParaCrossAssetTransfer = 670
TyLogParaBindMinerAddr = 671
TyLogParaBindMinerNode = 672
// Supervision Node
TyLogParaSupervisionNodeConfig = 680
TyLogParaSupervisionNodeGroupAddrsUpdate = 681
TyLogParaSupervisionNodeStatusUpdate = 682
)
// action type
......@@ -91,6 +95,8 @@ const (
// ParacrossActionCrossAssetTransfer crossChain asset transfer key
//注意: 此类型之后的一定也需要是跨链资产转移类型,方便代码计算,也就是在共识完成后,execCrossTx()处理到的类型。
ParacrossActionCrossAssetTransfer
// ParacrossActionSupervisionNodeConfig
ParacrossActionSupervisionNodeConfig
)
//跨链共识交易crossResult bitmap版本,支持多版本的bitmap管理
......@@ -184,6 +190,21 @@ const (
ParacrossNodeGroupModify
)
const (
ParacrossSupervisionNodeApply = iota + 1
ParacrossSupervisionNodeApprove
ParacrossSupervisionNodeQuit
ParacrossSupervisionNodeCancel
ParacrossSupervisionNodeModify
)
// 0 普通节点共识 1 授权节点正在共识 2 监督节点正在共识
const (
ParaCommitNode = iota
ParaCommitSuperNode
ParaCommitSupervisionNode
)
var (
// ParacrossActionCommitStr Commit string
ParacrossActionCommitStr = string("Commit")
......@@ -338,6 +359,7 @@ func GetDappForkHeight(cfg *types.Chain33Config, forkKey string) int64 {
if forkHeight <= 0 {
forkHeight = types.MaxHeight
}
} else {
forkHeight = cfg.GetDappFork(ParaX, forkKey)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -24,10 +24,14 @@ var (
ForkLoopCheckCommitTxDone = "ForkLoopCheckCommitTxDone"
// MainLoopCheckCommitTxDoneForkHeight 平行链的配置项,对应主链的ForkLoopCheckCommitTxDone高度
MainLoopCheckCommitTxDoneForkHeight = "mainLoopCheckCommitTxDoneForkHeight"
//MainForkParaSupervision = "mainForkParaSupervision"
// ForkParaSelfConsStages 平行链自共识分阶段共识
ForkParaSelfConsStages = "ForkParaSelfConsStages"
// ForkParaAssetTransferRbk 平行链资产转移平行链失败主链回滚
ForkParaAssetTransferRbk = "ForkParaAssetTransferRbk"
// ForkParaSupervision 平行链新增监督节点
ForkParaSupervision = "ForkParaSupervision"
// ForkParaFullMinerHeight 平行链全挖矿开启高度
ForkParaFullMinerHeight = "ForkParaFullMinerHeight"
......@@ -58,6 +62,7 @@ func InitFork(cfg *types.Chain33Config) {
cfg.RegisterDappFork(ParaX, ForkCommitTx, 1850000)
cfg.RegisterDappFork(ParaX, ForkLoopCheckCommitTxDone, 3230000)
cfg.RegisterDappFork(ParaX, ForkParaAssetTransferRbk, 4500000)
cfg.RegisterDappFork(ParaX, ForkParaSupervision, 6000000)
//只在平行链启用
cfg.RegisterDappFork(ParaX, ForkParaSelfConsStages, types.MaxHeight)
......@@ -95,43 +100,47 @@ func (p *ParacrossType) GetName() string {
// GetLogMap get receipt log map
func (p *ParacrossType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogParacrossCommit: {Ty: reflect.TypeOf(ReceiptParacrossCommit{}), Name: "LogParacrossCommit"},
TyLogParacrossCommitDone: {Ty: reflect.TypeOf(ReceiptParacrossDone{}), Name: "LogParacrossCommitDone"},
TyLogParacrossCommitRecord: {Ty: reflect.TypeOf(ReceiptParacrossRecord{}), Name: "LogParacrossCommitRecord"},
TyLogParaAssetWithdraw: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetWithdraw"},
TyLogParaAssetTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetTransfer"},
TyLogParaAssetDeposit: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetDeposit"},
TyLogParaCrossAssetTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaCrossAssetTransfer"},
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"},
TyLogParaNodeGroupStatusUpdate: {Ty: reflect.TypeOf(ReceiptParaNodeGroupConfig{}), Name: "LogParaNodeGroupStatusUpdate"},
TyLogParaSelfConsStageConfig: {Ty: reflect.TypeOf(ReceiptSelfConsStageConfig{}), Name: "LogParaSelfConsStageConfig"},
TyLogParaStageVoteDone: {Ty: reflect.TypeOf(ReceiptSelfConsStageVoteDone{}), Name: "LogParaSelfConfStageVoteDoen"},
TyLogParaStageGroupUpdate: {Ty: reflect.TypeOf(ReceiptSelfConsStagesUpdate{}), Name: "LogParaSelfConfStagesUpdate"},
TyLogParaBindMinerAddr: {Ty: reflect.TypeOf(ReceiptParaBindMinerInfo{}), Name: "TyLogParaBindMinerAddrUpdate"},
TyLogParaBindMinerNode: {Ty: reflect.TypeOf(ReceiptParaNodeBindListUpdate{}), Name: "TyLogParaBindNodeListUpdate"},
TyLogParacrossCommit: {Ty: reflect.TypeOf(ReceiptParacrossCommit{}), Name: "LogParacrossCommit"},
TyLogParacrossCommitDone: {Ty: reflect.TypeOf(ReceiptParacrossDone{}), Name: "LogParacrossCommitDone"},
TyLogParacrossCommitRecord: {Ty: reflect.TypeOf(ReceiptParacrossRecord{}), Name: "LogParacrossCommitRecord"},
TyLogParaAssetWithdraw: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetWithdraw"},
TyLogParaAssetTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetTransfer"},
TyLogParaAssetDeposit: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetDeposit"},
TyLogParaCrossAssetTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaCrossAssetTransfer"},
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"},
TyLogParaNodeGroupStatusUpdate: {Ty: reflect.TypeOf(ReceiptParaNodeGroupConfig{}), Name: "LogParaNodeGroupStatusUpdate"},
TyLogParaSelfConsStageConfig: {Ty: reflect.TypeOf(ReceiptSelfConsStageConfig{}), Name: "LogParaSelfConsStageConfig"},
TyLogParaStageVoteDone: {Ty: reflect.TypeOf(ReceiptSelfConsStageVoteDone{}), Name: "LogParaSelfConfStageVoteDoen"},
TyLogParaStageGroupUpdate: {Ty: reflect.TypeOf(ReceiptSelfConsStagesUpdate{}), Name: "LogParaSelfConfStagesUpdate"},
TyLogParaBindMinerAddr: {Ty: reflect.TypeOf(ReceiptParaBindMinerInfo{}), Name: "TyLogParaBindMinerAddrUpdate"},
TyLogParaBindMinerNode: {Ty: reflect.TypeOf(ReceiptParaNodeBindListUpdate{}), Name: "TyLogParaBindNodeListUpdate"},
TyLogParaSupervisionNodeConfig: {Ty: reflect.TypeOf(ReceiptParaNodeConfig{}), Name: "LogParaSupervisionNodeConfig"},
TyLogParaSupervisionNodeGroupAddrsUpdate: {Ty: reflect.TypeOf(types.ReceiptConfig{}), Name: "LogParaSupervisionNodeGroupAddrsUpdate"},
TyLogParaSupervisionNodeStatusUpdate: {Ty: reflect.TypeOf(ReceiptParaNodeAddrStatUpdate{}), Name: "LogParaSupervisionNodeStatusUpdate"},
}
}
// GetTypeMap get action type
func (p *ParacrossType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Commit": ParacrossActionCommit,
"Miner": ParacrossActionMiner,
"AssetTransfer": ParacrossActionAssetTransfer,
"AssetWithdraw": ParacrossActionAssetWithdraw,
"Transfer": ParacrossActionTransfer,
"Withdraw": ParacrossActionWithdraw,
"TransferToExec": ParacrossActionTransferToExec,
"CrossAssetTransfer": ParacrossActionCrossAssetTransfer,
"NodeConfig": ParacrossActionNodeConfig,
"NodeGroupConfig": ParacrossActionNodeGroupApply,
"SelfStageConfig": ParacrossActionSelfStageConfig,
"ParaBindMiner": ParacrossActionParaBindMiner,
"Commit": ParacrossActionCommit,
"Miner": ParacrossActionMiner,
"AssetTransfer": ParacrossActionAssetTransfer,
"AssetWithdraw": ParacrossActionAssetWithdraw,
"Transfer": ParacrossActionTransfer,
"Withdraw": ParacrossActionWithdraw,
"TransferToExec": ParacrossActionTransferToExec,
"CrossAssetTransfer": ParacrossActionCrossAssetTransfer,
"NodeConfig": ParacrossActionNodeConfig,
"NodeGroupConfig": ParacrossActionNodeGroupApply,
"SelfStageConfig": ParacrossActionSelfStageConfig,
"ParaBindMiner": ParacrossActionParaBindMiner,
"SupervisionNodeConfig": ParacrossActionSupervisionNodeConfig,
}
}
......
......@@ -253,6 +253,7 @@ ForkParaSelfConsStages=0
ForkParaAssetTransferRbk=0
#仅平行链适用,开启挖矿交易的高度,已有代码版本可能未在0高度开启挖矿,需要设置这个高度,新版本默认从0开启挖矿,通过交易配置分阶段奖励
ForkParaFullMinerHeight=0
ForkParaSupervision=0
[fork.sub.qbftNode]
Enable=0
......@@ -322,6 +322,7 @@ ForkParaSelfConsStages=0
ForkParaAssetTransferRbk=0
#仅平行链适用,开启挖矿交易的高度,已有代码版本可能未在0高度开启挖矿,需要设置这个高度,新版本默认从0开启挖矿,通过交易配置分阶段奖励
ForkParaFullMinerHeight=0
ForkParaSupervision=0
[fork.sub.evm]
Enable=0
......
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