diff --git a/cmd/dcld/cmd/genaccounts.go b/cmd/dcld/cmd/genaccounts.go index d7565f5ac..8968d66f6 100644 --- a/cmd/dcld/cmd/genaccounts.go +++ b/cmd/dcld/cmd/genaccounts.go @@ -4,6 +4,7 @@ import ( "bufio" "encoding/json" "fmt" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" "strings" "github.com/cosmos/cosmos-sdk/client" @@ -110,7 +111,7 @@ the address will be looked up in the local Keybase. } } - var pidRanges []*dclauthtypes.Int32Range + var pidRanges []*types.Int32Range if pidStrRanges := viper.GetString(FlagPIDs); len(pidStrRanges) > 0 { var lastMax int32 = 0 for _, pidStrRange := range strings.Split(pidStrRanges, ",") { @@ -130,10 +131,10 @@ the address will be looked up in the local Keybase. if min > max || max == 0 || min == 0 { return fmt.Errorf("invalid PID Range is provided: min=%d, max=%d", min, max) } - if lastMax >= max { - return fmt.Errorf("invalid PID Range is provided: product ID %d is duplicated", max) + if max <= lastMax || min <= lastMax { + return fmt.Errorf("invalid PID Range is provided: {%d-%d}, ranges are overlapped, range items must be provided in increased order", min, max) } - pid := dclauthtypes.Int32Range{Min: min, Max: max} + pid := types.Int32Range{Min: min, Max: max} pidRanges = append(pidRanges, &pid) lastMax = max } diff --git a/integration_tests/constants/constants.go b/integration_tests/constants/constants.go index 79cacf514..b7e3cda90 100644 --- a/integration_tests/constants/constants.go +++ b/integration_tests/constants/constants.go @@ -19,6 +19,7 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" ) func strToPubKey(pkStr string, cdc codec.Codec) cryptotypes.PubKey { @@ -130,15 +131,19 @@ var ( UpgradePlanInfo = "Some upgrade info" // - Address1, _ = sdk.AccAddressFromBech32("cosmos1s5xf3aanx7w84hgplk9z3l90qfpantg6nsmhpf") - Address2, _ = sdk.AccAddressFromBech32("cosmos1nl4uaesk9gtu7su3n89lne6xpa6lq8gljn79rq") - Address3, _ = sdk.AccAddressFromBech32("cosmos12r9vsus5js32pvnayt33zhcd4y9wcqcly45gr9") - Address4, _ = sdk.AccAddressFromBech32("cosmos1vvwldfef3yuggm7ge9p34d6dvpz5s74nus6n7g") - VendorID1 int32 = 1000 - VendorID2 int32 = 2000 - VendorID3 int32 = 3000 - VendorID4 int32 = 4000 - PubKey1 = strToPubKey( + Address1, _ = sdk.AccAddressFromBech32("cosmos1s5xf3aanx7w84hgplk9z3l90qfpantg6nsmhpf") + Address2, _ = sdk.AccAddressFromBech32("cosmos1nl4uaesk9gtu7su3n89lne6xpa6lq8gljn79rq") + Address3, _ = sdk.AccAddressFromBech32("cosmos12r9vsus5js32pvnayt33zhcd4y9wcqcly45gr9") + Address4, _ = sdk.AccAddressFromBech32("cosmos1vvwldfef3yuggm7ge9p34d6dvpz5s74nus6n7g") + VendorID1 int32 = 1000 + VendorID2 int32 = 2000 + VendorID3 int32 = 3000 + VendorID4 int32 = 4000 + ProductIDsEmpty []*types.Int32Range + ProductIDsFull = append([]*types.Int32Range{}, &types.Int32Range{Min: 1, Max: 65535}) + ProductIDs100 = append([]*types.Int32Range{}, &types.Int32Range{Min: 1, Max: 100}) + ProductIDs200 = append([]*types.Int32Range{}, &types.Int32Range{Min: 1, Max: 100}, &types.Int32Range{Min: 101, Max: 200}) + PubKey1 = strToPubKey( `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Aw1XXHQ8i6JVNKsFQ9eQArJVt2GXEO0EBFsQL6XJ5BxY"}`, defEncConfig.Marshaler, ) diff --git a/integration_tests/grpc_rest/compliance/helpers.go b/integration_tests/grpc_rest/compliance/helpers.go index 80d2d4e2f..225c7f431 100644 --- a/integration_tests/grpc_rest/compliance/helpers.go +++ b/integration_tests/grpc_rest/compliance/helpers.go @@ -523,6 +523,7 @@ func CDCertificateIDUpdateChangesOnlyOneComplianceInfo(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -538,6 +539,7 @@ func CDCertificateIDUpdateChangesOnlyOneComplianceInfo(suite *utils.TestSuite) { certCenter, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, 1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -646,6 +648,7 @@ func DeleteComplianceInfoForAllCertStatuses(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -661,6 +664,7 @@ func DeleteComplianceInfoForAllCertStatuses(suite *utils.TestSuite) { certCenter, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, 1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -835,6 +839,7 @@ func DemoTrackCompliance(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -850,6 +855,7 @@ func DemoTrackCompliance(suite *utils.TestSuite) { certCenter, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, 1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1162,6 +1168,7 @@ func DemoTrackRevocation(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1177,6 +1184,7 @@ func DemoTrackRevocation(suite *utils.TestSuite) { certCenter, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, 1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1339,6 +1347,7 @@ func DemoTrackProvision(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1354,6 +1363,7 @@ func DemoTrackProvision(suite *utils.TestSuite) { certCenter, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, 1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1682,6 +1692,7 @@ func DemoTrackComplianceWithHexVidAndPid(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1698,6 +1709,7 @@ func DemoTrackComplianceWithHexVidAndPid(suite *utils.TestSuite) { certCenter, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, 1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1791,6 +1803,7 @@ func DemoTrackRevocationWithHexVidAndPid(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1807,6 +1820,7 @@ func DemoTrackRevocationWithHexVidAndPid(suite *utils.TestSuite) { certCenter, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, 1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1924,6 +1938,7 @@ func DemoTrackProvisionByHexVidAndPid(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1939,6 +1954,7 @@ func DemoTrackProvisionByHexVidAndPid(suite *utils.TestSuite) { certCenter, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, 1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, diff --git a/integration_tests/grpc_rest/dclauth/helpers.go b/integration_tests/grpc_rest/dclauth/helpers.go index 081a04301..43bce6ae0 100644 --- a/integration_tests/grpc_rest/dclauth/helpers.go +++ b/integration_tests/grpc_rest/dclauth/helpers.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/require" testconstants "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/constants" "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/utils" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types" modeltypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/model/types" ) @@ -333,12 +334,13 @@ func ProposeAddAccount( accKey cryptotypes.PubKey, roles dclauthtypes.AccountRoles, vendorID int32, + productIDs []*types.Int32Range, signerName string, signerAccount *dclauthtypes.Account, info string, ) (*sdk.TxResponse, error) { msg, err := dclauthtypes.NewMsgProposeAddAccount( - suite.GetAddress(signerName), accAddr, accKey, roles, vendorID, info) + suite.GetAddress(signerName), accAddr, accKey, roles, vendorID, productIDs, info) require.NoError(suite.T, err) return suite.BuildAndBroadcastTx([]sdk.Msg{msg}, signerName, signerAccount) @@ -410,6 +412,7 @@ func CreateAccount( accountName string, roles dclauthtypes.AccountRoles, vendorID int32, + productIDs []*types.Int32Range, proposerName string, proposerAccount *dclauthtypes.Account, approverName string, @@ -424,6 +427,7 @@ func CreateAccount( accountInfo.GetPubKey(), roles, vendorID, + productIDs, proposerName, proposerAccount, info, @@ -450,6 +454,7 @@ func CreateVendorAccount( accountName string, roles dclauthtypes.AccountRoles, vendorID int32, + productIDs []*types.Int32Range, proposerName string, proposerAccount *dclauthtypes.Account, approverName string, @@ -464,6 +469,7 @@ func CreateVendorAccount( accountInfo.GetPubKey(), roles, vendorID, + productIDs, proposerName, proposerAccount, info, @@ -565,7 +571,7 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.NodeAdmin}, 0, + dclauthtypes.AccountRoles{dclauthtypes.NodeAdmin}, 0, testconstants.ProductIDsEmpty, jackName, jackAccount, testconstants.Info, ) @@ -718,7 +724,7 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.NodeAdmin}, 0, + dclauthtypes.AccountRoles{dclauthtypes.NodeAdmin}, 0, testconstants.ProductIDsEmpty, jackName, jackAccount, testconstants.Info, ) @@ -823,7 +829,7 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.NodeAdmin}, 0, + dclauthtypes.AccountRoles{dclauthtypes.NodeAdmin}, 0, testconstants.ProductIDsEmpty, jackName, jackAccount, testconstants.Info, ) @@ -964,7 +970,8 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.Vendor, dclauthtypes.NodeAdmin}, testconstants.Vid, + dclauthtypes.AccountRoles{dclauthtypes.Vendor, dclauthtypes.NodeAdmin}, + testconstants.Vid, testconstants.ProductIDsEmpty, jackName, jackAccount, testconstants.Info, ) @@ -987,6 +994,7 @@ func AuthDemo(suite *utils.TestSuite) { require.NoError(suite.T, err) require.Equal(suite.T, testAccAddr, testProposedVendorAccount.GetAddress()) require.Equal(suite.T, []dclauthtypes.AccountRole{dclauthtypes.Vendor, dclauthtypes.NodeAdmin}, testProposedVendorAccount.GetRoles()) + require.Equal(suite.T, []*types.Int32Range{}, testProposedVendorAccount.GetProductIDs()) // Alice approves new account _, err = ApproveAddAccount(suite, testAccAddr, aliceName, aliceAccount, testconstants.Info) @@ -1037,7 +1045,8 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.Vendor}, testconstants.Vid, + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + testconstants.Vid, testconstants.ProductIDsEmpty, jackName, jackAccount, testconstants.Info, ) @@ -1052,6 +1061,7 @@ func AuthDemo(suite *utils.TestSuite) { require.NoError(suite.T, err) require.Equal(suite.T, testAccAddr, testVendorAccount.GetAddress()) require.Equal(suite.T, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testVendorAccount.GetRoles()) + require.Equal(suite.T, []*types.Int32Range{}, testVendorAccount.GetProductIDs()) // Query all proposed accounts receivedProposedAccounts, _ = GetProposedAccounts(suite) @@ -1072,7 +1082,8 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.Trustee}, 0, + dclauthtypes.AccountRoles{dclauthtypes.Trustee}, + 0, testconstants.ProductIDsEmpty, jackName, jackAccount, testconstants.Info, ) @@ -1095,7 +1106,8 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.Trustee}, 0, + dclauthtypes.AccountRoles{dclauthtypes.Trustee}, + 0, testconstants.ProductIDsEmpty, jackName, jackAccount, testconstants.Info, ) @@ -1146,7 +1158,8 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.Vendor}, testconstants.Vid, + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + testconstants.Vid, testconstants.ProductIDsFull, jackName, jackAccount, testconstants.Info, ) @@ -1177,7 +1190,8 @@ func AuthDemo(suite *utils.TestSuite) { _, err = ProposeAddAccount( suite, testAccAddr, testAccPubKey, - dclauthtypes.AccountRoles{dclauthtypes.Vendor}, testconstants.Vid, + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + testconstants.Vid, testconstants.ProductIDsFull, jackName, jackAccount, testconstants.Info, ) @@ -1200,6 +1214,7 @@ func AuthDemo(suite *utils.TestSuite) { require.NoError(suite.T, err) require.Equal(suite.T, testAccAddr, testProposedVendorAccount.GetAddress()) require.Equal(suite.T, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testProposedVendorAccount.GetRoles()) + require.Equal(suite.T, []*types.Int32Range{{Min: 1, Max: 65535}}, testVendorAccount.GetProductIDs()) // Alice approves new account _, err = ApproveAddAccount(suite, testAccAddr, aliceName, aliceAccount, testconstants.Info) @@ -1218,4 +1233,5 @@ func AuthDemo(suite *utils.TestSuite) { require.NoError(suite.T, err) require.Equal(suite.T, testAccAddr, testVendorAccount.GetAddress()) require.Equal(suite.T, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testVendorAccount.GetRoles()) + require.Equal(suite.T, []*types.Int32Range{{Min: 1, Max: 65535}}, testVendorAccount.GetProductIDs()) } diff --git a/integration_tests/grpc_rest/dclupgrade/helpers.go b/integration_tests/grpc_rest/dclupgrade/helpers.go index aac0f1c8f..c94d7884a 100644 --- a/integration_tests/grpc_rest/dclupgrade/helpers.go +++ b/integration_tests/grpc_rest/dclupgrade/helpers.go @@ -446,6 +446,7 @@ func ProposeUpgradeByNonTrustee(suite *utils.TestSuite) { dclauthtypes.NodeAdmin, }, int32(tmrand.Uint16()+1), + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -490,6 +491,7 @@ func ApproveUpgradeByNonTrustee(suite *utils.TestSuite) { dclauthtypes.NodeAdmin, }, int32(tmrand.Uint16()+1), + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, diff --git a/integration_tests/grpc_rest/model/grpc_test.go b/integration_tests/grpc_rest/model/grpc_test.go index 5502c372f..6369c9f1c 100644 --- a/integration_tests/grpc_rest/model/grpc_test.go +++ b/integration_tests/grpc_rest/model/grpc_test.go @@ -38,6 +38,11 @@ func TestAddModelByNonVendorGRPC(t *testing.T) { model.AddModelByNonVendor(&suite) } +func TestAddModelByVendorWithNonAssociatedProductIdsGRPC(t *testing.T) { + suite := utils.SetupTest(t, testconstants.ChainID, false) + model.AddModelByVendorWithNonAssociatedProductIds(&suite) +} + func TestAddModelByDifferentVendorGRPC(t *testing.T) { suite := utils.SetupTest(t, testconstants.ChainID, false) model.AddModelByDifferentVendor(&suite) diff --git a/integration_tests/grpc_rest/model/helpers.go b/integration_tests/grpc_rest/model/helpers.go index b2a4f29e6..b528bd3ba 100644 --- a/integration_tests/grpc_rest/model/helpers.go +++ b/integration_tests/grpc_rest/model/helpers.go @@ -25,6 +25,7 @@ import ( testconstants "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/constants" testDclauth "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/grpc_rest/dclauth" "github.com/zigbee-alliance/distributed-compliance-ledger/integration_tests/utils" + common_types "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" "github.com/zigbee-alliance/distributed-compliance-ledger/x/compliance/types" dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types" modeltypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/model/types" @@ -363,6 +364,85 @@ func GetVendorModelsByHexVid( return &res, nil } +func AddModelByVendorProductIds(suite *utils.TestSuite) { + // Alice and Bob are predefined Trustees + aliceName := testconstants.AliceAccount + aliceKeyInfo, err := suite.Kr.Key(aliceName) + require.NoError(suite.T, err) + aliceAccount, err := testDclauth.GetAccount(suite, aliceKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + bobName := testconstants.BobAccount + bobKeyInfo, err := suite.Kr.Key(bobName) + require.NoError(suite.T, err) + bobAccount, err := testDclauth.GetAccount(suite, bobKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + // register new account with Vendor role + vendorAccountName := utils.RandString() + vid := int32(tmrand.Uint16()) + pid := int32(100) + vendorAccount := testDclauth.CreateAccount( + suite, + vendorAccountName, + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + vid, + testconstants.ProductIDs100, + aliceName, + aliceAccount, + bobName, + bobAccount, + testconstants.Info, + ) + + createModelMsg := NewMsgCreateModel(vid, pid, vendorAccount.Address) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, vendorAccountName, vendorAccount) + require.NoError(suite.T, err) +} + +func UpdateByVendorWithProductIds(suite *utils.TestSuite) { + // Alice and Bob are predefined Trustees + aliceName := testconstants.AliceAccount + aliceKeyInfo, err := suite.Kr.Key(aliceName) + require.NoError(suite.T, err) + aliceAccount, err := testDclauth.GetAccount(suite, aliceKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + bobName := testconstants.BobAccount + bobKeyInfo, err := suite.Kr.Key(bobName) + require.NoError(suite.T, err) + bobAccount, err := testDclauth.GetAccount(suite, bobKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + // register new account with Vendor role + ownerName := utils.RandString() + vid := int32(tmrand.Uint16()) + pid := int32(200) + owner := testDclauth.CreateAccount( + suite, + ownerName, + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + vid, + testconstants.ProductIDs200, + aliceName, + aliceAccount, + bobName, + bobAccount, + testconstants.Info, + ) + + createModelMsg := NewMsgCreateModel(vid, pid, owner.Address) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, ownerName, owner) + require.NoError(suite.T, err) + + updateModelMsg := NewMsgUpdateModel(vid, pid, owner.Address) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{updateModelMsg}, ownerName, owner) + require.NoError(suite.T, err) + + model, err := GetModel(suite, vid, pid) + require.Equal(suite.T, 2, model.LsfRevision) +} + func DeleteModelWithAssociatedModelVersions(suite *utils.TestSuite) { // Alice and Bob are predefined Trustees aliceName := testconstants.AliceAccount @@ -379,12 +459,14 @@ func DeleteModelWithAssociatedModelVersions(suite *utils.TestSuite) { // Register new Vendor account vid := int32(tmrand.Uint16()) + pid := int32(tmrand.Uint16()) vendorName := utils.RandString() vendorAccount := testDclauth.CreateVendorAccount( suite, vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + []*common_types.Int32Range{{Min: pid, Max: pid}}, aliceName, aliceAccount, bobName, @@ -394,7 +476,6 @@ func DeleteModelWithAssociatedModelVersions(suite *utils.TestSuite) { require.NotNil(suite.T, vendorAccount) // New vendor adds a model - pid := int32(tmrand.Uint16()) createModelMsg := NewMsgCreateModel(vid, pid, vendorAccount.Address) _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, vendorName, vendorAccount) require.NoError(suite.T, err) @@ -449,6 +530,7 @@ func DeleteModelWithAssociatedModelVersionsCertified(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -460,11 +542,13 @@ func DeleteModelWithAssociatedModelVersionsCertified(suite *utils.TestSuite) { // Register new Certification center ccvid := int32(tmrand.Uint16()) ccName := utils.RandString() + pid := int32(tmrand.Uint16()) ccAccount := testDclauth.CreateAccount( suite, ccName, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, ccvid, + []*common_types.Int32Range{{Min: pid, Max: pid}}, aliceName, aliceAccount, bobName, @@ -474,7 +558,6 @@ func DeleteModelWithAssociatedModelVersionsCertified(suite *utils.TestSuite) { require.NotNil(suite.T, vendorAccount) // New vendor adds a model - pid := int32(tmrand.Uint16()) createModelMsg := NewMsgCreateModel(vid, pid, vendorAccount.Address) _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, vendorName, vendorAccount) require.NoError(suite.T, err) @@ -529,11 +612,13 @@ func DeleteModelVersion(suite *utils.TestSuite) { // Register new Vendor account vid := int32(tmrand.Uint16()) vendorName := utils.RandString() + pid := int32(tmrand.Uint16()) vendorAccount := testDclauth.CreateVendorAccount( suite, vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + []*common_types.Int32Range{{Min: pid, Max: pid}}, aliceName, aliceAccount, bobName, @@ -543,7 +628,6 @@ func DeleteModelVersion(suite *utils.TestSuite) { require.NotNil(suite.T, vendorAccount) // New vendor adds a model - pid := int32(tmrand.Uint16()) createModelMsg := NewMsgCreateModel(vid, pid, vendorAccount.Address) _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, vendorName, vendorAccount) require.NoError(suite.T, err) @@ -578,12 +662,14 @@ func DeleteModelVersionDifferentVid(suite *utils.TestSuite) { // Register new Vendor account vid := int32(tmrand.Uint16()) + pid := int32(tmrand.Uint16()) vendorName := utils.RandString() vendorAccount := testDclauth.CreateVendorAccount( suite, vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + []*common_types.Int32Range{{Min: pid, Max: pid}}, aliceName, aliceAccount, bobName, @@ -593,7 +679,6 @@ func DeleteModelVersionDifferentVid(suite *utils.TestSuite) { require.NotNil(suite.T, vendorAccount) // vendor adds a model - pid := int32(tmrand.Uint16()) createModelMsg := NewMsgCreateModel(vid, pid, vendorAccount.Address) _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, vendorName, vendorAccount) require.NoError(suite.T, err) @@ -610,6 +695,7 @@ func DeleteModelVersionDifferentVid(suite *utils.TestSuite) { vendor2Name, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid2, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -652,6 +738,7 @@ func DeleteModelVersionDoesNotExist(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -688,6 +775,7 @@ func DeleteModelVersionNotByCreator(suite *utils.TestSuite) { vendor1Name, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -704,6 +792,7 @@ func DeleteModelVersionNotByCreator(suite *utils.TestSuite) { vendor2Name, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid2, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -756,6 +845,7 @@ func DeleteModelVersionCertified(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -780,6 +870,7 @@ func DeleteModelVersionCertified(suite *utils.TestSuite) { certCenterName, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -834,12 +925,15 @@ func Demo(suite *utils.TestSuite) { // Register new Vendor account vid := int32(tmrand.Uint16()) + var pid1 int32 = 1 + var pid2 int32 = 2 vendorName := utils.RandString() vendorAccount := testDclauth.CreateVendorAccount( suite, vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + []*common_types.Int32Range{{Min: pid1, Max: pid2}}, aliceName, aliceAccount, bobName, @@ -853,7 +947,6 @@ func Demo(suite *utils.TestSuite) { require.NoError(suite.T, err) // New vendor adds first model - pid1 := int32(tmrand.Uint16()) createFirstModelMsg := NewMsgCreateModel(vid, pid1, vendorAccount.Address) _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createFirstModelMsg}, vendorName, vendorAccount) require.NoError(suite.T, err) @@ -867,7 +960,6 @@ func Demo(suite *utils.TestSuite) { require.Equal(suite.T, createFirstModelMsg.ProductLabel, receivedModel.ProductLabel) // Add second model - pid2 := int32(tmrand.Uint16()) createSecondModelMsg := NewMsgCreateModel(vid, pid2, vendorAccount.Address) _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createSecondModelMsg}, vendorName, vendorAccount) require.NoError(suite.T, err) @@ -943,6 +1035,7 @@ func AddModelByNonVendor(suite *utils.TestSuite) { nonVendorAccountName, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -960,6 +1053,152 @@ func AddModelByNonVendor(suite *utils.TestSuite) { require.True(suite.T, sdkerrors.ErrUnauthorized.Is(err)) } +func AddModelByVendorWithNonAssociatedProductIds(suite *utils.TestSuite) { + // Alice and Bob are predefined Trustees + aliceName := testconstants.AliceAccount + aliceKeyInfo, err := suite.Kr.Key(aliceName) + require.NoError(suite.T, err) + aliceAccount, err := testDclauth.GetAccount(suite, aliceKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + bobName := testconstants.BobAccount + bobKeyInfo, err := suite.Kr.Key(bobName) + require.NoError(suite.T, err) + bobAccount, err := testDclauth.GetAccount(suite, bobKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + // register new account with Vendor role + vendorAccountName := utils.RandString() + vid := int32(tmrand.Uint16()) + pid := int32(101) + vendorAccount := testDclauth.CreateAccount( + suite, + vendorAccountName, + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + vid, + testconstants.ProductIDs100, + aliceName, + aliceAccount, + bobName, + bobAccount, + testconstants.Info, + ) + + // try to add createModelMsg + createModelMsg := NewMsgCreateModel(vid, pid, vendorAccount.Address) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, vendorAccountName, vendorAccount) + require.Error(suite.T, err) + require.True(suite.T, sdkerrors.ErrUnauthorized.Is(err)) +} + +func UpdateModelByVendorWithNonAssociatedProductIds(suite *utils.TestSuite) { + // Alice and Bob are predefined Trustees + aliceName := testconstants.AliceAccount + aliceKeyInfo, err := suite.Kr.Key(aliceName) + require.NoError(suite.T, err) + aliceAccount, err := testDclauth.GetAccount(suite, aliceKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + bobName := testconstants.BobAccount + bobKeyInfo, err := suite.Kr.Key(bobName) + require.NoError(suite.T, err) + bobAccount, err := testDclauth.GetAccount(suite, bobKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + // register new account with Vendor role + ownerName := utils.RandString() + vid := int32(tmrand.Uint16()) + pid := int32(200) + owner := testDclauth.CreateAccount( + suite, + ownerName, + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + vid, + testconstants.ProductIDs200, + aliceName, + aliceAccount, + bobName, + bobAccount, + testconstants.Info, + ) + vendorName := utils.RandString() + vendor := testDclauth.CreateAccount( + suite, + utils.RandString(), + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + vid, + testconstants.ProductIDs100, + aliceName, + aliceAccount, + bobName, + bobAccount, + testconstants.Info, + ) + + createModelMsg := NewMsgCreateModel(vid, pid, owner.Address) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, ownerName, owner) + require.NoError(suite.T, err) + + updateModelMsg := NewMsgUpdateModel(vid, pid, vendor.Address) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{updateModelMsg}, vendorName, vendor) + require.Error(suite.T, err) + require.True(suite.T, sdkerrors.ErrUnauthorized.Is(err)) +} + +func DeleteModelByVendorWithNonAssociatedProductIds(suite *utils.TestSuite) { + // Alice and Bob are predefined Trustees + aliceName := testconstants.AliceAccount + aliceKeyInfo, err := suite.Kr.Key(aliceName) + require.NoError(suite.T, err) + aliceAccount, err := testDclauth.GetAccount(suite, aliceKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + bobName := testconstants.BobAccount + bobKeyInfo, err := suite.Kr.Key(bobName) + require.NoError(suite.T, err) + bobAccount, err := testDclauth.GetAccount(suite, bobKeyInfo.GetAddress()) + require.NoError(suite.T, err) + + // register new account with Vendor role + ownerName := utils.RandString() + vid := int32(tmrand.Uint16()) + pid := int32(200) + owner := testDclauth.CreateAccount( + suite, + ownerName, + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + vid, + testconstants.ProductIDs200, + aliceName, + aliceAccount, + bobName, + bobAccount, + testconstants.Info, + ) + vendorName := utils.RandString() + vendor := testDclauth.CreateAccount( + suite, + utils.RandString(), + dclauthtypes.AccountRoles{dclauthtypes.Vendor}, + vid, + testconstants.ProductIDs100, + aliceName, + aliceAccount, + bobName, + bobAccount, + testconstants.Info, + ) + + createModelMsg := NewMsgCreateModel(vid, pid, owner.Address) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{createModelMsg}, ownerName, owner) + require.NoError(suite.T, err) + + deleteModel := NewMsgDeleteModel(vid, pid, vendor.Address) + _, err = suite.BuildAndBroadcastTx([]sdk.Msg{deleteModel}, vendorName, vendor) + require.Error(suite.T, err) + require.True(suite.T, sdkerrors.ErrUnauthorized.Is(err)) +} + func AddModelByDifferentVendor(suite *utils.TestSuite) { // Alice and Bob are predefined Trustees aliceName := testconstants.AliceAccount @@ -982,6 +1221,7 @@ func AddModelByDifferentVendor(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid+1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -1019,6 +1259,7 @@ func AddModelTwice(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -1090,6 +1331,7 @@ func DemoWithHexVidAndPid(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, diff --git a/integration_tests/grpc_rest/model/rest_test.go b/integration_tests/grpc_rest/model/rest_test.go index 91c993472..2cb3965ff 100644 --- a/integration_tests/grpc_rest/model/rest_test.go +++ b/integration_tests/grpc_rest/model/rest_test.go @@ -38,6 +38,11 @@ func TestAddModelByNonVendorREST(t *testing.T) { model.AddModelByNonVendor(&suite) } +func TestAddModelByVendorWithNonAssociatedProductIdsREST(t *testing.T) { + suite := utils.SetupTest(t, testconstants.ChainID, true) + model.AddModelByVendorWithNonAssociatedProductIds(&suite) +} + func TestAddModelByDifferentVendorREST(t *testing.T) { suite := utils.SetupTest(t, testconstants.ChainID, true) model.AddModelByDifferentVendor(&suite) diff --git a/integration_tests/grpc_rest/pki/helpers.go b/integration_tests/grpc_rest/pki/helpers.go index 92b381f7c..32591ae19 100644 --- a/integration_tests/grpc_rest/pki/helpers.go +++ b/integration_tests/grpc_rest/pki/helpers.go @@ -641,6 +641,7 @@ func Demo(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -656,6 +657,7 @@ func Demo(suite *utils.TestSuite) { vendorAdminName, dclauthtypes.AccountRoles{dclauthtypes.VendorAdmin}, 0, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1427,6 +1429,7 @@ func Demo(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, 65521, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, @@ -1519,6 +1522,7 @@ func Demo(suite *utils.TestSuite) { venName65522, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, 65522, + testconstants.ProductIDsEmpty, jackName, jackAccount, aliceName, diff --git a/integration_tests/grpc_rest/validator/helpers.go b/integration_tests/grpc_rest/validator/helpers.go index b1ec52953..fff674b78 100644 --- a/integration_tests/grpc_rest/validator/helpers.go +++ b/integration_tests/grpc_rest/validator/helpers.go @@ -298,6 +298,7 @@ func Demo(suite *utils.TestSuite) { nodeAdminName, dclauthtypes.AccountRoles{dclauthtypes.NodeAdmin}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, jackName, diff --git a/integration_tests/grpc_rest/vendorinfo/helpers.go b/integration_tests/grpc_rest/vendorinfo/helpers.go index 6881de4c9..753de4a10 100644 --- a/integration_tests/grpc_rest/vendorinfo/helpers.go +++ b/integration_tests/grpc_rest/vendorinfo/helpers.go @@ -147,6 +147,7 @@ func Demo(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -198,6 +199,7 @@ func AddVendorInfoByNonVendor(suite *utils.TestSuite) { nonVendorAccountNamew, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -236,6 +238,7 @@ func AddVendorInfoByDifferentVendor(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid+1, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -272,6 +275,7 @@ func AddVendorInfoByNonVendorAdmin(suite *utils.TestSuite) { nonVendorAdminAccountNamew, dclauthtypes.AccountRoles{dclauthtypes.CertificationCenter, dclauthtypes.NodeAdmin}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -310,6 +314,7 @@ func AddVendorInfoByVendorAdmin(suite *utils.TestSuite) { vendorAdminAccountName, dclauthtypes.AccountRoles{dclauthtypes.VendorAdmin}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -347,6 +352,7 @@ func UpdateVendorInfoByVendorAdmin(suite *utils.TestSuite) { vendorAdminAccountName, dclauthtypes.AccountRoles{dclauthtypes.VendorAdmin}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -396,6 +402,7 @@ func AddVendorInfoTwice(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, @@ -451,6 +458,7 @@ func DemoWithHexVid(suite *utils.TestSuite) { vendorName, dclauthtypes.AccountRoles{dclauthtypes.Vendor}, vid, + testconstants.ProductIDsEmpty, aliceName, aliceAccount, bobName, diff --git a/proto/dclauth/int32_range.proto b/proto/common/int32_range.proto similarity index 75% rename from proto/dclauth/int32_range.proto rename to proto/common/int32_range.proto index c8e9fc836..3d51c38e8 100644 --- a/proto/dclauth/int32_range.proto +++ b/proto/common/int32_range.proto @@ -1,9 +1,9 @@ syntax = "proto3"; -package zigbeealliance.distributedcomplianceledger.dclauth; +package zigbeealliance.distributedcomplianceledger.common; import "gogoproto/gogo.proto"; -option go_package = "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types"; +option go_package = "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types"; message Int32Range { int32 min = 1 [(gogoproto.moretags) = "validate:\"gte=1,lte=65535\""]; diff --git a/proto/dclauth/account.proto b/proto/dclauth/account.proto index 125f85071..6af0d15fe 100644 --- a/proto/dclauth/account.proto +++ b/proto/dclauth/account.proto @@ -6,7 +6,7 @@ option go_package = "github.com/zigbee-alliance/distributed-compliance-ledger/x/ import "gogoproto/gogo.proto"; import "cosmos/auth/v1beta1/auth.proto"; import "dclauth/grant.proto"; -import "dclauth/int32_range.proto"; +import "common/int32_range.proto"; message Account { // TODO issue 99: do we need that ??? @@ -21,6 +21,6 @@ message Account { repeated Grant approvals = 3; int32 vendorID = 4; repeated Grant rejects = 5; - repeated Int32Range productIDs = 6; + repeated common.Int32Range productIDs = 6; } diff --git a/proto/dclauth/tx.proto b/proto/dclauth/tx.proto index 6494fe0e2..05a0df868 100644 --- a/proto/dclauth/tx.proto +++ b/proto/dclauth/tx.proto @@ -8,7 +8,7 @@ option go_package = "github.com/zigbee-alliance/distributed-compliance-ledger/x/ import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; -import "dclauth/int32_range.proto"; +import "common/int32_range.proto"; // Msg defines the Msg service. service Msg { @@ -28,7 +28,7 @@ message MsgProposeAddAccount { int32 vendorID = 5 [(gogoproto.moretags) = "validate:\"gte=0,lte=65535\""]; string info = 6 [(gogoproto.moretags) = "validate:\"max=4096\""]; int64 time = 7; - repeated Int32Range productIDs = 8; + repeated common.Int32Range productIDs = 8; } message MsgProposeAddAccountResponse { diff --git a/x/dclauth/types/int32_range.pb.go b/x/common/types/int32_range.pb.go similarity index 100% rename from x/dclauth/types/int32_range.pb.go rename to x/common/types/int32_range.pb.go diff --git a/x/dclauth/client/cli/tx_propose_add_account.go b/x/dclauth/client/cli/tx_propose_add_account.go index 63a5eba5e..744c302ad 100644 --- a/x/dclauth/client/cli/tx_propose_add_account.go +++ b/x/dclauth/client/cli/tx_propose_add_account.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + types2 "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" "strconv" "strings" @@ -58,7 +59,7 @@ func CmdProposeAddAccount() *cobra.Command { } } - var pidRanges []*types.Int32Range + var pidRanges []*types2.Int32Range if pidStrRanges := viper.GetString(FlagPIDs); len(pidStrRanges) > 0 { var lastMax int32 = 0 for _, pidStrRange := range strings.Split(pidStrRanges, ",") { @@ -78,10 +79,10 @@ func CmdProposeAddAccount() *cobra.Command { if min > max || max <= 0 || min <= 0 { return fmt.Errorf("invalid PID Range is provided: min=%d, max=%d", min, max) } - if lastMax >= max { - return fmt.Errorf("invalid PID Range is provided: product ID %d is duplicated", max) + if max <= lastMax || min <= lastMax { + return fmt.Errorf("invalid PID Range is provided: {%d-%d}, ranges are overlapped, range items must be provided in increased order", min, max) } - pid := types.Int32Range{Min: min, Max: max} + pid := types2.Int32Range{Min: min, Max: max} pidRanges = append(pidRanges, &pid) lastMax = max } @@ -89,7 +90,7 @@ func CmdProposeAddAccount() *cobra.Command { argInfo := viper.GetString(FlagInfo) - msg, err := types.NewMsgProposeAddAccountNew( + msg, err := types.NewMsgProposeAddAccount( clientCtx.GetFromAddress(), argAddress, argPubKey, diff --git a/x/dclauth/handler_test.go b/x/dclauth/handler_test.go index a629ae96f..9aa4235c0 100644 --- a/x/dclauth/handler_test.go +++ b/x/dclauth/handler_test.go @@ -356,6 +356,7 @@ func TestHandler_ProposeAddAccount_ForExistingActiveAccount(t *testing.T) { pubKey, types.AccountRoles{types.Vendor}, testconstants.VendorID1, + testconstants.ProductIDsEmpty, testconstants.Info, ) require.NoError(t, err) @@ -385,6 +386,7 @@ func TestHandler_ProposeAddAccount_ForExistingPendingAccount(t *testing.T) { pubKey, types.AccountRoles{types.Vendor}, testconstants.VendorID1, + testconstants.ProductIDsEmpty, testconstants.Info, ) require.NoError(t, err) @@ -862,6 +864,7 @@ func TestHandler_ProposeAddAccount_VendorIDNotRequiredForNonVendorAccounts(t *te pubKey, types.AccountRoles{types.Trustee}, 0, + testconstants.ProductIDsEmpty, testconstants.Info, ) require.NoError(t, err) @@ -875,6 +878,7 @@ func TestHandler_ProposeAddAccount_VendorIDNotRequiredForNonVendorAccounts(t *te pubKey, types.AccountRoles{types.CertificationCenter}, 0, + testconstants.ProductIDsEmpty, testconstants.Info, ) require.NoError(t, err) @@ -893,6 +897,7 @@ func TestHandler_ProposeAddAccount_VendorIDRequiredForVendorAccounts(t *testing. pubKey, types.AccountRoles{types.Vendor}, 0, + testconstants.ProductIDsEmpty, testconstants.Info, ) require.NoError(t, err) @@ -1761,7 +1766,7 @@ func storeTrustee(setup TestSetup) sdk.AccAddress { func storeAccountWithVendorID(setup TestSetup, role types.AccountRole, vendorID int32) sdk.AccAddress { _, pubKey, address := testdata.KeyTestPubAddr() ba := authtypes.NewBaseAccount(address, pubKey, 0, 0) - account := types.NewAccount(ba, types.AccountRoles{role}, nil, nil, vendorID) + account := types.NewAccount(ba, types.AccountRoles{role}, nil, nil, vendorID, testconstants.ProductIDsEmpty) account.AccountNumber = setup.Keeper.GetNextAccountNumber(setup.Ctx) setup.Keeper.SetAccount(setup.Ctx, account) @@ -1776,6 +1781,7 @@ func proposeAddAccount(setup TestSetup, signer sdk.AccAddress, roles types.Accou pubKey, roles, testconstants.VendorID1, + testconstants.ProductIDsEmpty, testconstants.Info, ) // TODO check the err here diff --git a/x/dclauth/keeper/account.go b/x/dclauth/keeper/account.go index 566b297d6..b320e42ae 100644 --- a/x/dclauth/keeper/account.go +++ b/x/dclauth/keeper/account.go @@ -150,11 +150,7 @@ func (k Keeper) HasRightsToChange(ctx sdk.Context, addr sdk.AccAddress, pid int3 return false } - if account.HasRightsToChange(pid) { - return true - } - - return false + return account.HasRightsToChange(pid) } // Count account with assigned role. diff --git a/x/dclauth/types/account.go b/x/dclauth/types/account.go index c0c3cceb8..bd19e73d4 100644 --- a/x/dclauth/types/account.go +++ b/x/dclauth/types/account.go @@ -16,6 +16,7 @@ package types import ( "encoding/json" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -65,11 +66,11 @@ type DCLAccountI interface { GetVendorID() int32 GetApprovals() []*Grant GetRejects() []*Grant - GetProductIDs() []*Int32Range + GetProductIDs() []*types.Int32Range } // NewAccount creates a new Account object. -func NewAccount(ba *authtypes.BaseAccount, roles AccountRoles, approvals []*Grant, rejects []*Grant, vendorID int32, productIDs []*Int32Range) *Account { +func NewAccount(ba *authtypes.BaseAccount, roles AccountRoles, approvals []*Grant, rejects []*Grant, vendorID int32, productIDs []*types.Int32Range) *Account { return &Account{ BaseAccount: ba, Roles: roles, @@ -113,7 +114,7 @@ func (acc Account) GetRejects() []*Grant { return acc.Rejects } -func (acc Account) GetProductIDs() []*Int32Range { +func (acc Account) GetProductIDs() []*types.Int32Range { return acc.ProductIDs } @@ -146,7 +147,7 @@ func (acc Account) HasRightsToChange(productID int32) bool { } for _, productRange := range acc.ProductIDs { - if (productRange.Min <= productID) || (productID <= productRange.Max) { + if (productRange.Min <= productID) && (productID <= productRange.Max) { return true } } diff --git a/x/dclauth/types/account.pb.go b/x/dclauth/types/account.pb.go index 09358e302..067e86950 100644 --- a/x/dclauth/types/account.pb.go +++ b/x/dclauth/types/account.pb.go @@ -8,6 +8,7 @@ import ( types "github.com/cosmos/cosmos-sdk/x/auth/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" + types2 "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" io "io" math "math" math_bits "math/bits" @@ -29,11 +30,11 @@ type Account struct { // NOTE. we do not user AccountRoles casting here to preserve repeated form // so protobuf takes care about repeated items in generated code, // (but that might be not the final solution) - Roles []AccountRole `protobuf:"bytes,2,rep,name=roles,proto3,casttype=AccountRole" json:"roles,omitempty"` - Approvals []*Grant `protobuf:"bytes,3,rep,name=approvals,proto3" json:"approvals,omitempty"` - VendorID int32 `protobuf:"varint,4,opt,name=vendorID,proto3" json:"vendorID,omitempty"` - Rejects []*Grant `protobuf:"bytes,5,rep,name=rejects,proto3" json:"rejects,omitempty"` - ProductIDs []*Int32Range `protobuf:"bytes,6,rep,name=productIDs,proto3" json:"productIDs,omitempty"` + Roles []AccountRole `protobuf:"bytes,2,rep,name=roles,proto3,casttype=AccountRole" json:"roles,omitempty"` + Approvals []*Grant `protobuf:"bytes,3,rep,name=approvals,proto3" json:"approvals,omitempty"` + VendorID int32 `protobuf:"varint,4,opt,name=vendorID,proto3" json:"vendorID,omitempty"` + Rejects []*Grant `protobuf:"bytes,5,rep,name=rejects,proto3" json:"rejects,omitempty"` + ProductIDs []*types2.Int32Range `protobuf:"bytes,6,rep,name=productIDs,proto3" json:"productIDs,omitempty"` } func (m *Account) Reset() { *m = Account{} } @@ -465,7 +466,7 @@ func (m *Account) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProductIDs = append(m.ProductIDs, &Int32Range{}) + m.ProductIDs = append(m.ProductIDs, &types2.Int32Range{}) if err := m.ProductIDs[len(m.ProductIDs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/x/dclauth/types/account_test.go b/x/dclauth/types/account_test.go index 03550fc65..3f621088b 100644 --- a/x/dclauth/types/account_test.go +++ b/x/dclauth/types/account_test.go @@ -15,6 +15,7 @@ package types import ( + types2 "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" "reflect" "testing" @@ -113,7 +114,7 @@ func TestNewAccount(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := NewAccount(tt.args.ba, tt.args.roles, tt.args.approvals, tt.args.rejects, tt.args.vendorID); !reflect.DeepEqual(got, tt.want) { + if got := NewAccount(tt.args.ba, tt.args.roles, tt.args.approvals, tt.args.rejects, tt.args.vendorID, []*types2.Int32Range{}); !reflect.DeepEqual(got, tt.want) { t.Errorf("NewAccount() = %v, want %v", got, tt.want) } }) diff --git a/x/dclauth/types/message_propose_add_account.go b/x/dclauth/types/message_propose_add_account.go index ca50243dc..fa06aff77 100644 --- a/x/dclauth/types/message_propose_add_account.go +++ b/x/dclauth/types/message_propose_add_account.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" "time" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -22,35 +23,7 @@ func NewMsgProposeAddAccount( roles AccountRoles, // roles []string, vendorID int32, - info string, -) (*MsgProposeAddAccount, error) { - var pkAny *codectypes.Any - if pubKey != nil { - var err error - if pkAny, err = codectypes.NewAnyWithValue(pubKey); err != nil { - return nil, err - } - } - - return &MsgProposeAddAccount{ - Signer: signer.String(), - Address: address.String(), - PubKey: pkAny, - Roles: roles, - VendorID: vendorID, - Info: info, - Time: time.Now().Unix(), - }, nil -} - -func NewMsgProposeAddAccountNew( - signer sdk.AccAddress, - address sdk.AccAddress, - pubKey cryptotypes.PubKey, //nolint:interfacer - roles AccountRoles, - // roles []string, - vendorID int32, - productIDs []*Int32Range, + productIDs []*types.Int32Range, info string, ) (*MsgProposeAddAccount, error) { var pkAny *codectypes.Any @@ -91,6 +64,21 @@ func (msg *MsgProposeAddAccount) HasRole(targetRole AccountRole) bool { return false } +func (msg *MsgProposeAddAccount) HasValidProductIDs() bool { + var lastMax int32 = 0 + for _, productRange := range msg.ProductIDs { + if productRange.Min > productRange.Max { + return false + } + if productRange.Max <= lastMax || productRange.Min <= lastMax { + return false + } + lastMax = productRange.Max + } + + return true +} + func (msg *MsgProposeAddAccount) GetSigners() []sdk.AccAddress { signer, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { @@ -153,6 +141,10 @@ func (msg *MsgProposeAddAccount) ValidateBasic() error { return ErrMissingVendorIDForVendorAccount() } + if !msg.HasValidProductIDs() { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "Invalid ProductID ranges are provided") + } + err = validator.Validate(msg) if err != nil { return err diff --git a/x/dclauth/types/message_propose_add_account_test.go b/x/dclauth/types/message_propose_add_account_test.go index 2bde74cb0..2246c68ea 100644 --- a/x/dclauth/types/message_propose_add_account_test.go +++ b/x/dclauth/types/message_propose_add_account_test.go @@ -3,6 +3,7 @@ package types // TODO issue 99. import ( fmt "fmt" + "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" "testing" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -20,9 +21,10 @@ func NewMsgProposeAddAccountWrapper( pubKey cryptotypes.PubKey, roles AccountRoles, vendorID int32, + productIDs []*types.Int32Range, ) *MsgProposeAddAccount { t.Helper() - msg, err := NewMsgProposeAddAccount(signer, address, pubKey, roles, vendorID, testconstants.Info) + msg, err := NewMsgProposeAddAccount(signer, address, pubKey, roles, vendorID, productIDs, testconstants.Info) require.NoError(t, err) return msg @@ -33,7 +35,7 @@ func TestNewMsgProposeAddAccount(t *testing.T) { t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{}, testconstants.VendorID1, + AccountRoles{}, testconstants.VendorID1, testconstants.ProductIDsEmpty, ) require.Equal(t, msg.Route(), RouterKey) @@ -49,23 +51,33 @@ func TestValidateMsgProposeAddAccount(t *testing.T) { { valid: true, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{NodeAdmin}, 1), + AccountRoles{NodeAdmin}, 1, []*types.Int32Range{{Min: 1, Max: 1000}}), }, { valid: true, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{Vendor, NodeAdmin}, testconstants.VendorID1), + AccountRoles{Vendor, NodeAdmin}, testconstants.VendorID1, []*types.Int32Range{{Min: 1, Max: 65535}}), + }, + { + valid: true, + msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, + AccountRoles{Vendor, NodeAdmin}, testconstants.VendorID1, testconstants.ProductIDsEmpty), }, // zero VID without Vendor role - no error { valid: true, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{NodeAdmin}, 0), + AccountRoles{NodeAdmin}, 0, []*types.Int32Range{{Min: 1, Max: 2}}), + }, + { + valid: true, + msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, + AccountRoles{Vendor, NodeAdmin}, testconstants.VendorID1, []*types.Int32Range{{Min: 1, Max: 1}}), }, { valid: true, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{Vendor, NodeAdmin}, testconstants.VendorID1), + AccountRoles{Vendor, NodeAdmin}, testconstants.VendorID1, []*types.Int32Range{{Min: 1, Max: 1}, {Min: 2, Max: 2}}), }, } @@ -77,7 +89,7 @@ func TestValidateMsgProposeAddAccount(t *testing.T) { { valid: false, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{}, 1), // no roles provided + AccountRoles{}, 1, testconstants.ProductIDsEmpty), // no roles provided err: sdkerrors.Wrapf(MissingRoles, "No roles provided"), }, @@ -85,7 +97,7 @@ func TestValidateMsgProposeAddAccount(t *testing.T) { { valid: false, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{Vendor, NodeAdmin}, 0), + AccountRoles{Vendor, NodeAdmin}, 0, testconstants.ProductIDsEmpty), err: sdkerrors.Wrapf(MissingVendorIDForVendorAccount, "No Vendor ID is provided in the Vendor Role for the new account"), }, @@ -93,7 +105,7 @@ func TestValidateMsgProposeAddAccount(t *testing.T) { { valid: false, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{Vendor, NodeAdmin}, -1), + AccountRoles{Vendor, NodeAdmin}, -1, testconstants.ProductIDsEmpty), err: sdkerrors.Wrapf(MissingVendorIDForVendorAccount, "No Vendor ID is provided in the Vendor Role for the new account"), }, @@ -101,13 +113,13 @@ func TestValidateMsgProposeAddAccount(t *testing.T) { { valid: false, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{Vendor, NodeAdmin}, 65535+1), + AccountRoles{Vendor, NodeAdmin}, 65535+1, testconstants.ProductIDsEmpty), err: validator.ErrFieldUpperBoundViolated, }, { valid: false, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, nil, testconstants.PubKey1, - AccountRoles{NodeAdmin}, 1), + AccountRoles{NodeAdmin}, 1, testconstants.ProductIDsEmpty), err: sdkerrors.ErrInvalidAddress, }, // { @@ -119,15 +131,33 @@ func TestValidateMsgProposeAddAccount(t *testing.T) { { valid: false, msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, - AccountRoles{"Wrong Role"}, 1), + AccountRoles{"Wrong Role"}, 1, testconstants.ProductIDsEmpty), err: sdkerrors.ErrUnknownRequest, }, { valid: false, msg: NewMsgProposeAddAccountWrapper(t, nil, testconstants.Address1, testconstants.PubKey1, - AccountRoles{NodeAdmin}, 1), + AccountRoles{NodeAdmin}, 1, testconstants.ProductIDsEmpty), err: sdkerrors.ErrInvalidAddress, }, + { + valid: false, + msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, + AccountRoles{Vendor}, 1, []*types.Int32Range{{Min: 1, Max: 200}, {Min: 101, Max: 200}}), + err: sdkerrors.ErrInvalidRequest, + }, + { + valid: false, + msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, + AccountRoles{Vendor}, 1, []*types.Int32Range{{Min: 10, Max: 100}, {Min: 100, Max: 200}}), + err: sdkerrors.ErrInvalidRequest, + }, + { + valid: false, + msg: NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address1, testconstants.PubKey1, + AccountRoles{Vendor}, 1, []*types.Int32Range{{Min: 100, Max: 1}}), + err: sdkerrors.ErrInvalidRequest, + }, } for _, tt := range positiveTests { @@ -154,7 +184,7 @@ func TestValidateMsgProposeAddAccount(t *testing.T) { func TestMsgProposeAddAccountGetSignBytes(t *testing.T) { msg := NewMsgProposeAddAccountWrapper(t, testconstants.Signer, testconstants.Address2, testconstants.PubKey2, - AccountRoles{}, testconstants.VendorID1) + AccountRoles{}, testconstants.VendorID1, testconstants.ProductIDsEmpty) transcationTime := msg.Time expected := fmt.Sprintf(`{"address":"cosmos1nl4uaesk9gtu7su3n89lne6xpa6lq8gljn79rq","info":"Information for Proposal/Approval/Revoke","pubKey":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A2wJ7uOEE5Zm04K52czFTXfDj1qF2mholzi1zOJVlKlr"},"roles":[],"signer":"cosmos1s5xf3aanx7w84hgplk9z3l90qfpantg6nsmhpf","time":"%v","vendorID":1000}`, transcationTime) diff --git a/x/dclauth/types/tx.pb.go b/x/dclauth/types/tx.pb.go index 4f3ef0251..3870825af 100644 --- a/x/dclauth/types/tx.pb.go +++ b/x/dclauth/types/tx.pb.go @@ -11,6 +11,7 @@ import ( _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" + types2 "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -31,14 +32,14 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type MsgProposeAddAccount struct { - Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty" validate:"required"` - Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty" validate:"required"` - PubKey *types.Any `protobuf:"bytes,3,opt,name=pubKey,proto3" json:"pubKey,omitempty" validate:"required"` - Roles []AccountRole `protobuf:"bytes,4,rep,name=roles,proto3,casttype=AccountRole" json:"roles,omitempty" validate:"required"` - VendorID int32 `protobuf:"varint,5,opt,name=vendorID,proto3" json:"vendorID,omitempty" validate:"gte=0,lte=65535"` - Info string `protobuf:"bytes,6,opt,name=info,proto3" json:"info,omitempty" validate:"max=4096"` - Time int64 `protobuf:"varint,7,opt,name=time,proto3" json:"time,omitempty"` - ProductIDs []*Int32Range `protobuf:"bytes,8,rep,name=productIDs,proto3" json:"productIDs,omitempty"` + Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty" validate:"required"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty" validate:"required"` + PubKey *types.Any `protobuf:"bytes,3,opt,name=pubKey,proto3" json:"pubKey,omitempty" validate:"required"` + Roles []AccountRole `protobuf:"bytes,4,rep,name=roles,proto3,casttype=AccountRole" json:"roles,omitempty" validate:"required"` + VendorID int32 `protobuf:"varint,5,opt,name=vendorID,proto3" json:"vendorID,omitempty" validate:"gte=0,lte=65535"` + Info string `protobuf:"bytes,6,opt,name=info,proto3" json:"info,omitempty" validate:"max=4096"` + Time int64 `protobuf:"varint,7,opt,name=time,proto3" json:"time,omitempty"` + ProductIDs []*types2.Int32Range `protobuf:"bytes,8,rep,name=productIDs,proto3" json:"productIDs,omitempty"` } func (m *MsgProposeAddAccount) Reset() { *m = MsgProposeAddAccount{} } @@ -123,7 +124,7 @@ func (m *MsgProposeAddAccount) GetTime() int64 { return 0 } -func (m *MsgProposeAddAccount) GetProductIDs() []*Int32Range { +func (m *MsgProposeAddAccount) GetProductIDs() []*types2.Int32Range { if m != nil { return m.ProductIDs } @@ -1731,7 +1732,7 @@ func (m *MsgProposeAddAccount) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProductIDs = append(m.ProductIDs, &Int32Range{}) + m.ProductIDs = append(m.ProductIDs, &types2.Int32Range{}) if err := m.ProductIDs[len(m.ProductIDs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/x/model/handler_test.go b/x/model/handler_test.go index bafac60bd..72e7e2d9f 100644 --- a/x/model/handler_test.go +++ b/x/model/handler_test.go @@ -17,6 +17,7 @@ package model import ( "context" + types2 "github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -39,8 +40,9 @@ type DclauthKeeperMock struct { } func (m *DclauthKeeperMock) HasRightsToChange(ctx sdk.Context, addr sdk.AccAddress, pid int32) bool { - //TODO PID scoped implement me - panic("implement me") + args := m.Called(ctx, addr, pid) + + return args.Bool(0) } func (m *DclauthKeeperMock) HasRole( @@ -93,14 +95,16 @@ type TestSetup struct { ComplianceKeeper *ComplianceKeeperMock Handler sdk.Handler // Querier sdk.Querier - Vendor sdk.AccAddress - VendorID int32 + Vendor sdk.AccAddress + VendorID int32 + ProductIDs []*types2.Int32Range } func (setup *TestSetup) AddAccount( accAddress sdk.AccAddress, roles []dclauthtypes.AccountRole, vendorID int32, + productIDs []*types2.Int32Range, ) { dclauthKeeper := setup.DclauthKeeper @@ -111,6 +115,16 @@ func (setup *TestSetup) AddAccount( dclauthKeeper.On("HasVendorID", mock.Anything, accAddress, vendorID).Return(true) dclauthKeeper.On("HasVendorID", mock.Anything, accAddress, mock.Anything).Return(false) + + if len(productIDs) == 0 { + dclauthKeeper.On("HasRightsToChange", mock.Anything, accAddress, mock.Anything).Return(true) + } + for _, productIDRange := range productIDs { + for productId := productIDRange.Min; productId <= productIDRange.Max; productId++ { + dclauthKeeper.On("HasRightsToChange", mock.Anything, accAddress, productId).Return(true) + } + } + dclauthKeeper.On("HasRightsToChange", mock.Anything, accAddress, mock.Anything).Return(false) } func Setup(t *testing.T) *TestSetup { @@ -121,7 +135,7 @@ func Setup(t *testing.T) *TestSetup { vendor := testdata.GenerateAccAddress() vendorID := testconstants.VendorID1 - + productIDs := testconstants.ProductIDsEmpty setup := &TestSetup{ T: t, Ctx: ctx, @@ -132,9 +146,10 @@ func Setup(t *testing.T) *TestSetup { Handler: NewHandler(*keeper), Vendor: vendor, VendorID: vendorID, + ProductIDs: productIDs, } - setup.AddAccount(vendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, vendorID) + setup.AddAccount(vendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, vendorID, productIDs) return setup } @@ -187,6 +202,45 @@ func TestHandler_UpdateModel(t *testing.T) { require.Equal(t, msgUpdateModel.ProductLabel, receivedModel.ProductLabel) } +func TestHandler_UpdateModelByVendorWithProductIds(t *testing.T) { + setup := Setup(t) + + owner := testdata.GenerateAccAddress() + setup.AddAccount(owner, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1, testconstants.ProductIDs200) + + // add new model + msgCreateModel := NewMsgCreateModel(owner) + msgCreateModel.Pid = 200 + _, err := setup.Handler(setup.Ctx, msgCreateModel) + require.NoError(t, err) + + anotherVendor := testdata.GenerateAccAddress() + setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2, testconstants.ProductIDs100) + + // update existing model by vendor with another VendorID + msgUpdateModel := NewMsgUpdateModel(anotherVendor) + _, err = setup.Handler(setup.Ctx, msgUpdateModel) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) + + // update existing model by owner + msgUpdateModel = NewMsgUpdateModel(owner) + msgUpdateModel.Pid = 200 + _, err = setup.Handler(setup.Ctx, msgUpdateModel) + require.NoError(t, err) + + vendorWithoutProductIDs := testdata.GenerateAccAddress() + setup.AddAccount(vendorWithoutProductIDs, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, testconstants.ProductIDsEmpty) + + // update existing model by vendor with the same VendorID as owner's one + msgUpdateModel = NewMsgUpdateModel(vendorWithoutProductIDs) + msgUpdateModel.Pid = 200 + msgUpdateModel.ProductLabel += "-updated-once-more" + msgUpdateModel.LsfRevision++ + _, err = setup.Handler(setup.Ctx, msgUpdateModel) + require.NoError(t, err) +} + func TestHandler_OnlyOwnerAndVendorWithSameVidCanUpdateModel(t *testing.T) { setup := Setup(t) @@ -201,7 +255,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanUpdateModel(t *testing.T) { dclauthtypes.NodeAdmin, } { accAddress := testdata.GenerateAccAddress() - setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, setup.VendorID) + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, setup.VendorID, setup.ProductIDs) // update existing model by user without Vendor role msgUpdateModel := NewMsgUpdateModel(accAddress) @@ -211,7 +265,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanUpdateModel(t *testing.T) { } anotherVendor := testdata.GenerateAccAddress() - setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2) + setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2, setup.ProductIDs) // update existing model by vendor with another VendorID msgUpdateModel := NewMsgUpdateModel(anotherVendor) @@ -225,7 +279,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanUpdateModel(t *testing.T) { require.NoError(t, err) vendorWithSameVid := testdata.GenerateAccAddress() - setup.AddAccount(vendorWithSameVid, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID) + setup.AddAccount(vendorWithSameVid, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, setup.ProductIDs) // update existing model by vendor with the same VendorID as owner's one msgUpdateModel = NewMsgUpdateModel(vendorWithSameVid) @@ -358,7 +412,7 @@ func TestHandler_AddModelByNonVendor(t *testing.T) { dclauthtypes.NodeAdmin, } { accAddress := testdata.GenerateAccAddress() - setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, setup.VendorID) + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, setup.VendorID, setup.ProductIDs) // add new model model := NewMsgCreateModel(accAddress) @@ -372,7 +426,7 @@ func TestHandler_AddModelByVendorWithAnotherVendorId(t *testing.T) { setup := Setup(t) anotherVendor := testdata.GenerateAccAddress() - setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2) + setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2, testconstants.ProductIDsEmpty) // add new model model := NewMsgCreateModel(anotherVendor) @@ -381,6 +435,35 @@ func TestHandler_AddModelByVendorWithAnotherVendorId(t *testing.T) { require.True(t, sdkerrors.ErrUnauthorized.Is(err)) } +func TestHandler_AddModelByVendorWithProductIds(t *testing.T) { + setup := Setup(t) + + owner := testdata.GenerateAccAddress() + setup.AddAccount(owner, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, testconstants.ProductIDs200) + + model := NewMsgCreateModel(owner) + model.Pid = 200 + _, err := setup.Handler(setup.Ctx, model) + require.NoError(t, err) + + vendor := testdata.GenerateAccAddress() + setup.AddAccount(vendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, testconstants.ProductIDs100) + model = NewMsgCreateModel(vendor) + model.Pid = 101 + _, err = setup.Handler(setup.Ctx, model) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) + + vendorWithSameVid := testdata.GenerateAccAddress() + setup.AddAccount(vendorWithSameVid, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, testconstants.ProductIDsEmpty) + + // add model by vendor with non-assigned PIDs + model = NewMsgCreateModel(vendorWithSameVid) + model.Pid = 201 + _, err = setup.Handler(setup.Ctx, model) + require.NoError(t, err) +} + func TestHandler_PartiallyUpdateModel(t *testing.T) { setup := Setup(t) @@ -534,6 +617,50 @@ func TestHandler_DeleteModelWithAssociatedModelVersionsCertified(t *testing.T) { require.NoError(t, err) } +func TestHandler_DeleteModelByVendorWitProductIds(t *testing.T) { + setup := Setup(t) + + owner := testdata.GenerateAccAddress() + setup.AddAccount(owner, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1, testconstants.ProductIDs200) + + // add new model + msgCreateModel := NewMsgCreateModel(owner) + msgCreateModel.Pid = 200 + _, err := setup.Handler(setup.Ctx, msgCreateModel) + require.NoError(t, err) + + vendor := testdata.GenerateAccAddress() + setup.AddAccount(vendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2, testconstants.ProductIDs100) + + // delete existing model by vendor with another VendorID + msgDeleteModel := NewMsgDeleteModel(vendor) + msgDeleteModel.Pid = 200 + _, err = setup.Handler(setup.Ctx, msgDeleteModel) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) + + // delete existing model by owner + msgDeleteModel = NewMsgDeleteModel(owner) + msgDeleteModel.Pid = 200 + _, err = setup.Handler(setup.Ctx, msgDeleteModel) + require.NoError(t, err) + + // add new model + msgCreateModel = NewMsgCreateModel(owner) + msgCreateModel.Pid = 199 + _, err = setup.Handler(setup.Ctx, msgCreateModel) + require.NoError(t, err) + + vendorWithSameVid := testdata.GenerateAccAddress() + setup.AddAccount(vendorWithSameVid, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, testconstants.ProductIDsEmpty) + + // delete existing model by vendor with non-assigned PIDs + msgDeleteModel = NewMsgDeleteModel(vendorWithSameVid) + msgDeleteModel.Pid = 199 + _, err = setup.Handler(setup.Ctx, msgDeleteModel) + require.NoError(t, err) +} + func TestHandler_OnlyOwnerAndVendorWithSameVidCanDeleteModel(t *testing.T) { setup := Setup(t) @@ -548,7 +675,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanDeleteModel(t *testing.T) { dclauthtypes.NodeAdmin, } { accAddress := testdata.GenerateAccAddress() - setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, setup.VendorID) + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, setup.VendorID, setup.ProductIDs) // delete existing model by user without Vendor role msgDeleteModel := NewMsgDeleteModel(accAddress) @@ -558,7 +685,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanDeleteModel(t *testing.T) { } anotherVendor := testdata.GenerateAccAddress() - setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2) + setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2, testconstants.ProductIDsEmpty) // delete existing model by vendor with another VendorID msgDeleteModel := NewMsgDeleteModel(anotherVendor) @@ -577,7 +704,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanDeleteModel(t *testing.T) { require.NoError(t, err) vendorWithSameVid := testdata.GenerateAccAddress() - setup.AddAccount(vendorWithSameVid, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID) + setup.AddAccount(vendorWithSameVid, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, setup.ProductIDs) // delete existing model by vendor with the same VendorID as owner's one msgDeleteModel = NewMsgDeleteModel(vendorWithSameVid) @@ -760,6 +887,51 @@ func TestHandler_UpdateModelVersion(t *testing.T) { require.Equal(t, []uint32{msgCreateModelVersion.SoftwareVersion}, receivedModelVersions.SoftwareVersions) } +func TestHandler_UpdateModelVersionByVendorWithProductIds(t *testing.T) { + setup := Setup(t) + + owner := testdata.GenerateAccAddress() + setup.AddAccount(owner, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1, testconstants.ProductIDs200) + + // add new model + msgCreteModel := NewMsgCreateModel(owner) + msgCreteModel.Pid = 200 + _, err := setup.Handler(setup.Ctx, msgCreteModel) + require.NoError(t, err) + + // add new model version + msgCreateModelVersion := NewMsgCreateModelVersion(owner, testconstants.SoftwareVersion) + msgCreateModelVersion.Pid = 200 + _, err = setup.Handler(setup.Ctx, msgCreateModelVersion) + require.NoError(t, err) + + vendor := testdata.GenerateAccAddress() + setup.AddAccount(vendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2, testconstants.ProductIDs100) + + // update existing model by vendor with another productIDs + msgUpdateModelVersion := NewMsgUpdateModelVersion(vendor) + msgUpdateModelVersion.Pid = 200 + _, err = setup.Handler(setup.Ctx, msgUpdateModelVersion) + require.Error(t, err) + require.True(t, sdkerrors.ErrUnauthorized.Is(err)) + + // update existing model version by owner + msgUpdateModelVersion = NewMsgUpdateModelVersion(owner) + msgUpdateModelVersion.Pid = 200 + _, err = setup.Handler(setup.Ctx, msgUpdateModelVersion) + require.NoError(t, err) + + vendorWithoutProductIDs := testdata.GenerateAccAddress() + setup.AddAccount(vendorWithoutProductIDs, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, testconstants.ProductIDsEmpty) + + msgUpdateModelVersion = NewMsgUpdateModelVersion(vendorWithoutProductIDs) + msgUpdateModelVersion.Pid = 200 + + msgUpdateModelVersion.ReleaseNotesUrl += "/updated-once-more" + _, err = setup.Handler(setup.Ctx, msgUpdateModelVersion) + require.NoError(t, err) +} + func TestHandler_PartiallyUpdateModelVersion(t *testing.T) { setup := Setup(t) @@ -1029,7 +1201,6 @@ func TestHandler_UpdateOTAFieldsInitiallySet(t *testing.T) { require.Equal(t, receivedModelVersion.OtaChecksum, msgUpdateModelVersion.OtaChecksum) require.Equal(t, receivedModelVersion.OtaFileSize, msgUpdateModelVersion.OtaFileSize) } - func TestHandler_OnlyOwnerAndVendorWithSameVidCanUpdateModelVersion(t *testing.T) { setup := Setup(t) @@ -1049,7 +1220,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanUpdateModelVersion(t *testing.T dclauthtypes.NodeAdmin, } { accAddress := testdata.GenerateAccAddress() - setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, setup.VendorID) + setup.AddAccount(accAddress, []dclauthtypes.AccountRole{role}, setup.VendorID, setup.ProductIDs) // update existing model version by user without Vendor role msgUpdateModelVersion := NewMsgUpdateModelVersion(accAddress) @@ -1059,7 +1230,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanUpdateModelVersion(t *testing.T } anotherVendor := testdata.GenerateAccAddress() - setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2) + setup.AddAccount(anotherVendor, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2, testconstants.ProductIDsEmpty) // update existing model by vendor with another VendorID msgUpdateModelVersion := NewMsgUpdateModelVersion(anotherVendor) @@ -1074,7 +1245,7 @@ func TestHandler_OnlyOwnerAndVendorWithSameVidCanUpdateModelVersion(t *testing.T require.NoError(t, err) vendorWithSameVid := testdata.GenerateAccAddress() - setup.AddAccount(vendorWithSameVid, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID) + setup.AddAccount(vendorWithSameVid, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, setup.VendorID, setup.ProductIDs) // update existing model by vendor with the same VendorID as owner's one msgUpdateModelVersion = NewMsgUpdateModelVersion(vendorWithSameVid) @@ -1117,7 +1288,7 @@ func TestHandler_DeleteModelVersion(t *testing.T) { require.Equal(t, codes.NotFound, status.Code(err)) } -func TestHandler_DeleteModelVersionDifferendAccSameVid(t *testing.T) { +func TestHandler_DeleteModelVersionDifferentAccSameVid(t *testing.T) { setup := Setup(t) // add new model @@ -1133,7 +1304,7 @@ func TestHandler_DeleteModelVersionDifferendAccSameVid(t *testing.T) { secondAcc := testdata.GenerateAccAddress() secondAccVid := testconstants.VendorID1 - setup.AddAccount(secondAcc, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, secondAccVid) + setup.AddAccount(secondAcc, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, secondAccVid, testconstants.ProductIDsEmpty) msgDeleteModelVersion := NewMsgDeleteModelVersion(secondAcc) @@ -1168,14 +1339,13 @@ func TestHandler_DeleteModelVersionNotByVendor(t *testing.T) { _, err = setup.Handler(setup.Ctx, msgCreateModelVersion) require.NoError(t, err) - setup.AddAccount(testconstants.Address1, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, testconstants.VendorID2) + setup.AddAccount(testconstants.Address1, []dclauthtypes.AccountRole{dclauthtypes.Trustee}, testconstants.VendorID2, testconstants.ProductIDsEmpty) msgDeleteModelVersion := NewMsgDeleteModelVersion(testconstants.Address1) _, err = setup.Handler(setup.Ctx, msgDeleteModelVersion) require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) } - func TestHandler_DeleteModelVersionDifferentVid(t *testing.T) { setup := Setup(t) @@ -1229,7 +1399,7 @@ func TestHandler_DeleteModelVersionNotByCreator(t *testing.T) { _, err = setup.Handler(setup.Ctx, msgCreateModelVersion) require.NoError(t, err) - setup.AddAccount(testconstants.Address1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2) + setup.AddAccount(testconstants.Address1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID2, testconstants.ProductIDsEmpty) msgDeleteModelVersion := NewMsgDeleteModelVersion(testconstants.Address1) @@ -1260,6 +1430,53 @@ func TestHandler_DeleteModelVersionCertified(t *testing.T) { require.ErrorIs(t, err, types.ErrModelVersionDeletionCertified) } +func TestHandler_DeleteModelVersionByVendorWithProductIds(t *testing.T) { + setup := Setup(t) + + owner := testdata.GenerateAccAddress() + setup.AddAccount(owner, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1, testconstants.ProductIDs200) + + // add new model + msgCreateModel := NewMsgCreateModel(owner) + msgCreateModel.Pid = 200 + _, err := setup.Handler(setup.Ctx, msgCreateModel) + require.NoError(t, err) + + // add new model version + msgCreateModelVersion := NewMsgCreateModelVersion(owner, testconstants.SoftwareVersion) + msgCreateModelVersion.Pid = 200 + _, err = setup.Handler(setup.Ctx, msgCreateModelVersion) + require.NoError(t, err) + + setup.AddAccount(testconstants.Address1, []dclauthtypes.AccountRole{dclauthtypes.Vendor}, testconstants.VendorID1, testconstants.ProductIDs100) + + msgDeleteModelVersion := NewMsgDeleteModelVersion(testconstants.Address1) + msgDeleteModelVersion.Pid = 200 + + _, err = setup.Handler(setup.Ctx, msgDeleteModelVersion) + require.ErrorIs(t, err, sdkerrors.ErrUnauthorized) + + msgDeleteModelVersion = NewMsgDeleteModelVersion(owner) + msgDeleteModelVersion.Pid = 200 + + complianceKeeper := setup.ComplianceKeeper + complianceKeeper.On("GetComplianceInfo", mock.Anything, msgDeleteModelVersion.Vid, msgDeleteModelVersion.Pid, msgDeleteModelVersion.SoftwareVersion, mock.Anything).Return(false) + complianceKeeper.On("GetComplianceInfo", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(true) + + _, err = setup.Handler(setup.Ctx, msgDeleteModelVersion) + require.NoError(t, err) + + // query model version + _, err = queryModelVersion( + setup, + msgDeleteModelVersion.Vid, + msgDeleteModelVersion.Pid, + msgDeleteModelVersion.SoftwareVersion, + ) + require.Error(t, err) + require.Equal(t, codes.NotFound, status.Code(err)) +} + func queryModel( setup *TestSetup, vid int32,