Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize UX loading for keystores #5043

Merged
merged 9 commits into from
Feb 7, 2023
Merged

Optimize UX loading for keystores #5043

merged 9 commits into from
Feb 7, 2023

Conversation

nazarhussain
Copy link
Contributor

Motivation

Improve the UX for the keystores loading.

Description

Add key caching to the keystore loading logic.

Closes #4179

Steps to test or reproduce

  • Run all unit tests

@nazarhussain nazarhussain requested a review from a team as a code owner January 23, 2023 15:27
@github-actions
Copy link
Contributor

github-actions bot commented Jan 23, 2023

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 3521449 Previous: 0efcb16 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 588.59 us/op 617.86 us/op 0.95
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 72.521 us/op 43.302 us/op 1.67
BLS verify - blst-native 1.3843 ms/op 1.1750 ms/op 1.18
BLS verifyMultipleSignatures 3 - blst-native 2.6700 ms/op 2.3810 ms/op 1.12
BLS verifyMultipleSignatures 8 - blst-native 5.7759 ms/op 5.1272 ms/op 1.13
BLS verifyMultipleSignatures 32 - blst-native 21.085 ms/op 18.482 ms/op 1.14
BLS aggregatePubkeys 32 - blst-native 27.869 us/op 24.657 us/op 1.13
BLS aggregatePubkeys 128 - blst-native 113.28 us/op 96.657 us/op 1.17
getAttestationsForBlock 68.403 ms/op 53.904 ms/op 1.27
isKnown best case - 1 super set check 282.00 ns/op 276.00 ns/op 1.02
isKnown normal case - 2 super set checks 275.00 ns/op 272.00 ns/op 1.01
isKnown worse case - 16 super set checks 274.00 ns/op 273.00 ns/op 1.00
CheckpointStateCache - add get delete 6.2650 us/op 5.0470 us/op 1.24
validate gossip signedAggregateAndProof - struct 2.8916 ms/op 2.6416 ms/op 1.09
validate gossip attestation - struct 1.3656 ms/op 1.2629 ms/op 1.08
pickEth1Vote - no votes 1.3689 ms/op 1.1687 ms/op 1.17
pickEth1Vote - max votes 12.837 ms/op 10.859 ms/op 1.18
pickEth1Vote - Eth1Data hashTreeRoot value x2048 10.317 ms/op 8.7832 ms/op 1.17
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 15.590 ms/op 14.816 ms/op 1.05
pickEth1Vote - Eth1Data fastSerialize value x2048 808.23 us/op 614.21 us/op 1.32
pickEth1Vote - Eth1Data fastSerialize tree x2048 7.4642 ms/op 7.0877 ms/op 1.05
bytes32 toHexString 823.00 ns/op 483.00 ns/op 1.70
bytes32 Buffer.toString(hex) 454.00 ns/op 342.00 ns/op 1.33
bytes32 Buffer.toString(hex) from Uint8Array 680.00 ns/op 571.00 ns/op 1.19
bytes32 Buffer.toString(hex) + 0x 452.00 ns/op 335.00 ns/op 1.35
Object access 1 prop 0.21600 ns/op 0.16400 ns/op 1.32
Map access 1 prop 0.18000 ns/op 0.16300 ns/op 1.10
Object get x1000 7.9640 ns/op 6.5540 ns/op 1.22
Map get x1000 0.71100 ns/op 0.58400 ns/op 1.22
Object set x1000 84.312 ns/op 52.351 ns/op 1.61
Map set x1000 62.753 ns/op 43.459 ns/op 1.44
Return object 10000 times 0.27340 ns/op 0.23860 ns/op 1.15
Throw Error 10000 times 4.4668 us/op 4.2125 us/op 1.06
fastMsgIdFn sha256 / 200 bytes 3.6850 us/op 3.4730 us/op 1.06
fastMsgIdFn h32 xxhash / 200 bytes 340.00 ns/op 286.00 ns/op 1.19
fastMsgIdFn h64 xxhash / 200 bytes 492.00 ns/op 385.00 ns/op 1.28
fastMsgIdFn sha256 / 1000 bytes 12.166 us/op 11.211 us/op 1.09
fastMsgIdFn h32 xxhash / 1000 bytes 465.00 ns/op 414.00 ns/op 1.12
fastMsgIdFn h64 xxhash / 1000 bytes 571.00 ns/op 470.00 ns/op 1.21
fastMsgIdFn sha256 / 10000 bytes 108.71 us/op 104.71 us/op 1.04
fastMsgIdFn h32 xxhash / 10000 bytes 2.1040 us/op 1.9400 us/op 1.08
fastMsgIdFn h64 xxhash / 10000 bytes 1.4970 us/op 1.3840 us/op 1.08
enrSubnets - fastDeserialize 64 bits 2.0090 us/op 1.3120 us/op 1.53
enrSubnets - ssz BitVector 64 bits 662.00 ns/op 496.00 ns/op 1.33
enrSubnets - fastDeserialize 4 bits 219.00 ns/op 172.00 ns/op 1.27
enrSubnets - ssz BitVector 4 bits 653.00 ns/op 505.00 ns/op 1.29
prioritizePeers score -10:0 att 32-0.1 sync 2-0 113.99 us/op 97.334 us/op 1.17
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 141.99 us/op 129.09 us/op 1.10
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 217.97 us/op 161.24 us/op 1.35
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 346.66 us/op 304.82 us/op 1.14
prioritizePeers score 0:0 att 64-1 sync 4-1 396.71 us/op 363.92 us/op 1.09
array of 16000 items push then shift 1.7059 us/op 1.6378 us/op 1.04
LinkedList of 16000 items push then shift 9.5940 ns/op 8.8980 ns/op 1.08
array of 16000 items push then pop 101.87 ns/op 84.463 ns/op 1.21
LinkedList of 16000 items push then pop 8.8300 ns/op 8.5840 ns/op 1.03
array of 24000 items push then shift 2.4324 us/op 2.3720 us/op 1.03
LinkedList of 24000 items push then shift 9.6870 ns/op 8.8040 ns/op 1.10
array of 24000 items push then pop 91.287 ns/op 73.518 ns/op 1.24
LinkedList of 24000 items push then pop 9.0630 ns/op 8.5530 ns/op 1.06
intersect bitArray bitLen 8 14.557 ns/op 13.424 ns/op 1.08
intersect array and set length 8 89.443 ns/op 78.868 ns/op 1.13
intersect bitArray bitLen 128 47.456 ns/op 44.498 ns/op 1.07
intersect array and set length 128 1.2486 us/op 1.0700 us/op 1.17
Buffer.concat 32 items 2.9260 us/op 2.7900 us/op 1.05
Uint8Array.set 32 items 2.6010 us/op 2.3090 us/op 1.13
pass gossip attestations to forkchoice per slot 2.6427 ms/op 3.7409 ms/op 0.71
computeDeltas 4.4685 ms/op 2.8804 ms/op 1.55
computeProposerBoostScoreFromBalances 2.1132 ms/op 1.7616 ms/op 1.20
altair processAttestation - 250000 vs - 7PWei normalcase 3.8176 ms/op 2.3310 ms/op 1.64
altair processAttestation - 250000 vs - 7PWei worstcase 5.6374 ms/op 3.2574 ms/op 1.73
altair processAttestation - setStatus - 1/6 committees join 163.72 us/op 144.56 us/op 1.13
altair processAttestation - setStatus - 1/3 committees join 291.46 us/op 278.64 us/op 1.05
altair processAttestation - setStatus - 1/2 committees join 406.92 us/op 380.02 us/op 1.07
altair processAttestation - setStatus - 2/3 committees join 512.03 us/op 470.50 us/op 1.09
altair processAttestation - setStatus - 4/5 committees join 791.26 us/op 660.67 us/op 1.20
altair processAttestation - setStatus - 100% committees join 784.37 us/op 765.00 us/op 1.03
altair processBlock - 250000 vs - 7PWei normalcase 21.966 ms/op 16.408 ms/op 1.34
altair processBlock - 250000 vs - 7PWei normalcase hashState 30.612 ms/op 26.657 ms/op 1.15
altair processBlock - 250000 vs - 7PWei worstcase 57.092 ms/op 52.236 ms/op 1.09
altair processBlock - 250000 vs - 7PWei worstcase hashState 84.529 ms/op 68.702 ms/op 1.23
phase0 processBlock - 250000 vs - 7PWei normalcase 2.5432 ms/op 2.2708 ms/op 1.12
phase0 processBlock - 250000 vs - 7PWei worstcase 32.840 ms/op 29.253 ms/op 1.12
altair processEth1Data - 250000 vs - 7PWei normalcase 627.95 us/op 461.73 us/op 1.36
vc - 250000 eb 1 eth1 1 we 0 wn 0 - smpl 15 11.617 us/op 8.0400 us/op 1.44
vc - 250000 eb 0.95 eth1 0.1 we 0.05 wn 0 - smpl 219 32.723 us/op 20.706 us/op 1.58
vc - 250000 eb 0.95 eth1 0.3 we 0.05 wn 0 - smpl 42 15.042 us/op 8.6810 us/op 1.73
vc - 250000 eb 0.95 eth1 0.7 we 0.05 wn 0 - smpl 18 9.3320 us/op 7.8850 us/op 1.18
vc - 250000 eb 0.1 eth1 0.1 we 0 wn 0 - smpl 1020 106.26 us/op 99.244 us/op 1.07
vc - 250000 eb 0.03 eth1 0.03 we 0 wn 0 - smpl 11777 673.31 us/op 643.42 us/op 1.05
vc - 250000 eb 0.01 eth1 0.01 we 0 wn 0 - smpl 16384 939.25 us/op 920.97 us/op 1.02
vc - 250000 eb 0 eth1 0 we 0 wn 0 - smpl 16384 967.42 us/op 892.07 us/op 1.08
vc - 250000 eb 0 eth1 0 we 0 wn 0 nocache - smpl 16384 2.4579 ms/op 2.2816 ms/op 1.08
vc - 250000 eb 0 eth1 1 we 0 wn 0 - smpl 16384 1.6214 ms/op 1.4773 ms/op 1.10
vc - 250000 eb 0 eth1 1 we 0 wn 0 nocache - smpl 16384 5.1956 ms/op 3.9325 ms/op 1.32
Tree 40 250000 create 433.34 ms/op 307.37 ms/op 1.41
Tree 40 250000 get(125000) 197.09 ns/op 182.91 ns/op 1.08
Tree 40 250000 set(125000) 1.1656 us/op 897.69 ns/op 1.30
Tree 40 250000 toArray() 24.103 ms/op 16.997 ms/op 1.42
Tree 40 250000 iterate all - toArray() + loop 25.988 ms/op 17.410 ms/op 1.49
Tree 40 250000 iterate all - get(i) 79.912 ms/op 68.078 ms/op 1.17
MutableVector 250000 create 12.658 ms/op 11.112 ms/op 1.14
MutableVector 250000 get(125000) 6.4900 ns/op 6.4260 ns/op 1.01
MutableVector 250000 set(125000) 285.06 ns/op 255.53 ns/op 1.12
MutableVector 250000 toArray() 3.9553 ms/op 2.7787 ms/op 1.42
MutableVector 250000 iterate all - toArray() + loop 4.1456 ms/op 2.8907 ms/op 1.43
MutableVector 250000 iterate all - get(i) 1.5717 ms/op 1.5189 ms/op 1.03
Array 250000 create 3.7708 ms/op 2.6936 ms/op 1.40
Array 250000 clone - spread 1.2148 ms/op 1.1910 ms/op 1.02
Array 250000 get(125000) 0.63000 ns/op 0.58100 ns/op 1.08
Array 250000 set(125000) 0.71200 ns/op 0.65700 ns/op 1.08
Array 250000 iterate all - loop 93.817 us/op 106.19 us/op 0.88
effectiveBalanceIncrements clone Uint8Array 300000 49.334 us/op 27.405 us/op 1.80
effectiveBalanceIncrements clone MutableVector 300000 406.00 ns/op 383.00 ns/op 1.06
effectiveBalanceIncrements rw all Uint8Array 300000 171.07 us/op 169.80 us/op 1.01
effectiveBalanceIncrements rw all MutableVector 300000 113.88 ms/op 82.718 ms/op 1.38
phase0 afterProcessEpoch - 250000 vs - 7PWei 124.03 ms/op 115.22 ms/op 1.08
phase0 beforeProcessEpoch - 250000 vs - 7PWei 54.232 ms/op 42.479 ms/op 1.28
altair processEpoch - mainnet_e81889 363.41 ms/op 328.31 ms/op 1.11
mainnet_e81889 - altair beforeProcessEpoch 82.325 ms/op 66.698 ms/op 1.23
mainnet_e81889 - altair processJustificationAndFinalization 25.285 us/op 16.413 us/op 1.54
mainnet_e81889 - altair processInactivityUpdates 7.2273 ms/op 5.6195 ms/op 1.29
mainnet_e81889 - altair processRewardsAndPenalties 77.812 ms/op 47.094 ms/op 1.65
mainnet_e81889 - altair processRegistryUpdates 6.3970 us/op 2.7610 us/op 2.32
mainnet_e81889 - altair processSlashings 833.00 ns/op 412.00 ns/op 2.02
mainnet_e81889 - altair processEth1DataReset 924.00 ns/op 471.00 ns/op 1.96
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.4301 ms/op 1.2673 ms/op 1.13
mainnet_e81889 - altair processSlashingsReset 8.7620 us/op 4.5940 us/op 1.91
mainnet_e81889 - altair processRandaoMixesReset 14.985 us/op 8.9840 us/op 1.67
mainnet_e81889 - altair processHistoricalRootsUpdate 1.5590 us/op 679.00 ns/op 2.30
mainnet_e81889 - altair processParticipationFlagUpdates 4.9660 us/op 2.5750 us/op 1.93
mainnet_e81889 - altair processSyncCommitteeUpdates 1.0410 us/op 489.00 ns/op 2.13
mainnet_e81889 - altair afterProcessEpoch 158.00 ms/op 129.69 ms/op 1.22
phase0 processEpoch - mainnet_e58758 430.97 ms/op 364.38 ms/op 1.18
mainnet_e58758 - phase0 beforeProcessEpoch 179.29 ms/op 139.05 ms/op 1.29
mainnet_e58758 - phase0 processJustificationAndFinalization 35.000 us/op 16.131 us/op 2.17
mainnet_e58758 - phase0 processRewardsAndPenalties 82.763 ms/op 66.947 ms/op 1.24
mainnet_e58758 - phase0 processRegistryUpdates 18.229 us/op 7.7150 us/op 2.36
mainnet_e58758 - phase0 processSlashings 1.3400 us/op 539.00 ns/op 2.49
mainnet_e58758 - phase0 processEth1DataReset 1.2390 us/op 528.00 ns/op 2.35
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.8885 ms/op 1.0245 ms/op 1.84
mainnet_e58758 - phase0 processSlashingsReset 10.541 us/op 4.4140 us/op 2.39
mainnet_e58758 - phase0 processRandaoMixesReset 16.977 us/op 4.9700 us/op 3.42
mainnet_e58758 - phase0 processHistoricalRootsUpdate 1.6420 us/op 757.00 ns/op 2.17
mainnet_e58758 - phase0 processParticipationRecordUpdates 17.891 us/op 5.4440 us/op 3.29
mainnet_e58758 - phase0 afterProcessEpoch 111.55 ms/op 101.20 ms/op 1.10
phase0 processEffectiveBalanceUpdates - 250000 normalcase 2.2781 ms/op 1.2518 ms/op 1.82
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 2.5171 ms/op 1.4719 ms/op 1.71
altair processInactivityUpdates - 250000 normalcase 34.573 ms/op 23.225 ms/op 1.49
altair processInactivityUpdates - 250000 worstcase 29.171 ms/op 27.251 ms/op 1.07
phase0 processRegistryUpdates - 250000 normalcase 15.199 us/op 7.5220 us/op 2.02
phase0 processRegistryUpdates - 250000 badcase_full_deposits 441.56 us/op 286.63 us/op 1.54
phase0 processRegistryUpdates - 250000 worstcase 0.5 188.50 ms/op 130.69 ms/op 1.44
altair processRewardsAndPenalties - 250000 normalcase 74.770 ms/op 65.465 ms/op 1.14
altair processRewardsAndPenalties - 250000 worstcase 85.779 ms/op 72.228 ms/op 1.19
phase0 getAttestationDeltas - 250000 normalcase 9.8716 ms/op 7.0787 ms/op 1.39
phase0 getAttestationDeltas - 250000 worstcase 10.491 ms/op 6.7547 ms/op 1.55
phase0 processSlashings - 250000 worstcase 4.4594 ms/op 3.4048 ms/op 1.31
altair processSyncCommitteeUpdates - 250000 204.75 ms/op 176.37 ms/op 1.16
BeaconState.hashTreeRoot - No change 280.00 ns/op 306.00 ns/op 0.92
BeaconState.hashTreeRoot - 1 full validator 58.821 us/op 54.108 us/op 1.09
BeaconState.hashTreeRoot - 32 full validator 613.94 us/op 544.26 us/op 1.13
BeaconState.hashTreeRoot - 512 full validator 7.7676 ms/op 5.9584 ms/op 1.30
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 67.964 us/op 63.804 us/op 1.07
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 962.63 us/op 912.32 us/op 1.06
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 14.056 ms/op 11.691 ms/op 1.20
BeaconState.hashTreeRoot - 1 balances 58.621 us/op 49.564 us/op 1.18
BeaconState.hashTreeRoot - 32 balances 531.39 us/op 470.02 us/op 1.13
BeaconState.hashTreeRoot - 512 balances 5.2359 ms/op 4.5147 ms/op 1.16
BeaconState.hashTreeRoot - 250000 balances 93.070 ms/op 73.564 ms/op 1.27
aggregationBits - 2048 els - zipIndexesInBitList 24.264 us/op 15.821 us/op 1.53
regular array get 100000 times 36.223 us/op 42.515 us/op 0.85
wrappedArray get 100000 times 37.100 us/op 33.208 us/op 1.12
arrayWithProxy get 100000 times 16.689 ms/op 15.313 ms/op 1.09
ssz.Root.equals 685.00 ns/op 550.00 ns/op 1.25
byteArrayEquals 698.00 ns/op 554.00 ns/op 1.26
shuffle list - 16384 els 8.0863 ms/op 6.7965 ms/op 1.19
shuffle list - 250000 els 114.78 ms/op 99.994 ms/op 1.15
processSlot - 1 slots 9.9160 us/op 8.7400 us/op 1.13
processSlot - 32 slots 1.5027 ms/op 1.3464 ms/op 1.12
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 266.44 us/op 193.93 us/op 1.37
getCommitteeAssignments - req 1 vs - 250000 vc 3.5627 ms/op 2.8679 ms/op 1.24
getCommitteeAssignments - req 100 vs - 250000 vc 4.9137 ms/op 4.1510 ms/op 1.18
getCommitteeAssignments - req 1000 vs - 250000 vc 5.2533 ms/op 4.3591 ms/op 1.21
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 5.4500 ns/op 4.9000 ns/op 1.11
state getBlockRootAtSlot - 250000 vs - 7PWei 805.07 ns/op 835.89 ns/op 0.96
computeProposers - vc 250000 11.627 ms/op 10.255 ms/op 1.13
computeEpochShuffling - vc 250000 118.67 ms/op 108.14 ms/op 1.10
getNextSyncCommittee - vc 250000 197.74 ms/op 179.44 ms/op 1.10

by benchmarkbot/action

const password = passwords.join("");
// We can't use Keystore.parse as it validates the `encrypted message` to be only 32 bytes.
const keystore = new Keystore(JSON.parse(fs.readFileSync(cacheFilepath, "utf8")));
const secretKeyConcatenatedBytes = await keystore.decrypt(password);
Copy link
Member

@nflaig nflaig Feb 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of encrypting the keystore at all if we store the passwords in the same place? I assume the decrypting still takes a long time if the keystore is big but probably still better then decryption every single key separately as it was done before

It does not seem ideal to me that we store passwords in plain text at all which is currently done by Lodestar as we have a keystore and a secrets (with passwords) file. Those files are stored on the same device (and even the same folder) so it pointless in terms of security.

In my opinion, we should never store the password, only the first time the user imports a encrypted keystore the password should be interactively provided through the cli or keymanager API. After keystores are imported they should be stored unecrypted which makes subsequently loading them much faster and we never store passwords in plain text.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Local keystores is a feature, which is consistent across all CL clients. As you mentioned it's not the best way in terms of security.
  2. To overcome security issue, there is a feature of remote key manager, which does not involve storing passing in local file.

It's upto user to use one feature or other. In regard to decryption, for cache decryption it will take time upto one keystore. So if we have 100 validators keys we can save upto 99% of time with the cache.

Copy link
Member

@nflaig nflaig Feb 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I figured, looks like all CLs implement it like this. We also quickly discussed this topic in the standup, I will create a separate issue for this to get some ideas how we could improve the current security model but it might just be the case that a remoter signer/key manager is the only solution.

So if we have 100 validators keys we can save upto 99% of time with the cache.

that's a great performance improvement, I was assuming it will be much faster but having constant time is really a big deal if you have a lot of validators

packages/cli/test/unit/util/progress.test.ts Show resolved Hide resolved
nflaig
nflaig previously approved these changes Feb 7, 2023
Copy link
Member

@nflaig nflaig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Really good UX and performance improvement!

const password = passwords.join("");
// We can't use Keystore.parse as it validates the `encrypted message` to be only 32 bytes.
const keystore = new Keystore(JSON.parse(fs.readFileSync(cacheFilepath, "utf8")));
const secretKeyConcatenatedBytes = await keystore.decrypt(password);
Copy link
Member

@nflaig nflaig Feb 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I figured, looks like all CLs implement it like this. We also quickly discussed this topic in the standup, I will create a separate issue for this to get some ideas how we could improve the current security model but it might just be the case that a remoter signer/key manager is the only solution.

So if we have 100 validators keys we can save upto 99% of time with the cache.

that's a great performance improvement, I was assuming it will be much faster but having constant time is really a big deal if you have a lot of validators

packages/cli/src/cmds/validator/signers/index.ts Outdated Show resolved Hide resolved
@@ -16,6 +16,7 @@ export function showProgress({
let current = 0;
let last = 0;
let lastProcessTime: number = Date.now();
let internalId: NodeJS.Timeout;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use a more descriptive name for the interval, I think it will also not be just an ID but the whole Timeout object

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's common convention among JS community to suffix output of setTimeout or setInterval as Ids because these are just the pointers to v8 internal timers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the name to be more descriptive.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's common convention among JS community to suffix output of setTimeout or setInterval as Ids because these are just the pointers to v8 internal timers

gotcha, thanks for pointing that out, I didn't know about that

describe("writeKeystoreCache", () => {
it("should write a valid keystore cache file", async () => {
await expect(writeKeystoreCache(keystoreCacheFile, signers, passwords)).to.fulfilled;
expect(fs.existsSync(keystoreCacheFile)).to.be.true;
Copy link
Member

@nflaig nflaig Feb 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there an easy way to do some basic sanitiy checks on the written file? I guess the proper check happens in the others test were the file is written and then loaded, so maybe should not bother too much here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The authenticity of files could better be checked in e2e tests.

@wemeetagain wemeetagain merged commit 684f3dc into unstable Feb 7, 2023
@wemeetagain wemeetagain deleted the nh/4179-key-cache branch February 7, 2023 20:57
return decryptKeystoreDefinitions(keystoreDefinitions, {
...args,
onDecrypt: needle,
cacheFilePath: `${args.importKeystores[0]}.cache`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nazarhussain I noticed that the validator_keys.cache is stored in the same directory as my validator_keys folder which I set via --importKeystores. This is a not ideal in a containerized environment as the cache file is likely not mounted to the container or persistent in a volume. Maybe it would be better to store the cache file in the data directory (dataDir).

In our docker-compose.validator.yml file we also only mount the /keystores which would not include the cache file.

image: chainsafe/lodestar:next
restart: always
volumes:
- validator:/data
- logs:/logs
- ./keystores:/keystores
env_file: .env
command: validator --dataDir /data --importKeystores /keystores --importKeystoresPassword /keystores/password.txt --server http://beacon_node:9596 --logFile /logs/validator.log --logFileLevel debug --logFileDailyRotate 5

@wemeetagain
Copy link
Member

🎉 This PR is included in v1.6.0 🎉

maschad added a commit to maschad/lodestar that referenced this pull request Mar 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optimize UX loading +100 keystores on vc
3 participants