diff --git a/pkg/client/resmgmt/example_test.go b/pkg/client/resmgmt/example_test.go index b86b1c8325..d388255fec 100644 --- a/pkg/client/resmgmt/example_test.go +++ b/pkg/client/resmgmt/example_test.go @@ -12,8 +12,6 @@ import ( "path/filepath" "time" - "github.com/hyperledger/fabric-sdk-go/pkg/util/test" - "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric-protos-go/common" @@ -249,43 +247,6 @@ func ExampleClient_SaveChannel_withOrdererEndpoint() { } -func ExampleClient_UpdateChannelConfig_success() { - - c, err := New(mockClientProvider()) - if err != nil { - fmt.Printf("failed to create client: %s\n", err) - } - - block, err := c.QueryConfigBlockFromOrderer("mychannel", WithOrdererEndpoint("example.com")) - if err != nil { - fmt.Printf("QueryConfigBlockFromOrderer returned error: %s\n", err) - } - channelConfig, err := resource.ExtractConfigFromBlock(block) - if err != nil { - fmt.Println("extractConfigFromBlock failed") - } - - // Modify channel configuration - _, err = test.ModifyMaxMessageCount(channelConfig) - if err != nil { - fmt.Printf("error modifying channel configuration: %s\n", err) - } - - resp, err := c.UpdateChannelConfig(UpdateChannelConfigRequest{ChannelID: "mychannel", ChannelConfig: channelConfig}, WithOrdererEndpoint("example.com")) - if err != nil { - fmt.Printf("failed to update channel config: %s\n", err) - } - - if resp.TransactionID == "" { - fmt.Println("Failed to save channel") - } - - fmt.Println("Updated channel config") - - // Output: Updated channel config - -} - func ExampleClient_JoinChannel() { c, err := New(mockClientProvider()) diff --git a/pkg/client/resmgmt/resmgmt.go b/pkg/client/resmgmt/resmgmt.go index 1e1d747257..3f061c2035 100644 --- a/pkg/client/resmgmt/resmgmt.go +++ b/pkg/client/resmgmt/resmgmt.go @@ -112,9 +112,11 @@ type requestOptions struct { //SaveChannelRequest holds parameters for save channel request type SaveChannelRequest struct { ChannelID string - ChannelConfig io.Reader // ChannelConfig data source - ChannelConfigPath string // Convenience option to use the named file as ChannelConfig reader - SigningIdentities []msp.SigningIdentity // Users that sign channel configuration + ChannelConfig io.Reader // ChannelConfig data source + ChannelConfigPath string // Convenience option to use the named file as ChannelConfig reader + // Users that sign channel configuration + // deprecated - one entity shouldn't have access to another entities' keys to sign on their behalf + SigningIdentities []msp.SigningIdentity } // SaveChannelResponse contains response parameters for save channel @@ -122,18 +124,6 @@ type SaveChannelResponse struct { TransactionID fab.TransactionID } -// UpdateChannelConfigRequest holds parameters for update channel config request. -type UpdateChannelConfigRequest struct { - ChannelID string - ChannelConfig *common.Config // Desired channel config. - SigningIdentities []msp.SigningIdentity // Users that sign channel configuration -} - -// UpdateChannelConfigResponse contains response parameters for update channel config -type UpdateChannelConfigResponse struct { - TransactionID fab.TransactionID -} - //RequestOption func for each Opts argument type RequestOption func(ctx context.Client, opts *requestOptions) error @@ -971,54 +961,6 @@ func (rc *Client) SaveChannel(req SaveChannelRequest, options ...RequestOption) return SaveChannelResponse{TransactionID: txID}, nil } -// UpdateChannelConfig updates channel configuration. -// Parameters: -// req holds info about mandatory channel name and configuration -// options holds optional request options -// if options have signatures (WithConfigSignatures() or 1 or more WithConfigSignature() calls), then UpdateChannelConfig will -// use these signatures instead of creating ones for the SigningIdentities found in req. -// Make sure that req.ChannelConfig has the channel config matching these signatures. -// -// Returns: -// update channel config response with transaction ID -func (rc *Client) UpdateChannelConfig(req UpdateChannelConfigRequest, options ...RequestOption) (UpdateChannelConfigResponse, error) { - - opts, err := rc.prepareRequestOpts(options...) - if err != nil { - return UpdateChannelConfigResponse{}, err - } - - err = rc.validateUpdateChannelConfigRequest(req) - if err != nil { - return UpdateChannelConfigResponse{}, err - } - - logger.Debugf("updating channel config: %s", req.ChannelID) - - orderer, err := rc.requestOrderer(&opts, req.ChannelID) - if err != nil { - return UpdateChannelConfigResponse{}, errors.WithMessage(err, "failed to find orderer for request") - } - - chConfig, err := rc.calculateConfigUpdate(req, orderer) - if err != nil { - return UpdateChannelConfigResponse{}, errors.WithMessage(err, "prepare channel ConfigTx failed") - } - - txID, err := rc.signAndSubmitChannelConfigTx( - req.ChannelID, - req.SigningIdentities, - opts, - chConfig, - orderer, - ) - if err != nil { - return UpdateChannelConfigResponse{}, errors.WithMessage(err, "update channel config failed") - } - - return UpdateChannelConfigResponse{TransactionID: txID}, nil -} - func (rc *Client) signAndSubmitChannelConfigTx(channelID string, signingIdentities []msp.SigningIdentity, opts requestOptions, chConfigTx []byte, orderer fab.Orderer) (fab.TransactionID, error) { var configSignatures []*common.ConfigSignature var err error @@ -1048,28 +990,23 @@ func (rc *Client) signAndSubmitChannelConfigTx(channelID string, signingIdentiti return txID, nil } -func (rc *Client) calculateConfigUpdate(req UpdateChannelConfigRequest, orderer fab.Orderer) ([]byte, error) { - block, err := rc.QueryConfigBlockFromOrderer(req.ChannelID, WithOrderer(orderer)) - if err != nil { - return nil, errors.WithMessage(err, "retrieving current channel config failed") - } - currentConfig, err := resource.ExtractConfigFromBlock(block) - if err != nil { - return nil, errors.WithMessage(err, "extracting config from the latest block failed") +// CalculateConfigUpdate calculates channel config update based on the difference between provided +// current channel config and proposed new channel config. +func CalculateConfigUpdate(channelID string, currentConfig, newConfig *common.Config) (*common.ConfigUpdate, error) { + + if channelID == "" || currentConfig == nil || newConfig == nil { + return nil, errors.New("must provide channel ID and current and new channel config") } - if currentConfig.Sequence != req.ChannelConfig.Sequence { + + if currentConfig.Sequence != newConfig.Sequence { return nil, errors.New("channel config sequence mismatch") } - configUpdate, err := update.Compute(currentConfig, req.ChannelConfig) + configUpdate, err := update.Compute(currentConfig, newConfig) if err != nil { return nil, errors.WithMessage(err, "config update computation failed") } - configUpdate.ChannelId = req.ChannelID - configUpdateBytes, err := proto.Marshal(configUpdate) - if err != nil { - return nil, errors.WithMessage(err, "marshalling config update failed") - } - return configUpdateBytes, nil + configUpdate.ChannelId = channelID + return configUpdate, nil } func (rc *Client) validateSaveChannelRequest(req SaveChannelRequest) error { @@ -1080,14 +1017,6 @@ func (rc *Client) validateSaveChannelRequest(req SaveChannelRequest) error { return nil } -func (rc *Client) validateUpdateChannelConfigRequest(req UpdateChannelConfigRequest) error { - - if req.ChannelID == "" || req.ChannelConfig == nil { - return errors.New("must provide channel ID and channel config") - } - return nil -} - func (rc *Client) getConfigSignatures(signingIdentities []msp.SigningIdentity, chConfig []byte) ([]*common.ConfigSignature, error) { // Signing user has to belong to one of configured channel organisations // In case that order org is one of channel orgs we can use context user diff --git a/pkg/client/resmgmt/resmgmt_test.go b/pkg/client/resmgmt/resmgmt_test.go index faf37f4597..e26409efdb 100644 --- a/pkg/client/resmgmt/resmgmt_test.go +++ b/pkg/client/resmgmt/resmgmt_test.go @@ -19,6 +19,8 @@ import ( "testing" "time" + "github.com/hyperledger/fabric-protos-go/orderer" + "github.com/hyperledger/fabric-sdk-go/pkg/util/test" "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" @@ -1075,17 +1077,9 @@ func getNetworkConfigWithoutOrderer(t *testing.T) fab.EndpointConfig { return config } -func TestUpdateChannelConfigSuccess(t *testing.T) { - ctx := setupTestContext("test", "Org1MSP") +func TestCalculateConfigUpdate(t *testing.T) { - // Create mock orderer with simple mock block - orderer := fcmocks.NewMockOrderer("", nil) - //defer orderer.CloseQueue() - - setupCustomOrderer(ctx, orderer) - cc := setupResMgmtClient(t, ctx) - - // Test valid Save Channel request using config block (success) + // Get the original configuration originalConfiglBlockBytes, err := ioutil.ReadFile(filepath.Join("testdata", "config.block")) assert.Nil(t, err, "opening config.block file failed") originalConfigBlock := &common.Block{} @@ -1093,22 +1087,6 @@ func TestUpdateChannelConfigSuccess(t *testing.T) { originalConfig, err := resource.ExtractConfigFromBlock(originalConfigBlock) assert.Nil(t, err, "extractConfigFromBlock failed") - orderer.EnqueueForSendDeliver( - // The first call to orderer returns the very last block - // For testing, we can put here any valid block. - originalConfigBlock, - common.Status_SUCCESS, - ) - orderer.EnqueueForSendDeliver( - // The next call returns the last configuration block, - // which is the input to config update tx calculation - originalConfigBlock, - common.Status_SUCCESS, - ) - resp, err := cc.UpdateChannelConfig(UpdateChannelConfigRequest{ChannelID: "mychannel", ChannelConfig: originalConfig}, WithOrderer(orderer)) - assert.NotNil(t, err, "Should have failed for unchanged configuration") - assert.Contains(t, err.Error(), "no differences detected between original and updated config") - // Prepare new configuration modifiedConfigBytes, err := proto.Marshal(originalConfig) assert.Nil(t, err, "error marshalling originalConfig") @@ -1118,19 +1096,18 @@ func TestUpdateChannelConfigSuccess(t *testing.T) { assert.Nil(t, err, "error modifying config") assert.Nil(t, test.VerifyMaxMessageCount(modifiedConfig, newMaxMessageCount), "error verifying modified config") - orderer.EnqueueForSendDeliver( - originalConfigBlock, - common.Status_SUCCESS, - ) - orderer.EnqueueForSendDeliver( - originalConfigBlock, - common.Status_SUCCESS, - ) - resp, err = cc.UpdateChannelConfig(UpdateChannelConfigRequest{ChannelID: "mychannel", ChannelConfig: modifiedConfig}, WithOrderer(orderer)) - assert.Nil(t, err, "error should be nil") - assert.NotEmpty(t, resp.TransactionID, "transaction ID should be populated") + channelID := "mychannel" + + configUpdate, err := CalculateConfigUpdate(channelID, originalConfig, modifiedConfig) + assert.NoError(t, err, "calculating config update failed") + assert.NotNil(t, configUpdate, "calculated config update is nil") + assert.Equal(t, channelID, configUpdate.ChannelId, "channel ID mismatch") + + updatedBatchSizeBytes := configUpdate.WriteSet.Groups["Orderer"].Values["BatchSize"].Value + batchSize := &orderer.BatchSize{} + assert.Nil(t, proto.Unmarshal(updatedBatchSizeBytes, batchSize), "unmarshalling BatchSize failed") + assert.Equal(t, newMaxMessageCount, batchSize.MaxMessageCount, "MaxMessageCount mismatch") - orderer.CloseQueue() } func TestSaveChannelSuccess(t *testing.T) { diff --git a/pkg/util/test/util.go b/pkg/util/test/util.go index 869138f7b8..83879351cd 100644 --- a/pkg/util/test/util.go +++ b/pkg/util/test/util.go @@ -9,11 +9,58 @@ package test import ( "fmt" + "github.com/hyperledger/fabric-protos-go/peer" + + "github.com/pkg/errors" + + "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/protoutil" + "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric-protos-go/common" "github.com/hyperledger/fabric-protos-go/orderer" ) +// AddACL adds an ACL config value to channel config +func AddACL(config *common.Config, policyName, policy string) error { + + aclsConfigValue, ok := config.ChannelGroup.Groups["Application"].Values["ACLs"] + if !ok { + return errors.New("ACL missing from Application config") + } + acls := &peer.ACLs{} + err := proto.Unmarshal(aclsConfigValue.Value, acls) + if err != nil { + return err + } + acls.Acls[policyName] = &peer.APIResource{PolicyRef: policy} + aclsConfigValue.Value = protoutil.MarshalOrPanic(acls) + + return nil +} + +// VerifyACL verifies an ACL config value +func VerifyACL(config *common.Config, expectedPolicyName, expectedPolicy string) error { + + aclsConfigValue, ok := config.ChannelGroup.Groups["Application"].Values["ACLs"] + if !ok { + return errors.New("ACL missing from Application config") + } + acls := &peer.ACLs{} + err := proto.Unmarshal(aclsConfigValue.Value, acls) + if err != nil { + return err + } + resource, ok := acls.Acls[expectedPolicyName] + if !ok { + return errors.Errorf("missing expected policy name: %s", expectedPolicyName) + } + if resource.PolicyRef != expectedPolicy { + return errors.Errorf("unexpected policy ref: %s, expected: %s", resource.PolicyRef, expectedPolicy) + } + + return nil +} + // ModifyMaxMessageCount increments the orderer's BatchSize.MaxMessageCount in a channel config func ModifyMaxMessageCount(config *common.Config) (uint32, error) { diff --git a/test/integration/e2e/orgs/multi_orgs_ch_update_signatures_test.go b/test/integration/e2e/orgs/multi_orgs_ch_update_signatures_test.go index 884ff56136..d2598bb73a 100644 --- a/test/integration/e2e/orgs/multi_orgs_ch_update_signatures_test.go +++ b/test/integration/e2e/orgs/multi_orgs_ch_update_signatures_test.go @@ -18,6 +18,15 @@ import ( "path/filepath" "strings" "testing" + "time" + + "github.com/golang/protobuf/proto" + + "github.com/hyperledger/fabric-sdk-go/pkg/util/protolator" + + "github.com/hyperledger/fabric-sdk-go/pkg/util/test" + + "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource" "github.com/hyperledger/fabric-protos-go/common" "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/bccsp/utils" @@ -67,7 +76,7 @@ type chCfgSignatures struct { // DistributedSignaturesTests will create at least 2 clients, each from 2 different orgs and creates two channel where these 2 orgs are members // one channel created by using the conventional SDK signatures (exported into a file and loaded to simulate external signature loading) // the second one is created by using OpenSSL to sign the channel Config data. -func DistributedSignaturesTests(t *testing.T, examplecc string) { +func DistributedSignaturesTests(t *testing.T, exampleCC string) { ordererClCtx := createDSClientCtx(t, ordererOrgName) defer ordererClCtx.sdk.Close() @@ -85,6 +94,182 @@ func DistributedSignaturesTests(t *testing.T, examplecc string) { e2eCreateAndQueryChannel(t, ordererClCtx, org1ClCtx, org2ClCtx, dsChannelExternal, exampleCC) } + // modify channel config, must be endorsed by two orgs + e2eModifyChannel(t, ordererClCtx, org1ClCtx, org2ClCtx, dsChannelSDK) +} + +var resourceCounter = 0 + +func e2eModifyChannel(t *testing.T, ordererClCtx *dsClientCtx, org1ClCtx *dsClientCtx, org2ClCtx *dsClientCtx, channelID string) { + + // retrieve channel config + channelConfig, err := getCurrentChannelConfig(t, ordererClCtx, channelID) + if err != nil { + t.Fatalf("getCurrentChannelConfig returned error: %s", err) + } + + // channel config is modified by adding a new application policy. + // This change must be signed by the majority of org admins. + // The modified config becomes the proposed channel config. + resourceCounter = resourceCounter + 1 + newACLPolicyName := fmt.Sprintf("my/new/resource/%d", resourceCounter) + newACLPolicy := "/Channel/Application/Admins" + err = test.AddACL(channelConfig, newACLPolicyName, newACLPolicy) + if err != nil { + t.Fatalf("error modifying channel configuration: %s", err) + } + + // proposed config is distributed to other orgs as JSON string for signing + var buf bytes.Buffer + if err := protolator.DeepMarshalJSON(&buf, channelConfig); err != nil { + t.Fatalf("DeepMarshalJSON returned error: %s", err) + } + proposedChannelConfigJSON := buf.String() + //t.Log("------ proposed config ------\n") + //t.Log(proposedChannelConfigJSON) + + // orderer calculates and signs config update tx + signedConfigOrderer, err := signConfigUpdate(t, ordererClCtx, channelID, proposedChannelConfigJSON) + if err != nil { + t.Fatalf("error getting signed configuration: %s", err) + } + + // org1 calculates and signs config update tx + signedConfigOrg1, err := signConfigUpdate(t, org1ClCtx, channelID, proposedChannelConfigJSON) + if err != nil { + t.Fatalf("error getting signed configuration: %s", err) + } + + // org2 calculates and signs config update tx + signedConfigOrg2, err := signConfigUpdate(t, org2ClCtx, channelID, proposedChannelConfigJSON) + if err != nil { + t.Fatalf("error getting signed configuration: %s", err) + } + + // build config update envelope for constructing channel update request + configUpdate, err := getConfigUpdate(t, org1ClCtx, channelID, proposedChannelConfigJSON) + if err != nil { + t.Fatalf("getConfigUpdate returned error: %s", err) + } + configUpdate.ChannelId = channelID + configEnvelopeBytes, err := getConfigEnvelopeBytes(t, configUpdate) + if err != nil { + t.Fatalf("error marshaling channel configuration: %s", err) + } + + // Verify that orderer org cannot sign the change + configReader := bytes.NewReader(configEnvelopeBytes) + req := resmgmt.SaveChannelRequest{ChannelID: channelID, ChannelConfig: configReader} + txID, err := ordererClCtx.rsCl.SaveChannel(req, resmgmt.WithConfigSignatures(signedConfigOrderer), resmgmt.WithOrdererEndpoint("orderer.example.com")) + require.Errorf(t, err, "SaveChannel should fail when signed by orderer org") + + // Vefiry that org1 alone cannot sign the change + configReader = bytes.NewReader(configEnvelopeBytes) + req = resmgmt.SaveChannelRequest{ChannelID: channelID, ChannelConfig: configReader} + txID, err = org1ClCtx.rsCl.SaveChannel(req, resmgmt.WithConfigSignatures(signedConfigOrg1), resmgmt.WithOrdererEndpoint("orderer.example.com")) + require.Errorf(t, err, "SaveChannel should fail when signed by org1 only") + + // Vefiry that org2 alone cannot sign the change + configReader = bytes.NewReader(configEnvelopeBytes) + req = resmgmt.SaveChannelRequest{ChannelID: channelID, ChannelConfig: configReader} + txID, err = org2ClCtx.rsCl.SaveChannel(req, resmgmt.WithConfigSignatures(signedConfigOrg2), resmgmt.WithOrdererEndpoint("orderer.example.com")) + require.Errorf(t, err, "SaveChannel should fail when signed by org2 only") + + // Sign by both orgs and submit tx by the orderer org + configReader = bytes.NewReader(configEnvelopeBytes) + req = resmgmt.SaveChannelRequest{ChannelID: channelID, ChannelConfig: configReader} + txID, err = ordererClCtx.rsCl.SaveChannel(req, resmgmt.WithConfigSignatures(signedConfigOrg1, signedConfigOrg2), resmgmt.WithOrdererEndpoint("orderer.example.com")) + require.NoError(t, err, "error saving channel %s", channelID) + require.NotEmpty(t, txID, "transaction ID should be populated for SaveChannel %s", channelID) + + time.Sleep(time.Second * 3) + + // verify updated channel config + updatedChannelConfig, err := getCurrentChannelConfig(t, ordererClCtx, channelID) + if err != nil { + t.Fatalf("get updated channel config returned error: %s", err) + } + assert.Nilf(t, test.VerifyACL(updatedChannelConfig, newACLPolicyName, newACLPolicy), "VerifyACL failed") +} + +func getConfigEnvelopeBytes(t *testing.T, configUpdate *common.ConfigUpdate) ([]byte, error) { + + var buf bytes.Buffer + if err := protolator.DeepMarshalJSON(&buf, configUpdate); err != nil { + return nil, err + } + + channelConfigBytes, err := proto.Marshal(configUpdate) + if err != nil { + return nil, err + } + configUpdateEnvelope := &common.ConfigUpdateEnvelope{ + ConfigUpdate: channelConfigBytes, + Signatures: nil, + } + configUpdateEnvelopeBytes, err := proto.Marshal(configUpdateEnvelope) + if err != nil { + return nil, err + } + payload := &common.Payload{ + Data: configUpdateEnvelopeBytes, + } + payloadBytes, err := proto.Marshal(payload) + if err != nil { + return nil, err + } + configEnvelope := &common.Envelope{ + Payload: payloadBytes, + } + + return proto.Marshal(configEnvelope) +} + +func getCurrentChannelConfig(t *testing.T, ctx *dsClientCtx, channelID string) (*common.Config, error) { + block, err := ctx.rsCl.QueryConfigBlockFromOrderer(channelID, resmgmt.WithOrdererEndpoint("orderer.example.com")) + if err != nil { + return nil, err + } + return resource.ExtractConfigFromBlock(block) +} + +func getConfigUpdate(t *testing.T, ctx *dsClientCtx, channelID string, proposedConfigJSON string) (*common.ConfigUpdate, error) { + + proposedConfig := &common.Config{} + err := protolator.DeepUnmarshalJSON(bytes.NewReader([]byte(proposedConfigJSON)), proposedConfig) + if err != nil { + return nil, err + } + channelConfig, err := getCurrentChannelConfig(t, ctx, channelID) + if err != nil { + return nil, err + } + configUpdate, err := resmgmt.CalculateConfigUpdate(channelID, channelConfig, proposedConfig) + if err != nil { + return nil, err + } + configUpdate.ChannelId = channelID + + return configUpdate, nil +} + +func signConfigUpdate(t *testing.T, ctx *dsClientCtx, channelID string, proposedConfigJSON string) (*common.ConfigSignature, error) { + configUpdate, err := getConfigUpdate(t, ctx, channelID, proposedConfigJSON) + if err != nil { + t.Fatalf("getConfigUpdate returned error: %s", err) + } + configUpdate.ChannelId = channelID + + configUpdateBytes, err := proto.Marshal(configUpdate) + if err != nil { + t.Fatalf("ConfigUpdate marshal returned error: %s", err) + } + + org1Client, err := ctx.clCtx() + if err != nil { + t.Fatalf("Client provider returned error: %s", err) + } + return resource.CreateConfigSignature(org1Client, configUpdateBytes) } func e2eCreateAndQueryChannel(t *testing.T, ordererClCtx, org1ClCtx, org2ClCtx *dsClientCtx, channelID, examplecc string) { diff --git a/test/integration/pkg/client/resmgmt/main_test.go b/test/integration/pkg/client/resmgmt/main_test.go index bad49656c7..145afbec11 100644 --- a/test/integration/pkg/client/resmgmt/main_test.go +++ b/test/integration/pkg/client/resmgmt/main_test.go @@ -15,13 +15,11 @@ import ( ) const ( - ordererOrgName = "OrdererOrg" - org1Name = "Org1" - org2Name = "Org2" - ordererOrgAdminUser = "Admin" - org1AdminUser = "Admin" - org2AdminUser = "Admin" - orgChannelID = "orgchannel" + org1Name = "Org1" + org2Name = "Org2" + org1AdminUser = "Admin" + org2AdminUser = "Admin" + orgChannelID = "orgchannel" ) var mainSDK *fabsdk.FabricSDK diff --git a/test/integration/pkg/client/resmgmt/resmgmt_queries_test.go b/test/integration/pkg/client/resmgmt/resmgmt_queries_test.go index 2c2e269dcc..91adbd0977 100644 --- a/test/integration/pkg/client/resmgmt/resmgmt_queries_test.go +++ b/test/integration/pkg/client/resmgmt/resmgmt_queries_test.go @@ -8,13 +8,6 @@ package resmgmt import ( "testing" - "time" - - "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource" - - "github.com/stretchr/testify/assert" - - "github.com/hyperledger/fabric-sdk-go/pkg/util/test" "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" @@ -48,13 +41,6 @@ func TestResMgmtClientQueries(t *testing.T) { testQueryChannels(t, testSetup.ChannelID, target, client) - ordererAdminClientContext := sdk.Context(fabsdk.WithUser(ordererOrgAdminUser), fabsdk.WithOrg(ordererOrgName)) - ordererAdminClient, err := resmgmt.New(ordererAdminClientContext) - if err != nil { - t.Fatalf("Failed to create new resource management client: %s", err) - } - - testUpdateChannelConfig(t, testSetup.ChannelID, ordererAdminClient) } func testInstantiatedChaincodes(t *testing.T, channelID string, ccID string, target string, client *resmgmt.Client) { @@ -147,35 +133,6 @@ func testQueryConfigFromOrderer(t *testing.T, channelID string, client *resmgmt. } -func testUpdateChannelConfig(t *testing.T, channelID string, client *resmgmt.Client) { - block, err := client.QueryConfigBlockFromOrderer(channelID, resmgmt.WithOrdererEndpoint("orderer.example.com")) - if err != nil { - t.Fatalf("QueryConfigBlockFromOrderer returned error: %s", err) - } - channelConfig, err := resource.ExtractConfigFromBlock(block) - assert.Nil(t, err, "extractConfigFromBlock failed") - - newMaxMessageCount, err := test.ModifyMaxMessageCount(channelConfig) - if err != nil { - t.Fatalf("error modifying channel configuration: %s", err) - } - _, err = client.UpdateChannelConfig(resmgmt.UpdateChannelConfigRequest{ChannelID: "mychannel", ChannelConfig: channelConfig}, resmgmt.WithOrdererEndpoint("orderer.example.com")) - if err != nil { - t.Fatalf("error saving channel: %s", err) - } - time.Sleep(time.Second * 10) - nextConfigBlock, err := client.QueryConfigBlockFromOrderer(channelID, resmgmt.WithOrdererEndpoint("orderer.example.com")) - if err != nil { - t.Fatalf("QueryConfigBlockFromOrderer returned error: %s", err) - } - nextChannelConfig, err := resource.ExtractConfigFromBlock(nextConfigBlock) - assert.Nil(t, err, "extractConfigFromBlock failed") - err = test.VerifyMaxMessageCount(nextChannelConfig, newMaxMessageCount) - if err != nil { - t.Fatalf("VerifyMaxMessageCount returned error: %s", err) - } -} - func contains(list []string, value string) bool { for _, e := range list { if e == value {