fix(*): fix bugs about governance

1. Fix the bug that changes the state of the managed object when submitting a proposal fails;
2. Add interface to get rule state.
This commit is contained in:
dawn-to-dusk 2021-04-28 18:02:01 +08:00
parent ef8e17263f
commit 35d298ac00
7 changed files with 149 additions and 74 deletions

View File

@ -41,6 +41,23 @@ func ruleMgrCMD() cli.Command {
},
Action: getAvailableRuleAddress,
},
cli.Command{
Name: "status",
Usage: "query rule status by rule address and chain id",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Usage: "chain id",
Required: true,
},
cli.StringFlag{
Name: "addr",
Usage: "rule addr",
Required: true,
},
},
Action: getRuleStatus,
},
cli.Command{
Name: "bind",
Usage: "bind rule with chain id",
@ -149,6 +166,27 @@ func getAvailableRuleAddress(ctx *cli.Context) error {
return nil
}
func getRuleStatus(ctx *cli.Context) error {
chainId := ctx.String("id")
ruleAddr := ctx.String("addr")
receipt, err := invokeBVMContract(ctx, constant.RuleManagerContractAddr.String(), "GetRuleByAddr", pb.String(chainId), pb.String(ruleAddr))
if err != nil {
return err
}
if receipt.IsSuccess() {
rule := &ruleMgr.Rule{}
if err := json.Unmarshal(receipt.Ret, rule); err != nil {
return fmt.Errorf("unmarshal receipt error: %w", err)
}
color.Green("the rule %s is %s", ruleAddr, string(rule.Status))
} else {
color.Red("get rule status error: %s\n", string(receipt.Ret))
}
return nil
}
func bindRule(ctx *cli.Context) error {
id := ctx.String("id")
addr := ctx.String("addr")

5
go.mod
View File

@ -1,5 +1,7 @@
module github.com/meshplus/bitxhub
go 1.14
require (
github.com/Rican7/retry v0.1.0
github.com/cbergoon/merkletree v0.2.0
@ -26,7 +28,7 @@ require (
github.com/juju/ratelimit v1.0.1
github.com/libp2p/go-libp2p-core v0.5.6
github.com/magiconair/properties v1.8.4
github.com/meshplus/bitxhub-core v1.3.1-0.20210427092928-3ee6c9cc2b90
github.com/meshplus/bitxhub-core v1.3.1-0.20210428092651-1f8706d3f2f7
github.com/meshplus/bitxhub-kit v1.2.0
github.com/meshplus/bitxhub-model v1.2.1-0.20210427070329-44b1020dd703
github.com/meshplus/bitxid v0.0.0-20210412025850-e0eaf0f9063a
@ -65,4 +67,3 @@ replace google.golang.org/grpc => google.golang.org/grpc v1.33.0
replace github.com/hyperledger/fabric => github.com/hyperledger/fabric v2.0.1+incompatible
go 1.13

4
go.sum
View File

@ -818,8 +818,8 @@ github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpe
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20210318102029-494ee3060b0c/go.mod h1:G19Wrz1u66UmwaES/iLM19jmlv3APAZ5qfYOlNnIIZw=
github.com/meshplus/bitxhub-core v1.3.1-0.20210427092928-3ee6c9cc2b90 h1:+0fXphLgVFrXIjSRPiXge03nNzTv2kSyYGyzOZ60xig=
github.com/meshplus/bitxhub-core v1.3.1-0.20210427092928-3ee6c9cc2b90/go.mod h1:2ksSKEiox4B06gSPT6h4+GcdWnh92/FDPUUImX/dI04=
github.com/meshplus/bitxhub-core v1.3.1-0.20210428092651-1f8706d3f2f7 h1:UXnPICvoLAommzMgCIEGW2smIOclNmTMowI88ws2l2Y=
github.com/meshplus/bitxhub-core v1.3.1-0.20210428092651-1f8706d3f2f7/go.mod h1:2ksSKEiox4B06gSPT6h4+GcdWnh92/FDPUUImX/dI04=
github.com/meshplus/bitxhub-kit v1.1.1 h1:vkPO88oA3+Kpc0N8lIgfj/U52KBuI+633hPbMYt1xm8=
github.com/meshplus/bitxhub-kit v1.1.1/go.mod h1:r4l4iqn0RPJreb/OmoYKfjCjQJrXpZX++6Qc31VG/1k=
github.com/meshplus/bitxhub-kit v1.1.2-0.20201021105954-468d0a9d7957/go.mod h1:r4l4iqn0RPJreb/OmoYKfjCjQJrXpZX++6Qc31VG/1k=

View File

@ -188,10 +188,6 @@ func (am *AppchainManager) UpdateAppchain(id, docAddr, docHash, validators strin
return boltvm.Error("check permission error:" + string(res.Result))
}
if ok, data := am.AppchainManager.ChangeStatus(id, string(governance.EventUpdate), nil); !ok {
return boltvm.Error(string(data))
}
chain := &appchainMgr.Appchain{
ID: id,
Name: name,
@ -210,7 +206,7 @@ func (am *AppchainManager) UpdateAppchain(id, docAddr, docHash, validators strin
return boltvm.Error(err.Error())
}
return am.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res = am.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(am.Caller()),
pb.String(string(governance.EventUpdate)),
pb.String(""),
@ -218,6 +214,14 @@ func (am *AppchainManager) UpdateAppchain(id, docAddr, docHash, validators strin
pb.String(id),
pb.Bytes(data),
)
if !res.Ok {
return boltvm.Error("submit proposal error:" + string(res.Result))
}
if ok, data := am.AppchainManager.ChangeStatus(id, string(governance.EventUpdate), nil); !ok {
return boltvm.Error(string(data))
}
return boltvm.Success(res.Result)
}
// FreezeAppchain freezes available appchain
@ -243,10 +247,6 @@ func (am *AppchainManager) FreezeAppchain(id string) *boltvm.Response {
return boltvm.Error("check permission error:" + string(res.Result))
}
if ok, data := am.AppchainManager.ChangeStatus(id, string(governance.EventFreeze), nil); !ok {
return boltvm.Error(string(data))
}
chain := &appchainMgr.Appchain{
ID: id,
}
@ -255,7 +255,7 @@ func (am *AppchainManager) FreezeAppchain(id string) *boltvm.Response {
return boltvm.Error(err.Error())
}
return am.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res = am.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(am.Caller()),
pb.String(string(governance.EventFreeze)),
pb.String(""),
@ -263,6 +263,14 @@ func (am *AppchainManager) FreezeAppchain(id string) *boltvm.Response {
pb.String(id),
pb.Bytes(chainData),
)
if !res.Ok {
return boltvm.Error("submit proposal error:" + string(res.Result))
}
if ok, data := am.AppchainManager.ChangeStatus(id, string(governance.EventFreeze), nil); !ok {
return boltvm.Error(string(data))
}
return boltvm.Success(res.Result)
}
// ActivateAppchain updates freezing appchain
@ -289,9 +297,6 @@ func (am *AppchainManager) ActivateAppchain(id string) *boltvm.Response {
}
am.AppchainManager.Persister = am.Stub
if ok, data := am.AppchainManager.ChangeStatus(id, string(governance.EventActivate), nil); !ok {
return boltvm.Error(string(data))
}
chain := &appchainMgr.Appchain{
ID: id,
@ -301,7 +306,7 @@ func (am *AppchainManager) ActivateAppchain(id string) *boltvm.Response {
return boltvm.Error(err.Error())
}
return am.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res = am.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(am.Caller()),
pb.String(string(governance.EventActivate)),
pb.String(""),
@ -309,6 +314,14 @@ func (am *AppchainManager) ActivateAppchain(id string) *boltvm.Response {
pb.String(id),
pb.Bytes(data),
)
if !res.Ok {
return boltvm.Error("submit proposal error:" + string(res.Result))
}
if ok, data := am.AppchainManager.ChangeStatus(id, string(governance.EventActivate), nil); !ok {
return boltvm.Error(string(data))
}
return boltvm.Success(res.Result)
}
// LogoutAppchain updates available appchain
@ -334,10 +347,6 @@ func (am *AppchainManager) LogoutAppchain(id string) *boltvm.Response {
return boltvm.Error("check permission error:" + string(res.Result))
}
if ok, data := am.AppchainManager.ChangeStatus(id, string(governance.EventLogout), nil); !ok {
return boltvm.Error(string(data))
}
chain := &appchainMgr.Appchain{
ID: id,
}
@ -346,7 +355,7 @@ func (am *AppchainManager) LogoutAppchain(id string) *boltvm.Response {
return boltvm.Error(err.Error())
}
return am.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res = am.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(am.Caller()),
pb.String(string(governance.EventLogout)),
pb.String(""),
@ -354,6 +363,14 @@ func (am *AppchainManager) LogoutAppchain(id string) *boltvm.Response {
pb.String(id),
pb.Bytes(data),
)
if !res.Ok {
return boltvm.Error("submit proposal error:" + string(res.Result))
}
if ok, data := am.AppchainManager.ChangeStatus(id, string(governance.EventLogout), nil); !ok {
return boltvm.Error(string(data))
}
return boltvm.Success(res.Result)
}
// CountAvailableAppchains counts all available appchains

View File

@ -73,12 +73,7 @@ func (rm *RuleManager) BindRule(chainId string, ruleAddress string) *boltvm.Resp
return boltvm.Error("bind prepare error: " + string(data))
}
// 5. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventBind), []byte(chainId)); !ok {
return boltvm.Error("change status error: " + string(data))
}
// 6. submit proposal
// 5. submit proposal
ruleData, err := json.Marshal(&ruleMgr.Rule{
Address: ruleAddress,
ChainId: chainId,
@ -86,7 +81,8 @@ func (rm *RuleManager) BindRule(chainId string, ruleAddress string) *boltvm.Resp
if err != nil {
return boltvm.Error("marshal rule error: " + err.Error())
}
return rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res := rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(rm.Caller()),
pb.String(string(governance.EventBind)),
pb.String(""),
@ -94,6 +90,15 @@ func (rm *RuleManager) BindRule(chainId string, ruleAddress string) *boltvm.Resp
pb.String(ruleAddress),
pb.Bytes(ruleData),
)
if !res.Ok {
return boltvm.Error("cross invoke SubmitProposal error: " + string(res.Result))
}
// 6. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventBind), []byte(chainId)); !ok {
return boltvm.Error("change status error: " + string(data))
}
return boltvm.Success(res.Result)
}
// UnbindRule unbinds the validation rule address with the chain id
@ -110,12 +115,7 @@ func (rm *RuleManager) UnbindRule(chainId string, ruleAddress string) *boltvm.Re
return boltvm.Error("cross invoke IsAvailable error: " + string(res.Result))
}
// 3. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventUnbind), []byte(chainId)); !ok {
return boltvm.Error(string(data))
}
// 4. submit proposal
// 3. submit proposal
ruleData, err := json.Marshal(&ruleMgr.Rule{
Address: ruleAddress,
ChainId: chainId,
@ -123,7 +123,8 @@ func (rm *RuleManager) UnbindRule(chainId string, ruleAddress string) *boltvm.Re
if err != nil {
return boltvm.Error("marshal rule error: " + err.Error())
}
return rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res := rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(rm.Caller()),
pb.String(string(governance.EventUnbind)),
pb.String(""),
@ -131,6 +132,15 @@ func (rm *RuleManager) UnbindRule(chainId string, ruleAddress string) *boltvm.Re
pb.String(ruleAddress),
pb.Bytes(ruleData),
)
if !res.Ok {
return boltvm.Error("cross invoke SubmitProposal error: " + string(res.Result))
}
// 4. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventUnbind), []byte(chainId)); !ok {
return boltvm.Error(string(data))
}
return boltvm.Success(res.Result)
}
// FreezeRule freezes the validation rule address with the chain id
@ -147,12 +157,7 @@ func (rm *RuleManager) FreezeRule(chainId string, ruleAddress string) *boltvm.Re
return boltvm.Error("cross invoke IsAvailable error: " + string(res.Result))
}
// 3. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventFreeze), []byte(chainId)); !ok {
return boltvm.Error(string(data))
}
// 4. submit proposal
// 3. submit proposal
ruleData, err := json.Marshal(&ruleMgr.Rule{
Address: ruleAddress,
ChainId: chainId,
@ -160,7 +165,8 @@ func (rm *RuleManager) FreezeRule(chainId string, ruleAddress string) *boltvm.Re
if err != nil {
return boltvm.Error("marshal rule error: " + err.Error())
}
return rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res := rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(rm.Caller()),
pb.String(string(governance.EventFreeze)),
pb.String(""),
@ -168,6 +174,15 @@ func (rm *RuleManager) FreezeRule(chainId string, ruleAddress string) *boltvm.Re
pb.String(ruleAddress),
pb.Bytes(ruleData),
)
if !res.Ok {
return boltvm.Error("cross invoke SubmitProposal error: " + string(res.Result))
}
// 4. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventFreeze), []byte(chainId)); !ok {
return boltvm.Error(string(data))
}
return boltvm.Success(res.Result)
}
// ActivateRule activate the validation rule address with the chain id
@ -184,12 +199,7 @@ func (rm *RuleManager) ActivateRule(chainId string, ruleAddress string) *boltvm.
return boltvm.Error("cross invoke IsAvailable error: " + string(res.Result))
}
// 3. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventActivate), []byte(chainId)); !ok {
return boltvm.Error(string(data))
}
// 4. submit proposal
// 3. submit proposal
ruleData, err := json.Marshal(&ruleMgr.Rule{
Address: ruleAddress,
ChainId: chainId,
@ -197,7 +207,8 @@ func (rm *RuleManager) ActivateRule(chainId string, ruleAddress string) *boltvm.
if err != nil {
return boltvm.Error("marshal rule error: " + err.Error())
}
return rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res := rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(rm.Caller()),
pb.String(string(governance.EventActivate)),
pb.String(""),
@ -205,6 +216,15 @@ func (rm *RuleManager) ActivateRule(chainId string, ruleAddress string) *boltvm.
pb.String(ruleAddress),
pb.Bytes(ruleData),
)
if !res.Ok {
return boltvm.Error("cross invoke SubmitProposal error: " + string(res.Result))
}
// 4. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventActivate), []byte(chainId)); !ok {
return boltvm.Error(string(data))
}
return boltvm.Success(res.Result)
}
// LogoutRule logout the validation rule address with the chain id
@ -221,12 +241,7 @@ func (rm *RuleManager) LogoutRule(chainId string, ruleAddress string) *boltvm.Re
return boltvm.Error("cross invoke IsAvailable error: " + string(res.Result))
}
// 3. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventLogout), []byte(chainId)); !ok {
return boltvm.Error(string(data))
}
// 4. submit proposal
// 3. submit proposal
ruleData, err := json.Marshal(&ruleMgr.Rule{
Address: ruleAddress,
ChainId: chainId,
@ -234,7 +249,8 @@ func (rm *RuleManager) LogoutRule(chainId string, ruleAddress string) *boltvm.Re
if err != nil {
return boltvm.Error("marshal rule error: " + err.Error())
}
return rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
res := rm.CrossInvoke(constant.GovernanceContractAddr.String(), "SubmitProposal",
pb.String(rm.Caller()),
pb.String(string(governance.EventLogout)),
pb.String(""),
@ -242,6 +258,15 @@ func (rm *RuleManager) LogoutRule(chainId string, ruleAddress string) *boltvm.Re
pb.String(ruleAddress),
pb.Bytes(ruleData),
)
if !res.Ok {
return boltvm.Error("cross invoke SubmitProposal error: " + string(res.Result))
}
// 4. change status
if ok, data := rm.RuleManager.ChangeStatus(ruleAddress, string(governance.EventLogout), []byte(chainId)); !ok {
return boltvm.Error(string(data))
}
return boltvm.Success(res.Result)
}
// CountAvailableRules counts all available rules (should be 0 or 1)
@ -263,7 +288,13 @@ func (rm *RuleManager) Rules(chainId string) *boltvm.Response {
}
// GetRule returns available rule address by appchain id and rule address
func (rm *RuleManager) GetRuleAddress(chainId, chainType string) *boltvm.Response {
func (rm *RuleManager) GetRuleByAddr(chainId, ruleAddr string) *boltvm.Response {
rm.RuleManager.Persister = rm.Stub
return responseWrapper(rm.QueryById(ruleAddr, []byte(chainId)))
}
// GetRule returns available rule address by appchain id and rule address
func (rm *RuleManager) GetAvailableRuleAddr(chainId, chainType string) *boltvm.Response {
rm.RuleManager.Persister = rm.Stub
return responseWrapper(rm.GetAvailableRuleAddress(chainId, chainType))
}

View File

@ -5,8 +5,6 @@
package mock_peermgr
import (
reflect "reflect"
event "github.com/ethereum/go-ethereum/event"
gomock "github.com/golang/mock/gomock"
peer "github.com/libp2p/go-libp2p-core/peer"
@ -14,6 +12,7 @@ import (
events "github.com/meshplus/bitxhub/internal/model/events"
peermgr "github.com/meshplus/bitxhub/pkg/peermgr"
network "github.com/meshplus/go-lightp2p"
reflect "reflect"
)
// MockPeerManager is a mock of PeerManager interface

View File

@ -260,12 +260,6 @@ func (suite *Role) TestGetRuleAddress() {
suite.Require().Nil(err)
k1Nonce++
bytes, err = ioutil.ReadFile("./test_data/hpc_rule.wasm")
suite.Require().Nil(err)
ruleAddr11, err := deployContract(suite.api, k1, k1Nonce, bytes)
suite.Require().Nil(err)
k1Nonce++
bytes, err = ioutil.ReadFile("./test_data/fabric_policy.wasm")
suite.Require().Nil(err)
ruleAddr2, err := deployContract(suite.api, k2, k2Nonce, bytes)
@ -281,11 +275,6 @@ func (suite *Role) TestGetRuleAddress() {
k1Nonce++
proposalRuleId := string(ret.Ret)
ret, err = invokeBVMContract(suite.api, k1, k1Nonce, constant.RuleManagerContractAddr.Address(), "BindRule", pb.String(id1), pb.String(ruleAddr11.String()))
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess(), string(ret.Ret))
k1Nonce++
ret, err = invokeBVMContract(suite.api, priAdmin1, adminNonce1, constant.GovernanceContractAddr.Address(), "Vote",
pb.String(proposalRuleId),
pb.String(string(contracts.APPOVED)),
@ -347,13 +336,13 @@ func (suite *Role) TestGetRuleAddress() {
adminNonce3++
// get role address
ret, err = invokeBVMContract(suite.api, k1, k1Nonce, constant.RuleManagerContractAddr.Address(), "GetRuleAddress", pb.String(string(id1)), pb.String("hyperchain"))
ret, err = invokeBVMContract(suite.api, k1, k1Nonce, constant.RuleManagerContractAddr.Address(), "GetAvailableRuleAddr", pb.String(string(id1)), pb.String("hyperchain"))
suite.Assert().Nil(err)
suite.Require().True(ret.IsSuccess(), string(ret.Ret))
suite.Require().Equal(ruleAddr1.String(), string(ret.Ret))
k1Nonce++
ret, err = invokeBVMContract(suite.api, k2, k2Nonce, constant.RuleManagerContractAddr.Address(), "GetRuleAddress", pb.String(string(id2)), pb.String("fabric"))
ret, err = invokeBVMContract(suite.api, k2, k2Nonce, constant.RuleManagerContractAddr.Address(), "GetAvailableRuleAddr", pb.String(string(id2)), pb.String("fabric"))
suite.Assert().Nil(err)
suite.Require().True(ret.IsSuccess())
suite.Require().Equal(ruleAddr2.String(), string(ret.Ret))