feat(*): add bvm transaction receipt error type
This commit is contained in:
parent
80d8057fcf
commit
b04f2c2a52
|
@ -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 {
|
||||
|
|
|
@ -732,11 +732,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,
|
||||
|
@ -752,12 +752,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)
|
||||
|
@ -778,7 +778,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)
|
||||
|
|
|
@ -18,6 +18,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
|
||||
}
|
||||
|
@ -180,7 +188,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 {
|
||||
|
@ -197,15 +205,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 {
|
||||
|
@ -214,16 +222,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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,13 +260,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 {
|
||||
|
@ -266,7 +274,7 @@ func (x *InterchainManager) checkAppchain(id string) (*pb.Interchain, *appchainM
|
|||
}
|
||||
|
||||
if app.Status != appchainMgr.AppchainAvailable {
|
||||
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
|
||||
|
@ -277,7 +285,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
|
||||
}
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,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
|
||||
|
@ -73,12 +80,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)
|
||||
|
@ -87,7 +94,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
|
||||
}
|
||||
|
||||
|
@ -98,7 +105,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)
|
||||
|
@ -110,33 +117,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 {
|
||||
|
@ -148,18 +154,18 @@ func (pl *VerifyPool) verifyProof(ibtp *pb.IBTP, proof []byte) (bool, error) {
|
|||
ok, data = pl.getAccountState(constant.RuleManagerContractAddr, contracts.RuleKey(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
|
||||
}
|
||||
|
|
|
@ -171,14 +171,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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue