Merge branch 'master' into feat/improve-governance

This commit is contained in:
dawn-to-dusk 2021-04-26 17:39:19 +08:00 committed by dawn-to-dusk
commit a6b8b54d14
15 changed files with 428 additions and 2504 deletions

View File

@ -52,6 +52,9 @@ func (cbs *ChainBrokerService) GetAccountBalance(ctx context.Context, req *pb.Ad
}
func (cbs *ChainBrokerService) GetPendingNonceByAccount(ctx context.Context, req *pb.Address) (*pb.Response, error) {
if !types.IsValidAddressByte([]byte(req.Address)) {
return nil, fmt.Errorf("invalid account address: %v", req.Address)
}
nonce := cbs.api.Broker().GetPendingNonceByAccount(req.Address)
return &pb.Response{
Data: []byte(strconv.FormatUint(nonce, 10)),

View File

@ -15,7 +15,7 @@ import (
func (cbs *ChainBrokerService) GetReceipt(ctx context.Context, req *pb.TransactionHashMsg) (*pb.Receipt, error) {
hash := types.NewHashByStr(req.TxHash)
if hash == nil {
return nil, fmt.Errorf("invalid format of receipt hash for querying receipt")
return nil, status.Newf(codes.InvalidArgument, fmt.Sprintf("invalid format of receipt hash %s for querying receipt", hash)).Err()
}
r, err := cbs.api.Broker().GetReceipt(hash)
if err != nil {

19
go.mod
View File

@ -2,14 +2,12 @@ module github.com/meshplus/bitxhub
require (
github.com/Rican7/retry v0.1.0
github.com/aristanetworks/goarista v0.0.0-20200310212843-2da4c1f5881b // indirect
github.com/cbergoon/merkletree v0.2.0
github.com/cheynewallace/tabby v1.1.1
github.com/common-nighthawk/go-figure v0.0.0-20190529165535-67e0ed34491a
github.com/coreos/etcd v3.3.18+incompatible
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/ethereum/go-ethereum v1.9.18
github.com/ethereum/go-ethereum v1.10.2
github.com/fatih/color v1.7.0
github.com/gobuffalo/envy v1.9.0 // indirect
github.com/gobuffalo/packd v1.0.0
@ -20,14 +18,14 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/hashicorp/golang-lru v0.5.4
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e
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 v0.1.0-rc1.0.20210426091507-ee162793a333
github.com/meshplus/bitxhub-kit v1.1.2-0.20210112075018-319e668d6359
github.com/meshplus/bitxhub-model v1.1.2-0.20210409090411-de23bd385c5f
github.com/meshplus/bitxhub-core v1.2.1-0.20210426113834-e5d1e9078142
github.com/meshplus/bitxhub-kit v1.2.0
github.com/meshplus/bitxhub-model v1.2.0
github.com/meshplus/bitxid v0.0.0-20210412025850-e0eaf0f9063a
github.com/meshplus/did-registry v0.0.0-20210413035015-509c6c3a0bae
github.com/meshplus/go-libp2p-cert v0.0.0-20210125063330-7c25fd5b7a49
@ -38,13 +36,14 @@ require (
github.com/pelletier/go-toml v1.8.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.5.0
github.com/prometheus/procfs v0.0.10 // indirect
github.com/rogpeppe/go-internal v1.8.0 // indirect
github.com/rs/cors v1.7.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cast v1.3.1
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.6.1
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d
github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954
github.com/tidwall/gjson v1.6.8
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5
github.com/urfave/cli v1.22.1
@ -63,6 +62,4 @@ 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
//replace github.com/meshplus/bitxhub-core => ../bitxhub-core
go 1.13

343
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -110,7 +110,7 @@ func (am *AppchainManager) Register(appchainAdminDID, appchainMethod string, doc
}
chain := &appchainMgr.Appchain{
ID: appchainAdminDID,
ID: appchainMethod,
Name: name,
Validators: validators,
ConsensusType: consensusType,
@ -121,7 +121,7 @@ func (am *AppchainManager) Register(appchainAdminDID, appchainMethod string, doc
PublicKey: pubkey,
DidDocAddr: docAddr,
DidDocHash: docHash,
OwnerDID: appchainMethod,
OwnerDID: appchainAdminDID,
}
chainData, err := json.Marshal(chain)
if err != nil {

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,14 @@ import (
"github.com/meshplus/bitxid"
)
const (
AppchainNotAvailable = "appchain not available"
InvalidIBTP = "invalid ibtp"
internalError = "internal server error"
ibtpIndexExist = "index already exists"
ibtpIndexWrong = "wrong index"
)
type InterchainManager struct {
boltvm.Stub
}
@ -181,7 +189,7 @@ func (x *InterchainManager) HandleIBTPs(data []byte) *boltvm.Response {
func (x *InterchainManager) checkIBTP(ibtp *pb.IBTP, interchain *pb.Interchain) error {
if ibtp.To == "" {
return fmt.Errorf("empty destination chain id")
return fmt.Errorf("%s: empty destination chain id", InvalidIBTP)
}
if _, ok := x.getInterchain(ibtp.To); !ok {
@ -198,15 +206,15 @@ func (x *InterchainManager) checkIBTP(ibtp *pb.IBTP, interchain *pb.Interchain)
pb.IBTP_ASSET_EXCHANGE_REFUND == ibtp.Type {
if srcChainInfo.ChainType != appchainMgr.RelaychainType {
if err := x.checkPubKeyAndCaller(srcChainInfo.PublicKey); err != nil {
return fmt.Errorf("caller is not bind to ibtp from: %w", err)
return fmt.Errorf("%s: caller is not bind to ibtp from: %w", InvalidIBTP, err)
}
}
idx := interchain.InterchainCounter[ibtp.To]
if ibtp.Index <= idx {
return fmt.Errorf(fmt.Sprintf("index already exists, required %d, but %d", idx+1, ibtp.Index))
return fmt.Errorf(fmt.Sprintf("%s: required %d, but %d", ibtpIndexExist, idx+1, ibtp.Index))
}
if ibtp.Index > idx+1 {
return fmt.Errorf(fmt.Sprintf("wrong index, required %d, but %d", idx+1, ibtp.Index))
return fmt.Errorf(fmt.Sprintf("%s: required %d, but %d", ibtpIndexWrong, idx+1, ibtp.Index))
}
} else {
if srcChainInfo.ChainType != appchainMgr.RelaychainType {
@ -215,16 +223,16 @@ func (x *InterchainManager) checkIBTP(ibtp *pb.IBTP, interchain *pb.Interchain)
return err
}
if err := x.checkPubKeyAndCaller(destChainInfo.PublicKey); err != nil {
return fmt.Errorf("caller is not bind to ibtp to")
return fmt.Errorf("%s: caller is not bind to ibtp to", InvalidIBTP)
}
}
idx := interchain.ReceiptCounter[ibtp.To]
if ibtp.Index <= idx {
return fmt.Errorf(fmt.Sprintf("receipt index already exists, required %d, but %d", idx+1, ibtp.Index))
return fmt.Errorf(fmt.Sprintf("%s: required %d, but %d", ibtpIndexExist, idx+1, ibtp.Index))
}
if ibtp.Index > idx+1 {
return fmt.Errorf(fmt.Sprintf("wrong receipt index, required %d, but %d", idx+1, ibtp.Index))
return fmt.Errorf(fmt.Sprintf("%s: required %d, but %d", ibtpIndexWrong, idx+1, ibtp.Index))
}
}
@ -253,13 +261,13 @@ func (x *InterchainManager) checkPubKeyAndCaller(pub string) error {
func (x *InterchainManager) checkAppchain(id string) (*pb.Interchain, *appchainMgr.Appchain, error) {
interchain, ok := x.getInterchain(id)
if !ok {
return nil, nil, fmt.Errorf("this appchain does not exist")
return nil, nil, fmt.Errorf("%s: this appchain does not exist", AppchainNotAvailable)
}
app := &appchainMgr.Appchain{}
res := x.CrossInvoke(constant.AppchainMgrContractAddr.String(), "GetAppchain", pb.String(id))
if !res.Ok {
return nil, nil, fmt.Errorf("get appchain info error: " + string(res.Result))
return nil, nil, fmt.Errorf("%s: get appchain info error: %s", AppchainNotAvailable, string(res.Result))
}
if err := json.Unmarshal(res.Result, app); err != nil {
@ -267,7 +275,7 @@ func (x *InterchainManager) checkAppchain(id string) (*pb.Interchain, *appchainM
}
if app.Status != governance.GovernanceAvailable {
return nil, nil, fmt.Errorf("the appchain status is " + string(app.Status) + ", can not handle IBTP")
return nil, nil, fmt.Errorf("%s: the appchain status is %s, can not handle IBTP", AppchainNotAvailable, string(app.Status))
}
return interchain, app, nil
@ -278,7 +286,7 @@ func (x *InterchainManager) getAppchainInfo(chainMethod string) (*appchainMgr.Ap
srcChain := &appchainMgr.Appchain{}
res := x.CrossInvoke(constant.AppchainMgrContractAddr.String(), "GetAppchain", pb.String(chainMethod))
if err := json.Unmarshal(res.Result, srcChain); err != nil {
return nil, fmt.Errorf("unmarshal appchain info error: %w", err)
return nil, fmt.Errorf("%s: unmarshal appchain info error: %w", internalError, err)
}
return srcChain, nil
}

View File

@ -228,11 +228,11 @@ func TestInterchainManager_HandleIBTP(t *testing.T) {
res := im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "this appchain does not exist", string(res.Result))
assert.Equal(t, "appchain not available: this appchain does not exist", string(res.Result))
res = im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "empty destination chain id", string(res.Result))
assert.Equal(t, "invalid ibtp: empty destination chain id", string(res.Result))
ibtp = &pb.IBTP{
From: appchainMethod,
@ -248,12 +248,12 @@ func TestInterchainManager_HandleIBTP(t *testing.T) {
ibtp.From = appchainMethod2
res = im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, true, strings.HasPrefix(string(res.Result), "caller is not bind to ibtp from"))
assert.Equal(t, true, strings.Contains(string(res.Result), "caller is not bind to ibtp from"))
ibtp.From = appchainMethod
res = im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "index already exists, required 2, but 0", string(res.Result))
assert.Equal(t, "index already exists: required 2, but 0", string(res.Result))
ibtp.Index = 2
res = im.HandleIBTP(ibtp)
@ -274,7 +274,7 @@ func TestInterchainManager_HandleIBTP(t *testing.T) {
ibtp.Type = pb.IBTP_RECEIPT_SUCCESS
res = im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "caller is not bind to ibtp to", string(res.Result))
assert.Equal(t, "invalid ibtp: caller is not bind to ibtp to", string(res.Result))
mockStub.EXPECT().Caller().Return(to.String()).AnyTimes()
res = im.HandleIBTP(ibtp)

View File

@ -54,7 +54,7 @@ func (rm *RuleManager) BindRule(chainId string, ruleAddress string) *boltvm.Resp
rm.RuleManager.Persister = rm.Stub
// 1. check permission
if err := rm.checkPermission(chainId, PermissionSelf); err != nil {
if err := rm.checkPermission(chainId, PermissionSelfAdmin); err != nil {
return boltvm.Error(err.Error())
}
@ -94,7 +94,7 @@ func (rm *RuleManager) UnbindRule(chainId string, ruleAddress string) *boltvm.Re
rm.RuleManager.Persister = rm.Stub
// 1. check permission
if err := rm.checkPermission(chainId, PermissionSelf); err != nil {
if err := rm.checkPermission(chainId, PermissionSelfAdmin); err != nil {
return boltvm.Error(err.Error())
}
@ -239,16 +239,12 @@ func (rm *RuleManager) IsAvailableRule(chainId, ruleAddress string) *boltvm.Resp
}
func (rm *RuleManager) checkRuleAddress(addr string) error {
ok, data := rm.Persister.GetAccount(addr)
ok, account1 := rm.Persister.GetAccount(addr)
if !ok {
return fmt.Errorf("get account error: %s", string(data))
}
account := &ledger.Account{}
if err := json.Unmarshal(data, account); err != nil {
return fmt.Errorf("unmarshal account error: %s", err.Error())
return fmt.Errorf("get account error")
}
account := account1.(*ledger.Account)
if account.Code() == nil {
return fmt.Errorf("the validation rule does not exist")
}

View File

@ -180,15 +180,17 @@ func (exec *BlockExecutor) verifyProofs(blockWrapper *BlockWrapper) {
txs := block.Transactions
wg.Add(len(txs))
errM := make(map[int]string)
for i, tx := range txs {
go func(i int, tx *pb.Transaction) {
defer wg.Done()
if _, ok := blockWrapper.invalidTx[i]; !ok {
ok, _ := exec.ibtpVerify.CheckProof(tx)
ok, err := exec.ibtpVerify.CheckProof(tx)
if !ok {
lock.Lock()
defer lock.Unlock()
invalidTxs = append(invalidTxs, i)
errM[i] = err.Error()
}
}
}(i, tx)
@ -196,7 +198,7 @@ func (exec *BlockExecutor) verifyProofs(blockWrapper *BlockWrapper) {
wg.Wait()
for _, i := range invalidTxs {
blockWrapper.invalidTx[i] = "tx has invalid ibtp proof"
blockWrapper.invalidTx[i] = agency.InvalidReason(errM[i])
}
}

View File

@ -25,6 +25,13 @@ import (
"github.com/sirupsen/logrus"
)
const (
InvalidIBTP = "invalid ibtp"
AppchainNotAvailable = "appchain not available"
NoBindRule = "appchain didn't register rule"
internalError = "internal server error"
)
type VerifyPool struct {
proofs sync.Map //ibtp proof cache
ledger ledger.Ledger
@ -76,12 +83,12 @@ type bxhValidators struct {
// verifyMultiSign .
func verifyMultiSign(app *appchainMgr.Appchain, ibtp *pb.IBTP, proof []byte) (bool, error) {
if "" == app.Validators {
return false, fmt.Errorf("empty validators in relay chain:%s", app.ID)
if app.Validators == "" {
return false, fmt.Errorf("%s: empty validators in relay chain:%s", internalError, app.ID)
}
var validators bxhValidators
if err := json.Unmarshal([]byte(app.Validators), &validators); err != nil {
return false, err
return false, fmt.Errorf("%s: %w", InvalidIBTP, err)
}
m := make(map[string]struct{}, 0)
@ -90,7 +97,7 @@ func verifyMultiSign(app *appchainMgr.Appchain, ibtp *pb.IBTP, proof []byte) (bo
}
var signs pb.SignResponse
if err := signs.Unmarshal(ibtp.Proof); err != nil {
if err := signs.Unmarshal(proof); err != nil {
return false, err
}
@ -101,7 +108,7 @@ func verifyMultiSign(app *appchainMgr.Appchain, ibtp *pb.IBTP, proof []byte) (bo
hash := sha256.Sum256([]byte(ibtpHash.String()))
for v, sign := range signs.Sign {
if _, ok := m[v]; !ok {
return false, fmt.Errorf("wrong validator: %s", v)
return false, fmt.Errorf("%s: wrong validator: %s", InvalidIBTP, v)
}
delete(m, v)
addr := types.NewAddressByStr(v)
@ -113,33 +120,32 @@ func verifyMultiSign(app *appchainMgr.Appchain, ibtp *pb.IBTP, proof []byte) (bo
return true, nil
}
}
return false, fmt.Errorf("multi signs verify fail, counter: %d", counter)
return false, fmt.Errorf("%s: multi signs verify fail, counter: %d", InvalidIBTP, counter)
}
func (pl *VerifyPool) verifyProof(ibtp *pb.IBTP, proof []byte) (bool, error) {
if proof == nil {
return false, fmt.Errorf("empty proof")
return false, fmt.Errorf("%s:, empty proof", InvalidIBTP)
}
proofHash := sha256.Sum256(proof)
if !bytes.Equal(proofHash[:], ibtp.Proof) {
return false, fmt.Errorf("proof hash is not correct")
return false, fmt.Errorf("%s: proof hash is not correct", InvalidIBTP)
}
// get real appchain id for union ibtp
from := ibtp.From
if len(strings.Split(ibtp.From, "-")) == 2 {
from = strings.Split(ibtp.From, "-")[1]
return true, nil
}
app := &appchainMgr.Appchain{}
ok, data := pl.getAccountState(constant.AppchainMgrContractAddr, contracts.AppchainKey(from)) // ibtp.From
if !ok {
return false, fmt.Errorf("cannot get registered appchain")
return false, fmt.Errorf("%s: cannot get registered appchain", AppchainNotAvailable)
}
err := json.Unmarshal(data, app)
if err != nil {
return false, fmt.Errorf("unmarshal appchain data fail: %w", err)
return false, fmt.Errorf("%s: unmarshal appchain data fail: %w", internalError, err)
}
if len(strings.Split(ibtp.From, "-")) == 2 {
@ -151,18 +157,18 @@ func (pl *VerifyPool) verifyProof(ibtp *pb.IBTP, proof []byte) (bool, error) {
ok, data = pl.getRule(from)
if ok {
if err := json.Unmarshal(data, rl); err != nil {
return false, fmt.Errorf("unmarshal rule data error: %w", err)
return false, fmt.Errorf("%s: unmarshal rule data error: %w", internalError, err)
}
validateAddr = rl.Address
} else {
if app.ChainType != appchainMgr.FabricType {
return false, fmt.Errorf("appchain didn't register rule")
return false, fmt.Errorf(NoBindRule)
}
}
ok, err = pl.ve.Validate(validateAddr, from, proof, ibtp.Payload, app.Validators) // ibtp.From
if err != nil {
return false, err
return false, fmt.Errorf("%s: %w", InvalidIBTP, err)
}
return ok, nil
}

View File

@ -175,14 +175,14 @@ func TestVerifyPool_CheckProof2(t *testing.T) {
}
signData, err := sign.Marshal()
require.Nil(t, err)
ibtp.Proof = signData
proof := signData
ok, err := verifyMultiSign(chain, ibtp, nil)
require.NotNil(t, err)
require.False(t, ok)
chain.Validators = string(addrsData)
ok, err = verifyMultiSign(chain, ibtp, nil)
ok, err = verifyMultiSign(chain, ibtp, proof)
require.Nil(t, err)
require.True(t, ok)
}

View File

@ -154,13 +154,9 @@ func (b *BoltStubImpl) ValidationEngine() validator.Engine {
return b.ve
}
func (b *BoltStubImpl) GetAccount(address string) (bool, []byte) {
func (b *BoltStubImpl) GetAccount(address string) (bool, interface{}) {
addr := types.NewAddressByStr(address)
account := b.ctx.Ledger.GetAccount(addr)
data, err := json.Marshal(account)
if err != nil {
return false, []byte(err.Error())
}
return true, data
return true, account
}

View File

@ -186,7 +186,7 @@ func (suite *Interchain) TestHandleIBTP() {
// register rule
ret, err = invokeBVMContract(suite.api, k1, k1Nonce, constant.RuleManagerContractAddr.Address(),
"RegisterRule", pb.String(string(bitxid.DID(did).GetChainDID())), pb.String(addr.String()))
"BindRule", pb.String(string(bitxid.DID(did).GetChainDID())), pb.String(addr.String()))
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess())
k1Nonce++
@ -362,10 +362,38 @@ func (suite *Interchain) TestGetIBTPByID() {
k1Nonce++
// register rule
_, err = invokeBVMContract(suite.api, k1, k1Nonce, constant.RuleManagerContractAddr.Address(),
"RegisterRule", pb.String(id1), pb.String(addr.String()))
ret, err = invokeBVMContract(suite.api, k1, k1Nonce, constant.RuleManagerContractAddr.Address(),
"BindRule", pb.String(id1), pb.String(addr.String()))
suite.Require().Nil(err)
k1Nonce++
proposalRuleId := gjson.Get(string(ret.Ret), "proposal_id").String()
ret, err = invokeBVMContract(suite.api, priAdmin1, adminNonce1, constant.GovernanceContractAddr.Address(), "Vote",
pb.String(proposalRuleId),
pb.String(string(contracts.APPOVED)),
pb.String("reason"),
)
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess(), string(ret.Ret))
adminNonce1++
ret, err = invokeBVMContract(suite.api, priAdmin2, adminNonce2, constant.GovernanceContractAddr.Address(), "Vote",
pb.String(proposalRuleId),
pb.String(string(contracts.APPOVED)),
pb.String("reason"),
)
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess(), string(ret.Ret))
adminNonce2++
ret, err = invokeBVMContract(suite.api, priAdmin3, adminNonce3, constant.GovernanceContractAddr.Address(), "Vote",
pb.String(proposalRuleId),
pb.String(string(contracts.APPOVED)),
pb.String("reason"),
)
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess(), string(ret.Ret))
adminNonce3++
proof, err := ioutil.ReadFile("./test_data/proof")
suite.Require().Nil(err)

View File

@ -1,11 +1,14 @@
package tester
import (
"encoding/base64"
"encoding/json"
"io/ioutil"
"path/filepath"
"strconv"
"github.com/meshplus/bitxhub/internal/repo"
"github.com/meshplus/bitxid"
"github.com/meshplus/bitxhub/internal/executor/contracts"
@ -147,9 +150,9 @@ func (suite *Role) TestGetRuleAddress() {
k1Nonce := uint64(1)
k2Nonce := uint64(1)
pub1, err := k1.PublicKey().Bytes()
chainAdminKeyPath, err := repo.PathRootWithDefault("test_data/admin.json")
suite.Require().Nil(err)
pub2, err := k2.PublicKey().Bytes()
pubKey, err := getPubKey(chainAdminKeyPath)
suite.Require().Nil(err)
addr1, err := k1.PublicKey().Address()
@ -170,7 +173,7 @@ func (suite *Role) TestGetRuleAddress() {
pb.String("婚姻链"),
pb.String("趣链婚姻链"),
pb.String("1.8"),
pb.String(string(pub1)),
pb.String(string(pubKey)),
)
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess(), string(ret.Ret))
@ -217,7 +220,7 @@ func (suite *Role) TestGetRuleAddress() {
pb.String("政务链"),
pb.String("fabric政务"),
pb.String("1.4"),
pb.String(string(pub2)),
pb.String(string(pubKey)),
)
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess(), string(ret.Ret))
@ -268,12 +271,12 @@ func (suite *Role) TestGetRuleAddress() {
suite.Require().NotEqual(addr1, addr2)
// register rule
ret, err = invokeBVMContract(suite.api, k1, k1Nonce, constant.RuleManagerContractAddr.Address(), "RegisterRule", pb.String(string(bitxid.DID(did).GetChainDID())), pb.String(addr1.String()))
ret, err = invokeBVMContract(suite.api, k1, k1Nonce, constant.RuleManagerContractAddr.Address(), "BindRule", pb.String(string(bitxid.DID(did).GetChainDID())), pb.String(addr1.String()))
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess(), string(ret.Ret))
k1Nonce++
ret, err = invokeBVMContract(suite.api, k2, k2Nonce, constant.RuleManagerContractAddr.Address(), "RegisterRule", pb.String(string(bitxid.DID(did2).GetChainDID())), pb.String(addr2.String()))
ret, err = invokeBVMContract(suite.api, k2, k2Nonce, constant.RuleManagerContractAddr.Address(), "BindRule", pb.String(string(bitxid.DID(did2).GetChainDID())), pb.String(addr2.String()))
suite.Require().Nil(err)
suite.Require().True(ret.IsSuccess())
k2Nonce++
@ -394,3 +397,16 @@ func (suite *Role) TestSetAdminRoles() {
suite.EqualValues(4, len(ret3.Array()))
adminNonce++
}
func getPubKey(keyPath string) (string, error) {
privKey, err := asym.RestorePrivateKey(keyPath, "bitxhub")
if err != nil {
return "", err
}
pubBytes, err := privKey.PublicKey().Bytes()
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(pubBytes), nil
}