Skip to content

Commit c357994

Browse files
committed
Enable multiple policies type
This commit updates the proto messages to define policy using various rules such as threshold, signature, and hierarchical. Signed-off-by: Senthil Nathan N <[email protected]>
1 parent da4efa0 commit c357994

35 files changed

+1250
-333
lines changed

api/protoblocktx/block_tx.pb.go

Lines changed: 583 additions & 180 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: 54 additions & 5 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,54 @@ 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+
PolicyType type = 1; // The type of policy used.
83+
bytes policy = 2; // The policy rule.
84+
}
85+
86+
enum PolicyType {
87+
// A policy for verifying a single signature that was generated via a Threshold Signature
88+
// Scheme (TSS). In a TSS, a threshold (T) of N parties must cooperate to
89+
// collectively compute and produce the single signature.
90+
THRESHOLD_RULE = 0;
91+
92+
// A policy defined by an explicit rule that evaluates one or more required signatures.
93+
// For example: "OR('Org1MSP.admin', 'Org2MSP.admin')"
94+
SIGNATURE_RULE = 1;
95+
}
96+
97+
message ThresholdRule {
98+
string scheme = 1; // The scheme for signature verification.
5099
bytes public_key = 2; // The public key for signature verification.
51100
}
52101

@@ -78,7 +127,7 @@ message NamespacePolicies {
78127

79128
message PolicyItem {
80129
string namespace = 1;
81-
bytes policy = 2;
130+
bytes policy = 2; // This holds the complete NamespacePolicy.
82131
uint64 version = 3;
83132
}
84133

go.mod

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

99
require (
1010
github.com/cenkalti/backoff/v4 v4.3.0
11-
github.com/cockroachdb/errors v1.11.3
11+
github.com/cockroachdb/errors v1.12.0
1212
github.com/consensys/gnark-crypto v0.14.0
1313
github.com/docker/docker v28.0.0+incompatible
1414
github.com/docker/go-connections v0.5.0
@@ -20,7 +20,7 @@ require (
2020
github.com/hyperledger/fabric v1.4.0-rc1.0.20240918034325-94590aa4332b
2121
github.com/hyperledger/fabric-lib-go v1.1.3-0.20240523144151-25edd1eaf5f5
2222
github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3
23-
github.com/hyperledger/fabric-x-common v0.0.0-20250701155113-a1ddf93333d8
23+
github.com/hyperledger/fabric-x-common v0.0.0-20250916061807-0d5dacc2a10f
2424
github.com/jackc/puddle v1.3.0
2525
github.com/mitchellh/mapstructure v1.5.0
2626
github.com/onsi/gomega v1.34.2
@@ -79,6 +79,7 @@ require (
7979
github.com/gogo/protobuf v1.3.2 // indirect
8080
github.com/golang/snappy v0.0.4 // indirect
8181
github.com/google/go-cmp v0.6.0 // indirect
82+
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect
8283
github.com/hyperledger-labs/SmartBFT v0.0.0-20240916013553-852e5be5889b // indirect
8384
github.com/hyperledger/aries-bbs-go v0.0.0-20240528084656-761671ea73bc // indirect
8485
github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 // indirect
@@ -113,6 +114,7 @@ require (
113114
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
114115
github.com/nxadm/tail v1.4.11 // indirect
115116
github.com/onsi/ginkgo v1.16.5 // indirect
117+
github.com/onsi/ginkgo/v2 v2.20.2 // indirect
116118
github.com/opencontainers/go-digest v1.0.0 // indirect
117119
github.com/opencontainers/image-spec v1.1.0 // indirect
118120
github.com/pelletier/go-toml/v2 v2.2.3 // indirect

go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -673,8 +673,8 @@ github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWH
673673
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
674674
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
675675
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
676-
github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I=
677-
github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8=
676+
github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo=
677+
github.com/cockroachdb/errors v1.12.0/go.mod h1:SvzfYNNBshAVbZ8wzNc/UPK3w1vf0dKDUP41ucAIf7g=
678678
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
679679
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
680680
github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
@@ -921,8 +921,10 @@ github.com/hyperledger/fabric-lib-go v1.1.3-0.20240523144151-25edd1eaf5f5 h1:RPW
921921
github.com/hyperledger/fabric-lib-go v1.1.3-0.20240523144151-25edd1eaf5f5/go.mod h1:SHNCq8AB0VpHAmvJEtdbzabv6NNV1F48JdmDihasBjc=
922922
github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3 h1:Xpd6fzG/KjAOHJsq7EQXY2l+qi/y8muxBaY7R6QWABk=
923923
github.com/hyperledger/fabric-protos-go-apiv2 v0.3.3/go.mod h1:2pq0ui6ZWA0cC8J+eCErgnMDCS1kPOEYVY+06ZAK0qE=
924-
github.com/hyperledger/fabric-x-common v0.0.0-20250701155113-a1ddf93333d8 h1:6cGlSZDuTxCIFOU2JUNDoaFoxZRhchJ3oncTGo9GDOE=
925-
github.com/hyperledger/fabric-x-common v0.0.0-20250701155113-a1ddf93333d8/go.mod h1:xO5q1ytO5d5/DeWkDKMGAgoaWBnhmLIjT/ZS2BZfFVs=
924+
github.com/hyperledger/fabric-x-common v0.0.0-20250907124409-88f08cdf7476 h1:+tTSBVeQUr1a9bNiN7ySvsfDySGAHWvBzlYtLRlowvo=
925+
github.com/hyperledger/fabric-x-common v0.0.0-20250907124409-88f08cdf7476/go.mod h1:rZykFq62cc4k4cDuUytAWd6T1Cfun4Wy5roMNCA85GQ=
926+
github.com/hyperledger/fabric-x-common v0.0.0-20250916061807-0d5dacc2a10f h1:X2JNwMg6cYDCFcxfS47+Fskst2aI3GfllNLNHNOC8qY=
927+
github.com/hyperledger/fabric-x-common v0.0.0-20250916061807-0d5dacc2a10f/go.mod h1:rZykFq62cc4k4cDuUytAWd6T1Cfun4Wy5roMNCA85GQ=
926928
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
927929
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
928930
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
@@ -387,9 +387,9 @@ func (c *CommitterRuntime) MakeAndSendTransactionsToOrderer(
387387
Namespaces: namespaces,
388388
}
389389
if expectedStatus != nil && expectedStatus[i] == protoblocktx.Status_ABORTED_SIGNATURE_INVALID {
390-
tx.Signatures = make([][]byte, len(namespaces))
390+
tx.Endorsements = make([]*protoblocktx.Endorsements, len(namespaces))
391391
for nsIdx := range namespaces {
392-
tx.Signatures[nsIdx] = []byte("dummy")
392+
tx.Endorsements[nsIdx] = test.CreateEndorsementsForThresholdRule([]byte("dummy"))[0]
393393
}
394394
}
395395
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.Policy,
9595
})
9696
}
9797
submitConfigBlock(ordererEnv.AllRealOrdererEndpoints())

loadgen/workload/config_tx.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func CreateConfigBlock(policy *PolicyProfile) (*common.Block, error) {
9797

9898
// CreateDefaultConfigBlock creates a config block with default values.
9999
func CreateDefaultConfigBlock(conf *ConfigBlock) (*common.Block, error) {
100-
configBlock := genesisconfig.Load(genesisconfig.SampleFabricX, configtest.GetDevConfigDir())
100+
configBlock := genesisconfig.Load(genesisconfig.TwoOrgsSampleFabricX, 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: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ import (
1010
"os"
1111

1212
"github.com/cockroachdb/errors"
13+
"github.com/hyperledger/fabric-x-common/protoutil"
1314

1415
"github.com/hyperledger/fabric-x-committer/api/protoblocktx"
1516
"github.com/hyperledger/fabric-x-committer/api/types"
1617
"github.com/hyperledger/fabric-x-committer/utils"
1718
"github.com/hyperledger/fabric-x-committer/utils/logging"
1819
"github.com/hyperledger/fabric-x-committer/utils/signature"
1920
"github.com/hyperledger/fabric-x-committer/utils/signature/sigtest"
21+
"github.com/hyperledger/fabric-x-committer/utils/test"
2022
)
2123

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

5860
// Sign signs a TX.
5961
func (e *TxSignerVerifier) Sign(txID string, tx *protoblocktx.Tx) {
60-
tx.Signatures = make([][]byte, len(tx.Namespaces))
62+
tx.Endorsements = make([]*protoblocktx.Endorsements, len(tx.Namespaces))
6163
for nsIndex, ns := range tx.Namespaces {
6264
signer, ok := e.HashSigners[ns.NsId]
6365
if !ok {
6466
continue
6567
}
66-
tx.Signatures[nsIndex] = signer.Sign(txID, tx, nsIndex)
68+
tx.Endorsements[nsIndex] = test.CreateEndorsementsForThresholdRule(signer.Sign(txID, tx, nsIndex))[0]
6769
}
6870
}
6971

7072
// Verify verifies a signature on the transaction.
7173
func (e *TxSignerVerifier) Verify(txID string, tx *protoblocktx.Tx) bool {
72-
if len(tx.Signatures) < len(tx.Namespaces) {
74+
if len(tx.Endorsements) < len(tx.Namespaces) {
7375
return false
7476
}
7577

@@ -130,8 +132,11 @@ func (e *HashSignerVerifier) Verify(txID string, tx *protoblocktx.Tx, nsIndex in
130132
// GetVerificationPolicy returns the verification policy.
131133
func (e *HashSignerVerifier) GetVerificationPolicy() *protoblocktx.NamespacePolicy {
132134
return &protoblocktx.NamespacePolicy{
133-
Scheme: e.scheme,
134-
PublicKey: e.pubKey,
135+
Type: protoblocktx.PolicyType_THRESHOLD_RULE,
136+
Policy: protoutil.MarshalOrPanic(&protoblocktx.ThresholdRule{
137+
Scheme: e.scheme,
138+
PublicKey: e.pubKey,
139+
}),
135140
}
136141
}
137142

loadgen/workload/tx_builder.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,14 @@ func (txb *TxBuilder) makeTx(optionalTxID *string, blockTx *protoblocktx.Tx) *pr
8989

9090
// 2. Signs the TX:
9191
switch {
92-
case blockTx.Signatures != nil:
92+
case len(blockTx.Endorsements) > 0:
9393
// If the TX already have a signature, it doesn't re-sign it.
9494
case txb.TxSigner != nil:
9595
// If TxSigner is given, it is used to sign the TX.
9696
txb.TxSigner.Sign(txID, blockTx)
9797
case txb.TxSigner == nil:
9898
// Otherwise, it puts empty signatures for all namespaces to ensure well-formed TX.
99-
blockTx.Signatures = make([][]byte, len(blockTx.Namespaces))
99+
blockTx.Endorsements = make([]*protoblocktx.Endorsements, len(blockTx.Namespaces))
100100
}
101101

102102
// 3. Serializes the envelope's payload.

0 commit comments

Comments
 (0)