Skip to content

Commit 0417461

Browse files
authored
Enable multiple policies type (#129)
#### Type of change - New feature #### Description This commit updates the proto messages to define policy using various rules such as threshold, signature, and hierarchical. Further, it integrates the signature rules with the verifier component. #### Related issues <!--- Include a link to any associated Github issue --> --------- Signed-off-by: Senthil Nathan N <cendhu@gmail.com> Signed-off-by: senthil <cendhu@gmail.com>
1 parent 173570e commit 0417461

44 files changed

Lines changed: 1332 additions & 414 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/protoblocktx/block_tx.pb.go

Lines changed: 553 additions & 173 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/protoblocktx/block_tx.proto

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ option go_package = "github.com/hyperledger/fabric-x-committer/api/protoblocktx"
1010

1111
package protoblocktx;
1212

13-
// Represents a transaction in the blockchain.
1413
message Tx {
15-
repeated TxNamespace namespaces = 1; // Namespaces associated with the transaction.
16-
repeated bytes signatures = 2; // Signature per namespace.
14+
// A list of namespaces that define the transaction's scope.
15+
repeated TxNamespace namespaces = 1;
16+
17+
// A list of endorsements.
18+
// IMPORTANT: This list MUST be the same size as the namespaces list.
19+
// The Endorsement at index i corresponds to the namespace at index i.
20+
repeated Endorsements endorsements = 2;
1721
}
1822

1923
// Represents a namespace within a transaction.
@@ -44,9 +48,45 @@ message Write {
4448
bytes value = 2; // The value associated with the key being written.
4549
}
4650

51+
// Endorsements holds all the signatures that correspond to a single namespace
52+
// in the transaction's namespaces list.
53+
message Endorsements {
54+
// The list of individual signatures for the corresponding namespace.
55+
repeated EndorsementWithIdentity endorsements_with_identity = 1;
56+
}
57+
58+
// EndorsementWithIdentity bundles a single signature with the identity of its creator.
59+
message EndorsementWithIdentity {
60+
// The actual cryptographic signature bytes.
61+
bytes endorsement = 1;
62+
63+
// The identity of the creator who produced the signature, i.e., the endorsement.
64+
Identity identity = 2;
65+
}
66+
67+
message Identity {
68+
// The identifier of the associated membership service provider
69+
string msp_id = 1;
70+
71+
oneof creator {
72+
// The full raw bytes of the creator's certificate (e.g., an X.509 certificate).
73+
bytes certificate = 2;
74+
75+
// An identifier for a certificate that is pre-stored or known by the committer.
76+
string certificate_id = 3;
77+
}
78+
}
79+
4780
// Represents a namespace policy.
4881
message NamespacePolicy {
49-
string scheme = 1; // The scheme for signature verification.
82+
oneof rule {
83+
ThresholdRule threshold_rule = 1;
84+
bytes msp_rule = 2;
85+
}
86+
}
87+
88+
message ThresholdRule {
89+
string scheme = 1; // The scheme for signature verification.
5090
bytes public_key = 2; // The public key for signature verification.
5191
}
5292

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ go 1.24.3
88

99
require (
1010
github.com/cenkalti/backoff/v4 v4.3.0
11-
github.com/cockroachdb/errors v1.11.3
12-
github.com/consensys/gnark-crypto v0.18.1
11+
github.com/cockroachdb/errors v1.12.0
12+
github.com/consensys/gnark-crypto v0.18.0
1313
github.com/docker/docker v28.0.0+incompatible
1414
github.com/docker/go-connections v0.5.0
1515
github.com/fsouza/go-dockerclient v1.12.0
@@ -19,7 +19,7 @@ require (
1919
github.com/google/uuid v1.6.0
2020
github.com/hyperledger/fabric-lib-go v1.1.3-0.20240523144151-25edd1eaf5f5
2121
github.com/hyperledger/fabric-protos-go-apiv2 v0.3.7
22-
github.com/hyperledger/fabric-x-common v0.0.0-20251023133631-047a3c32c228
22+
github.com/hyperledger/fabric-x-common v0.0.0-20251027142320-96a137a5adfb
2323
github.com/jackc/puddle v1.3.0
2424
github.com/mitchellh/mapstructure v1.5.0
2525
github.com/onsi/gomega v1.34.2

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -675,14 +675,14 @@ github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWH
675675
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
676676
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
677677
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
678-
github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I=
679-
github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8=
678+
github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo=
679+
github.com/cockroachdb/errors v1.12.0/go.mod h1:SvzfYNNBshAVbZ8wzNc/UPK3w1vf0dKDUP41ucAIf7g=
680680
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
681681
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
682682
github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
683683
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
684-
github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI=
685-
github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c=
684+
github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0=
685+
github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c=
686686
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
687687
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
688688
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -918,8 +918,8 @@ github.com/hyperledger/fabric-lib-go v1.1.3-0.20240523144151-25edd1eaf5f5 h1:RPW
918918
github.com/hyperledger/fabric-lib-go v1.1.3-0.20240523144151-25edd1eaf5f5/go.mod h1:SHNCq8AB0VpHAmvJEtdbzabv6NNV1F48JdmDihasBjc=
919919
github.com/hyperledger/fabric-protos-go-apiv2 v0.3.7 h1:sQ5qv8vQQfwewa1JlCiSCC8dLElmaU2/frLolpgibEY=
920920
github.com/hyperledger/fabric-protos-go-apiv2 v0.3.7/go.mod h1:bJnwzfv03oZQeCc863pdGTDgf5nmCy6Za3RAE7d2XsQ=
921-
github.com/hyperledger/fabric-x-common v0.0.0-20251023133631-047a3c32c228 h1:JdVLvE5ExlHvGL2LuaX3IQLo+7ZExsJhPkDutmNCJEU=
922-
github.com/hyperledger/fabric-x-common v0.0.0-20251023133631-047a3c32c228/go.mod h1:eztTd6MwzVOZtlWcOXWZepDBK/pQz3c3epu91BXAp6o=
921+
github.com/hyperledger/fabric-x-common v0.0.0-20251027142320-96a137a5adfb h1:oh/k9KIvG/GOuBC92LaEZoI6IlFM91inQ7quoAV8L6w=
922+
github.com/hyperledger/fabric-x-common v0.0.0-20251027142320-96a137a5adfb/go.mod h1:5C4Ab/S56VXzP9BpePfbKr3Clmi1t1soKMThJeGBSIQ=
923923
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
924924
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
925925
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=

integration/runner/runtime.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,9 @@ func (c *CommitterRuntime) MakeAndSendTransactionsToOrderer(
402402
Namespaces: namespaces,
403403
}
404404
if expectedStatus != nil && expectedStatus[i] == protoblocktx.Status_ABORTED_SIGNATURE_INVALID {
405-
tx.Signatures = make([][]byte, len(namespaces))
405+
tx.Endorsements = make([]*protoblocktx.Endorsements, len(namespaces))
406406
for nsIdx := range namespaces {
407-
tx.Signatures[nsIdx] = []byte("dummy")
407+
tx.Endorsements[nsIdx] = test.CreateEndorsementsForThresholdRule([]byte("dummy"))[0]
408408
}
409409
}
410410
txs[i] = c.TxBuilder.MakeTx(tx)

integration/test/config_update_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func TestConfigUpdate(t *testing.T) {
9191
ordererEnv.SubmitConfigBlock(t, &workload.ConfigBlock{
9292
ChannelID: c.SystemConfig.Policy.ChannelID,
9393
OrdererEndpoints: endpoints,
94-
MetaNamespaceVerificationKey: metaPolicy.PublicKey,
94+
MetaNamespaceVerificationKey: metaPolicy.GetThresholdRule().GetPublicKey(),
9595
})
9696
}
9797
submitConfigBlock(ordererEnv.AllRealOrdererEndpoints())

loadgen/adapters/sigverifier.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,15 @@ func createUpdate(policy *workload.PolicyProfile) (*protosigverifierservice.Upda
101101
if ns == types.MetaNamespaceID {
102102
continue
103103
}
104-
policyBytes, err := proto.Marshal(p.GetVerificationPolicy())
104+
policy, err := proto.Marshal(p.GetVerificationPolicy())
105105
if err != nil {
106106
return nil, errors.Wrap(err, "failed to serialize policy")
107107
}
108108
updateMsg.NamespacePolicies.Policies = append(
109109
updateMsg.NamespacePolicies.Policies,
110110
&protoblocktx.PolicyItem{
111111
Namespace: ns,
112-
Policy: policyBytes,
112+
Policy: policy,
113113
},
114114
)
115115
}

loadgen/workload/config_tx.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,12 @@ func CreateConfigBlock(policy *PolicyProfile) (*common.Block, error) {
9292
MetaNamespaceVerificationKey: policyNamespaceSigner.pubKey,
9393
OrdererEndpoints: policy.OrdererEndpoints,
9494
ChannelID: policy.ChannelID,
95-
})
95+
}, genesisconfig.TwoOrgsSampleFabricX)
9696
}
9797

9898
// CreateDefaultConfigBlock creates a config block with default values.
99-
func CreateDefaultConfigBlock(conf *ConfigBlock) (*common.Block, error) {
100-
configBlock := genesisconfig.Load(genesisconfig.SampleFabricX, configtest.GetDevConfigDir())
99+
func CreateDefaultConfigBlock(conf *ConfigBlock, profileName string) (*common.Block, error) {
100+
configBlock := genesisconfig.Load(profileName, configtest.GetDevConfigDir())
101101
tlsCertPath := filepath.Join(configtest.GetDevConfigDir(), "msp", "tlscacerts", "tlsroot.pem")
102102
for _, consenter := range configBlock.Orderer.ConsenterMapping {
103103
consenter.Identity = tlsCertPath

loadgen/workload/conflicts.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"math/rand"
1212

1313
"github.com/hyperledger/fabric-x-committer/api/protoblocktx"
14+
"github.com/hyperledger/fabric-x-committer/utils/test"
1415
)
1516

1617
// Dependency types.
@@ -61,9 +62,9 @@ func newSignTxModifier(rnd *rand.Rand, profile *Profile) *signTxModifier {
6162
func (g *signTxModifier) Modify(tx *protoblocktx.Tx) {
6263
if g.invalidSignGenerator.Next() {
6364
// Pre-assigning prevents TxBuilder from re-signing the TX.
64-
tx.Signatures = make([][]byte, len(tx.Namespaces))
65-
for i := range tx.Namespaces {
66-
tx.Signatures[i] = g.invalidSignature
65+
tx.Endorsements = make([]*protoblocktx.Endorsements, len(tx.Namespaces))
66+
for i := range len(tx.Namespaces) {
67+
tx.Endorsements[i] = test.CreateEndorsementsForThresholdRule(g.invalidSignature)[0]
6768
}
6869
}
6970
}

loadgen/workload/sign.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/hyperledger/fabric-x-committer/utils/logging"
1818
"github.com/hyperledger/fabric-x-committer/utils/signature"
1919
"github.com/hyperledger/fabric-x-committer/utils/signature/sigtest"
20+
"github.com/hyperledger/fabric-x-committer/utils/test"
2021
)
2122

2223
var logger = logging.New("load-gen-sign")
@@ -57,19 +58,19 @@ func NewTxSignerVerifier(policy *PolicyProfile) *TxSignerVerifier {
5758

5859
// Sign signs a TX.
5960
func (e *TxSignerVerifier) Sign(txID string, tx *protoblocktx.Tx) {
60-
tx.Signatures = make([][]byte, len(tx.Namespaces))
61+
tx.Endorsements = make([]*protoblocktx.Endorsements, len(tx.Namespaces))
6162
for nsIndex, ns := range tx.Namespaces {
6263
signer, ok := e.HashSigners[ns.NsId]
6364
if !ok {
6465
continue
6566
}
66-
tx.Signatures[nsIndex] = signer.Sign(txID, tx, nsIndex)
67+
tx.Endorsements[nsIndex] = test.CreateEndorsementsForThresholdRule(signer.Sign(txID, tx, nsIndex))[0]
6768
}
6869
}
6970

7071
// Verify verifies a signature on the transaction.
7172
func (e *TxSignerVerifier) Verify(txID string, tx *protoblocktx.Tx) bool {
72-
if len(tx.Signatures) < len(tx.Namespaces) {
73+
if len(tx.Endorsements) < len(tx.Namespaces) {
7374
return false
7475
}
7576

@@ -130,8 +131,11 @@ func (e *HashSignerVerifier) Verify(txID string, tx *protoblocktx.Tx, nsIndex in
130131
// GetVerificationPolicy returns the verification policy.
131132
func (e *HashSignerVerifier) GetVerificationPolicy() *protoblocktx.NamespacePolicy {
132133
return &protoblocktx.NamespacePolicy{
133-
Scheme: e.scheme,
134-
PublicKey: e.pubKey,
134+
Rule: &protoblocktx.NamespacePolicy_ThresholdRule{
135+
ThresholdRule: &protoblocktx.ThresholdRule{
136+
Scheme: e.scheme, PublicKey: e.pubKey,
137+
},
138+
},
135139
}
136140
}
137141

0 commit comments

Comments
 (0)