diff --git a/common/cauthdsl/cauthdsl_test.go b/common/cauthdsl/cauthdsl_test.go
index 8322274ab76..3ccd8ec11cd 100644
--- a/common/cauthdsl/cauthdsl_test.go
+++ b/common/cauthdsl/cauthdsl_test.go
@@ -67,7 +67,7 @@ func (id *mockIdentity) Serialize() ([]byte, error) {
 	return id.idBytes, nil
 }
 
-func toSignedData(idBytesSlice [][]byte, deserializer msp.IdentityDeserializer) ([]msp.Identity, []bool) {
+func toIdentities(idBytesSlice [][]byte, deserializer msp.IdentityDeserializer) ([]msp.Identity, []bool) {
 	identities := make([]msp.Identity, len(idBytesSlice))
 	for i, idBytes := range idBytesSlice {
 		id, _ := deserializer.DeserializeIdentity(idBytes)
@@ -105,10 +105,10 @@ func TestSimpleSignature(t *testing.T) {
 		t.Fatalf("Could not create a new SignaturePolicyEvaluator using the given policy, crypto-helper: %s", err)
 	}
 
-	if !spe(toSignedData([][]byte{signers[0]}, &mockDeserializer{})) {
+	if !spe(toIdentities([][]byte{signers[0]}, &mockDeserializer{})) {
 		t.Errorf("Expected authentication to succeed with valid signatures")
 	}
-	if spe(toSignedData([][]byte{signers[1]}, &mockDeserializer{})) {
+	if spe(toIdentities([][]byte{signers[1]}, &mockDeserializer{})) {
 		t.Errorf("Expected authentication to fail because signers[1] is not authorized in the policy, despite his valid signature")
 	}
 }
@@ -121,10 +121,10 @@ func TestMultipleSignature(t *testing.T) {
 		t.Fatalf("Could not create a new SignaturePolicyEvaluator using the given policy, crypto-helper: %s", err)
 	}
 
-	if !spe(toSignedData(signers, &mockDeserializer{})) {
+	if !spe(toIdentities(signers, &mockDeserializer{})) {
 		t.Errorf("Expected authentication to succeed with  valid signatures")
 	}
-	if spe(toSignedData([][]byte{signers[0], signers[0]}, &mockDeserializer{})) {
+	if spe(toIdentities([][]byte{signers[0], signers[0]}, &mockDeserializer{})) {
 		t.Errorf("Expected authentication to fail because although there were two valid signatures, one was duplicated")
 	}
 }
@@ -137,16 +137,16 @@ func TestComplexNestedSignature(t *testing.T) {
 		t.Fatalf("Could not create a new SignaturePolicyEvaluator using the given policy, crypto-helper: %s", err)
 	}
 
-	if !spe(toSignedData(append(signers, [][]byte{[]byte("signer0")}...), &mockDeserializer{})) {
+	if !spe(toIdentities(append(signers, [][]byte{[]byte("signer0")}...), &mockDeserializer{})) {
 		t.Errorf("Expected authentication to succeed with valid signatures")
 	}
-	if !spe(toSignedData([][]byte{[]byte("signer0"), []byte("signer0"), []byte("signer0")}, &mockDeserializer{})) {
+	if !spe(toIdentities([][]byte{[]byte("signer0"), []byte("signer0"), []byte("signer0")}, &mockDeserializer{})) {
 		t.Errorf("Expected authentication to succeed with valid signatures")
 	}
-	if spe(toSignedData(signers, &mockDeserializer{})) {
+	if spe(toIdentities(signers, &mockDeserializer{})) {
 		t.Errorf("Expected authentication to fail with too few signatures")
 	}
-	if spe(toSignedData(append(signers, [][]byte{[]byte("signer1")}...), &mockDeserializer{})) {
+	if spe(toIdentities(append(signers, [][]byte{[]byte("signer1")}...), &mockDeserializer{})) {
 		t.Errorf("Expected authentication failure as there was a signature from signer[0] missing")
 	}
 }
diff --git a/common/cauthdsl/policy.go b/common/cauthdsl/policy.go
index 6b45be9ac7f..3930c428c02 100644
--- a/common/cauthdsl/policy.go
+++ b/common/cauthdsl/policy.go
@@ -7,7 +7,6 @@ SPDX-License-Identifier: Apache-2.0
 package cauthdsl
 
 import (
-	"errors"
 	"fmt"
 
 	"github.com/golang/protobuf/proto"
@@ -15,6 +14,7 @@ import (
 	"github.com/hyperledger/fabric/common/policies"
 	"github.com/hyperledger/fabric/msp"
 	"github.com/hyperledger/fabric/protoutil"
+	"github.com/pkg/errors"
 )
 
 type provider struct {
@@ -86,7 +86,7 @@ type policy struct {
 // 2) the signing identities satisfy the policy
 func (p *policy) EvaluateSignedData(signatureSet []*protoutil.SignedData) error {
 	if p == nil {
-		return fmt.Errorf("No such policy")
+		return errors.New("no such policy")
 	}
 
 	ids := policies.SignatureSetToValidIdentities(signatureSet, p.deserializer)
diff --git a/common/cauthdsl/policy_test.go b/common/cauthdsl/policy_test.go
index 8e047b58cac..50ef3838ede 100644
--- a/common/cauthdsl/policy_test.go
+++ b/common/cauthdsl/policy_test.go
@@ -116,7 +116,7 @@ func TestNewPolicyErrorCase(t *testing.T) {
 
 	var pol4 *policy
 	err4 := pol4.EvaluateSignedData([]*protoutil.SignedData{})
-	assert.EqualError(t, err4, "No such policy")
+	assert.EqualError(t, err4, "no such policy")
 }
 
 func TestEnvelopeBasedPolicyProvider(t *testing.T) {
diff --git a/common/policies/implicitmeta.go b/common/policies/implicitmeta.go
index fa98a69d03a..d00a7aad6df 100644
--- a/common/policies/implicitmeta.go
+++ b/common/policies/implicitmeta.go
@@ -109,21 +109,24 @@ func (imp *ImplicitMetaPolicy) EvaluateIdentities(identities []msp.Identity) err
 	remaining := imp.Threshold
 
 	defer func() {
-		if remaining != 0 {
-			// This log message may be large and expensive to construct, so worth checking the log level
-			if logger.IsEnabledFor(zapcore.DebugLevel) {
-				var b bytes.Buffer
-				b.WriteString(fmt.Sprintf("Evaluation Failed: Only %d policies were satisfied, but needed %d of [ ", imp.Threshold-remaining, imp.Threshold))
-				for m := range imp.managers {
-					b.WriteString(m)
-					b.WriteString("/")
-					b.WriteString(imp.SubPolicyName)
-					b.WriteString(" ")
-				}
-				b.WriteString("]")
-				logger.Debugf(b.String())
-			}
+		// This log message may be large and expensive to construct, so worth checking the log level
+		if remaining == 0 {
+			return
+		}
+		if !logger.IsEnabledFor(zapcore.DebugLevel) {
+			return
+		}
+
+		var b bytes.Buffer
+		b.WriteString(fmt.Sprintf("Evaluation Failed: Only %d policies were satisfied, but needed %d of [ ", imp.Threshold-remaining, imp.Threshold))
+		for m := range imp.managers {
+			b.WriteString(m)
+			b.WriteString("/")
+			b.WriteString(imp.SubPolicyName)
+			b.WriteString(" ")
 		}
+		b.WriteString("]")
+		logger.Debugf(b.String())
 	}()
 
 	for _, policy := range imp.SubPolicies {
diff --git a/common/policies/mocks/identity.go b/common/policies/mocks/identity.go
new file mode 100644
index 00000000000..fb80b020655
--- /dev/null
+++ b/common/policies/mocks/identity.go
@@ -0,0 +1,648 @@
+// Code generated by counterfeiter. DO NOT EDIT.
+package mocks
+
+import (
+	"sync"
+	"time"
+
+	mspa "github.com/hyperledger/fabric-protos-go/msp"
+	"github.com/hyperledger/fabric/msp"
+)
+
+type Identity struct {
+	AnonymousStub        func() bool
+	anonymousMutex       sync.RWMutex
+	anonymousArgsForCall []struct {
+	}
+	anonymousReturns struct {
+		result1 bool
+	}
+	anonymousReturnsOnCall map[int]struct {
+		result1 bool
+	}
+	ExpiresAtStub        func() time.Time
+	expiresAtMutex       sync.RWMutex
+	expiresAtArgsForCall []struct {
+	}
+	expiresAtReturns struct {
+		result1 time.Time
+	}
+	expiresAtReturnsOnCall map[int]struct {
+		result1 time.Time
+	}
+	GetIdentifierStub        func() *msp.IdentityIdentifier
+	getIdentifierMutex       sync.RWMutex
+	getIdentifierArgsForCall []struct {
+	}
+	getIdentifierReturns struct {
+		result1 *msp.IdentityIdentifier
+	}
+	getIdentifierReturnsOnCall map[int]struct {
+		result1 *msp.IdentityIdentifier
+	}
+	GetMSPIdentifierStub        func() string
+	getMSPIdentifierMutex       sync.RWMutex
+	getMSPIdentifierArgsForCall []struct {
+	}
+	getMSPIdentifierReturns struct {
+		result1 string
+	}
+	getMSPIdentifierReturnsOnCall map[int]struct {
+		result1 string
+	}
+	GetOrganizationalUnitsStub        func() []*msp.OUIdentifier
+	getOrganizationalUnitsMutex       sync.RWMutex
+	getOrganizationalUnitsArgsForCall []struct {
+	}
+	getOrganizationalUnitsReturns struct {
+		result1 []*msp.OUIdentifier
+	}
+	getOrganizationalUnitsReturnsOnCall map[int]struct {
+		result1 []*msp.OUIdentifier
+	}
+	SatisfiesPrincipalStub        func(*mspa.MSPPrincipal) error
+	satisfiesPrincipalMutex       sync.RWMutex
+	satisfiesPrincipalArgsForCall []struct {
+		arg1 *mspa.MSPPrincipal
+	}
+	satisfiesPrincipalReturns struct {
+		result1 error
+	}
+	satisfiesPrincipalReturnsOnCall map[int]struct {
+		result1 error
+	}
+	SerializeStub        func() ([]byte, error)
+	serializeMutex       sync.RWMutex
+	serializeArgsForCall []struct {
+	}
+	serializeReturns struct {
+		result1 []byte
+		result2 error
+	}
+	serializeReturnsOnCall map[int]struct {
+		result1 []byte
+		result2 error
+	}
+	ValidateStub        func() error
+	validateMutex       sync.RWMutex
+	validateArgsForCall []struct {
+	}
+	validateReturns struct {
+		result1 error
+	}
+	validateReturnsOnCall map[int]struct {
+		result1 error
+	}
+	VerifyStub        func([]byte, []byte) error
+	verifyMutex       sync.RWMutex
+	verifyArgsForCall []struct {
+		arg1 []byte
+		arg2 []byte
+	}
+	verifyReturns struct {
+		result1 error
+	}
+	verifyReturnsOnCall map[int]struct {
+		result1 error
+	}
+	invocations      map[string][][]interface{}
+	invocationsMutex sync.RWMutex
+}
+
+func (fake *Identity) Anonymous() bool {
+	fake.anonymousMutex.Lock()
+	ret, specificReturn := fake.anonymousReturnsOnCall[len(fake.anonymousArgsForCall)]
+	fake.anonymousArgsForCall = append(fake.anonymousArgsForCall, struct {
+	}{})
+	fake.recordInvocation("Anonymous", []interface{}{})
+	fake.anonymousMutex.Unlock()
+	if fake.AnonymousStub != nil {
+		return fake.AnonymousStub()
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.anonymousReturns
+	return fakeReturns.result1
+}
+
+func (fake *Identity) AnonymousCallCount() int {
+	fake.anonymousMutex.RLock()
+	defer fake.anonymousMutex.RUnlock()
+	return len(fake.anonymousArgsForCall)
+}
+
+func (fake *Identity) AnonymousCalls(stub func() bool) {
+	fake.anonymousMutex.Lock()
+	defer fake.anonymousMutex.Unlock()
+	fake.AnonymousStub = stub
+}
+
+func (fake *Identity) AnonymousReturns(result1 bool) {
+	fake.anonymousMutex.Lock()
+	defer fake.anonymousMutex.Unlock()
+	fake.AnonymousStub = nil
+	fake.anonymousReturns = struct {
+		result1 bool
+	}{result1}
+}
+
+func (fake *Identity) AnonymousReturnsOnCall(i int, result1 bool) {
+	fake.anonymousMutex.Lock()
+	defer fake.anonymousMutex.Unlock()
+	fake.AnonymousStub = nil
+	if fake.anonymousReturnsOnCall == nil {
+		fake.anonymousReturnsOnCall = make(map[int]struct {
+			result1 bool
+		})
+	}
+	fake.anonymousReturnsOnCall[i] = struct {
+		result1 bool
+	}{result1}
+}
+
+func (fake *Identity) ExpiresAt() time.Time {
+	fake.expiresAtMutex.Lock()
+	ret, specificReturn := fake.expiresAtReturnsOnCall[len(fake.expiresAtArgsForCall)]
+	fake.expiresAtArgsForCall = append(fake.expiresAtArgsForCall, struct {
+	}{})
+	fake.recordInvocation("ExpiresAt", []interface{}{})
+	fake.expiresAtMutex.Unlock()
+	if fake.ExpiresAtStub != nil {
+		return fake.ExpiresAtStub()
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.expiresAtReturns
+	return fakeReturns.result1
+}
+
+func (fake *Identity) ExpiresAtCallCount() int {
+	fake.expiresAtMutex.RLock()
+	defer fake.expiresAtMutex.RUnlock()
+	return len(fake.expiresAtArgsForCall)
+}
+
+func (fake *Identity) ExpiresAtCalls(stub func() time.Time) {
+	fake.expiresAtMutex.Lock()
+	defer fake.expiresAtMutex.Unlock()
+	fake.ExpiresAtStub = stub
+}
+
+func (fake *Identity) ExpiresAtReturns(result1 time.Time) {
+	fake.expiresAtMutex.Lock()
+	defer fake.expiresAtMutex.Unlock()
+	fake.ExpiresAtStub = nil
+	fake.expiresAtReturns = struct {
+		result1 time.Time
+	}{result1}
+}
+
+func (fake *Identity) ExpiresAtReturnsOnCall(i int, result1 time.Time) {
+	fake.expiresAtMutex.Lock()
+	defer fake.expiresAtMutex.Unlock()
+	fake.ExpiresAtStub = nil
+	if fake.expiresAtReturnsOnCall == nil {
+		fake.expiresAtReturnsOnCall = make(map[int]struct {
+			result1 time.Time
+		})
+	}
+	fake.expiresAtReturnsOnCall[i] = struct {
+		result1 time.Time
+	}{result1}
+}
+
+func (fake *Identity) GetIdentifier() *msp.IdentityIdentifier {
+	fake.getIdentifierMutex.Lock()
+	ret, specificReturn := fake.getIdentifierReturnsOnCall[len(fake.getIdentifierArgsForCall)]
+	fake.getIdentifierArgsForCall = append(fake.getIdentifierArgsForCall, struct {
+	}{})
+	fake.recordInvocation("GetIdentifier", []interface{}{})
+	fake.getIdentifierMutex.Unlock()
+	if fake.GetIdentifierStub != nil {
+		return fake.GetIdentifierStub()
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.getIdentifierReturns
+	return fakeReturns.result1
+}
+
+func (fake *Identity) GetIdentifierCallCount() int {
+	fake.getIdentifierMutex.RLock()
+	defer fake.getIdentifierMutex.RUnlock()
+	return len(fake.getIdentifierArgsForCall)
+}
+
+func (fake *Identity) GetIdentifierCalls(stub func() *msp.IdentityIdentifier) {
+	fake.getIdentifierMutex.Lock()
+	defer fake.getIdentifierMutex.Unlock()
+	fake.GetIdentifierStub = stub
+}
+
+func (fake *Identity) GetIdentifierReturns(result1 *msp.IdentityIdentifier) {
+	fake.getIdentifierMutex.Lock()
+	defer fake.getIdentifierMutex.Unlock()
+	fake.GetIdentifierStub = nil
+	fake.getIdentifierReturns = struct {
+		result1 *msp.IdentityIdentifier
+	}{result1}
+}
+
+func (fake *Identity) GetIdentifierReturnsOnCall(i int, result1 *msp.IdentityIdentifier) {
+	fake.getIdentifierMutex.Lock()
+	defer fake.getIdentifierMutex.Unlock()
+	fake.GetIdentifierStub = nil
+	if fake.getIdentifierReturnsOnCall == nil {
+		fake.getIdentifierReturnsOnCall = make(map[int]struct {
+			result1 *msp.IdentityIdentifier
+		})
+	}
+	fake.getIdentifierReturnsOnCall[i] = struct {
+		result1 *msp.IdentityIdentifier
+	}{result1}
+}
+
+func (fake *Identity) GetMSPIdentifier() string {
+	fake.getMSPIdentifierMutex.Lock()
+	ret, specificReturn := fake.getMSPIdentifierReturnsOnCall[len(fake.getMSPIdentifierArgsForCall)]
+	fake.getMSPIdentifierArgsForCall = append(fake.getMSPIdentifierArgsForCall, struct {
+	}{})
+	fake.recordInvocation("GetMSPIdentifier", []interface{}{})
+	fake.getMSPIdentifierMutex.Unlock()
+	if fake.GetMSPIdentifierStub != nil {
+		return fake.GetMSPIdentifierStub()
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.getMSPIdentifierReturns
+	return fakeReturns.result1
+}
+
+func (fake *Identity) GetMSPIdentifierCallCount() int {
+	fake.getMSPIdentifierMutex.RLock()
+	defer fake.getMSPIdentifierMutex.RUnlock()
+	return len(fake.getMSPIdentifierArgsForCall)
+}
+
+func (fake *Identity) GetMSPIdentifierCalls(stub func() string) {
+	fake.getMSPIdentifierMutex.Lock()
+	defer fake.getMSPIdentifierMutex.Unlock()
+	fake.GetMSPIdentifierStub = stub
+}
+
+func (fake *Identity) GetMSPIdentifierReturns(result1 string) {
+	fake.getMSPIdentifierMutex.Lock()
+	defer fake.getMSPIdentifierMutex.Unlock()
+	fake.GetMSPIdentifierStub = nil
+	fake.getMSPIdentifierReturns = struct {
+		result1 string
+	}{result1}
+}
+
+func (fake *Identity) GetMSPIdentifierReturnsOnCall(i int, result1 string) {
+	fake.getMSPIdentifierMutex.Lock()
+	defer fake.getMSPIdentifierMutex.Unlock()
+	fake.GetMSPIdentifierStub = nil
+	if fake.getMSPIdentifierReturnsOnCall == nil {
+		fake.getMSPIdentifierReturnsOnCall = make(map[int]struct {
+			result1 string
+		})
+	}
+	fake.getMSPIdentifierReturnsOnCall[i] = struct {
+		result1 string
+	}{result1}
+}
+
+func (fake *Identity) GetOrganizationalUnits() []*msp.OUIdentifier {
+	fake.getOrganizationalUnitsMutex.Lock()
+	ret, specificReturn := fake.getOrganizationalUnitsReturnsOnCall[len(fake.getOrganizationalUnitsArgsForCall)]
+	fake.getOrganizationalUnitsArgsForCall = append(fake.getOrganizationalUnitsArgsForCall, struct {
+	}{})
+	fake.recordInvocation("GetOrganizationalUnits", []interface{}{})
+	fake.getOrganizationalUnitsMutex.Unlock()
+	if fake.GetOrganizationalUnitsStub != nil {
+		return fake.GetOrganizationalUnitsStub()
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.getOrganizationalUnitsReturns
+	return fakeReturns.result1
+}
+
+func (fake *Identity) GetOrganizationalUnitsCallCount() int {
+	fake.getOrganizationalUnitsMutex.RLock()
+	defer fake.getOrganizationalUnitsMutex.RUnlock()
+	return len(fake.getOrganizationalUnitsArgsForCall)
+}
+
+func (fake *Identity) GetOrganizationalUnitsCalls(stub func() []*msp.OUIdentifier) {
+	fake.getOrganizationalUnitsMutex.Lock()
+	defer fake.getOrganizationalUnitsMutex.Unlock()
+	fake.GetOrganizationalUnitsStub = stub
+}
+
+func (fake *Identity) GetOrganizationalUnitsReturns(result1 []*msp.OUIdentifier) {
+	fake.getOrganizationalUnitsMutex.Lock()
+	defer fake.getOrganizationalUnitsMutex.Unlock()
+	fake.GetOrganizationalUnitsStub = nil
+	fake.getOrganizationalUnitsReturns = struct {
+		result1 []*msp.OUIdentifier
+	}{result1}
+}
+
+func (fake *Identity) GetOrganizationalUnitsReturnsOnCall(i int, result1 []*msp.OUIdentifier) {
+	fake.getOrganizationalUnitsMutex.Lock()
+	defer fake.getOrganizationalUnitsMutex.Unlock()
+	fake.GetOrganizationalUnitsStub = nil
+	if fake.getOrganizationalUnitsReturnsOnCall == nil {
+		fake.getOrganizationalUnitsReturnsOnCall = make(map[int]struct {
+			result1 []*msp.OUIdentifier
+		})
+	}
+	fake.getOrganizationalUnitsReturnsOnCall[i] = struct {
+		result1 []*msp.OUIdentifier
+	}{result1}
+}
+
+func (fake *Identity) SatisfiesPrincipal(arg1 *mspa.MSPPrincipal) error {
+	fake.satisfiesPrincipalMutex.Lock()
+	ret, specificReturn := fake.satisfiesPrincipalReturnsOnCall[len(fake.satisfiesPrincipalArgsForCall)]
+	fake.satisfiesPrincipalArgsForCall = append(fake.satisfiesPrincipalArgsForCall, struct {
+		arg1 *mspa.MSPPrincipal
+	}{arg1})
+	fake.recordInvocation("SatisfiesPrincipal", []interface{}{arg1})
+	fake.satisfiesPrincipalMutex.Unlock()
+	if fake.SatisfiesPrincipalStub != nil {
+		return fake.SatisfiesPrincipalStub(arg1)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.satisfiesPrincipalReturns
+	return fakeReturns.result1
+}
+
+func (fake *Identity) SatisfiesPrincipalCallCount() int {
+	fake.satisfiesPrincipalMutex.RLock()
+	defer fake.satisfiesPrincipalMutex.RUnlock()
+	return len(fake.satisfiesPrincipalArgsForCall)
+}
+
+func (fake *Identity) SatisfiesPrincipalCalls(stub func(*mspa.MSPPrincipal) error) {
+	fake.satisfiesPrincipalMutex.Lock()
+	defer fake.satisfiesPrincipalMutex.Unlock()
+	fake.SatisfiesPrincipalStub = stub
+}
+
+func (fake *Identity) SatisfiesPrincipalArgsForCall(i int) *mspa.MSPPrincipal {
+	fake.satisfiesPrincipalMutex.RLock()
+	defer fake.satisfiesPrincipalMutex.RUnlock()
+	argsForCall := fake.satisfiesPrincipalArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *Identity) SatisfiesPrincipalReturns(result1 error) {
+	fake.satisfiesPrincipalMutex.Lock()
+	defer fake.satisfiesPrincipalMutex.Unlock()
+	fake.SatisfiesPrincipalStub = nil
+	fake.satisfiesPrincipalReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *Identity) SatisfiesPrincipalReturnsOnCall(i int, result1 error) {
+	fake.satisfiesPrincipalMutex.Lock()
+	defer fake.satisfiesPrincipalMutex.Unlock()
+	fake.SatisfiesPrincipalStub = nil
+	if fake.satisfiesPrincipalReturnsOnCall == nil {
+		fake.satisfiesPrincipalReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.satisfiesPrincipalReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *Identity) Serialize() ([]byte, error) {
+	fake.serializeMutex.Lock()
+	ret, specificReturn := fake.serializeReturnsOnCall[len(fake.serializeArgsForCall)]
+	fake.serializeArgsForCall = append(fake.serializeArgsForCall, struct {
+	}{})
+	fake.recordInvocation("Serialize", []interface{}{})
+	fake.serializeMutex.Unlock()
+	if fake.SerializeStub != nil {
+		return fake.SerializeStub()
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	fakeReturns := fake.serializeReturns
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *Identity) SerializeCallCount() int {
+	fake.serializeMutex.RLock()
+	defer fake.serializeMutex.RUnlock()
+	return len(fake.serializeArgsForCall)
+}
+
+func (fake *Identity) SerializeCalls(stub func() ([]byte, error)) {
+	fake.serializeMutex.Lock()
+	defer fake.serializeMutex.Unlock()
+	fake.SerializeStub = stub
+}
+
+func (fake *Identity) SerializeReturns(result1 []byte, result2 error) {
+	fake.serializeMutex.Lock()
+	defer fake.serializeMutex.Unlock()
+	fake.SerializeStub = nil
+	fake.serializeReturns = struct {
+		result1 []byte
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *Identity) SerializeReturnsOnCall(i int, result1 []byte, result2 error) {
+	fake.serializeMutex.Lock()
+	defer fake.serializeMutex.Unlock()
+	fake.SerializeStub = nil
+	if fake.serializeReturnsOnCall == nil {
+		fake.serializeReturnsOnCall = make(map[int]struct {
+			result1 []byte
+			result2 error
+		})
+	}
+	fake.serializeReturnsOnCall[i] = struct {
+		result1 []byte
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *Identity) Validate() error {
+	fake.validateMutex.Lock()
+	ret, specificReturn := fake.validateReturnsOnCall[len(fake.validateArgsForCall)]
+	fake.validateArgsForCall = append(fake.validateArgsForCall, struct {
+	}{})
+	fake.recordInvocation("Validate", []interface{}{})
+	fake.validateMutex.Unlock()
+	if fake.ValidateStub != nil {
+		return fake.ValidateStub()
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.validateReturns
+	return fakeReturns.result1
+}
+
+func (fake *Identity) ValidateCallCount() int {
+	fake.validateMutex.RLock()
+	defer fake.validateMutex.RUnlock()
+	return len(fake.validateArgsForCall)
+}
+
+func (fake *Identity) ValidateCalls(stub func() error) {
+	fake.validateMutex.Lock()
+	defer fake.validateMutex.Unlock()
+	fake.ValidateStub = stub
+}
+
+func (fake *Identity) ValidateReturns(result1 error) {
+	fake.validateMutex.Lock()
+	defer fake.validateMutex.Unlock()
+	fake.ValidateStub = nil
+	fake.validateReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *Identity) ValidateReturnsOnCall(i int, result1 error) {
+	fake.validateMutex.Lock()
+	defer fake.validateMutex.Unlock()
+	fake.ValidateStub = nil
+	if fake.validateReturnsOnCall == nil {
+		fake.validateReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.validateReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *Identity) Verify(arg1 []byte, arg2 []byte) error {
+	var arg1Copy []byte
+	if arg1 != nil {
+		arg1Copy = make([]byte, len(arg1))
+		copy(arg1Copy, arg1)
+	}
+	var arg2Copy []byte
+	if arg2 != nil {
+		arg2Copy = make([]byte, len(arg2))
+		copy(arg2Copy, arg2)
+	}
+	fake.verifyMutex.Lock()
+	ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)]
+	fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct {
+		arg1 []byte
+		arg2 []byte
+	}{arg1Copy, arg2Copy})
+	fake.recordInvocation("Verify", []interface{}{arg1Copy, arg2Copy})
+	fake.verifyMutex.Unlock()
+	if fake.VerifyStub != nil {
+		return fake.VerifyStub(arg1, arg2)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.verifyReturns
+	return fakeReturns.result1
+}
+
+func (fake *Identity) VerifyCallCount() int {
+	fake.verifyMutex.RLock()
+	defer fake.verifyMutex.RUnlock()
+	return len(fake.verifyArgsForCall)
+}
+
+func (fake *Identity) VerifyCalls(stub func([]byte, []byte) error) {
+	fake.verifyMutex.Lock()
+	defer fake.verifyMutex.Unlock()
+	fake.VerifyStub = stub
+}
+
+func (fake *Identity) VerifyArgsForCall(i int) ([]byte, []byte) {
+	fake.verifyMutex.RLock()
+	defer fake.verifyMutex.RUnlock()
+	argsForCall := fake.verifyArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2
+}
+
+func (fake *Identity) VerifyReturns(result1 error) {
+	fake.verifyMutex.Lock()
+	defer fake.verifyMutex.Unlock()
+	fake.VerifyStub = nil
+	fake.verifyReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *Identity) VerifyReturnsOnCall(i int, result1 error) {
+	fake.verifyMutex.Lock()
+	defer fake.verifyMutex.Unlock()
+	fake.VerifyStub = nil
+	if fake.verifyReturnsOnCall == nil {
+		fake.verifyReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.verifyReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *Identity) Invocations() map[string][][]interface{} {
+	fake.invocationsMutex.RLock()
+	defer fake.invocationsMutex.RUnlock()
+	fake.anonymousMutex.RLock()
+	defer fake.anonymousMutex.RUnlock()
+	fake.expiresAtMutex.RLock()
+	defer fake.expiresAtMutex.RUnlock()
+	fake.getIdentifierMutex.RLock()
+	defer fake.getIdentifierMutex.RUnlock()
+	fake.getMSPIdentifierMutex.RLock()
+	defer fake.getMSPIdentifierMutex.RUnlock()
+	fake.getOrganizationalUnitsMutex.RLock()
+	defer fake.getOrganizationalUnitsMutex.RUnlock()
+	fake.satisfiesPrincipalMutex.RLock()
+	defer fake.satisfiesPrincipalMutex.RUnlock()
+	fake.serializeMutex.RLock()
+	defer fake.serializeMutex.RUnlock()
+	fake.validateMutex.RLock()
+	defer fake.validateMutex.RUnlock()
+	fake.verifyMutex.RLock()
+	defer fake.verifyMutex.RUnlock()
+	copiedInvocations := map[string][][]interface{}{}
+	for key, value := range fake.invocations {
+		copiedInvocations[key] = value
+	}
+	return copiedInvocations
+}
+
+func (fake *Identity) recordInvocation(key string, args []interface{}) {
+	fake.invocationsMutex.Lock()
+	defer fake.invocationsMutex.Unlock()
+	if fake.invocations == nil {
+		fake.invocations = map[string][][]interface{}{}
+	}
+	if fake.invocations[key] == nil {
+		fake.invocations[key] = [][]interface{}{}
+	}
+	fake.invocations[key] = append(fake.invocations[key], args)
+}
diff --git a/common/policies/mocks/identity_deserializer.go b/common/policies/mocks/identity_deserializer.go
new file mode 100644
index 00000000000..ed003251e5e
--- /dev/null
+++ b/common/policies/mocks/identity_deserializer.go
@@ -0,0 +1,192 @@
+// Code generated by counterfeiter. DO NOT EDIT.
+package mocks
+
+import (
+	"sync"
+
+	mspa "github.com/hyperledger/fabric-protos-go/msp"
+	"github.com/hyperledger/fabric/msp"
+)
+
+type IdentityDeserializer struct {
+	DeserializeIdentityStub        func([]byte) (msp.Identity, error)
+	deserializeIdentityMutex       sync.RWMutex
+	deserializeIdentityArgsForCall []struct {
+		arg1 []byte
+	}
+	deserializeIdentityReturns struct {
+		result1 msp.Identity
+		result2 error
+	}
+	deserializeIdentityReturnsOnCall map[int]struct {
+		result1 msp.Identity
+		result2 error
+	}
+	IsWellFormedStub        func(*mspa.SerializedIdentity) error
+	isWellFormedMutex       sync.RWMutex
+	isWellFormedArgsForCall []struct {
+		arg1 *mspa.SerializedIdentity
+	}
+	isWellFormedReturns struct {
+		result1 error
+	}
+	isWellFormedReturnsOnCall map[int]struct {
+		result1 error
+	}
+	invocations      map[string][][]interface{}
+	invocationsMutex sync.RWMutex
+}
+
+func (fake *IdentityDeserializer) DeserializeIdentity(arg1 []byte) (msp.Identity, error) {
+	var arg1Copy []byte
+	if arg1 != nil {
+		arg1Copy = make([]byte, len(arg1))
+		copy(arg1Copy, arg1)
+	}
+	fake.deserializeIdentityMutex.Lock()
+	ret, specificReturn := fake.deserializeIdentityReturnsOnCall[len(fake.deserializeIdentityArgsForCall)]
+	fake.deserializeIdentityArgsForCall = append(fake.deserializeIdentityArgsForCall, struct {
+		arg1 []byte
+	}{arg1Copy})
+	fake.recordInvocation("DeserializeIdentity", []interface{}{arg1Copy})
+	fake.deserializeIdentityMutex.Unlock()
+	if fake.DeserializeIdentityStub != nil {
+		return fake.DeserializeIdentityStub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	fakeReturns := fake.deserializeIdentityReturns
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *IdentityDeserializer) DeserializeIdentityCallCount() int {
+	fake.deserializeIdentityMutex.RLock()
+	defer fake.deserializeIdentityMutex.RUnlock()
+	return len(fake.deserializeIdentityArgsForCall)
+}
+
+func (fake *IdentityDeserializer) DeserializeIdentityCalls(stub func([]byte) (msp.Identity, error)) {
+	fake.deserializeIdentityMutex.Lock()
+	defer fake.deserializeIdentityMutex.Unlock()
+	fake.DeserializeIdentityStub = stub
+}
+
+func (fake *IdentityDeserializer) DeserializeIdentityArgsForCall(i int) []byte {
+	fake.deserializeIdentityMutex.RLock()
+	defer fake.deserializeIdentityMutex.RUnlock()
+	argsForCall := fake.deserializeIdentityArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *IdentityDeserializer) DeserializeIdentityReturns(result1 msp.Identity, result2 error) {
+	fake.deserializeIdentityMutex.Lock()
+	defer fake.deserializeIdentityMutex.Unlock()
+	fake.DeserializeIdentityStub = nil
+	fake.deserializeIdentityReturns = struct {
+		result1 msp.Identity
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *IdentityDeserializer) DeserializeIdentityReturnsOnCall(i int, result1 msp.Identity, result2 error) {
+	fake.deserializeIdentityMutex.Lock()
+	defer fake.deserializeIdentityMutex.Unlock()
+	fake.DeserializeIdentityStub = nil
+	if fake.deserializeIdentityReturnsOnCall == nil {
+		fake.deserializeIdentityReturnsOnCall = make(map[int]struct {
+			result1 msp.Identity
+			result2 error
+		})
+	}
+	fake.deserializeIdentityReturnsOnCall[i] = struct {
+		result1 msp.Identity
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *IdentityDeserializer) IsWellFormed(arg1 *mspa.SerializedIdentity) error {
+	fake.isWellFormedMutex.Lock()
+	ret, specificReturn := fake.isWellFormedReturnsOnCall[len(fake.isWellFormedArgsForCall)]
+	fake.isWellFormedArgsForCall = append(fake.isWellFormedArgsForCall, struct {
+		arg1 *mspa.SerializedIdentity
+	}{arg1})
+	fake.recordInvocation("IsWellFormed", []interface{}{arg1})
+	fake.isWellFormedMutex.Unlock()
+	if fake.IsWellFormedStub != nil {
+		return fake.IsWellFormedStub(arg1)
+	}
+	if specificReturn {
+		return ret.result1
+	}
+	fakeReturns := fake.isWellFormedReturns
+	return fakeReturns.result1
+}
+
+func (fake *IdentityDeserializer) IsWellFormedCallCount() int {
+	fake.isWellFormedMutex.RLock()
+	defer fake.isWellFormedMutex.RUnlock()
+	return len(fake.isWellFormedArgsForCall)
+}
+
+func (fake *IdentityDeserializer) IsWellFormedCalls(stub func(*mspa.SerializedIdentity) error) {
+	fake.isWellFormedMutex.Lock()
+	defer fake.isWellFormedMutex.Unlock()
+	fake.IsWellFormedStub = stub
+}
+
+func (fake *IdentityDeserializer) IsWellFormedArgsForCall(i int) *mspa.SerializedIdentity {
+	fake.isWellFormedMutex.RLock()
+	defer fake.isWellFormedMutex.RUnlock()
+	argsForCall := fake.isWellFormedArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *IdentityDeserializer) IsWellFormedReturns(result1 error) {
+	fake.isWellFormedMutex.Lock()
+	defer fake.isWellFormedMutex.Unlock()
+	fake.IsWellFormedStub = nil
+	fake.isWellFormedReturns = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *IdentityDeserializer) IsWellFormedReturnsOnCall(i int, result1 error) {
+	fake.isWellFormedMutex.Lock()
+	defer fake.isWellFormedMutex.Unlock()
+	fake.IsWellFormedStub = nil
+	if fake.isWellFormedReturnsOnCall == nil {
+		fake.isWellFormedReturnsOnCall = make(map[int]struct {
+			result1 error
+		})
+	}
+	fake.isWellFormedReturnsOnCall[i] = struct {
+		result1 error
+	}{result1}
+}
+
+func (fake *IdentityDeserializer) Invocations() map[string][][]interface{} {
+	fake.invocationsMutex.RLock()
+	defer fake.invocationsMutex.RUnlock()
+	fake.deserializeIdentityMutex.RLock()
+	defer fake.deserializeIdentityMutex.RUnlock()
+	fake.isWellFormedMutex.RLock()
+	defer fake.isWellFormedMutex.RUnlock()
+	copiedInvocations := map[string][][]interface{}{}
+	for key, value := range fake.invocations {
+		copiedInvocations[key] = value
+	}
+	return copiedInvocations
+}
+
+func (fake *IdentityDeserializer) recordInvocation(key string, args []interface{}) {
+	fake.invocationsMutex.Lock()
+	defer fake.invocationsMutex.Unlock()
+	if fake.invocations == nil {
+		fake.invocations = map[string][][]interface{}{}
+	}
+	if fake.invocations[key] == nil {
+		fake.invocations[key] = [][]interface{}{}
+	}
+	fake.invocations[key] = append(fake.invocations[key], args)
+}
diff --git a/common/policies/policy.go b/common/policies/policy.go
index 69a25ed9803..20048c82458 100644
--- a/common/policies/policy.go
+++ b/common/policies/policy.go
@@ -359,9 +359,9 @@ func (pm *ManagerImpl) GetPolicy(id string) (Policy, bool) {
 
 // SignatureSetToValidIdentities takes a slice of pointers to signed data,
 // checks the validity of the signature and of the signer and returns a
-// slice of associated identities
+// slice of associated identities. The returned identities are deduplicated.
 func SignatureSetToValidIdentities(signedData []*protoutil.SignedData, identityDeserializer mspi.IdentityDeserializer) []mspi.Identity {
-	idMap := make(map[string]struct{})
+	idMap := map[string]struct{}{}
 	identities := make([]mspi.Identity, 0, len(signedData))
 
 	for i, sd := range signedData {
@@ -376,13 +376,13 @@ func SignatureSetToValidIdentities(signedData []*protoutil.SignedData, identityD
 		// We check if this identity has already appeared before doing a signature check, to ensure that
 		// someone cannot force us to waste time checking the same signature thousands of times
 		if _, ok := idMap[key]; ok {
-			logger.Warningf("De-duplicating identity [%+v] at index %d in signature set", key, i)
+			logger.Warningf("De-duplicating identity [%s] at index %d in signature set", key, i)
 			continue
 		}
 
 		err = identity.Verify(sd.Data, sd.Signature)
 		if err != nil {
-			logger.Warningf("%p signature for identity %d is invalid: %s", signedData, i, err)
+			logger.Warningf("signature for identity %d is invalid: %s", i, err)
 			continue
 		}
 		logger.Debugf("signature for identity %d validated", i)
diff --git a/common/policies/policy_test.go b/common/policies/policy_test.go
index a77d05c06ee..8cf074b85de 100644
--- a/common/policies/policy_test.go
+++ b/common/policies/policy_test.go
@@ -11,17 +11,27 @@ import (
 	"reflect"
 	"strconv"
 	"testing"
-	"time"
 
 	"github.com/golang/protobuf/proto"
 	cb "github.com/hyperledger/fabric-protos-go/common"
 	"github.com/hyperledger/fabric-protos-go/msp"
+	"github.com/hyperledger/fabric/common/policies/mocks"
 	mspi "github.com/hyperledger/fabric/msp"
 	"github.com/hyperledger/fabric/protoutil"
 	"github.com/pkg/errors"
 	"github.com/stretchr/testify/assert"
 )
 
+//go:generate counterfeiter -o mocks/identity_deserializer.go --fake-name IdentityDeserializer . identityDeserializer
+type identityDeserializer interface {
+	mspi.IdentityDeserializer
+}
+
+//go:generate counterfeiter -o mocks/identity.go --fake-name Identity . identity
+type identity interface {
+	mspi.Identity
+}
+
 type mockProvider struct{}
 
 func (mpp mockProvider) NewPolicy(data []byte) (Policy, proto.Message, error) {
@@ -239,62 +249,6 @@ func TestPrincipalSetContainingOnly(t *testing.T) {
 	assert.True(t, principalSets[0].ContainingOnly(between20And30))
 }
 
-type fakeID struct {
-	id     *mspi.IdentityIdentifier
-	mspid  string
-	valid  error
-	verify error
-}
-
-func (f *fakeID) ExpiresAt() time.Time {
-	return time.Time{}
-}
-
-func (f *fakeID) GetIdentifier() *mspi.IdentityIdentifier {
-	return f.id
-}
-
-func (f *fakeID) GetMSPIdentifier() string {
-	return f.mspid
-}
-
-func (f *fakeID) Validate() error {
-	return f.valid
-}
-
-func (f *fakeID) GetOrganizationalUnits() []*mspi.OUIdentifier {
-	return nil
-}
-
-func (f *fakeID) Anonymous() bool {
-	return false
-}
-
-func (f *fakeID) Verify(msg []byte, sig []byte) error {
-	return f.verify
-}
-
-func (f *fakeID) Serialize() ([]byte, error) {
-	return nil, nil
-}
-
-func (f *fakeID) SatisfiesPrincipal(principal *msp.MSPPrincipal) error {
-	return nil
-}
-
-type fakeIdDs struct {
-	DeserializeIdentityRv  mspi.Identity
-	DeserializeIdentityErr error
-}
-
-func (f *fakeIdDs) DeserializeIdentity(serializedIdentity []byte) (mspi.Identity, error) {
-	return f.DeserializeIdentityRv, f.DeserializeIdentityErr
-}
-
-func (f *fakeIdDs) IsWellFormed(identity *msp.SerializedIdentity) error {
-	return nil
-}
-
 func TestSignatureSetToValidIdentities(t *testing.T) {
 	sd := []*protoutil.SignedData{
 		{
@@ -309,19 +263,25 @@ func TestSignatureSetToValidIdentities(t *testing.T) {
 		},
 	}
 
-	fIDDs := &fakeIdDs{}
-	fIDDs.DeserializeIdentityRv = &fakeID{
-		id: &mspi.IdentityIdentifier{
-			Id:    "id",
-			Mspid: "mspid",
-		},
-	}
+	fIDDs := &mocks.IdentityDeserializer{}
+	fID := &mocks.Identity{}
+	fID.VerifyReturns(nil)
+	fID.GetIdentifierReturns(&mspi.IdentityIdentifier{
+		Id:    "id",
+		Mspid: "mspid",
+	})
+	fIDDs.DeserializeIdentityReturns(fID, nil)
 
 	ids := SignatureSetToValidIdentities(sd, fIDDs)
 	assert.Len(t, ids, 1)
 	assert.NotNil(t, ids[0].GetIdentifier())
 	assert.Equal(t, "id", ids[0].GetIdentifier().Id)
 	assert.Equal(t, "mspid", ids[0].GetIdentifier().Mspid)
+	data, sig := fID.VerifyArgsForCall(0)
+	assert.Equal(t, []byte("data1"), data)
+	assert.Equal(t, []byte("signature1"), sig)
+	sidBytes := fIDDs.DeserializeIdentityArgsForCall(0)
+	assert.Equal(t, []byte("identity1"), sidBytes)
 }
 
 func TestSignatureSetToValidIdentitiesDeserialiseErr(t *testing.T) {
@@ -333,11 +293,13 @@ func TestSignatureSetToValidIdentitiesDeserialiseErr(t *testing.T) {
 		},
 	}
 
-	fIDDs := &fakeIdDs{}
-	fIDDs.DeserializeIdentityErr = errors.New("bad identity")
+	fIDDs := &mocks.IdentityDeserializer{}
+	fIDDs.DeserializeIdentityReturns(nil, errors.New("bad identity"))
 
 	ids := SignatureSetToValidIdentities(sd, fIDDs)
 	assert.Len(t, ids, 0)
+	sidBytes := fIDDs.DeserializeIdentityArgsForCall(0)
+	assert.Equal(t, []byte("identity1"), sidBytes)
 }
 
 func TestSignatureSetToValidIdentitiesVerifyErr(t *testing.T) {
@@ -349,16 +311,20 @@ func TestSignatureSetToValidIdentitiesVerifyErr(t *testing.T) {
 		},
 	}
 
-	fIDDs := &fakeIdDs{}
-	fID := &fakeID{
-		id: &mspi.IdentityIdentifier{
-			Id:    "id",
-			Mspid: "mspid",
-		},
-	}
-	fID.verify = errors.New("bad signature")
-	fIDDs.DeserializeIdentityRv = fID
+	fIDDs := &mocks.IdentityDeserializer{}
+	fID := &mocks.Identity{}
+	fID.VerifyReturns(errors.New("bad signature"))
+	fID.GetIdentifierReturns(&mspi.IdentityIdentifier{
+		Id:    "id",
+		Mspid: "mspid",
+	})
+	fIDDs.DeserializeIdentityReturns(fID, nil)
 
 	ids := SignatureSetToValidIdentities(sd, fIDDs)
 	assert.Len(t, ids, 0)
+	data, sig := fID.VerifyArgsForCall(0)
+	assert.Equal(t, []byte("data1"), data)
+	assert.Equal(t, []byte("signature1"), sig)
+	sidBytes := fIDDs.DeserializeIdentityArgsForCall(0)
+	assert.Equal(t, []byte("identity1"), sidBytes)
 }