From bd0b04e63e265c1107d0960d0e658233ff78d1ec Mon Sep 17 00:00:00 2001 From: zhourong Date: Wed, 30 Sep 2020 10:45:50 +0800 Subject: [PATCH] test(executor): add more executor unit test --- internal/executor/contracts/asset_exchange.go | 13 - internal/executor/contracts/contracts_test.go | 966 ++++++++++++++++++ internal/executor/executor.go | 4 - internal/executor/executor_test.go | 149 ++- pkg/proof/proof_pool.go | 4 +- pkg/vm/boltvm/stub.go | 1 + 6 files changed, 1109 insertions(+), 28 deletions(-) create mode 100644 internal/executor/contracts/contracts_test.go diff --git a/internal/executor/contracts/asset_exchange.go b/internal/executor/contracts/asset_exchange.go index 69ec1ea..f6f4a46 100644 --- a/internal/executor/contracts/asset_exchange.go +++ b/internal/executor/contracts/asset_exchange.go @@ -120,16 +120,3 @@ func checkAssetExchangeInfo(aei *pb.AssetExchangeInfo) error { return nil } - -func checkAssetExchangeInfoPair(aei0, aei1 *pb.AssetExchangeInfo) error { - if aei0.SenderOnSrc != aei1.ReceiverOnDst || - aei0.ReceiverOnSrc != aei1.SenderOnDst || - aei0.SenderOnDst != aei1.ReceiverOnSrc || - aei0.ReceiverOnDst != aei1.SenderOnSrc || - aei0.AssetOnSrc != aei1.AssetOnDst || - aei0.AssetOnDst != aei1.AssetOnSrc { - return fmt.Errorf("unmatched exchange info pair") - } - - return nil -} diff --git a/internal/executor/contracts/contracts_test.go b/internal/executor/contracts/contracts_test.go new file mode 100644 index 0000000..108cf12 --- /dev/null +++ b/internal/executor/contracts/contracts_test.go @@ -0,0 +1,966 @@ +package contracts + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/golang/mock/gomock" + appchainMgr "github.com/meshplus/bitxhub-core/appchain-mgr" + "github.com/meshplus/bitxhub-core/validator" + "github.com/meshplus/bitxhub-kit/types" + "github.com/meshplus/bitxhub-model/pb" + "github.com/meshplus/bitxhub/internal/constant" + "github.com/meshplus/bitxhub/pkg/vm/boltvm" + "github.com/meshplus/bitxhub/pkg/vm/boltvm/mock_stub" + "github.com/stretchr/testify/assert" +) + +func TestAppchainManager_Appchain(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + addr0 := types.Address{0}.String() + addr1 := types.Address{1}.String() + + chain := &appchainMgr.Appchain{ + ID: addr0, + Name: "appchain A", + Validators: "", + ConsensusType: 0, + ChainType: "fabric", + Desc: "", + Version: "", + PublicKey: "11111", + } + + data, err := json.Marshal(chain) + assert.Nil(t, err) + + o1 := mockStub.EXPECT().Caller().Return(addr0) + o2 := mockStub.EXPECT().Caller().Return(addr1) + gomock.InOrder(o1, o2) + mockStub.EXPECT().Get("appchain-"+addr0).Return(true, data) + mockStub.EXPECT().Get("appchain-"+addr1).Return(false, nil) + + am := &AppchainManager{ + Stub: mockStub, + } + + res := am.Appchain() + assert.Equal(t, true, res.Ok) + assert.Equal(t, data, res.Result) + + res = am.Appchain() + assert.Equal(t, false, res.Ok) +} + +func TestAppchainManager_Appchains(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + var chains []*appchainMgr.Appchain + var chainsData [][]byte + for i := 0; i < 2; i++ { + addr := types.Address{byte(i)}.String() + + chain := &appchainMgr.Appchain{ + ID: addr, + Name: "appchain" + addr, + Validators: "", + ConsensusType: int32(i), + ChainType: "fabric", + Desc: "", + Version: "", + PublicKey: "pubkey" + addr, + } + + data, err := json.Marshal(chain) + assert.Nil(t, err) + + chainsData = append(chainsData, data) + chains = append(chains, chain) + } + + o1 := mockStub.EXPECT().Query(appchainMgr.PREFIX).Return(true, chainsData) + o2 := mockStub.EXPECT().Query(appchainMgr.PREFIX).Return(false, nil) + gomock.InOrder(o1, o2) + + am := &AppchainManager{ + Stub: mockStub, + } + + res := am.Appchains() + assert.Equal(t, true, res.Ok) + + var appchains []*appchainMgr.Appchain + err := json.Unmarshal(res.Result, &appchains) + assert.Nil(t, err) + assert.Equal(t, 2, len(chains)) + assert.Equal(t, chains[0], appchains[0]) + assert.Equal(t, chains[1], appchains[1]) + + res = am.Appchains() + assert.Equal(t, true, res.Ok) + assert.Equal(t, []byte(nil), res.Result) +} + +func TestInterchainManager_Register(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + addr := types.Address{}.String() + mockStub.EXPECT().Caller().Return(addr).AnyTimes() + mockStub.EXPECT().Set(gomock.Any(), gomock.Any()).AnyTimes() + o1 := mockStub.EXPECT().Get(appchainMgr.PREFIX+addr).Return(false, nil) + + interchain := pb.Interchain{ + ID: addr, + InterchainCounter: make(map[string]uint64), + ReceiptCounter: make(map[string]uint64), + SourceReceiptCounter: make(map[string]uint64), + } + interchain.InterchainCounter[addr] = 1 + interchain.ReceiptCounter[addr] = 1 + interchain.SourceReceiptCounter[addr] = 1 + data0, err := interchain.Marshal() + assert.Nil(t, err) + o2 := mockStub.EXPECT().Get(appchainMgr.PREFIX+addr).Return(true, data0) + + interchain = pb.Interchain{ + ID: addr, + InterchainCounter: make(map[string]uint64), + ReceiptCounter: make(map[string]uint64), + SourceReceiptCounter: make(map[string]uint64), + } + data1, err := interchain.Marshal() + assert.Nil(t, err) + o3 := mockStub.EXPECT().Get(appchainMgr.PREFIX+addr).Return(true, data1) + gomock.InOrder(o1, o2, o3) + + im := &InterchainManager{mockStub} + + res := im.Register() + assert.Equal(t, true, res.Ok) + + ic := &pb.Interchain{} + err = ic.Unmarshal(res.Result) + assert.Nil(t, err) + assert.Equal(t, addr, ic.ID) + assert.Equal(t, 0, len(ic.InterchainCounter)) + assert.Equal(t, 0, len(ic.ReceiptCounter)) + assert.Equal(t, 0, len(ic.SourceReceiptCounter)) + + res = im.Register() + assert.Equal(t, true, res.Ok) + assert.Equal(t, data0, res.Result) + + res = im.Register() + assert.Equal(t, true, res.Ok) + assert.Equal(t, data1, res.Result) +} + +func TestInterchainManager_Interchain(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + addr := types.Address{}.String() + mockStub.EXPECT().Caller().Return(addr).AnyTimes() + mockStub.EXPECT().Set(gomock.Any(), gomock.Any()).AnyTimes() + o1 := mockStub.EXPECT().Get(appchainMgr.PREFIX+addr).Return(false, nil) + + interchain := pb.Interchain{ + ID: addr, + InterchainCounter: make(map[string]uint64), + ReceiptCounter: make(map[string]uint64), + SourceReceiptCounter: make(map[string]uint64), + } + interchain.InterchainCounter[addr] = 1 + interchain.ReceiptCounter[addr] = 1 + interchain.SourceReceiptCounter[addr] = 1 + data0, err := interchain.Marshal() + assert.Nil(t, err) + o2 := mockStub.EXPECT().Get(appchainMgr.PREFIX+addr).Return(true, data0) + gomock.InOrder(o1, o2) + + im := &InterchainManager{mockStub} + + res := im.Interchain() + assert.False(t, res.Ok) + + res = im.Interchain() + assert.True(t, res.Ok) + assert.Equal(t, data0, res.Result) +} + +func TestInterchainManager_GetInterchain(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + addr := types.Address{}.String() + mockStub.EXPECT().Set(gomock.Any(), gomock.Any()).AnyTimes() + o1 := mockStub.EXPECT().Get(appchainMgr.PREFIX+addr).Return(false, nil) + + interchain := pb.Interchain{ + ID: addr, + InterchainCounter: make(map[string]uint64), + ReceiptCounter: make(map[string]uint64), + SourceReceiptCounter: make(map[string]uint64), + } + interchain.InterchainCounter[addr] = 1 + interchain.ReceiptCounter[addr] = 1 + interchain.SourceReceiptCounter[addr] = 1 + data0, err := interchain.Marshal() + assert.Nil(t, err) + o2 := mockStub.EXPECT().Get(appchainMgr.PREFIX+addr).Return(true, data0) + gomock.InOrder(o1, o2) + + im := &InterchainManager{mockStub} + + res := im.GetInterchain(addr) + assert.False(t, res.Ok) + + res = im.GetInterchain(addr) + assert.True(t, res.Ok) + assert.Equal(t, data0, res.Result) +} + +func TestInterchainManager_HandleIBTP(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + from := types.Address{0}.String() + to := types.Address{1}.String() + mockStub.EXPECT().Set(gomock.Any(), gomock.Any()).AnyTimes() + f1 := mockStub.EXPECT().Get(appchainMgr.PREFIX+from).Return(false, nil) + + interchain := pb.Interchain{ + ID: from, + InterchainCounter: make(map[string]uint64), + ReceiptCounter: make(map[string]uint64), + SourceReceiptCounter: make(map[string]uint64), + } + interchain.InterchainCounter[to] = 1 + interchain.ReceiptCounter[to] = 1 + interchain.SourceReceiptCounter[to] = 1 + data0, err := interchain.Marshal() + assert.Nil(t, err) + + f2 := mockStub.EXPECT().Get(appchainMgr.PREFIX+from).Return(true, data0).AnyTimes() + mockStub.EXPECT().Get(appchainMgr.PREFIX+to).Return(true, data0).AnyTimes() + mockStub.EXPECT().CrossInvoke(gomock.Any(), gomock.Any(), gomock.Any()).Return(boltvm.Success(nil)).AnyTimes() + mockStub.EXPECT().AddObject(gomock.Any(), gomock.Any()).AnyTimes() + mockStub.EXPECT().GetTxIndex().Return(uint64(1)).AnyTimes() + mockStub.EXPECT().PostInterchainEvent(gomock.Any()).AnyTimes() + mockStub.EXPECT().GetTxHash().Return(types.Hash{}).AnyTimes() + gomock.InOrder(f1, f2) + + im := &InterchainManager{mockStub} + + fakeIBTP := []byte{1} + res := im.HandleIBTP(fakeIBTP) + assert.False(t, res.Ok) + + ibtp := &pb.IBTP{ + From: from, + } + + ibtpd, err := ibtp.Marshal() + assert.Nil(t, err) + + res = im.HandleIBTP(ibtpd) + assert.False(t, res.Ok) + assert.Equal(t, "this appchain does not exist", string(res.Result)) + + res = im.HandleIBTP(ibtpd) + assert.False(t, res.Ok) + assert.Equal(t, "empty destination chain id", string(res.Result)) + + ibtp = &pb.IBTP{ + From: from, + To: to, + Index: 0, + Type: pb.IBTP_INTERCHAIN, + Timestamp: 0, + Proof: nil, + Payload: nil, + Version: "", + Extra: nil, + } + ibtpd, err = ibtp.Marshal() + assert.Nil(t, err) + + mockStub.EXPECT().Caller().Return(ibtp.To) + + res = im.HandleIBTP(ibtpd) + assert.False(t, res.Ok) + assert.Equal(t, "ibtp from != caller", string(res.Result)) + + mockStub.EXPECT().Caller().Return(ibtp.From).MaxTimes(6) + + res = im.HandleIBTP(ibtpd) + assert.False(t, res.Ok) + assert.Equal(t, "wrong index, required 2, but 0", string(res.Result)) + + ibtp.Index = 2 + ibtpd, err = ibtp.Marshal() + assert.Nil(t, err) + + res = im.HandleIBTP(ibtpd) + assert.True(t, res.Ok) + + ibtp.Type = pb.IBTP_ASSET_EXCHANGE_INIT + ibtpd, err = ibtp.Marshal() + assert.Nil(t, err) + + res = im.HandleIBTP(ibtpd) + assert.True(t, res.Ok) + + ibtp.Type = pb.IBTP_ASSET_EXCHANGE_REFUND + ibtpd, err = ibtp.Marshal() + assert.Nil(t, err) + + res = im.HandleIBTP(ibtpd) + assert.True(t, res.Ok) + + ibtp.Type = pb.IBTP_ASSET_EXCHANGE_REDEEM + ibtpd, err = ibtp.Marshal() + assert.Nil(t, err) + + res = im.HandleIBTP(ibtpd) + assert.True(t, res.Ok) + + ibtp.Type = pb.IBTP_RECEIPT_SUCCESS + ibtpd, err = ibtp.Marshal() + assert.Nil(t, err) + + res = im.HandleIBTP(ibtpd) + assert.False(t, res.Ok) + assert.Equal(t, "ibtp to != caller", string(res.Result)) + + mockStub.EXPECT().Caller().Return(ibtp.To).AnyTimes() + + res = im.HandleIBTP(ibtpd) + assert.True(t, res.Ok) + + ibtp.Type = pb.IBTP_RECEIPT_FAILURE + ibtpd, err = ibtp.Marshal() + assert.Nil(t, err) + + res = im.HandleIBTP(ibtpd) + assert.True(t, res.Ok) + + ibtp.Type = pb.IBTP_ASSET_EXCHANGE_RECEIPT + ibtpd, err = ibtp.Marshal() + assert.Nil(t, err) + + res = im.HandleIBTP(ibtpd) + assert.True(t, res.Ok) +} + +func TestInterchainManager_GetIBTPByID(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + from := types.Address{}.String() + to := types.Address{byte(1)}.String() + + validID := fmt.Sprintf("%s-%s-1", from, to) + + mockStub.EXPECT().Caller().Return(from).AnyTimes() + im := &InterchainManager{mockStub} + + res := im.GetIBTPByID("a") + assert.False(t, res.Ok) + assert.Equal(t, "wrong ibtp id", string(res.Result)) + + res = im.GetIBTPByID("abc-def-10") + assert.False(t, res.Ok) + assert.Equal(t, "The caller does not have access to this ibtp", string(res.Result)) + + unexistId := fmt.Sprintf("%s-%s-10", from, to) + mockStub.EXPECT().GetObject(fmt.Sprintf("index-tx-%s", unexistId), gomock.Any()).Return(false) + + res = im.GetIBTPByID(unexistId) + assert.False(t, res.Ok) + assert.Equal(t, "this id is not existed", string(res.Result)) + + mockStub.EXPECT().GetObject(fmt.Sprintf("index-tx-%s", validID), gomock.Any()).Return(true) + res = im.GetIBTPByID(validID) + assert.True(t, res.Ok) +} + +func TestRole_GetRole(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + addrs := []string{types.Address{0}.String(), types.Address{1}.String()} + + mockStub.EXPECT().GetObject(adminRolesKey, gomock.Any()).SetArg(1, addrs).AnyTimes() + mockStub.EXPECT().Caller().Return(types.Address{0}.String()) + + im := &Role{mockStub} + + res := im.GetRole() + assert.True(t, res.Ok) + assert.Equal(t, "admin", string(res.Result)) + + mockStub.EXPECT().Caller().Return(types.Address{2}.String()).AnyTimes() + mockStub.EXPECT().CrossInvoke(gomock.Any(), gomock.Any(), gomock.Any()).Return(boltvm.Error("")) + + res = im.GetRole() + assert.True(t, res.Ok) + assert.Equal(t, "none", string(res.Result)) + + mockStub.EXPECT().CrossInvoke(gomock.Any(), gomock.Any(), gomock.Any()).Return(boltvm.Success(nil)) + + res = im.GetRole() + assert.True(t, res.Ok) + assert.Equal(t, "appchain_admin", string(res.Result)) +} + +func TestRole_IsAdmin(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + addrs := []string{types.Address{0}.String(), types.Address{1}.String()} + + mockStub.EXPECT().GetObject(adminRolesKey, gomock.Any()).SetArg(1, addrs).AnyTimes() + + im := &Role{mockStub} + + res := im.IsAdmin(addrs[0]) + assert.True(t, res.Ok) + assert.Equal(t, "true", string(res.Result)) + + res = im.IsAdmin(types.Address{2}.String()) + assert.True(t, res.Ok) + assert.Equal(t, "false", string(res.Result)) +} + +func TestRole_GetAdminRoles(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + addrs := []string{types.Address{0}.String(), types.Address{1}.String()} + + mockStub.EXPECT().GetObject(adminRolesKey, gomock.Any()).SetArg(1, addrs).AnyTimes() + + im := &Role{mockStub} + + res := im.GetAdminRoles() + assert.True(t, res.Ok) + + var admins []string + err := json.Unmarshal(res.Result, &admins) + assert.Nil(t, err) + assert.Equal(t, len(addrs), len(admins)) + for i, addr := range addrs { + assert.Equal(t, addr, admins[i]) + } +} + +func TestRole_SetAdminRoles(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + addrs := []string{types.Address{0}.String(), types.Address{1}.String()} + mockStub.EXPECT().SetObject(adminRolesKey, addrs).AnyTimes() + + im := &Role{mockStub} + + data, err := json.Marshal(addrs) + assert.Nil(t, err) + + res := im.SetAdminRoles(string(data)) + assert.True(t, res.Ok) +} + +func TestRuleManager_RegisterRule(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + id0 := types.Address{0}.String() + id1 := types.Address{1}.String() + + mockStub.EXPECT().CrossInvoke(constant.AppchainMgrContractAddr.String(), "GetAppchain", pb.String(id0)).Return(boltvm.Success(nil)) + mockStub.EXPECT().CrossInvoke(constant.AppchainMgrContractAddr.String(), "GetAppchain", pb.String(id1)).Return(boltvm.Error("")) + mockStub.EXPECT().SetObject(gomock.Any(), gomock.Any()).AnyTimes() + + im := &RuleManager{mockStub} + + addr := types.Address{2}.String() + res := im.RegisterRule(id0, addr) + assert.True(t, res.Ok) + + res = im.RegisterRule(id1, addr) + assert.False(t, res.Ok) + assert.Equal(t, "this appchain does not exist", string(res.Result)) +} + +func TestRuleManager_GetRuleAddress(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + id0 := types.Address{0}.String() + id1 := types.Address{1}.String() + rule := Rule{ + Address: "123", + Status: 1, + } + + mockStub.EXPECT().GetObject(RuleKey(id0), gomock.Any()).SetArg(1, rule).Return(true) + mockStub.EXPECT().GetObject(RuleKey(id1), gomock.Any()).Return(false).MaxTimes(5) + + im := &RuleManager{mockStub} + + res := im.GetRuleAddress(id0, "") + assert.True(t, res.Ok) + assert.Equal(t, rule.Address, string(res.Result)) + + res = im.GetRuleAddress(id1, "fabric") + assert.True(t, res.Ok) + assert.Equal(t, validator.FabricRuleAddr, string(res.Result)) + + res = im.GetRuleAddress(id1, "hyperchain") + assert.False(t, res.Ok) + assert.Equal(t, "", string(res.Result)) +} + +func TestRuleManager_Audit(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + id0 := types.Address{0}.String() + id1 := types.Address{1}.String() + rule := Rule{ + Address: "123", + Status: 1, + } + + mockStub.EXPECT().GetObject(RuleKey(id0), gomock.Any()).SetArg(1, rule).Return(true) + mockStub.EXPECT().GetObject(RuleKey(id1), gomock.Any()).Return(false) + mockStub.EXPECT().SetObject(gomock.Any(), gomock.Any()).AnyTimes() + mockStub.EXPECT().GetObject("audit-record-"+id0, gomock.Any()).SetArg(1, []*ruleRecord{}).Return(true).AnyTimes() + + im := &RuleManager{mockStub} + + res := im.Audit(id1, 0, "") + assert.False(t, res.Ok) + assert.Equal(t, "this rule does not exist", string(res.Result)) + + res = im.Audit(id0, 1, "approve") + assert.True(t, res.Ok) +} + +func TestStore_Get(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + key0 := "1" + val0 := "10" + key1 := "1" + + mockStub.EXPECT().GetObject(key0, gomock.Any()).SetArg(1, val0).Return(true) + mockStub.EXPECT().GetObject(key1, gomock.Any()).Return(false) + + im := &Store{mockStub} + + res := im.Get(key0) + assert.True(t, res.Ok) + assert.Equal(t, val0, string(res.Result)) + + res = im.Get(key1) + assert.False(t, res.Ok) + assert.Equal(t, "there is not exist key", string(res.Result)) +} + +func TestStore_Set(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + mockStub.EXPECT().SetObject(gomock.Any(), gomock.Any()) + + im := &Store{mockStub} + + res := im.Set("1", "2") + assert.True(t, res.Ok) +} + +func TestTransactionManager_Begin(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + id := types.Hash{}.String() + mockStub.EXPECT().AddObject(fmt.Sprintf("%s-%s", PREFIX, id), pb.TransactionStatus_BEGIN) + + im := &TransactionManager{mockStub} + + res := im.Begin(id) + assert.True(t, res.Ok) +} + +func TestTransactionManager_Report(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + id0 := "id0" + id1 := "id1" + txInfoKey := fmt.Sprintf("%s-%s", PREFIX, id0) + + im := &TransactionManager{mockStub} + + mockStub.EXPECT().GetObject(txInfoKey, gomock.Any()).SetArg(1, pb.TransactionStatus_SUCCESS).Return(true) + res := im.Report(id0, 0) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("transaction with Id %s is finished", id0), string(res.Result)) + + mockStub.EXPECT().GetObject(txInfoKey, gomock.Any()).SetArg(1, pb.TransactionStatus_BEGIN).Return(true) + mockStub.EXPECT().SetObject(txInfoKey, pb.TransactionStatus_SUCCESS) + res = im.Report(id0, 0) + assert.True(t, res.Ok) + + mockStub.EXPECT().GetObject(txInfoKey, gomock.Any()).SetArg(1, pb.TransactionStatus_BEGIN).Return(true) + mockStub.EXPECT().SetObject(txInfoKey, pb.TransactionStatus_FAILURE) + res = im.Report(id0, 1) + assert.True(t, res.Ok) + + mockStub.EXPECT().GetObject(txInfoKey, gomock.Any()).Return(false).AnyTimes() + + mockStub.EXPECT().Get(id0).Return(false, nil) + res = im.Report(id0, 0) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("cannot get global id of child tx id %s", id0), string(res.Result)) + + globalId := "globalId" + globalInfoKey := fmt.Sprintf("global-%s-%s", PREFIX, globalId) + mockStub.EXPECT().Get(id0).Return(true, []byte(globalId)).AnyTimes() + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).Return(false) + res = im.Report(id0, 0) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("transaction global id %s does not exist", globalId), string(res.Result)) + + txInfo := TransactionInfo{ + GlobalState: pb.TransactionStatus_SUCCESS, + ChildTxInfo: make(map[string]pb.TransactionStatus), + } + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).SetArg(1, txInfo).Return(true) + res = im.Report(id0, 0) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("transaction with global Id %s is finished", globalId), string(res.Result)) + + txInfo.GlobalState = pb.TransactionStatus_BEGIN + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).SetArg(1, txInfo).Return(true) + res = im.Report(id0, 0) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("%s is not in transaction %s, %v", id0, globalId, txInfo), string(res.Result)) + + txInfo.ChildTxInfo[id0] = pb.TransactionStatus_SUCCESS + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).SetArg(1, txInfo).Return(true).MaxTimes(1) + res = im.Report(id0, 0) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("%s has already reported result", id0), string(res.Result)) + + txInfo.GlobalState = pb.TransactionStatus_BEGIN + txInfo.ChildTxInfo[id0] = pb.TransactionStatus_BEGIN + txInfo.ChildTxInfo[id1] = pb.TransactionStatus_BEGIN + expTxInfo := TransactionInfo{ + GlobalState: pb.TransactionStatus_BEGIN, + ChildTxInfo: make(map[string]pb.TransactionStatus), + } + expTxInfo.ChildTxInfo[id0] = pb.TransactionStatus_SUCCESS + expTxInfo.ChildTxInfo[id1] = pb.TransactionStatus_BEGIN + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).SetArg(1, txInfo).Return(true).MaxTimes(1) + mockStub.EXPECT().SetObject(globalInfoKey, expTxInfo).MaxTimes(1) + res = im.Report(id0, 0) + assert.True(t, res.Ok) + + txInfo.GlobalState = pb.TransactionStatus_BEGIN + txInfo.ChildTxInfo[id0] = pb.TransactionStatus_BEGIN + txInfo.ChildTxInfo[id1] = pb.TransactionStatus_SUCCESS + expTxInfo.GlobalState = pb.TransactionStatus_SUCCESS + expTxInfo.ChildTxInfo[id0] = pb.TransactionStatus_SUCCESS + expTxInfo.ChildTxInfo[id1] = pb.TransactionStatus_SUCCESS + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).SetArg(1, txInfo).Return(true).MaxTimes(1) + mockStub.EXPECT().SetObject(globalInfoKey, expTxInfo).MaxTimes(1) + res = im.Report(id0, 0) + assert.True(t, res.Ok) + + txInfo.GlobalState = pb.TransactionStatus_BEGIN + txInfo.ChildTxInfo[id0] = pb.TransactionStatus_BEGIN + txInfo.ChildTxInfo[id1] = pb.TransactionStatus_SUCCESS + expTxInfo.GlobalState = pb.TransactionStatus_FAILURE + expTxInfo.ChildTxInfo[id0] = pb.TransactionStatus_FAILURE + expTxInfo.ChildTxInfo[id1] = pb.TransactionStatus_SUCCESS + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).SetArg(1, txInfo).Return(true).MaxTimes(1) + mockStub.EXPECT().SetObject(globalInfoKey, expTxInfo).MaxTimes(1) + res = im.Report(id0, 1) + assert.True(t, res.Ok) +} + +func TestTransactionManager_GetStatus(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + id := "id" + txInfoKey := fmt.Sprintf("%s-%s", PREFIX, id) + globalInfoKey := fmt.Sprintf("global-%s-%s", PREFIX, id) + + im := &TransactionManager{mockStub} + + mockStub.EXPECT().GetObject(txInfoKey, gomock.Any()).SetArg(1, pb.TransactionStatus_SUCCESS).Return(true).MaxTimes(1) + res := im.GetStatus(id) + assert.True(t, res.Ok) + assert.Equal(t, "1", string(res.Result)) + + txInfo := TransactionInfo{ + GlobalState: pb.TransactionStatus_BEGIN, + ChildTxInfo: make(map[string]pb.TransactionStatus), + } + mockStub.EXPECT().GetObject(txInfoKey, gomock.Any()).Return(false).AnyTimes() + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).SetArg(1, txInfo).Return(true).MaxTimes(1) + res = im.GetStatus(id) + assert.True(t, res.Ok) + assert.Equal(t, "0", string(res.Result)) + + mockStub.EXPECT().GetObject(globalInfoKey, gomock.Any()).Return(false).AnyTimes() + mockStub.EXPECT().Get(id).Return(false, nil).MaxTimes(1) + res = im.GetStatus(id) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("cannot get global id of child tx id %s", id), string(res.Result)) + + globalId := "globalId" + globalIdInfoKey := fmt.Sprintf("global-%s-%s", PREFIX, globalId) + mockStub.EXPECT().Get(id).Return(true, []byte(globalId)).AnyTimes() + mockStub.EXPECT().GetObject(globalIdInfoKey, gomock.Any()).Return(false).MaxTimes(1) + res = im.GetStatus(id) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("transaction info for global id %s does not exist", globalId), string(res.Result)) + + mockStub.EXPECT().GetObject(globalIdInfoKey, gomock.Any()).SetArg(1, txInfo).Return(true).MaxTimes(1) + res = im.GetStatus(id) + assert.True(t, res.Ok) + assert.Equal(t, "0", string(res.Result)) +} + +func TestTransactionManager_BeginMultiTXs(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + id0 := "id0" + id1 := "id1" + globalId := "globalId" + txInfoKey := fmt.Sprintf("%s-%s", PREFIX, globalId) + globalInfoKey := fmt.Sprintf("global-%s-%s", PREFIX, globalId) + + im := &TransactionManager{mockStub} + + mockStub.EXPECT().Has(txInfoKey).Return(true).MaxTimes(1) + res := im.BeginMultiTXs(globalId, id0, id1) + assert.False(t, res.Ok) + assert.Equal(t, "Transaction id already exists", string(res.Result)) + + mockStub.EXPECT().Has(txInfoKey).Return(false).AnyTimes() + mockStub.EXPECT().Set(id0, []byte(globalId)) + mockStub.EXPECT().Set(id1, []byte(globalId)) + txInfo := TransactionInfo{ + GlobalState: pb.TransactionStatus_BEGIN, + ChildTxInfo: make(map[string]pb.TransactionStatus), + } + txInfo.ChildTxInfo[id0] = pb.TransactionStatus_BEGIN + txInfo.ChildTxInfo[id1] = pb.TransactionStatus_BEGIN + mockStub.EXPECT().SetObject(globalInfoKey, txInfo) + res = im.BeginMultiTXs(globalId, id0, id1) + assert.True(t, res.Ok) +} + +func TestAssetExchange_Init(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + from := types.Address{0}.String() + to := types.Address{1}.String() + + ae := &AssetExchange{mockStub} + + res := ae.Init(from, to, []byte{1}) + assert.False(t, res.Ok) + + aei := pb.AssetExchangeInfo{ + Id: "123", + SenderOnSrc: "aliceSrc", + ReceiverOnSrc: "bobSrc", + AssetOnSrc: 10, + SenderOnDst: "bobDst", + ReceiverOnDst: "aliceDst", + AssetOnDst: 0, + } + info, err := aei.Marshal() + assert.Nil(t, err) + + mockStub.EXPECT().Has(AssetExchangeKey(aei.Id)).Return(true).MaxTimes(1) + res = ae.Init(from, to, info) + assert.False(t, res.Ok) + assert.Equal(t, "asset exhcange id already exists", string(res.Result)) + + mockStub.EXPECT().Has(AssetExchangeKey(aei.Id)).Return(false).AnyTimes() + res = ae.Init(from, to, info) + assert.False(t, res.Ok) + assert.Equal(t, "illegal asset exchange info", string(res.Result)) + + aei.AssetOnDst = 100 + info, err = aei.Marshal() + assert.Nil(t, err) + + aer := AssetExchangeRecord{ + Chain0: from, + Chain1: to, + Status: AssetExchangeInit, + Info: aei, + } + mockStub.EXPECT().SetObject(AssetExchangeKey(aei.Id), aer) + res = ae.Init(from, to, info) + assert.True(t, res.Ok) +} + +func TestAssetExchange_Redeem(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + from := types.Address{0}.String() + to := types.Address{1}.String() + + ae := &AssetExchange{mockStub} + + aei := pb.AssetExchangeInfo{ + Id: "123", + SenderOnSrc: "aliceSrc", + ReceiverOnSrc: "bobSrc", + AssetOnSrc: 10, + SenderOnDst: "bobDst", + ReceiverOnDst: "aliceDst", + AssetOnDst: 100, + } + + aer := AssetExchangeRecord{ + Chain0: from, + Chain1: to, + Status: AssetExchangeRedeem, + Info: aei, + } + + mockStub.EXPECT().GetObject(AssetExchangeKey(aei.Id), gomock.Any()).Return(false).MaxTimes(1) + res := ae.Redeem(from, to, []byte(aei.Id)) + assert.False(t, res.Ok) + assert.Equal(t, "asset exchange record does not exist", string(res.Result)) + + mockStub.EXPECT().GetObject(AssetExchangeKey(aei.Id), gomock.Any()).SetArg(1, aer).Return(true).MaxTimes(1) + res = ae.Redeem(from, to, []byte(aei.Id)) + assert.False(t, res.Ok) + assert.Equal(t, "asset exchange status for this id is not 'Init'", string(res.Result)) + + aer.Status = AssetExchangeInit + mockStub.EXPECT().GetObject(AssetExchangeKey(aei.Id), gomock.Any()).SetArg(1, aer).Return(true).AnyTimes() + res = ae.Redeem(to, to, []byte(aei.Id)) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("invalid participator of asset exchange id %s", aei.Id), string(res.Result)) + + expAer := AssetExchangeRecord{ + Chain0: from, + Chain1: to, + Status: AssetExchangeRedeem, + Info: aei, + } + mockStub.EXPECT().SetObject(AssetExchangeKey(aei.Id), expAer) + res = ae.Redeem(from, to, []byte(aei.Id)) + assert.True(t, res.Ok) +} + +func TestAssetExchange_Refund(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + from := types.Address{0}.String() + to := types.Address{1}.String() + + ae := &AssetExchange{mockStub} + + aei := pb.AssetExchangeInfo{ + Id: "123", + SenderOnSrc: "aliceSrc", + ReceiverOnSrc: "bobSrc", + AssetOnSrc: 10, + SenderOnDst: "bobDst", + ReceiverOnDst: "aliceDst", + AssetOnDst: 100, + } + + aer := AssetExchangeRecord{ + Chain0: from, + Chain1: to, + Status: AssetExchangeRedeem, + Info: aei, + } + + mockStub.EXPECT().GetObject(AssetExchangeKey(aei.Id), gomock.Any()).Return(false).MaxTimes(1) + res := ae.Refund(from, to, []byte(aei.Id)) + assert.False(t, res.Ok) + assert.Equal(t, "asset exchange record does not exist", string(res.Result)) + + mockStub.EXPECT().GetObject(AssetExchangeKey(aei.Id), gomock.Any()).SetArg(1, aer).Return(true).MaxTimes(1) + res = ae.Refund(from, to, []byte(aei.Id)) + assert.False(t, res.Ok) + assert.Equal(t, "asset exchange status for this id is not 'Init'", string(res.Result)) + + aer.Status = AssetExchangeInit + mockStub.EXPECT().GetObject(AssetExchangeKey(aei.Id), gomock.Any()).SetArg(1, aer).Return(true).AnyTimes() + res = ae.Refund(to, to, []byte(aei.Id)) + assert.False(t, res.Ok) + assert.Equal(t, fmt.Sprintf("invalid participator of asset exchange id %s", aei.Id), string(res.Result)) + + expAer := AssetExchangeRecord{ + Chain0: from, + Chain1: to, + Status: AssetExchangeRefund, + Info: aei, + } + mockStub.EXPECT().SetObject(AssetExchangeKey(aei.Id), expAer) + res = ae.Refund(from, to, []byte(aei.Id)) + assert.True(t, res.Ok) +} + +func TestAssetExchange_GetStatus(t *testing.T) { + mockCtl := gomock.NewController(t) + mockStub := mock_stub.NewMockStub(mockCtl) + + aei := pb.AssetExchangeInfo{ + Id: "123", + SenderOnSrc: "aliceSrc", + ReceiverOnSrc: "bobSrc", + AssetOnSrc: 10, + SenderOnDst: "bobDst", + ReceiverOnDst: "aliceDst", + AssetOnDst: 100, + } + + from := types.Address{0}.String() + to := types.Address{1}.String() + aer := AssetExchangeRecord{ + Chain0: from, + Chain1: to, + Status: AssetExchangeRedeem, + Info: aei, + } + + ae := &AssetExchange{mockStub} + + mockStub.EXPECT().GetObject(AssetExchangeKey(aei.Id), gomock.Any()).Return(false).MaxTimes(1) + res := ae.GetStatus(aei.Id) + assert.False(t, res.Ok) + assert.Equal(t, "asset exchange record does not exist", string(res.Result)) + + mockStub.EXPECT().GetObject(AssetExchangeKey(aei.Id), gomock.Any()).SetArg(1, aer).Return(true).MaxTimes(1) + res = ae.GetStatus(aei.Id) + assert.True(t, res.Ok) + assert.Equal(t, "1", string(res.Result)) +} diff --git a/internal/executor/executor.go b/internal/executor/executor.go index bf343a1..4d236cb 100755 --- a/internal/executor/executor.go +++ b/internal/executor/executor.go @@ -105,10 +105,6 @@ func (exec *BlockExecutor) ExecuteBlock(block *pb.Block) { exec.preBlockC <- block } -func (exec *BlockExecutor) SyncExecuteBlock(block *pb.Block) { - exec.processExecuteEvent(block) -} - // SubscribeBlockEvent registers a subscription of NewBlockEvent. func (exec *BlockExecutor) SubscribeBlockEvent(ch chan<- events.NewBlockEvent) event.Subscription { return exec.blockFeed.Subscribe(ch) diff --git a/internal/executor/executor_test.go b/internal/executor/executor_test.go index 932a049..97db8b9 100644 --- a/internal/executor/executor_test.go +++ b/internal/executor/executor_test.go @@ -2,6 +2,7 @@ package executor import ( "encoding/json" + "fmt" "io/ioutil" "math/rand" "path/filepath" @@ -16,6 +17,7 @@ import ( "github.com/meshplus/bitxhub-kit/log" "github.com/meshplus/bitxhub-kit/types" "github.com/meshplus/bitxhub-model/pb" + "github.com/meshplus/bitxhub/internal/constant" "github.com/meshplus/bitxhub/internal/ledger" "github.com/meshplus/bitxhub/internal/ledger/mock_ledger" "github.com/meshplus/bitxhub/internal/model/events" @@ -29,8 +31,42 @@ import ( const ( keyPassword = "bitxhub" from = "0x3f9d18f7c3a6e5e4c0b877fe3e688ab08840b997" + to = "0x000018f7c3a6e5e4c0b877fe3e688ab08840b997" ) +func TestNew(t *testing.T) { + mockCtl := gomock.NewController(t) + mockLedger := mock_ledger.NewMockLedger(mockCtl) + + // mock data for ledger + chainMeta := &pb.ChainMeta{ + Height: 1, + BlockHash: types.String2Hash(from), + } + mockLedger.EXPECT().GetChainMeta().Return(chainMeta).AnyTimes() + + logger := log.NewWithModule("executor") + executor, err := New(mockLedger, logger) + assert.Nil(t, err) + assert.NotNil(t, executor) + + assert.Equal(t, mockLedger, executor.ledger) + assert.Equal(t, logger, executor.logger) + assert.NotNil(t, executor.interchainCounter) + assert.Equal(t, 0, len(executor.interchainCounter)) + assert.NotNil(t, executor.preBlockC) + assert.NotNil(t, executor.blockC) + assert.NotNil(t, executor.persistC) + assert.NotNil(t, executor.ibtpVerify) + assert.NotNil(t, executor.validationEngine) + assert.Equal(t, 0, len(executor.normalTxs)) + assert.Equal(t, 7, len(executor.boltContracts)) + assert.Equal(t, chainMeta.BlockHash, executor.currentBlockHash) + assert.Equal(t, chainMeta.Height, executor.currentHeight) + assert.NotNil(t, executor.wasmInstances) + assert.Equal(t, 0, len(executor.wasmInstances)) +} + func TestBlockExecutor_ExecuteBlock(t *testing.T) { mockCtl := gomock.NewController(t) mockLedger := mock_ledger.NewMockLedger(mockCtl) @@ -93,19 +129,22 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) { NormalData := mockTxData(t, pb.TransactionData_NORMAL, pb.TransactionData_XVM, ibtp3) NormalTx := mockTx(NormalData) txs = append(txs, NormalTx) + // set tx with empty transaction data + emptyDataTx := mockTx(nil) + txs = append(txs, emptyDataTx) // set signature for txs for _, tx := range txs { + tx.From, err = pubKey.Address() + assert.Nil(t, err) sig, err := privKey.Sign(tx.SignHash().Bytes()) assert.Nil(t, err) tx.Signature = sig - tx.From, err = pubKey.Address() - assert.Nil(t, err) } // set invalid signature tx invalidTx := mockTx(nil) - invalidTx.Signature = []byte("invalid") invalidTx.From = types.String2Address(from) + invalidTx.Signature = []byte("invalid") txs = append(txs, invalidTx) assert.Nil(t, exec.Start()) @@ -117,24 +156,67 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) { // count received block to end test var wg sync.WaitGroup - wg.Add(3) + wg.Add(2) go listenBlock(&wg, done, ch) // send blocks to executor + block1 := mockBlock(uint64(1), nil) block2 := mockBlock(uint64(2), txs) - block4 := mockBlock(uint64(4), txs) - block3 := mockBlock(uint64(3), txs) - block6 := mockBlock(uint64(6), txs) + exec.ExecuteBlock(block1) exec.ExecuteBlock(block2) - exec.ExecuteBlock(block4) - exec.ExecuteBlock(block6) - exec.ExecuteBlock(block3) wg.Wait() done <- true assert.Nil(t, exec.Stop()) } +func TestBlockExecutor_ApplyReadonlyTransactions(t *testing.T) { + mockCtl := gomock.NewController(t) + mockLedger := mock_ledger.NewMockLedger(mockCtl) + + // mock data for ledger + chainMeta := &pb.ChainMeta{ + Height: 1, + BlockHash: types.String2Hash(from), + } + + privKey, err := asym.GenerateKeyPair(crypto.Secp256k1) + assert.Nil(t, err) + + addr, err := privKey.PublicKey().Address() + assert.Nil(t, err) + id := fmt.Sprintf("%s-%s-%d", addr.String(), to, 1) + + hash := types.Hash{1} + val, err := json.Marshal(hash) + assert.Nil(t, err) + + mockLedger.EXPECT().GetChainMeta().Return(chainMeta).AnyTimes() + mockLedger.EXPECT().Events(gomock.Any()).Return(nil).AnyTimes() + mockLedger.EXPECT().Commit(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + mockLedger.EXPECT().Clear().AnyTimes() + mockLedger.EXPECT().GetState(constant.InterchainContractAddr.Address(), []byte(fmt.Sprintf("index-tx-%s", id))).Return(true, val).AnyTimes() + mockLedger.EXPECT().PersistExecutionResult(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + mockLedger.EXPECT().FlushDirtyDataAndComputeJournal().Return(make(map[types.Address]*ledger.Account), &ledger.BlockJournal{}).AnyTimes() + mockLedger.EXPECT().PersistBlockData(gomock.Any()).AnyTimes() + logger := log.NewWithModule("executor") + + exec, err := New(mockLedger, logger) + assert.Nil(t, err) + + // mock data for block + var txs []*pb.Transaction + tx, err := genBVMContractTransaction(privKey, 1, constant.InterchainContractAddr.Address(), "GetIBTPByID", pb.String(id)) + assert.Nil(t, err) + + txs = append(txs, tx) + receipts := exec.ApplyReadonlyTransactions(txs) + + assert.Equal(t, 1, len(receipts)) + assert.Equal(t, hash.Bytes(), receipts[0].Ret) + assert.Equal(t, pb.Receipt_SUCCESS, receipts[0].Status) +} + func listenBlock(wg *sync.WaitGroup, done chan bool, blockCh chan events.NewBlockEvent) { for { select { @@ -263,6 +345,53 @@ func randAddress(t *testing.T) types.Address { return address } +func genBVMContractTransaction(privateKey crypto.PrivateKey, nonce uint64, address types.Address, method string, args ...*pb.Arg) (*pb.Transaction, error) { + return genContractTransaction(pb.TransactionData_BVM, privateKey, nonce, address, method, args...) +} + +func genXVMContractTransaction(privateKey crypto.PrivateKey, nonce uint64, address types.Address, method string, args ...*pb.Arg) (*pb.Transaction, error) { + return genContractTransaction(pb.TransactionData_XVM, privateKey, nonce, address, method, args...) +} + +func genContractTransaction(vmType pb.TransactionData_VMType, privateKey crypto.PrivateKey, nonce uint64, address types.Address, method string, args ...*pb.Arg) (*pb.Transaction, error) { + from, err := privateKey.PublicKey().Address() + if err != nil { + return nil, err + } + + pl := &pb.InvokePayload{ + Method: method, + Args: args[:], + } + + data, err := pl.Marshal() + if err != nil { + return nil, err + } + + td := &pb.TransactionData{ + Type: pb.TransactionData_INVOKE, + VmType: vmType, + Payload: data, + } + + tx := &pb.Transaction{ + From: from, + To: address, + Data: td, + Timestamp: time.Now().UnixNano(), + Nonce: nonce, + } + + if err := tx.Sign(privateKey); err != nil { + return nil, fmt.Errorf("tx sign: %w", err) + } + + tx.TransactionHash = tx.Hash() + + return tx, nil +} + func mockTxData(t *testing.T, dataType pb.TransactionData_Type, vmType pb.TransactionData_VMType, ibtp proto.Marshaler) *pb.TransactionData { ib, err := ibtp.Marshal() assert.Nil(t, err) diff --git a/pkg/proof/proof_pool.go b/pkg/proof/proof_pool.go index 9fe5b15..bb2577f 100644 --- a/pkg/proof/proof_pool.go +++ b/pkg/proof/proof_pool.go @@ -115,7 +115,9 @@ func (pl *VerifyPool) verifyProof(ibtp *pb.IBTP, proof []byte) (bool, error) { } validateAddr = rl.Address } else { - return false, fmt.Errorf("appchain didn't register rule") + if app.ChainType != "fabric" { + return false, fmt.Errorf("appchain didn't register rule") + } } ok, err = pl.ve.Validate(validateAddr, ibtp.From, proof, ibtp.Payload, app.Validators) diff --git a/pkg/vm/boltvm/stub.go b/pkg/vm/boltvm/stub.go index 6a2f4c9..9d36e00 100644 --- a/pkg/vm/boltvm/stub.go +++ b/pkg/vm/boltvm/stub.go @@ -9,6 +9,7 @@ import ( type Contract interface{} +//go:generate mockgen -destination mock_stub/mock_stub.go -package mock_stub -source stub.go type Stub interface { // Caller Caller() string