Skip to content

Commit

Permalink
[FAB-10610] Include prior version capabilities
Browse files Browse the repository at this point in the history
When calling HasCapability() on a particular version (e.g. V1_1)
then true should be returned if the application has a newer
version capability (e.g. v1_2, v1_3, etc.).

Change-Id: I2778925d1e33c698fb563b8d589a4a92d8e8a147
Signed-off-by: Bob Stasyszyn <Bob.Stasyszyn@securekey.com>
  • Loading branch information
bstasyszyn committed Jun 12, 2018
1 parent 0bb0a3f commit 74c04ea
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
19 changes: 16 additions & 3 deletions pkg/fab/chconfig/chconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package chconfig
import (
reqContext "context"
"math/rand"
"regexp"

"github.com/golang/protobuf/proto"

Expand All @@ -32,6 +33,7 @@ var logger = logging.NewLogger("fabsdk/fab")

//overrideRetryHandler is private and used for unit-tests to test query retry behaviors
var overrideRetryHandler retry.Handler
var versionCapabilityPattern = regexp.MustCompile(`^V(\d+)_(\d+)$`)

const (
defaultMinResponses = 1
Expand Down Expand Up @@ -118,9 +120,16 @@ func (cfg *ChannelCfg) HasCapability(group fab.ConfigGroupKey, capability string
if groupCapabilities[capability] {
return true
}
if capability == fab.V1_1Capability {
// If V1_2 capability is supported then V1_1 is also supported
return groupCapabilities[fab.V1_2Capability]

// Special handling for version capabilities: V1_1 is supported if V1_2 or V1_3
// are supported; V1_2 is supported if V1_3 is supported, etc.
if isVersionCapability(capability) {
for c := range groupCapabilities {
if isVersionCapability(c) && c > capability {
logger.Debugf("[%s] is greater than [%s] and therefore capability is supported", c, capability)
return true
}
}
}
return false
}
Expand Down Expand Up @@ -640,3 +649,7 @@ func randomMaxTargets(targets []fab.ProposalProcessor, max int) []fab.ProposalPr
}
return targets[:max]
}

func isVersionCapability(capability string) bool {
return versionCapabilityPattern.MatchString(capability)
}
29 changes: 17 additions & 12 deletions pkg/fab/chconfig/chconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,11 @@ func TestResolveOptsDefaultValuesWithInvalidChannel(t *testing.T) {
}

func TestCapabilities(t *testing.T) {
capability1 := fab.V1_1Capability
capability2 := fab.V1_2Capability
capability3 := "V1_1_PVTDATA_EXPERIMENTAL"
capability4 := "V1_1_RESOURCETREE_EXPERIMENTAL"
capability1 := "V1_1_PVTDATA_EXPERIMENTAL"
capability2 := "V1_1_RESOURCETREE_EXPERIMENTAL"
v1_12Capability := "V1_12"
v2_0Capability := "V2_0"
v2_1Capability := "V2_1"

builder := &mocks.MockConfigBlockBuilder{
MockConfigGroupBuilder: mocks.MockConfigGroupBuilder{
Expand All @@ -249,9 +250,9 @@ func TestCapabilities(t *testing.T) {
},
OrdererAddress: "localhost:9999",
RootCA: validRootCA,
ChannelCapabilities: []string{capability1},
OrdererCapabilities: []string{capability1},
ApplicationCapabilities: []string{capability2, capability3},
ChannelCapabilities: []string{fab.V1_1Capability},
OrdererCapabilities: []string{fab.V1_1Capability, v2_0Capability},
ApplicationCapabilities: []string{fab.V1_2Capability, capability1},
},
Index: 0,
LastConfigIndex: 0,
Expand All @@ -260,11 +261,15 @@ func TestCapabilities(t *testing.T) {
chConfig, err := extractConfig("mychannel", builder.Build())
require.NoError(t, err)

assert.Truef(t, chConfig.HasCapability(fab.ChannelGroupKey, capability1), "expecting channel capability [%s]", capability1)
assert.Truef(t, chConfig.HasCapability(fab.OrdererGroupKey, capability1), "expecting orderer capability [%s]", capability1)
assert.Truef(t, chConfig.HasCapability(fab.ApplicationGroupKey, capability2), "expecting application capability [%s]", capability2)
assert.Truef(t, chConfig.HasCapability(fab.ApplicationGroupKey, capability3), "expecting application capability [%s]", capability3)
assert.Falsef(t, chConfig.HasCapability(fab.ApplicationGroupKey, capability4), "not expecting application capability [%s]", capability4)
assert.Truef(t, chConfig.HasCapability(fab.ChannelGroupKey, fab.V1_1Capability), "expecting channel capability [%s]", fab.V1_1Capability)
assert.Truef(t, chConfig.HasCapability(fab.OrdererGroupKey, fab.V1_1Capability), "expecting orderer capability [%s]", fab.V1_1Capability)
assert.Truef(t, chConfig.HasCapability(fab.OrdererGroupKey, v1_12Capability), "expecting orderer capability [%s] since [%s] is supported", v1_12Capability, v2_0Capability)
assert.Truef(t, chConfig.HasCapability(fab.OrdererGroupKey, v2_0Capability), "expecting orderer capability [%s]", v2_0Capability)
assert.Falsef(t, chConfig.HasCapability(fab.OrdererGroupKey, v2_1Capability), "not expecting orderer capability", v2_1Capability)
assert.Truef(t, chConfig.HasCapability(fab.ApplicationGroupKey, fab.V1_2Capability), "expecting application capability [%s]", fab.V1_2Capability)
assert.Truef(t, chConfig.HasCapability(fab.ApplicationGroupKey, fab.V1_1Capability), "expecting application capability [%s] since [%s] is supported", fab.V1_1Capability, fab.V1_2Capability)
assert.Truef(t, chConfig.HasCapability(fab.ApplicationGroupKey, capability1), "expecting application capability [%s]", capability1)
assert.Falsef(t, chConfig.HasCapability(fab.ApplicationGroupKey, capability2), "not expecting application capability [%s]", capability2)
}

func testResolveOptsDefaultValues(t *testing.T, channelID string) {
Expand Down

0 comments on commit 74c04ea

Please sign in to comment.