Skip to content

Commit 7cc55d9

Browse files
authored
Merge pull request #2276 from input-output-hk/jpraynaud/certify-protocol-parameters-certificate-chain
Feat: certify protocol parameters and epoch in certificate chain
2 parents b797355 + b86faf5 commit 7cc55d9

33 files changed

+3731
-2321
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ As a minor extension, we have adopted a slightly different versioning convention
1515

1616
- Activate aggregator HTTP responses compression by the reverse proxy in the infrastructure.
1717

18+
- Support certification of the protocol parameters and epoch in the certificate chain.
19+
1820
- **UNSTABLE** Cardano database incremental certification:
1921

2022
- Implement the artifact routes of the aggregator for the signed entity type `CardanoDatabase`.

Cargo.lock

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

docs/website/root/mithril/advanced/mithril-protocol/certificates.md

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ Where the following notations have been used:
3737
- `VK(n)`: Verification key at epoch `n`
3838
- `AVK(n)`: Aggregrate verification key at epoch `n` such as `AVK(n) = MKT_ROOT(SD(n) || VK(n))`
3939
- `MKT_ROOT()`: Merkle-tree root
40-
- `BEACON(p,n)`: Beacon at trigger `p` and epoch `n`
40+
- `PPARAMS(n)`: Protocol parameters at epoch `n`
41+
- `EPOCH(n)`: Epoch `n`
42+
- `BEACON(p,n)`: Beacon at trigger `p` and epoch `n` (includes `EPOCH(n)`)
4143
- `METADATA(p,n)`: Metadata of the certificate at trigger `p` and epoch `n`
4244
- `MSG(p,n)`: Message of the certificate at trigger `p` and epoch `n`
4345
- `MULTI_SIG(p,n)`: Multi-signature created to the message `H(MSG(p,n) || AVK(n-1))`
@@ -92,18 +94,23 @@ An implementation of the algorithm would work as follows for a certificate:
9294
- **Step 2**: Verify (or fail) that the `current_hash` of the `current_certificate` is valid by computing it and comparing it with the `hash` field of the certificate
9395
- **Step 3**: Get the `previous_hash` of the `previous_certificate` by reading its value in the `current_certificate`
9496
- **Step 4**: Verify (or fail) that the `multi_signature` of the `current_certificate` is valid
95-
- **Step 5**: Retrieve the `previous_certificate` that has the hash `previous_hash`:
96-
- **Step 5.1**: If it is not a `genesis_certificate`:
97-
- **Step 5.1.1**: Verify (or fail) that the `previous_hash` of the `previous_certificate` is valid by computing it and comparing it with the `hash` field of the certificate:
98-
- **Step 5.1.2**: Verify the `current_avk`:
99-
- **Step 5.1.2.1**: If the `current_certificate` is the `first_certificate` of the epoch, verify (or fail) that the `current_avk` of the `current_certificate` is part of the message signed by the multi-signature of the `previous_certificate`
100-
- **Step 5.1.2.2**: Else verify (or fail) that the `current_avk` of the `current_certificate` is the same as the `current_avk` of the `previous_certificate`
101-
- **Step 5.1.3**: Verify (or fail) that the `multi_signature` of the `previous_certificate` is valid
102-
- **Step 5.1.4**: Use the `previous_certificate` as `current_certificate` and start again at **Step 2**
103-
- **Step 5.2**: If it is a `genesis_certificate`:
104-
- **Step 5.2.1**: Verify (or fail) that the `previous_hash` of the `previous_certificate` is valid by computing it and comparing it with the `hash` field of the certificate
105-
- **Step 5.2.2**: Verify (or fail) that the `current_avk` of the `current_certificate` is part of the message signed by the genesis signature of the `previous_certificate`
106-
- **Step 5.2.3**: The certificate is valid (success).
97+
- **Step 5**: Verify (or fail) that the `current_epoch` of the `current_certificate` is part of the message signed by the multi-signature of the `current_certificate`
98+
- **Step 6**: Retrieve the `previous_certificate` that has the hash `previous_hash`:
99+
- **Step 6.1**: If it is not a `genesis_certificate`:
100+
- **Step 6.1.1**: Verify (or fail) that the `previous_hash` of the `previous_certificate` is valid by computing it and comparing it with the `hash` field of the certificate:
101+
- **Step 6.1.2**: Verify the `current_avk`:
102+
- **Step 6.1.2.1**: If the `current_certificate` is the `first_certificate` of the epoch
103+
- **Step 6.1.2.1.1**: Verify (or fail) that the `current_avk` of the `current_certificate` is part of the message signed by the multi-signature of the `previous_certificate`
104+
- **Step 6.1.2.1.2**: Verify (or fail) that the `current_protocol_parameters` of the `current_certificate` is part of the message signed by the multi-signature of the `previous_certificate`
105+
- **Step 6.1.2.2**: Else verify (or fail) that the `current_avk` of the `current_certificate` is the same as the `current_avk` of the `previous_certificate`
106+
- **Step 6.1.3**: Verify (or fail) that the `multi_signature` of the `previous_certificate` is valid
107+
- **Step 6.1.4**: Use the `previous_certificate` as `current_certificate` and start again at **Step 2**
108+
- **Step 6.2**: If it is a `genesis_certificate`:
109+
- **Step 6.2.1**: Verify (or fail) that the `previous_hash` of the `previous_certificate` is valid by computing it and comparing it with the `hash` field of the certificate
110+
- **Step 6.2.2**: Verify (or fail) that the `current_epoch` of the `previous_certificate` is part of the message signed by the genesis_certificate of the `previous_certificate`
111+
- **Step 6.2.3**: Verify (or fail) that the `current_avk` of the `current_certificate` is part of the message signed by the genesis signature of the `previous_certificate`
112+
- **Step 6.2.4**: Verify (or fail) that the `current_protocol_parameters` of the `current_certificate` is part of the message signed by the genesis signature of the `previous_certificate`
113+
- **Step 6.2.5**: The certificate is valid (success).
107114

108115
## The coexistence of multiple certificate chains
109116

-15.5 KB
Loading

mithril-aggregator/src/dependency_injection/builder.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,6 @@ impl DependenciesBuilder {
11761176
&self.configuration.db_directory,
11771177
self.root_logger(),
11781178
));
1179-
let era_checker = self.get_era_checker().await?;
11801179
let signable_builders_dependencies = SignableBuilderServiceDependencies::new(
11811180
mithril_stake_distribution_builder,
11821181
immutable_signable_builder,
@@ -1185,7 +1184,6 @@ impl DependenciesBuilder {
11851184
cardano_database_signable_builder,
11861185
);
11871186
let signable_builder_service = Arc::new(MithrilSignableBuilderService::new(
1188-
era_checker,
11891187
seed_signable_builder,
11901188
signable_builders_dependencies,
11911189
self.root_logger(),

mithril-aggregator/src/services/certifier/certifier_service.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,8 @@ mod tests {
717717
let network = fake_data::network();
718718
let beacon = CardanoDbBeacon::new(3, 1);
719719
let signed_entity_type = SignedEntityType::CardanoImmutableFilesFull(beacon.clone());
720-
let protocol_message = ProtocolMessage::new();
720+
let mut protocol_message = ProtocolMessage::new();
721+
protocol_message.set_message_part(ProtocolMessagePartKey::CurrentEpoch, "3".to_string());
721722
let epochs_with_signers = (1..=3).map(Epoch).collect::<Vec<_>>();
722723
let fixture = MithrilFixtureBuilder::default().with_signers(3).build();
723724
let certifier_service = setup_certifier_service_with_network(

mithril-aggregator/src/services/epoch_service.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ mod tests {
10561056
},
10571057
allowed_discriminants: SignedEntityConfig::dummy().allowed_discriminants,
10581058
cardano_era: "CardanoEra".to_string(),
1059-
mithril_era: SupportedEra::eras()[1],
1059+
mithril_era: SupportedEra::eras()[0],
10601060
total_spo: 10,
10611061
total_stake: 20_000_000,
10621062
..EpochServiceBuilder::new(epoch, current_epoch_fixture.clone())
@@ -1077,7 +1077,7 @@ mod tests {
10771077
data.clone(),
10781078
ExpectedEpochData {
10791079
cardano_era: "CardanoEra".to_string(),
1080-
mithril_era: SupportedEra::eras()[1],
1080+
mithril_era: SupportedEra::eras()[0],
10811081
epoch,
10821082
protocol_parameters: current_epoch_fixture.protocol_parameters(),
10831083
next_protocol_parameters: next_epoch_fixture.protocol_parameters(),

0 commit comments

Comments
 (0)