Commit f11abc5b authored by mdj33's avatar mdj33 Committed by vipwzw

add group id op

parent 7ce3ee2b
......@@ -77,7 +77,7 @@ func getConfigManageNodes(db dbm.KV, title string) (map[string]struct{}, []strin
}
func getParacrossNodes(db dbm.KV, title string) (map[string]struct{}, []string, error) {
key := calcParaNodeGroupKey(title)
key := calcParaNodeGroupAddrsKey(title)
return getNodes(db, key)
}
......
......@@ -91,7 +91,7 @@ func (e *Paracross) ExecLocal_NodeGroupConfig(payload *pt.ParaNodeGroupConfig, t
var set types.LocalDBSet
for _, log := range receiptData.Logs {
if log.Ty == pt.TyLogParaNodeGroupApply || log.Ty == pt.TyLogParaNodeGroupApprove ||
log.Ty == pt.TyLogParaNodeGroupQuit {
log.Ty == pt.TyLogParaNodeGroupQuit || log.Ty == pt.TyLogParaNodeGroupModify {
var g pt.ReceiptParaNodeGroupConfig
err := types.Decode(log.Log, &g)
if err != nil {
......
......@@ -16,7 +16,9 @@ var (
managerConfigNodes string //manager 合约配置的nodes
paraConfigNodes string //平行链自组织配置的nodes,最初是从manager同步过来
paraConfigNodeAddr string //平行链配置节点账户
paraNodeGroupApplyAddrs string
paraNodeGroupStatusAddrs string //正在申请的addrs
paraNodeId string
paraNodeGroupId string
localTx string
localTitle string
localTitleHeight string
......@@ -32,7 +34,9 @@ func setPrefix() {
managerConfigNodes = "paracross-nodes-"
paraConfigNodes = "mavl-paracross-nodes-title-"
paraConfigNodeAddr = "mavl-paracross-nodes-titleAddr-"
paraNodeGroupApplyAddrs = "mavl-paracross-nodegroup-apply-title-"
paraNodeGroupStatusAddrs = "mavl-paracross-nodegroup-apply-title-"
paraNodeId = "mavl-paracross-title-nodeid-"
paraNodeGroupId = "mavl-paracross-title-nodegroupid-"
localTx = "LODB-paracross-titleHeightAddr-"
localTitle = "LODB-paracross-title-"
localTitleHeight = "LODB-paracross-titleHeight-"
......@@ -62,7 +66,7 @@ func calcManageConfigNodesKey(title string) []byte {
return []byte(types.ManageKey(key))
}
func calcParaNodeGroupKey(title string) []byte {
func calcParaNodeGroupAddrsKey(title string) []byte {
return []byte(fmt.Sprintf(paraConfigNodes+"%s", title))
}
......@@ -70,8 +74,16 @@ func calcParaNodeAddrKey(title string, addr string) []byte {
return []byte(fmt.Sprintf(paraConfigNodeAddr+"%s-%s", title, addr))
}
func calcParaNodeGroupApplyKey(title string) []byte {
return []byte(fmt.Sprintf(paraNodeGroupApplyAddrs+"%s", title))
func calcParaNodeGroupStatusKey(title string) []byte {
return []byte(fmt.Sprintf(paraNodeGroupStatusAddrs+"%s", title))
}
func calcParaNodeIdKey(title, hash string) string {
return fmt.Sprintf(paraNodeId+"%s-%s", title, hash)
}
func calcParaNodeGroupIdKey(title, hash string) string {
return fmt.Sprintf(paraNodeGroupId+"%s-%s", title, hash)
}
func calcLocalTxKey(title string, height int64, addr string) []byte {
......
......@@ -75,7 +75,7 @@ func (p *Paracross) Query_GetNodeGroupAddrs(in *pt.ReqParacrossNodeInfo) (types.
nodes = append(nodes, k)
}
var reply types.ReplyConfig
reply.Key = string(calcParaNodeGroupKey(in.GetTitle()))
reply.Key = string(calcParaNodeGroupAddrsKey(in.GetTitle()))
reply.Value = fmt.Sprint(nodes)
return &reply, nil
}
......
......@@ -10,6 +10,9 @@ import (
"strings"
"strconv"
"github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
manager "github.com/33cn/chain33/system/dapp/manage/types"
......@@ -43,8 +46,19 @@ func getNodeAddr(db dbm.KV, title, addr string) (*pt.ParaNodeAddrStatus, error)
return &status, err
}
func getNodeId(db dbm.KV, id string) (*pt.ParaNodeAddrStatus, error) {
val, err := getDb(db, []byte(id))
if err != nil {
return nil, err
}
var status pt.ParaNodeAddrStatus
err = types.Decode(val, &status)
return &status, err
}
func getNodeGroupStatus(db dbm.KV, title string) (*pt.ParaNodeGroupStatus, error) {
key := calcParaNodeGroupApplyKey(title)
key := calcParaNodeGroupStatusKey(title)
val, err := db.Get(key)
if err != nil {
return nil, err
......@@ -55,19 +69,23 @@ func getNodeGroupStatus(db dbm.KV, title string) (*pt.ParaNodeGroupStatus, error
return &status, err
}
func saveDb(db dbm.KV, key []byte, status types.Message) error {
val := types.Encode(status)
return db.Set(key, val)
func getDb(db dbm.KV, key []byte) ([]byte, error) {
val, err := db.Get(key)
if err != nil {
return nil, err
}
return val, nil
}
func saveNodeAddr(db dbm.KV, title, addr string, status types.Message) error {
key := calcParaNodeAddrKey(title, addr)
return saveDb(db, key, status)
}
func getNodeGroupId(db dbm.KV, id string) (*pt.ParaNodeGroupStatus, error) {
val, err := getDb(db, []byte(id))
if err != nil {
return nil, err
}
func saveNodeGroup(db dbm.KV, title string, status types.Message) error {
key := calcParaNodeGroupApplyKey(title)
return saveDb(db, key, status)
var status pt.ParaNodeGroupStatus
err = types.Decode(val, &status)
return &status, err
}
func makeVoteDoneReceipt(config *pt.ParaNodeAddrConfig, totalCount, commitCount, most int, pass string, status int32) *types.Receipt {
......@@ -104,6 +122,7 @@ func makeNodeConfigReceipt(addr string, config *pt.ParaNodeAddrConfig, prev, cur
return &types.Receipt{
Ty: types.ExecOk,
KV: []*types.KeyValue{
{Key: []byte(current.Id), Value: types.Encode(current)},
{Key: key, Value: types.Encode(current)},
},
Logs: []*types.ReceiptLog{
......@@ -115,8 +134,28 @@ func makeNodeConfigReceipt(addr string, config *pt.ParaNodeAddrConfig, prev, cur
}
}
func makeParaNodeGroupApplyReiceipt(title, addr string, prev, current *pt.ParaNodeGroupStatus, logTy int32) *types.Receipt {
key := calcParaNodeGroupApplyKey(title)
func makeNodeGroupApplyReceipt(addr string, prev, current *pt.ParaNodeGroupStatus, logTy int32) *types.Receipt {
log := &pt.ReceiptParaNodeGroupConfig{
Addr: addr,
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: logTy,
Log: types.Encode(log),
},
},
}
}
func makeParaNodeGroupStatusReceipt(addr string, prev, current *pt.ParaNodeGroupStatus, logTy int32) *types.Receipt {
key := calcParaNodeGroupStatusKey(title)
log := &pt.ReceiptParaNodeGroupConfig{
Addr: addr,
Prev: prev,
......@@ -136,8 +175,8 @@ func makeParaNodeGroupApplyReiceipt(title, addr string, prev, current *pt.ParaNo
}
}
func makeParaNodeGroupReiceipt(title string, prev, current *types.ConfigItem) *types.Receipt {
key := calcParaNodeGroupKey(title)
func makeParaNodeGroupReceipt(title string, prev, current *types.ConfigItem) *types.Receipt {
key := calcParaNodeGroupAddrsKey(title)
log := &types.ReceiptConfig{Prev: prev, Current: current}
return &types.Receipt{
Ty: types.ExecOk,
......@@ -146,7 +185,7 @@ func makeParaNodeGroupReiceipt(title string, prev, current *types.ConfigItem) *t
},
Logs: []*types.ReceiptLog{
{
Ty: pt.TyLogParaNodeGroupUpdate,
Ty: pt.TyLogParaNodeGroupAddrsUpdate,
Log: types.Encode(log),
},
},
......@@ -169,8 +208,6 @@ func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
}
if config.CoinsFrozen < nodeGroupStatus.CoinsFrozen {
clog.Error("nodeJoin coinfrozen not enough", "title", config.Title, "addr", config.Addr,
"config", config.CoinsFrozen, "nodegroupConfig", nodeGroupStatus.CoinsFrozen)
return nil, errors.Wrapf(pt.ErrParaNodeGroupFrozenCoinsNotEnough,
"coinFrozen not enough:%d,expected:%d", config.CoinsFrozen, nodeGroupStatus.CoinsFrozen)
}
......@@ -191,13 +228,14 @@ func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
return nil, err
}
clog.Info("first time add node addr", "title", config.Title, "addr", config.Addr)
stat := &pt.ParaNodeAddrStatus{Status: pt.ParacrossNodeAdding,
stat := &pt.ParaNodeAddrStatus{
Id: calcParaNodeIdKey(config.Title, common.ToHex(a.txhash)),
Status: pt.ParacrossNodeJoining,
Title: config.Title,
ApplyAddr: config.Addr,
FromAddr: a.fromaddr,
Votes: &pt.ParaNodeVoteDetail{},
CoinsFrozen: config.CoinsFrozen}
saveNodeAddr(a.db, config.Title, config.Addr, stat)
r := makeNodeConfigReceipt(a.fromaddr, config, nil, stat)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
......@@ -210,36 +248,34 @@ func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
clog.Error("nodeaccount.nodeJoin deep copy fail", "copy", copyStat, "stat", stat)
return nil, err
}
if stat.Status != pt.ParacrossNodeQuited {
clog.Error("nodeaccount.nodeJoin key exist", "addr", config.Addr, "status", stat)
return nil, pt.ErrParaNodeAddrExisted
}
if stat.Status == pt.ParacrossNodeQuited {
stat = &pt.ParaNodeAddrStatus{
Status: pt.ParacrossNodeAdding,
Id: calcParaNodeIdKey(config.Title, common.ToHex(a.txhash)),
Status: pt.ParacrossNodeJoining,
Title: config.Title,
ApplyAddr: config.Addr,
FromAddr: a.fromaddr,
Votes: &pt.ParaNodeVoteDetail{},
CoinsFrozen: config.CoinsFrozen}
saveNodeAddr(a.db, config.Title, config.Addr, stat)
r := makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
clog.Error("nodeaccount.nodeJoin key exist", "addr", config.Addr, "status", stat)
return nil, pt.ErrParaNodeAddrExisted
}
func (a *action) nodeQuit(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
stat, err := getNodeAddr(a.db, config.Title, config.Addr)
stat, err := getNodeId(a.db, config.Id)
if err != nil {
return nil, err
}
//代替别人退出或者自己退出都允许,但代替别人退出时候创建账户也必须匹配
if a.fromaddr != stat.FromAddr && a.fromaddr != config.Addr {
clog.Error("nodeaccount.nodeQuit wrong addr", "createAddr", stat.FromAddr, "confAddr", config.Addr, "fromAddr", a.fromaddr)
return nil, types.ErrNotAllow
if config.Title != stat.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, stat.Title)
}
if stat.Status == pt.ParacrossNodeQuiting || stat.Status == pt.ParacrossNodeQuited {
......@@ -247,7 +283,13 @@ func (a *action) nodeQuit(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
return nil, errors.Wrapf(pt.ErrParaUnSupportNodeOper, "nodeAddr %s was quit status:%d", config.Addr, stat.Status)
}
if stat.Status == pt.ParacrossNodeAdded {
var copyStat pt.ParaNodeAddrStatus
err = deepCopy(&copyStat, stat)
if err != nil {
clog.Error("nodeaccount.nodeQuit deep copy fail", "copy", copyStat, "stat", stat)
return nil, err
}
if stat.Status == pt.ParacrossNodeJoined {
nodes, _, err := getParacrossNodes(a.db, config.Title)
if err != nil {
return nil, errors.Wrapf(err, "getNodes for title:%s", config.Title)
......@@ -259,21 +301,13 @@ func (a *action) nodeQuit(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
if len(nodes) == 1 {
return nil, errors.Wrapf(pt.ErrParaNodeGroupLastAddr, "nodeAddr last one:%s", config.Addr)
}
}
var copyStat pt.ParaNodeAddrStatus
err = deepCopy(&copyStat, stat)
if err != nil {
clog.Error("nodeaccount.nodeQuit deep copy fail", "copy", copyStat, "stat", stat)
return nil, err
}
if stat.Status == pt.ParacrossNodeAdded {
stat.Status = pt.ParacrossNodeQuiting
stat.Votes = &pt.ParaNodeVoteDetail{}
saveNodeAddr(a.db, config.Title, config.Addr, stat)
return makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat), nil
}
if stat.Status == pt.ParacrossNodeJoining {
//still adding status, quit directly
receipt := &types.Receipt{Ty: types.ExecOk}
if !types.IsPara() {
......@@ -287,12 +321,14 @@ func (a *action) nodeQuit(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
stat.Status = pt.ParacrossNodeQuited
stat.Votes = &pt.ParaNodeVoteDetail{}
saveNodeAddr(a.db, config.Title, config.Addr, stat)
r := makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
return nil, pt.ErrParaUnSupportNodeOper
}
......@@ -373,11 +409,15 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "not validNode:%s", a.fromaddr)
}
stat, err := getNodeAddr(a.db, config.Title, config.Addr)
stat, err := getNodeId(a.db, config.Id)
if err != nil {
return nil, err
}
if config.Title != stat.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, stat.Title)
}
var copyStat pt.ParaNodeAddrStatus
err = deepCopy(&copyStat, stat)
if err != nil {
......@@ -411,7 +451,6 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
//超级用户投yes票,共识停止了一定高度就可以通过,防止当前所有授权节点都忘掉私钥场景
if !(superManagerPass && most > 0 && vote == pt.ParaNodeVoteYes) {
saveNodeAddr(a.db, config.Title, config.Addr, stat)
return makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat), nil
}
}
......@@ -420,7 +459,7 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
var receiptGroup *types.Receipt
if vote == pt.ParaNodeVoteNo {
// 对已经在group里面的node,直接投票remove,对正在申请中的adding or quiting状态保持不变,对quited的保持不变
if stat.Status == pt.ParacrossNodeAdded {
if stat.Status == pt.ParacrossNodeJoined {
receiptGroup, err = unpdateNodeGroup(a.db, config.Title, config.Addr, false)
if err != nil {
return nil, err
......@@ -436,12 +475,12 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
}
}
} else {
if stat.Status == pt.ParacrossNodeAdding {
if stat.Status == pt.ParacrossNodeJoining {
receiptGroup, err = unpdateNodeGroup(a.db, config.Title, config.Addr, true)
if err != nil {
return nil, err
}
stat.Status = pt.ParacrossNodeAdded
stat.Status = pt.ParacrossNodeJoined
} else if stat.Status == pt.ParacrossNodeQuiting {
receiptGroup, err = unpdateNodeGroup(a.db, config.Title, config.Addr, false)
if err != nil {
......@@ -459,7 +498,6 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
}
}
}
saveNodeAddr(a.db, config.Title, config.Addr, stat)
receipt := makeNodeConfigReceipt(a.fromaddr, config, &copyStat, stat)
if receiptGroup != nil {
receipt.KV = append(receipt.KV, receiptGroup.KV...)
......@@ -475,7 +513,7 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
func unpdateNodeGroup(db dbm.KV, title, addr string, add bool) (*types.Receipt, error) {
var item types.ConfigItem
key := calcParaNodeGroupKey(title)
key := calcParaNodeGroupAddrsKey(title)
value, err := db.Get(key)
if err != nil {
return nil, err
......@@ -512,7 +550,7 @@ func unpdateNodeGroup(db dbm.KV, title, addr string, add bool) (*types.Receipt,
}
}
return makeParaNodeGroupReiceipt(title, &copyItem, &item), nil
return makeParaNodeGroupReceipt(title, &copyItem, &item), nil
}
func (a *action) checkConfig(title string) error {
......@@ -523,7 +561,7 @@ func (a *action) checkConfig(title string) error {
return nil
}
func getAddrGroup(addr string) []string {
func getConfigAddrs(addr string) []string {
addr = strings.Trim(addr, " ")
if addr == "" {
return nil
......@@ -549,7 +587,7 @@ func getAddrGroup(addr string) []string {
}
func (a *action) checkNodeGroupExist(title string) error {
key := calcParaNodeGroupKey(title)
key := calcParaNodeGroupAddrsKey(title)
value, err := a.db.Get(key)
if err != nil && !isNotFound(err) {
return err
......@@ -613,16 +651,7 @@ func (a *action) nodeGroupCoinsActive(createAddr string, configCoinsFrozen int64
// NodeGroupApply
func (a *action) nodeGroupApply(config *pt.ParaNodeGroupConfig) (*types.Receipt, error) {
status, err := getNodeGroupStatus(a.db, config.Title)
if err != nil && !isNotFound(err) {
return nil, err
}
if status != nil && status.Status != pt.ParacrossNodeGroupQuit {
clog.Error("node group apply exist", "status", status.Status)
return nil, pt.ErrParaNodeGroupExisted
}
addrs := getAddrGroup(config.Addrs)
addrs := getConfigAddrs(config.Addrs)
if len(addrs) == 0 {
clog.Error("node group apply addrs null", "addrs", config.Addrs)
return nil, types.ErrInvalidParam
......@@ -640,15 +669,32 @@ func (a *action) nodeGroupApply(config *pt.ParaNodeGroupConfig) (*types.Receipt,
receipt.Logs = append(receipt.Logs, r.Logs...)
}
stat := &pt.ParaNodeGroupStatus{Status: pt.ParacrossNodeGroupApply,
stat := &pt.ParaNodeGroupStatus{
Id: calcParaNodeGroupIdKey(config.Title, common.ToHex(a.txhash)),
Status: pt.ParacrossNodeGroupApply,
Title: config.Title,
ApplyAddr: strings.Join(addrs, ","),
ApplyAddrs: strings.Join(addrs, ","),
CoinsFrozen: config.CoinsFrozen,
MainHeight: a.exec.GetMainHeight(),
EmptyBlockInterval: config.EmptyBlockInterval,
FromAddr: a.fromaddr}
saveNodeGroup(a.db, config.Title, stat)
r := makeParaNodeGroupApplyReiceipt(config.Title, a.fromaddr, status, stat, pt.TyLogParaNodeGroupApply)
r := makeNodeGroupApplyReceipt(a.fromaddr, nil, stat, pt.TyLogParaNodeGroupApply)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
func (a *action) nodeGroupModify(config *pt.ParaNodeGroupConfig) (*types.Receipt, error) {
receipt := &types.Receipt{Ty: types.ExecOk}
stat := &pt.ParaNodeGroupStatus{
Id: calcParaNodeGroupIdKey(config.Title, common.ToHex(a.txhash)),
Status: pt.ParacrossNodeGroupModify,
Title: config.Title,
CoinsFrozen: config.CoinsFrozen,
MainHeight: a.exec.GetMainHeight(),
EmptyBlockInterval: config.EmptyBlockInterval}
r := makeNodeGroupApplyReceipt(a.fromaddr, nil, stat, pt.TyLogParaNodeGroupModify)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
......@@ -656,29 +702,27 @@ func (a *action) nodeGroupApply(config *pt.ParaNodeGroupConfig) (*types.Receipt,
}
func (a *action) nodeGroupQuit(config *pt.ParaNodeGroupConfig) (*types.Receipt, error) {
status, err := getNodeGroupStatus(a.db, config.Title)
status, err := getNodeGroupId(a.db, config.Id)
if err != nil {
return nil, err
}
if status.Status != pt.ParacrossNodeGroupApply {
clog.Error("node group apply exist", "status", status.Status)
return nil, pt.ErrParaNodeGroupStatusWrong
}
if status.FromAddr != a.fromaddr {
clog.Error("node group create addr err", "createAddr", status.FromAddr, "currAddr", a.fromaddr)
return nil, types.ErrNotAllow
if config.Title != status.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, status.Title)
}
applyAddrs, err := checkNodeGroupAddrsMatch(status.ApplyAddr, config.Addrs)
if err != nil {
return nil, err
//approved or quited
if status.Status != pt.ParacrossNodeGroupApply {
clog.Error("node group apply not apply", "status", status.Status)
return nil, pt.ErrParaNodeGroupStatusWrong
}
applyAddrs := strings.Split(status.ApplyAddrs, ",")
receipt := &types.Receipt{Ty: types.ExecOk}
//main chain
if !types.IsPara() {
r, err := a.nodeGroupCoinsActive(a.fromaddr, status.CoinsFrozen, int64(len(applyAddrs)))
r, err := a.nodeGroupCoinsActive(status.FromAddr, status.CoinsFrozen, int64(len(applyAddrs)))
if err != nil {
return nil, err
}
......@@ -686,49 +730,82 @@ func (a *action) nodeGroupQuit(config *pt.ParaNodeGroupConfig) (*types.Receipt,
receipt.Logs = append(receipt.Logs, r.Logs...)
}
stat := &pt.ParaNodeGroupStatus{Status: pt.ParacrossNodeGroupQuit,
Title: config.Title,
ApplyAddr: status.ApplyAddr,
CoinsFrozen: status.CoinsFrozen,
MainHeight: a.exec.GetMainHeight(),
EmptyBlockInterval: status.EmptyBlockInterval,
FromAddr: a.fromaddr}
saveNodeGroup(a.db, config.Title, stat)
r := makeParaNodeGroupApplyReiceipt(config.Title, a.fromaddr, status, stat, pt.TyLogParaNodeGroupQuit)
copyStat := *status
status.Status = pt.ParacrossNodeGroupQuit
r := makeNodeGroupApplyReceipt(a.fromaddr, &copyStat, status, pt.TyLogParaNodeGroupQuit)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
func checkNodeGroupAddrsMatch(applyAddr, confAddr string) ([]string, error) {
confAddrs := getAddrGroup(confAddr)
applyAddrs := strings.Split(applyAddr, ",")
applys := make(map[string]bool)
configs := make(map[string]bool)
diff := []string{}
for _, addr := range applyAddrs {
applys[addr] = true
}
for _, addr := range confAddrs {
configs[addr] = true
}
if len(applys) != len(configs) {
clog.Error("node group addrs count not match", "apply", applyAddr, "quit", confAddr)
return nil, pt.ErrParaNodeGroupAddrNotMatch
func (a *action) nodeGroupApproveModify(config *pt.ParaNodeGroupConfig, modify *pt.ParaNodeGroupStatus) (*types.Receipt, error) {
stat, err := getNodeGroupStatus(a.db, config.Title)
if err != nil {
return nil, err
}
for _, addr := range confAddrs {
if !applys[addr] {
diff = append(diff, addr)
//approve modify case
if modify.CoinsFrozen < config.CoinsFrozen {
clog.Error("nodeGroupApprove id not enough coins", "id.coins", modify.CoinsFrozen, "config.coins", config.CoinsFrozen)
return nil, pt.ErrParaNodeGroupFrozenCoinsNotEnough
}
receipt := &types.Receipt{Ty: types.ExecOk}
copyModify := *modify
modify.Status = pt.ParacrossNodeGroupApprove
r := makeNodeGroupApplyReceipt(a.fromaddr, &copyModify, modify, pt.TyLogParaNodeGroupApprove)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
copyStat := *stat
//对已经approved group和addrs不再统一修改active&frozen改动的coins,因为可能有些addr已经退出group了,没退出的,退出时候按最初设置解冻
// 这里只修改参数,对后面再加入的节点起作用
stat.Id = modify.Id
stat.CoinsFrozen = modify.CoinsFrozen
stat.EmptyBlockInterval = modify.EmptyBlockInterval
stat.MainHeight = a.exec.GetMainHeight()
r = makeParaNodeGroupStatusReceipt(a.fromaddr, &copyStat, stat, pt.TyLogParaNodeGroupStatusUpdate)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
func (a *action) nodeGroupApproveApply(config *pt.ParaNodeGroupConfig, apply *pt.ParaNodeGroupStatus) (*types.Receipt, error) {
err := a.checkNodeGroupExist(config.Title)
if err != nil {
return nil, err
}
if len(diff) > 0 {
clog.Error("node group addrs not match", "apply", applyAddr, "quit", confAddr)
return nil, pt.ErrParaNodeGroupAddrNotMatch
if apply.CoinsFrozen < config.CoinsFrozen {
clog.Error("nodeGroupApprove id not enough coins", "id.coins", apply.CoinsFrozen, "config.coins", config.CoinsFrozen)
return nil, pt.ErrParaNodeGroupFrozenCoinsNotEnough
}
return confAddrs, nil
receipt := &types.Receipt{Ty: types.ExecOk}
//create the node group
r := a.nodeGroupCreate(apply)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
copyStat := *apply
apply.Status = pt.ParacrossNodeGroupApprove
apply.MainHeight = a.exec.GetMainHeight()
r = makeNodeGroupApplyReceipt(a.fromaddr, &copyStat, apply, pt.TyLogParaNodeGroupApprove)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
r = makeParaNodeGroupStatusReceipt(a.fromaddr, nil, apply, pt.TyLogParaNodeGroupStatusUpdate)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
return receipt, nil
}
......@@ -739,80 +816,58 @@ func (a *action) nodeGroupApprove(config *pt.ParaNodeGroupConfig) (*types.Receip
return nil, types.ErrNotAllow
}
status, err := getNodeGroupStatus(a.db, config.Title)
IdStatus, err := getNodeGroupId(a.db, config.Id)
if err != nil {
return nil, err
}
if status.Status != pt.ParacrossNodeGroupApply {
clog.Error("node group approve not apply status", "status", status.Status)
return nil, pt.ErrParaNodeGroupStatusWrong
}
if status.CoinsFrozen < config.CoinsFrozen {
clog.Error("node group approve not apply status", "status", status.Status)
return nil, pt.ErrParaNodeGroupFrozenCoinsNotEnough
if config.Title != IdStatus.Title {
return nil, errors.Wrapf(pt.ErrNodeNotForTheTitle, "config title:%s,id title:%s", config.Title, IdStatus.Title)
}
applyAddrs, err := checkNodeGroupAddrsMatch(status.ApplyAddr, config.Addrs)
if err != nil {
return nil, err
if IdStatus.Status == pt.ParacrossNodeGroupModify {
return a.nodeGroupApproveModify(config, IdStatus)
}
receipt := &types.Receipt{Ty: types.ExecOk}
//create the node group
r, err := a.nodeGroupCreate(config.Title, applyAddrs, status.CoinsFrozen, status.FromAddr)
if err != nil {
return nil, err
if IdStatus.Status == pt.ParacrossNodeGroupApply {
return a.nodeGroupApproveApply(config, IdStatus)
}
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
stat := &pt.ParaNodeGroupStatus{Status: pt.ParacrossNodeGroupApprove,
Title: config.Title,
ApplyAddr: status.ApplyAddr,
CoinsFrozen: status.CoinsFrozen,
MainHeight: a.exec.GetMainHeight(),
EmptyBlockInterval: status.EmptyBlockInterval,
FromAddr: status.FromAddr}
saveNodeGroup(a.db, config.Title, stat)
r = makeParaNodeGroupApplyReiceipt(config.Title, a.fromaddr, status, stat, pt.TyLogParaNodeGroupApprove)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
clog.Error("nodeGroupApprove id wrong status", "status", IdStatus.Status, "id", config.Id)
return nil, pt.ErrParaNodeGroupStatusWrong
return receipt, nil
}
func (a *action) nodeGroupCreate(title string, nodes []string, coinFrozen int64, createAddr string) (*types.Receipt, error) {
func (a *action) nodeGroupCreate(status *pt.ParaNodeGroupStatus) *types.Receipt {
nodes := strings.Split(status.ApplyAddrs, ",")
var item types.ConfigItem
key := calcParaNodeGroupKey(title)
key := calcParaNodeGroupAddrsKey(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, nodes...)
item.Addr = a.fromaddr
a.db.Set(key, types.Encode(&item))
receipt := makeParaNodeGroupReiceipt(title, nil, &item)
receipt := makeParaNodeGroupReceipt(title, nil, &item)
//update addr status
for _, addr := range nodes {
stat := &pt.ParaNodeAddrStatus{Status: pt.ParacrossNodeAdded,
Title: title,
for i, addr := range nodes {
stat := &pt.ParaNodeAddrStatus{
Id: status.Id + "-" + strconv.Itoa(i),
Status: pt.ParacrossNodeJoined,
Title: status.Title,
ApplyAddr: addr,
Votes: &pt.ParaNodeVoteDetail{},
CoinsFrozen: coinFrozen,
FromAddr: createAddr}
saveNodeAddr(a.db, title, addr, stat)
config := &pt.ParaNodeAddrConfig{
Title: title,
Addr: addr,
CoinsFrozen: coinFrozen,
}
r := makeNodeConfigReceipt(a.fromaddr, config, nil, stat)
Votes: &pt.ParaNodeVoteDetail{Addrs: []string{a.fromaddr}, Votes: []string{"yes"}},
CoinsFrozen: status.CoinsFrozen,
FromAddr: status.FromAddr}
r := makeNodeConfigReceipt(a.fromaddr, nil, nil, stat)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
}
return receipt, nil
return receipt
}
//NodeGroupConfig support super node group config
......@@ -821,12 +876,11 @@ func (a *action) NodeGroupConfig(config *pt.ParaNodeGroupConfig) (*types.Receipt
return nil, pt.ErrInvalidTitle
}
if config.Op == pt.ParacrossNodeGroupApply {
s := strings.Trim(config.Addrs, " ")
if len(s) == 0 {
return nil, types.ErrInvalidParam
}
if config.Op == pt.ParacrossNodeGroupApply {
err := a.checkNodeGroupExist(config.Title)
if err != nil {
return nil, err
......@@ -834,14 +888,19 @@ func (a *action) NodeGroupConfig(config *pt.ParaNodeGroupConfig) (*types.Receipt
return a.nodeGroupApply(config)
} else if config.Op == pt.ParacrossNodeGroupApprove {
err := a.checkNodeGroupExist(config.Title)
if err != nil {
return nil, err
if config.Id == "" {
return nil, types.ErrInvalidParam
}
return a.nodeGroupApprove(config)
} else if config.Op == pt.ParacrossNodeGroupQuit {
if config.Id == "" {
return nil, types.ErrInvalidParam
}
return a.nodeGroupQuit(config)
} else if config.Op == pt.ParacrossNodeGroupModify {
return a.nodeGroupModify(config)
}
return nil, pt.ErrParaUnSupportNodeOper
......@@ -858,9 +917,15 @@ func (a *action) NodeConfig(config *pt.ParaNodeAddrConfig) (*types.Receipt, erro
return a.nodeJoin(config)
} else if config.Op == pt.ParaNodeQuit {
if config.Id == "" {
return nil, types.ErrInvalidParam
}
return a.nodeQuit(config)
} else if config.Op == pt.ParaNodeVote {
if config.Id == "" {
return nil, types.ErrInvalidParam
}
return a.nodeVote(config)
}
......
......@@ -74,7 +74,7 @@ func (suite *NodeManageTestSuite) SetupSuite() {
}
func (suite *NodeManageTestSuite) TestSetup() {
nodeConfigKey := calcParaNodeGroupKey(Title)
nodeConfigKey := calcParaNodeGroupAddrsKey(Title)
suite.T().Log(string(nodeConfigKey))
_, err := suite.stateDB.Get(nodeConfigKey)
if err != nil {
......@@ -139,7 +139,7 @@ func checkJoinReceipt(suite *NodeManageTestSuite, receipt *types.Receipt) {
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.ParacrossNodeAdding), stat.Status)
assert.Equal(suite.T(), int32(pt.ParacrossNodeJoining), stat.Status)
assert.NotNil(suite.T(), stat.Votes)
}
......@@ -310,22 +310,22 @@ func (suite *NodeManageTestSuite) TearDownSuite() {
func TestGetAddrGroup(t *testing.T) {
addrs := " 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4, 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR, 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k, ,,, 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs , "
retAddrs := getAddrGroup(addrs)
retAddrs := getConfigAddrs(addrs)
expectAddrs := []string{"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4", "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR", "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k", "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"}
assert.Equal(t, expectAddrs, retAddrs)
addrs = " 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 , , "
retAddrs = getAddrGroup(addrs)
retAddrs = getConfigAddrs(addrs)
expectAddrs = []string{"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}
assert.Equal(t, expectAddrs, retAddrs)
addrs = " , "
ret := getAddrGroup(addrs)
ret := getConfigAddrs(addrs)
assert.Equal(t, []string(nil), ret)
assert.Equal(t, 0, len(ret))
addrs = " "
ret = getAddrGroup(addrs)
ret = getConfigAddrs(addrs)
assert.Equal(t, []string(nil), ret)
assert.Equal(t, 0, len(ret))
......
......@@ -50,9 +50,10 @@ message ParacrossConsensusStatus {
message ParaNodeAddrConfig{
string title = 1;
string op = 2;
string addr = 3;
string value = 4;
int64 coinsFrozen = 5;
string id = 3;
string addr = 4;
string value = 5;
int64 coinsFrozen = 6;
}
......@@ -62,12 +63,13 @@ message ParaNodeVoteDetail{
}
message ParaNodeAddrStatus{
int32 status = 1;
string title = 2;
string applyAddr = 3;
int64 coinsFrozen = 4;
ParaNodeVoteDetail votes = 5;
string fromAddr = 6;
string id = 1;
int32 status = 2;
string title = 3;
string applyAddr = 4;
int64 coinsFrozen = 5;
ParaNodeVoteDetail votes = 6;
string fromAddr = 7;
}
......@@ -78,40 +80,38 @@ message ReceiptParaNodeConfig {
ParaNodeAddrStatus current = 4;
}
message ReceiptParaNodeVoteRecord {
string fromAddr = 1;
string voteAddr = 2;
int32 value = 3;
}
message ReceiptParaNodeVoteDone {
string title = 1;
string targetAddr = 2;
int32 totalNodes = 3;
int32 totalVote = 4;
int32 mostVote = 5;
string voteRst = 6;
int32 doneStatus = 7;
string id = 1;
string title = 2;
string targetAddr = 3;
int32 totalNodes = 4;
int32 totalVote = 5;
int32 mostVote = 6;
string voteRst = 7;
int32 doneStatus = 8;
}
message ParaNodeGroupConfig {
string title = 1;
uint32 op = 2;
string addrs = 3;
int64 coinsFrozen = 4;
uint32 emptyBlockInterval = 5;
string id = 3;
string addrs = 4;
int64 coinsFrozen = 5;
uint32 emptyBlockInterval = 6;
}
message ParaNodeGroupStatus {
int32 status = 1;
string title = 2;
string applyAddr = 3;
int64 coinsFrozen = 4;
uint32 emptyBlockInterval = 5;
int64 mainHeight = 6;
string fromAddr = 7;
string id = 1;
int32 status = 2;
string title = 3;
string applyAddrs = 4;
int64 coinsFrozen = 5;
uint32 emptyBlockInterval = 6;
int64 mainHeight = 7;
string fromAddr = 8;
}
message ReceiptParaNodeGroupConfig {
......
......@@ -47,8 +47,6 @@ var (
ErrParaNodeGroupFrozenCoinsNotEnough = errors.New("ErrParaNodeGroupFrozenCoinsNotEnough")
//ErrParaNodeGroupStatusWrong node group process wrong status
ErrParaNodeGroupStatusWrong = errors.New("ErrParaNodeGroupStatusWrong")
//ErrParaNodeGroupAddrNotMatch group addrs not match with apply
ErrParaNodeGroupAddrNotMatch = errors.New("ErrParaNodeGroupAddrNotMatch")
//ErrParaConsensStopBlocksNotReach consensus stop blocks not reach
ErrParaConsensStopBlocksNotReach = errors.New("ErrParaConsensStopBlocksNotReach")
)
......@@ -39,10 +39,12 @@ const (
// TyLogParaNodeConfig config super node log key
TyLogParaNodeConfig = 657
TyLogParaNodeVoteDone = 658
TyLogParaNodeGroupUpdate = 659
TyLogParaNodeGroupAddrsUpdate = 659
TyLogParaNodeGroupApply = 660
TyLogParaNodeGroupApprove = 661
TyLogParaNodeGroupQuit = 662
TyLogParaNodeGroupModify = 663
TyLogParaNodeGroupStatusUpdate = 664
)
type paracrossCommitTx struct {
......@@ -99,10 +101,10 @@ const (
)
const (
// ParacrossNodeAdding apply for adding group
ParacrossNodeAdding = iota + 1
// ParacrossNodeAdded pass to add by votes
ParacrossNodeAdded
// ParacrossNodeJoining apply for adding group
ParacrossNodeJoining = iota + 1
// ParacrossNodeJoined pass to add by votes
ParacrossNodeJoined
// ParacrossNodeQuiting apply for quiting
ParacrossNodeQuiting
// ParacrossNodeQuited pass to quite by votes
......@@ -116,6 +118,8 @@ const (
ParacrossNodeGroupApprove
//ParacrossNodeGroupQuit applyer quit the apply when not be approved
ParacrossNodeGroupQuit
//ParacrossNodeGroupModify applyer modify some parameters
ParacrossNodeGroupModify
)
var (
......
......@@ -62,11 +62,13 @@ func (p *ParacrossType) GetLogMap() map[int64]*types.LogInfo {
TyLogParaAssetDeposit: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetDeposit"},
TyLogParacrossMiner: {Ty: reflect.TypeOf(ReceiptParacrossMiner{}), Name: "LogParacrossMiner"},
TyLogParaNodeConfig: {Ty: reflect.TypeOf(ReceiptParaNodeConfig{}), Name: "LogParaNodeConfig"},
TyLogParaNodeGroupUpdate: {Ty: reflect.TypeOf(types.ReceiptConfig{}), Name: "LogParaNodeGroupUpdate"},
TyLogParaNodeGroupAddrsUpdate: {Ty: reflect.TypeOf(types.ReceiptConfig{}), Name: "LogParaNodeGroupAddrsUpdate"},
TyLogParaNodeVoteDone: {Ty: reflect.TypeOf(ReceiptParaNodeVoteDone{}), Name: "LogParaNodeVoteDone"},
TyLogParaNodeGroupApply: {Ty: reflect.TypeOf(ReceiptParaNodeGroupConfig{}), Name: "LogParaNodeGroupApply"},
TyLogParaNodeGroupApprove: {Ty: reflect.TypeOf(ReceiptParaNodeGroupConfig{}), Name: "LogParaNodeGroupApprove"},
TyLogParaNodeGroupQuit: {Ty: reflect.TypeOf(ReceiptParaNodeGroupConfig{}), Name: "LogParaNodeGroupQuit"},
TyLogParaNodeGroupModify: {Ty: reflect.TypeOf(ReceiptParaNodeGroupConfig{}), Name: "LogParaNodeGroupModify"},
TyLogParaNodeGroupStatusUpdate: {Ty: reflect.TypeOf(ReceiptParaNodeGroupConfig{}), Name: "LogParaNodeGroupStatusUpdate"},
}
}
......
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