Skip to content

Commit c974b6a

Browse files
authored
Merge pull request #1345 from input-output-hk/ensemble/1343-fix-recompute-hashes-certificates
Fix certificate hashes re-computation in aggregator
2 parents 25d3c9c + 8465a99 commit c974b6a

File tree

6 files changed

+104
-45
lines changed

6 files changed

+104
-45
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/runbook/recompute-certificates-hash/README.md

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ Export the environment variables:
55
```bash
66
export MITHRIL_VM=**MITHRIL_VM**
77
export CARDANO_NETWORK=**CARDANO_NETWORK**
8+
export MITHRIL_DISTRIBUTION_LINUX_PKG=**MITHRIL_DISTRIBUTION_LINUX_PKG**
89
```
910

1011
Here is an exmaple for the `release-mainnet` network:
1112
```bash
1213
export MITHRIL_VM=aggregator.release-mainnet.api.mithril.network
1314
export CARDANO_NETWORK=mainnet
15+
export MITHRIL_DISTRIBUTION_LINUX_PKG=https://github.com/input-output-hk/mithril/releases/download/2342.0/mithril-2342.0-linux-x64.tar.gz
1416
```
1517

1618
## Make a backup of the aggregator database
@@ -30,29 +32,64 @@ And copy the SQLite database file `aggregator.sqlite3`:
3032
cp /home/curry/data/$CARDANO_NETWORK/mithril-aggregator/mithril/stores/aggregator.sqlite3 /home/curry/data/$CARDANO_NETWORK/mithril-aggregator/mithril/stores/aggregator.sqlite3.bak.$(date +%Y-%m-%d)
3133
```
3234

33-
And connect to the aggregator container:
35+
## Create a temp directory
36+
37+
Create a temp directory:
3438
```bash
35-
docker exec -it mithril-aggregator bash
39+
rm -rf /home/curry/temp
40+
mkdir -p /home/curry/temp/config
41+
cd /home/curry/temp
3642
```
3743

38-
Once connected to the aggregator container, recompute the certificates hashes:
44+
And download the configuration file for tools:
3945
```bash
40-
/app/bin/mithril-aggregator -vvvv tools recompute-certificates-hash
46+
wget https://raw.githubusercontent.com/input-output-hk/mithril/main/docs/runbook/recompute-certificates-hash/config/tools.json -O /home/curry/temp/config/tools.json
4147
```
4248

43-
Then disconnect from the aggregator container:
49+
## Download the pre-compiled aggregator binary
50+
51+
Download the mithril pre-compiled binaries package:
4452
```bash
45-
exit
53+
wget $MITHRIL_DISTRIBUTION_LINUX_PKG -O mithril-bin.tar.gz
54+
```
55+
56+
Unpack the mithril aggregator binary:
57+
```bash
58+
tar xzf mithril-bin.tar.gz mithril-aggregator
59+
```
60+
61+
Make mithril aggregator binary executable:
62+
```bash
63+
chmod u+x mithril-aggregator
64+
```
65+
66+
Make sure you are running the expected version of the aggregator:
67+
```bash
68+
./mithril-aggregator --version
69+
```
70+
71+
## Stop the aggregator
72+
73+
Stop the aggregator container:
74+
```bash
75+
docker stop mithril-aggregator
76+
```
77+
78+
## Run the migration
79+
80+
Once connected to the aggregator container, recompute the certificates hashes:
81+
```bash
82+
DATA_STORES_DIRECTORY=/home/curry/data/$CARDANO_NETWORK/mithril-aggregator/mithril/stores/ ./mithril-aggregator --run-mode tools -vvv tools recompute-certificates-hash
4683
```
4784

4885
## Restart the aggregator
4986

5087
Restart the aggregator to make sure that the certificate chain is valid:
5188
```bash
52-
docker restart mithril-aggregator
89+
docker start mithril-aggregator
5390
```
5491

55-
Make sure that the certificate chain is valid (wait for the state machiene to go into the state `READY`):
92+
Make sure that the certificate chain is valid (wait for the state machine to go into the `READY` state):
5693
```bash
5794
docker logs -f --tail 1000 mithril-aggregator
5895
```
@@ -62,6 +99,13 @@ Then disconnect from the aggregator VM:
6299
exit
63100
```
64101

102+
## Cleanup the temp directory
103+
104+
Remove the temp directory:
105+
```bash
106+
rm -rf /home/curry/temp
107+
```
108+
65109
## Rollback procedure
66110

67111
If the recomputation fails, you can rollback the database.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"cardano_cli_path": "-",
3+
"cardano_node_socket_path": "-",
4+
"network": "-",
5+
"network_magic": 0,
6+
"run_interval": 0,
7+
"protocol_parameters": {
8+
"k": 0,
9+
"m": 0,
10+
"phi_f": 0
11+
},
12+
"snapshot_store_type": "local",
13+
"snapshot_uploader_type": "local",
14+
"genesis_verification_key": "-",
15+
"era_adapter_type": "bootstrap",
16+
"cardano_node_version": "-"
17+
}

docs/runbook/terraform-lock/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ Currently, the following [Mithril networks](https://mithril.network/doc/manual/d
2020

2121
A user with administrator rights can simply remove the lock file:
2222
- In GCP [**Cloud Storage**](https://console.cloud.google.com/storage/browser)
23-
- In the terraform administration bucket that you have identified earlier, the file that needs to be removed is at path `**TERRAFORM_BACKEND_BUCKET**/terraform/mithril-**MITHRIL_NETWORK_IDENTIFIER**/.terraform.lock.hcl` (e.g. `mithril-terraform-prod/terraform/mithril-release-mainnet/terraform.lock.hcl`)
23+
- In the terraform administration bucket that you have identified earlier, the file that needs to be removed is at path `**TERRAFORM_BACKEND_BUCKET**/terraform/mithril-**MITHRIL_NETWORK_IDENTIFIER**/default.tflock` (e.g. `mithril-terraform-prod/terraform/mithril-release-mainnet/terraform.lock.hcl`)
2424

2525
:warning: never delete/modify the `**TERRAFORM_BACKEND_BUCKET**/terraform/mithril-**MITHRIL_NETWORK_IDENTIFIER**/default.tfstate` file.

mithril-aggregator/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-aggregator"
3-
version = "0.4.8"
3+
version = "0.4.9"
44
description = "A Mithril Aggregator server"
55
authors = { workspace = true }
66
edition = { workspace = true }
@@ -48,7 +48,7 @@ zstd = { version = "0.13.0", features = ["zstdmt"] }
4848
httpmock = "0.6.8"
4949
mithril-common = { path = "../mithril-common", features = [
5050
"allow_skip_signer_certification",
51-
"test_tools"
51+
"test_tools",
5252
] }
5353
mockall = "0.11.4"
5454
slog-term = "2.9.0"

mithril-aggregator/src/tools/certificates_hash_migrator.rs

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ impl CertificatesHashMigrator {
4848
// arbitrary high value to get all existing certificates
4949
.get_latest_certificates(usize::MAX)
5050
.await?;
51+
let mut certificates_to_remove = vec![];
5152

5253
let mut migrated_certificates = vec![];
5354
let mut old_and_new_hashes: HashMap<String, String> = HashMap::new();
@@ -57,7 +58,7 @@ impl CertificatesHashMigrator {
5758
// in order to have a strong guarantee that when inserting a certificate in the db its
5859
// previous_hash exist we have to work in the reverse order.
5960
debug!("🔧 Certificate Hash Migrator: computing new hash for all certificates");
60-
for mut certificate in old_certificates.clone().into_iter().rev() {
61+
for mut certificate in old_certificates.into_iter().rev() {
6162
let old_previous_hash = if certificate.is_genesis() {
6263
certificate.previous_hash.clone()
6364
} else {
@@ -72,40 +73,37 @@ impl CertificatesHashMigrator {
7273
old_previous_hash
7374
};
7475

75-
let new_hash = {
76+
if let Some(new_hash) = {
7677
let computed_hash = certificate.compute_hash();
77-
// return none if the hash did not change to trigger an error
78+
// return none if the hash did not change
7879
(computed_hash != certificate.hash).then_some(computed_hash)
79-
}
80-
.ok_or(anyhow!(
81-
"Hash did not change for certificate {:?}, hash: {}",
82-
certificate.beacon,
83-
certificate.hash
84-
))?
85-
.to_owned();
86-
87-
old_and_new_hashes.insert(certificate.hash.clone(), new_hash.clone());
80+
} {
81+
old_and_new_hashes.insert(certificate.hash.clone(), new_hash.clone());
82+
83+
if certificate.is_genesis() {
84+
trace!(
85+
"🔧 Certificate Hash Migrator: new hash computed for genesis certificate {:?}",
86+
certificate.beacon;
87+
"old_hash" => &certificate.hash,
88+
"new_hash" => &new_hash,
89+
);
90+
} else {
91+
trace!(
92+
"🔧 Certificate Hash Migrator: new hash computed for certificate {:?}",
93+
certificate.beacon;
94+
"old_hash" => &certificate.hash,
95+
"new_hash" => &new_hash,
96+
"old_previous_hash" => &old_previous_hash,
97+
"new_previous_hash" => &certificate.previous_hash
98+
);
99+
}
88100

89-
if certificate.is_genesis() {
90-
trace!(
91-
"🔧 Certificate Hash Migrator: new hash computed for genesis certificate {:?}",
92-
certificate.beacon;
93-
"old_hash" => &certificate.hash,
94-
"new_hash" => &new_hash,
95-
);
101+
certificates_to_remove.push(certificate.clone());
102+
certificate.hash = new_hash;
103+
migrated_certificates.push(certificate);
96104
} else {
97-
trace!(
98-
"🔧 Certificate Hash Migrator: new hash computed for certificate {:?}",
99-
certificate.beacon;
100-
"old_hash" => &certificate.hash,
101-
"new_hash" => &new_hash,
102-
"old_previous_hash" => &old_previous_hash,
103-
"new_previous_hash" => &certificate.previous_hash
104-
);
105+
old_and_new_hashes.insert(certificate.hash.clone(), certificate.hash);
105106
}
106-
107-
certificate.hash = new_hash;
108-
migrated_certificates.push(certificate);
109107
}
110108

111109
// 2 - Certificates migrated, we can insert them in the db
@@ -123,7 +121,7 @@ impl CertificatesHashMigrator {
123121
})?;
124122
}
125123

126-
Ok((old_certificates, old_and_new_hashes))
124+
Ok((certificates_to_remove, old_and_new_hashes))
127125
}
128126

129127
async fn update_signed_entities_certificate_hash(
@@ -590,7 +588,7 @@ mod test {
590588
}
591589

592590
#[tokio::test]
593-
async fn should_fail_if_any_hash_doesnt_change() {
591+
async fn should_not_fail_if_some_hash_dont_change() {
594592
let connection = Arc::new(connection_without_foreign_key_support());
595593
let certificate = {
596594
let mut cert = dummy_genesis("whatever", 1, 2);
@@ -608,6 +606,6 @@ mod test {
608606
migrator
609607
.migrate()
610608
.await
611-
.expect_err("Migration should fail if an hash doesnt change");
609+
.expect("Migration should not fail if a hash doesn't change");
612610
}
613611
}

0 commit comments

Comments
 (0)