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
......
This diff is collapsed.
......@@ -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"
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -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
}
......
......@@ -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)
}
This diff is collapsed.
平行链目前有超级节点和普通节点两个角色,对超级节点账户组没有制衡的角色
波卡有钓鱼节点的概念,可以监督验证节点。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