Skip to content

Commit 1b13d70

Browse files
authored
Merge branch 'master' into spellcheck_github_action_update
2 parents e275989 + 9ad0b95 commit 1b13d70

File tree

333 files changed

+41243
-8996
lines changed

Some content is hidden

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

333 files changed

+41243
-8996
lines changed

app/app.go

+7
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,13 @@ func New(
624624
},
625625
)
626626

627+
app.UpgradeKeeper.SetUpgradeHandler(
628+
"v1.3",
629+
func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
630+
return app.mm.RunMigrations(ctx, cfg, fromVM)
631+
},
632+
)
633+
627634
return app
628635
}
629636

cmd/dcld/cmd/genaccounts.go

+32-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/spf13/cast"
2020
"github.com/spf13/cobra"
2121
"github.com/spf13/viper"
22+
"github.com/zigbee-alliance/distributed-compliance-ledger/x/common/types"
2223
dclauthtypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclauth/types"
2324
"github.com/zigbee-alliance/distributed-compliance-ledger/x/dclgenutil"
2425
dclgenutiltypes "github.com/zigbee-alliance/distributed-compliance-ledger/x/dclgenutil/types"
@@ -29,6 +30,7 @@ const (
2930
FlagPubKey = "pubkey"
3031
FlagRoles = "roles"
3132
FlagVID = "vid"
33+
FlagPIDs = "pid_ranges"
3234
)
3335

3436
// AddGenesisAccountCmd returns add-genesis-account cobra Command.
@@ -109,8 +111,36 @@ the address will be looked up in the local Keybase.
109111
}
110112
}
111113

114+
var pidRanges []*types.Uint16Range
115+
if pidStrRanges := viper.GetString(FlagPIDs); len(pidStrRanges) > 0 { //nolint:nestif
116+
var lastMax int32
117+
for _, pidStrRange := range strings.Split(pidStrRanges, ",") {
118+
pidRange := strings.Split(pidStrRange, "-")
119+
if len(pidRange) != 2 {
120+
return fmt.Errorf("failed to parse PID Range")
121+
}
122+
min, err := cast.ToInt32E(pidRange[0])
123+
if err != nil {
124+
return err
125+
}
126+
max, err := cast.ToInt32E(pidRange[1])
127+
if err != nil {
128+
return err
129+
}
130+
if min > max || max == 0 || min == 0 {
131+
return fmt.Errorf("invalid PID Range is provided: min=%d, max=%d", min, max)
132+
}
133+
if max <= lastMax || min <= lastMax {
134+
return fmt.Errorf("invalid PID Range is provided: {%d-%d}, ranges are overlapped, range items must be provided in increased order", min, max)
135+
}
136+
pid := types.Uint16Range{Min: min, Max: max}
137+
pidRanges = append(pidRanges, &pid)
138+
lastMax = max
139+
}
140+
}
141+
112142
// FIXME issue 99 VendorID
113-
genAccount = dclauthtypes.NewAccount(ba, roles, []*dclauthtypes.Grant{}, []*dclauthtypes.Grant{}, vendorID)
143+
genAccount = dclauthtypes.NewAccount(ba, roles, []*dclauthtypes.Grant{}, []*dclauthtypes.Grant{}, vendorID, pidRanges)
114144

115145
if err := genAccount.Validate(); err != nil {
116146
return fmt.Errorf("failed to validate new genesis account: %w", err)
@@ -154,6 +184,7 @@ the address will be looked up in the local Keybase.
154184
cmd.Flags().String(FlagRoles, "",
155185
fmt.Sprintf("The list of roles (split by comma) to assign to account (supported roles: %v)", dclauthtypes.Roles))
156186
cmd.Flags().String(FlagVID, "", "Vendor ID associated with this account. Required only for Vendor Roles")
187+
cmd.Flags().String(FlagPIDs, "", "The list of Product ID ranges (split by \"-\") associated with this account (for example: 1-101,101-6554)")
157188

158189
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
159190
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")

docker-compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,4 @@ networks:
122122
ipam:
123123
driver: default
124124
config:
125-
- subnet: 192.167.10.0/16
125+
- subnet: 192.167.10.0/24

docs/design/noc-root-cert-design.md

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# NOC Root Certificate Transactions Design
2+
3+
## User Stories
4+
5+
### 1. Add NOC Root Certificate
6+
A Vendor with DCL write privilege can submit a transaction to add a NOC root certificate associated with their Vendor ID.
7+
8+
### 2. Revoke NOC Root Certificate
9+
A Vendor with DCL write privilege can submit a transaction to revoke a NOC root certificate associated with their Vendor ID.
10+
11+
### 3. Remove NOC Root Certificate
12+
A Vendor with DCL write privilege can submit a transaction to remove a NOC root certificate associated with their Vendor ID. So that the Vendor can remove certificates that were added by mistake.
13+
14+
## Certificate Schema
15+
16+
To distinguesh NOC root certificates from others, an `isNOC` boolean field will be added to the [certificates](https://github.com/zigbee-alliance/distributed-compliance-ledger/blob/master/proto/pki/certificate.proto) schema
17+
18+
## Transactions
19+
20+
### 1. ADD_NOC_X509_ROOT_CERTIFICATE
21+
This transaction adds a NOC root certificate owned by the Vendor.
22+
23+
- Who can send: Vendor account
24+
- Validation:
25+
- The provided certificate must be a root certificate:
26+
- `Issuer` == `Subject`
27+
- `Authority Key Identifier` == `Subject Key Identifier`
28+
- No existing certificate with the same `<Certificate's Issuer>:<Certificate's Serial Number>` combination.
29+
- If certificates with the same `<Certificate's Subject>:<Certificate's Subject Key ID>` combination already exist:
30+
- The sender's VID must match the vid field of the existing certificates.
31+
- No existing certificate with the same `<Certificate's Subject>:<Certificate's Subject Key ID>` combination already published by another vendor.
32+
- The signature (self-signature) and expiration date must be valid.
33+
- Parameters:
34+
- cert: `string` - The NOC Root Certificate, encoded in X.509v3 PEM format. Can be a PEM string or a file path.
35+
- In State:
36+
- `pki/ApprovedCertificates/value/<Subject>/<SubjectKeyID>`
37+
- `pki/ApprovedCertificatesBySubject/value/<Subject>`
38+
- `pki/NOCRootCertificates/value/<VID>`
39+
- CLI Command:
40+
- `dcld tx pki add-noc-x509-root-cert --certificate=<string-or-path> --from=<account>`
41+
42+
### 2. REVOKE_NOC_X509_ROOT_CERTIFICATE
43+
This transaction revokes a NOC root certificate owned by the Vendor.
44+
Revoked NOC root certificates can be re-added using the `ADD_NOC_X509_ROOT_CERTIFICATE` transaction.
45+
46+
- Who can send: Vendor account
47+
- Vid field associated with the corresponding NOC root certificate on the ledger must be equal to the Vendor account's VID.
48+
- Validation:
49+
- A NOC Root Certificate with the provided `subject` and `subject_key_id` must exist in the ledger.
50+
- Parameters:
51+
- subject: `string` - Base64 encoded subject DER sequence bytes of the certificate.
52+
- subject_key_id: `string` - Certificate's `Subject Key Id` in hex string format, e.g., `5A:88:0E:6C:36:53:D0:7F:B0:89:71:A3:F4:73:79:09:30:E6:2B:DB`.
53+
- serial_number: `optional(string)` - Certificate's serial number. If not provided, the transaction will revoke all certificates that match the given `subject` and `subject_key_id` combination.
54+
- info: `optional(string)` - Information/notes for the revocation.
55+
- time: `optional(int64)` - Revocation time (number of nanoseconds elapsed since January 1, 1970 UTC). CLI uses the current time for that field.
56+
- revokeChild: `optional(bool)` - If true, then all certificates in the chain signed by the revoked certificate (intermediate, leaf) are revoked as well. If false, only the current root cert is revoked (default: false).
57+
- In State:
58+
- `pki/RevokedCertificates/value/<subject>/<subject_key_id>`
59+
- `pki/RevokedNOCRootCertificates/value/<subject>/<subject_key_id>`
60+
- CLI Command:
61+
- `dcld tx pki revoke-noc-x509-root-cert --subject=<base64 string> --subject-key-id=<hex string> --serial-number=<string> --info=<string> --time=<int64> --revokeChild=<bool> --from=<account>`
62+
63+
### 3. REMOVE_NOC_X509_ROOT_CERTIFICATE
64+
This transaction completely removes a NOC root certificate owned by the Vendor.
65+
Removed NOC root certificates can be re-added using the `ADD_NOC_X509_ROOT_CERTIFICATE` transaction.
66+
67+
Revoked certificates that match the specified parameters will also be removed.
68+
69+
The certificates in the chain signed by the removed certificate (intermediate, leaf) will not be removed.
70+
71+
- Who can send: Vendor account
72+
- Vid field associated with the corresponding NOC root certificate on the ledger must be equal to the Vendor account's VID.
73+
- Validation:
74+
- A NOC root certificate with the provided `subject` and `subject_key_id` must exist in the ledger.
75+
- Parameters:
76+
- subject: `string` - Base64 encoded subject DER sequence bytes of the certificate.
77+
- subject_key_id: `string` - Certificate's `Subject Key Id` in hex string format, e.g., `5A:88:0E:6C:36:53:D0:7F:B0:89:71:A3:F4:73:79:09:30:E6:2B:DB`.
78+
- serial_number: `optional(string)` - Certificate's serial number. If not provided, the transaction will remove all certificates that match the given `subject` and `subject_key_id` combination.
79+
- info: `optional(string)` - Information/notes for the removal.
80+
- CLI Command:
81+
- `dcld tx pki remove-noc-x509-root-cert --subject=<base64 string> --subject-key-id=<hex string> --serial-number=<string> --info=<string> --from=<account>`
82+
83+
## Query
84+
85+
To retrieve NOC certificates by Subject and Subject Key Identifier, use the [GET_X509_CERT](https://github.com/zigbee-alliance/distributed-compliance-ledger/blob/master/docs/transactions.md#get_x509_cert) or [GET_ALL_SUBJECT_X509_CERTS](https://github.com/zigbee-alliance/distributed-compliance-ledger/blob/master/docs/transactions.md#get_all_subject_x509_certs:) query.
86+
87+
To retrieve a revoked NOC certificate by Subject and Subject Key Identifier, use the [GET_REVOKED_CERT](https://github.com/zigbee-alliance/distributed-compliance-ledger/blob/master/docs/transactions.md#get_revoked_cert)
88+
89+
### GET_NOC_X509_ROOT_CERTS_BY_VID
90+
91+
Retrieve NOC root certificates associated with a specific VID.
92+
93+
- Who can send: Any account
94+
- Parameters:
95+
- vid: `uint16` - Vendor ID (positive non-zero)
96+
- CLI Command:
97+
- `dcld query pki get_noc_x509_root_certs --vid=<uint16>`
98+
- REST API:
99+
- GET `/dcl/pki/noc-root-certificates/{vid}`
100+
101+
### GET_ALL_NOC_X509_ROOT_CERTS
102+
103+
Retrieve a list of all of NOC root certificates
104+
105+
- Who can send: Any account
106+
- Parameters:
107+
- Common pagination parameters
108+
- CLI Command:
109+
- `dcld query pki get_all_noc_x509_root_certs`
110+
- REST API:
111+
- GET `/dcl/pki/noc-root-certificates`
112+
113+
### GET_ALL_REVOKED_NOC_X509_ROOT_CERTS
114+
115+
Gets all revoked NOC root certificates.
116+
117+
- Who can send: Any account
118+
- Parameters:
119+
- Common pagination parameters
120+
- CLI command:
121+
- `dcld query pki all-revoked-noc-x509-root-certs`
122+
- REST API:
123+
- GET `/dcl/pki/revoked-noc-root-certificates`

docs/design/schema-compatibility.md

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Support for forward and backward compatibility in DCL schemes
2+
3+
Schema changes can cover a wide range of modifications with varying impacts on application compatibility and data integrity. Below are use cases with strategies to manage schema changes and ensure compatibility.
4+
5+
## I. Multiple versions can live in parallel
6+
7+
### 1. Strategy for Compatible Changes
8+
9+
For changes that are backward-compatible, such as adding optional fields or extending enumerations.
10+
11+
#### Option A: Add an optional version field to all DCL schema
12+
13+
**Description:**
14+
Implement an optional version field in all DCL schemas to track the schema version. This approach is simple and quick to execute, suitable primarily for compatible updates.
15+
16+
**Strategy steps:**
17+
18+
- One time actions:
19+
- Add an optional version field to all DCL schema
20+
- For each update:
21+
- Update the schema by introducing compatible changes (such as adding a new optional field).
22+
- Update transactions and queries if needed.
23+
- DCL doesn't fulfill the Schema version automatically
24+
- It will be up to the transaction submitter (Vendor) to specify a correct Schema version
25+
- If Schema Version is not set - then the initial version (version 0 or 1) is assumed
26+
- It will be up to the client application to process the Schema version
27+
28+
### 2. Strategy for Non-Compatible Changes
29+
30+
For significant changes that directly impact compatibility, such as adding mandatory fields or removing fields, splitting or merging schemas, changing enumerations.
31+
32+
#### Option B: Separate Schemas for Each Version
33+
34+
**Description:**
35+
Each version has its distinct schema, state and its own queries/requests. This strategy eliminates the need for data migration and allows different schema versions to coexist seamlessly.
36+
37+
**Strategy steps:**
38+
39+
- For each update:
40+
- Create a new version of a Schema and state (a new .proto file)
41+
- Implement transactions and queries for the new schema version.
42+
43+
#### Option C: Generic Schema Storage (Not Recommended for Production)
44+
45+
**Description:**
46+
Implement a flexible, generic schema structure that can support a wide range of data formats.
47+
48+
While offering a robust solution for handling radical changes, this method requires careful planning and development, which can potentially take a significant amount of time.
49+
50+
**Strategy steps:**
51+
52+
- One time actions:
53+
- Create a more flexible, generic schema structure to hold a wide range of data formats (Can be used [Any](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/any.proto) as described in [ADR-19](https://docs.cosmos.network/v0.47/build/architecture/adr-019-protobuf-state-encoding#usage-of-any-to-encode-interfaces))
54+
- Migrate old states to the newer, generic schema.
55+
- Remove the states associated with the older schema versions.
56+
- Optioanlly can be implemented queries for requesting schemas with any return type
57+
- For each update:
58+
- Create a new Schema version (a new .proto file)
59+
- Implement transactions and queries that can handle data according to its version, including mechanisms for converting generic values into the corresponding schema version.
60+
61+
## II. New version replaces the legacy one (V2 replaces V1)
62+
63+
### 1. Strategy for Compatible or Convertible changes
64+
65+
For changes that are backward-compatible, such as adding optional or mandatory fields or extending enumerations
66+
67+
#### Option D: Not keeping backward compatibility in API
68+
69+
**Description:**
70+
This strategy focuses on updating the schema without ensuring backward compatibility at the API level. Since the schemas are compatible, there will likely be no need for migration.
71+
72+
**Strategy steps:**
73+
74+
- For each update:
75+
- Update the schema by introducing compatible changes (such as adding a new optional field).
76+
- Migrate old states to the newer if needed.
77+
- Update transactions and queries if needed.
78+
79+
#### Option E: Keeping backward compatibility in API
80+
81+
**Description:**
82+
The main idea of this strategy is the dynamically converting newer schemas into older ones. However, this method is only possible if there is compatibility between the newer and legacy schemas, allowing them to be converted to each other. Due to the on-the-fly data conversion, this approach does not support the Light Client in legacy APIs because the converted data is not stored in the state, preventing the generation of proofs.
83+
84+
**Strategy steps:**
85+
86+
- For each update:
87+
- Create a new version of a Schema and state (a new .proto file)
88+
- Migrate older states to newer schema version.
89+
- Remove the states associated with the older schema versions.
90+
- Implement transactions and queries for the new schema version.
91+
- Update older transactions and queries to converting data between the latest and older schema version, ensuring backward compatibility.
92+
- There will be separated API for each version of the schema, for example::
93+
- models/vid/pid
94+
- modelsV2/vid/pid
95+
- modelsV3/vid/pid
96+
97+
### 2. Strategy for Non-Compatible changes
98+
99+
For significant changes that directly impact compatibility, such as adding mandatory fields or removing fields, splitting or merging schemas, changing enumerations.
100+
101+
#### Optiona F: Not keeping backward compatibility in API
102+
103+
**Description:**
104+
This strategy focuses on updating the schema without ensuring backward compatibility at the API level. Since the schemas are not compatible, migration is carried out manually through a special transaction.
105+
106+
**Strategy steps:**
107+
108+
- For each update:
109+
- Update the schema by introducing changes.
110+
- Update transactions and queries if needed.
111+
- Add a new transaction to fulfill new required fields (essentially this is a manual migration via transactions)
112+
113+
#### Option G: Keeping backward compatibility in API
114+
115+
**Description:**
116+
It's not possible to replace an old version here. [Multiple versions can live in parallel: Strategy for Non-Compatible Changes](#2-strategy-for-non-compatible-changes) options should be used instead.
117+
118+
## Conclusion
119+
120+
To lay the foundation for future compatibility improvements, it's a good idea to start by adding a version field to each schema. For subsequent changes, we will then select the most appropriate strategy based on the nature of these changes.

docs/how-to.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ Once approved the account can be used to send transactions. See [use_case_txn_au
127127
### 1. Create an Account proposal for the user
128128

129129
```bash
130-
dcld tx auth propose-add-account --address=<bench32 encoded string> --pubkey=<protobuf JSON encoded> --roles=<role1,role2,...> --vid=<uint16> --from=<account>
130+
dcld tx auth propose-add-account --address=<bench32 encoded string> --pubkey=<protobuf JSON encoded> --roles=<role1,role2,...> --vid=<uint16> --pid_ranges=<uint16-range,uint16-range,...> --from=<account>
131131
```
132132

133133
### 2. Approve proposed Account
@@ -211,6 +211,7 @@ Minimal command:
211211
```bash
212212
dcld tx model add-model --vid=<uint16> --pid=<uint16> --deviceTypeID=<uint16> --productName=<string> --from=<account>
213213
```
214+
Note that if `account` was created with product ID ranges then the `pid` must fall within that specified range
214215

215216
Full command:
216217

@@ -229,6 +230,7 @@ Minimal command:
229230
dcld tx model add-model-version --vid=<uint16> --pid=<uint16> --softwareVersion=<uint32> --softwareVersionString=<string> --cdVersionNumber=<uint32>
230231
--minApplicableSoftwareVersion=<uint32> --maxApplicableSoftwareVersion=<uint32> --from=<account>
231232
```
233+
Note that if `account` was created with product ID ranges then the `pid` must fall within that specified range
232234

233235
Full command:
234236

@@ -250,12 +252,14 @@ dcld tx vendorinfo update-vendor --vid=<uint16> ... --from=<account>
250252
```bash
251253
dcld tx model update-model --vid=<uint16> --pid=<uint16> ... --from=<account>
252254
```
255+
Note that if `account` was created with product ID ranges then the `pid` must fall within that specified range
253256

254257
### 7. Edit Model Version
255258

256259
```bash
257260
dcld tx model update-model-version --vid=<uint16> --pid=<uint16> --softwareVersion=<uint32> ... --from=<account>
258261
```
262+
Note that if `account` was created with product ID ranges then the `pid` must fall within that specified range
259263

260264
### 8. Add PKI Revocation Distribution Point
261265

0 commit comments

Comments
 (0)