From 35d298ac007ed4164955b60e560582639b1d10d7 Mon Sep 17 00:00:00 2001 From: dawn-to-dusk <1927529251@qq.com> Date: Wed, 28 Apr 2021 18:02:01 +0800 Subject: [PATCH] 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. --- cmd/bitxhub/client/rule_manage.go | 38 +++++++ go.mod | 5 +- go.sum | 4 +- .../executor/contracts/appchain_manager.go | 55 ++++++---- internal/executor/contracts/rule_manager.go | 103 ++++++++++++------ pkg/peermgr/mock_peermgr/mock_peermgr.go | 3 +- tester/case004_role_test.go | 15 +-- 7 files changed, 149 insertions(+), 74 deletions(-) diff --git a/cmd/bitxhub/client/rule_manage.go b/cmd/bitxhub/client/rule_manage.go index 83dd7d0..3a1c235 100644 --- a/cmd/bitxhub/client/rule_manage.go +++ b/cmd/bitxhub/client/rule_manage.go @@ -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") diff --git a/go.mod b/go.mod index 3606da8..a7b821b 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 461a415..5b1bd35 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/internal/executor/contracts/appchain_manager.go b/internal/executor/contracts/appchain_manager.go index b14da20..0fa90a4 100644 --- a/internal/executor/contracts/appchain_manager.go +++ b/internal/executor/contracts/appchain_manager.go @@ -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 diff --git a/internal/executor/contracts/rule_manager.go b/internal/executor/contracts/rule_manager.go index 433d273..86fd9b3 100644 --- a/internal/executor/contracts/rule_manager.go +++ b/internal/executor/contracts/rule_manager.go @@ -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)) } diff --git a/pkg/peermgr/mock_peermgr/mock_peermgr.go b/pkg/peermgr/mock_peermgr/mock_peermgr.go index dca6487..c08f90b 100644 --- a/pkg/peermgr/mock_peermgr/mock_peermgr.go +++ b/pkg/peermgr/mock_peermgr/mock_peermgr.go @@ -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 diff --git a/tester/case004_role_test.go b/tester/case004_role_test.go index 37d25b4..0ceb323 100644 --- a/tester/case004_role_test.go +++ b/tester/case004_role_test.go @@ -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))