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

Cache and reuse old validator registration data if no params change #4447

Merged
merged 7 commits into from
Sep 2, 2022

Conversation

g11tech
Copy link
Contributor

@g11tech g11tech commented Aug 19, 2022

Motivation
The FB team requested not to create/send new registration objects unless params change.

This PR caches the registration objects and reuses them to register them to builder.
Reference:

@g11tech g11tech requested a review from a team as a code owner August 19, 2022 11:30
@g11tech g11tech changed the title Cache and reuse old validator registation data if no params change Cache and reuse old validator registration data if no params change Aug 19, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Aug 19, 2022

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 07fe5f5 Previous: 05218d8 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 2.3478 ms/op 2.5258 ms/op 0.93
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 66.901 us/op 108.55 us/op 0.62
BLS verify - blst-native 2.1628 ms/op 2.8069 ms/op 0.77
BLS verifyMultipleSignatures 3 - blst-native 4.4713 ms/op 5.6046 ms/op 0.80
BLS verifyMultipleSignatures 8 - blst-native 9.6669 ms/op 12.161 ms/op 0.79
BLS verifyMultipleSignatures 32 - blst-native 35.378 ms/op 44.288 ms/op 0.80
BLS aggregatePubkeys 32 - blst-native 46.918 us/op 59.892 us/op 0.78
BLS aggregatePubkeys 128 - blst-native 182.28 us/op 236.21 us/op 0.77
getAttestationsForBlock 156.06 ms/op 206.79 ms/op 0.75
isKnown best case - 1 super set check 471.00 ns/op 520.00 ns/op 0.91
isKnown normal case - 2 super set checks 463.00 ns/op 511.00 ns/op 0.91
isKnown worse case - 16 super set checks 477.00 ns/op 511.00 ns/op 0.93
CheckpointStateCache - add get delete 9.2590 us/op 11.465 us/op 0.81
validate gossip signedAggregateAndProof - struct 5.0348 ms/op 6.4892 ms/op 0.78
validate gossip attestation - struct 2.3652 ms/op 3.0128 ms/op 0.79
pickEth1Vote - no votes 2.1577 ms/op 2.5610 ms/op 0.84
pickEth1Vote - max votes 20.251 ms/op 23.197 ms/op 0.87
pickEth1Vote - Eth1Data hashTreeRoot value x2048 13.389 ms/op 14.753 ms/op 0.91
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 22.383 ms/op 25.066 ms/op 0.89
pickEth1Vote - Eth1Data fastSerialize value x2048 1.5705 ms/op 1.8320 ms/op 0.86
pickEth1Vote - Eth1Data fastSerialize tree x2048 13.798 ms/op 14.809 ms/op 0.93
bytes32 toHexString 1.0600 us/op 1.2930 us/op 0.82
bytes32 Buffer.toString(hex) 758.00 ns/op 824.00 ns/op 0.92
bytes32 Buffer.toString(hex) from Uint8Array 1.0790 us/op 1.1560 us/op 0.93
bytes32 Buffer.toString(hex) + 0x 751.00 ns/op 809.00 ns/op 0.93
Object access 1 prop 0.40700 ns/op 0.42900 ns/op 0.95
Map access 1 prop 0.31200 ns/op 0.35100 ns/op 0.89
Object get x1000 11.400 ns/op 16.565 ns/op 0.69
Map get x1000 1.0640 ns/op 1.0220 ns/op 1.04
Object set x1000 82.202 ns/op 121.09 ns/op 0.68
Map set x1000 54.478 ns/op 82.747 ns/op 0.66
Return object 10000 times 0.43180 ns/op 0.42560 ns/op 1.01
Throw Error 10000 times 6.1908 us/op 8.3428 us/op 0.74
enrSubnets - fastDeserialize 64 bits 2.8260 us/op 3.2920 us/op 0.86
enrSubnets - ssz BitVector 64 bits 795.00 ns/op 857.00 ns/op 0.93
enrSubnets - fastDeserialize 4 bits 417.00 ns/op 470.00 ns/op 0.89
enrSubnets - ssz BitVector 4 bits 792.00 ns/op 890.00 ns/op 0.89
prioritizePeers score -10:0 att 32-0.1 sync 2-0 89.657 us/op 116.00 us/op 0.77
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 128.76 us/op 166.58 us/op 0.77
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 225.97 us/op 300.39 us/op 0.75
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 338.07 us/op 546.86 us/op 0.62
prioritizePeers score 0:0 att 64-1 sync 4-1 406.74 us/op 663.64 us/op 0.61
RateTracker 1000000 limit, 1 obj count per request 205.90 ns/op 223.95 ns/op 0.92
RateTracker 1000000 limit, 2 obj count per request 152.01 ns/op 164.51 ns/op 0.92
RateTracker 1000000 limit, 4 obj count per request 126.59 ns/op 136.91 ns/op 0.92
RateTracker 1000000 limit, 8 obj count per request 113.22 ns/op 123.70 ns/op 0.92
RateTracker with prune 4.3380 us/op 6.1810 us/op 0.70
array of 16000 items push then shift 51.594 us/op 5.2531 us/op 9.82
LinkedList of 16000 items push then shift 12.904 ns/op 19.947 ns/op 0.65
array of 16000 items push then pop 213.39 ns/op 253.54 ns/op 0.84
LinkedList of 16000 items push then pop 12.299 ns/op 18.989 ns/op 0.65
array of 24000 items push then shift 77.368 us/op 7.9549 us/op 9.73
LinkedList of 24000 items push then shift 13.471 ns/op 20.034 ns/op 0.67
array of 24000 items push then pop 199.13 ns/op 230.81 ns/op 0.86
LinkedList of 24000 items push then pop 12.386 ns/op 17.958 ns/op 0.69
intersect bitArray bitLen 8 10.809 ns/op 12.386 ns/op 0.87
intersect array and set length 8 144.19 ns/op 202.38 ns/op 0.71
intersect bitArray bitLen 128 55.588 ns/op 71.395 ns/op 0.78
intersect array and set length 128 1.8900 us/op 2.4977 us/op 0.76
Buffer.concat 32 items 2.0270 ns/op 2.2590 ns/op 0.90
pass gossip attestations to forkchoice per slot 2.8963 ms/op 4.0624 ms/op 0.71
computeDeltas 3.6129 ms/op 3.7848 ms/op 0.95
computeProposerBoostScoreFromBalances 805.07 us/op 893.66 us/op 0.90
altair processAttestation - 250000 vs - 7PWei normalcase 3.7730 ms/op 5.4126 ms/op 0.70
altair processAttestation - 250000 vs - 7PWei worstcase 5.6581 ms/op 8.5705 ms/op 0.66
altair processAttestation - setStatus - 1/6 committees join 182.98 us/op 252.63 us/op 0.72
altair processAttestation - setStatus - 1/3 committees join 353.45 us/op 488.47 us/op 0.72
altair processAttestation - setStatus - 1/2 committees join 505.28 us/op 684.78 us/op 0.74
altair processAttestation - setStatus - 2/3 committees join 662.21 us/op 923.52 us/op 0.72
altair processAttestation - setStatus - 4/5 committees join 930.21 us/op 1.2948 ms/op 0.72
altair processAttestation - setStatus - 100% committees join 1.1278 ms/op 1.5257 ms/op 0.74
altair processBlock - 250000 vs - 7PWei normalcase 25.345 ms/op 30.688 ms/op 0.83
altair processBlock - 250000 vs - 7PWei normalcase hashState 34.153 ms/op 46.714 ms/op 0.73
altair processBlock - 250000 vs - 7PWei worstcase 88.338 ms/op 106.77 ms/op 0.83
altair processBlock - 250000 vs - 7PWei worstcase hashState 101.29 ms/op 128.97 ms/op 0.79
phase0 processBlock - 250000 vs - 7PWei normalcase 3.5346 ms/op 4.7087 ms/op 0.75
phase0 processBlock - 250000 vs - 7PWei worstcase 51.844 ms/op 67.311 ms/op 0.77
altair processEth1Data - 250000 vs - 7PWei normalcase 846.06 us/op 1.1207 ms/op 0.75
Tree 40 250000 create 759.19 ms/op 1.0851 s/op 0.70
Tree 40 250000 get(125000) 268.14 ns/op 331.92 ns/op 0.81
Tree 40 250000 set(125000) 2.3414 us/op 3.7415 us/op 0.63
Tree 40 250000 toArray() 28.690 ms/op 36.020 ms/op 0.80
Tree 40 250000 iterate all - toArray() + loop 28.824 ms/op 37.079 ms/op 0.78
Tree 40 250000 iterate all - get(i) 110.99 ms/op 136.66 ms/op 0.81
MutableVector 250000 create 15.868 ms/op 18.945 ms/op 0.84
MutableVector 250000 get(125000) 11.051 ns/op 14.257 ns/op 0.78
MutableVector 250000 set(125000) 588.65 ns/op 1.1425 us/op 0.52
MutableVector 250000 toArray() 6.7239 ms/op 8.3808 ms/op 0.80
MutableVector 250000 iterate all - toArray() + loop 6.8619 ms/op 9.0877 ms/op 0.76
MutableVector 250000 iterate all - get(i) 2.5933 ms/op 6.4560 ms/op 0.40
Array 250000 create 6.7830 ms/op 7.1307 ms/op 0.95
Array 250000 clone - spread 3.6008 ms/op 3.1722 ms/op 1.14
Array 250000 get(125000) 1.5730 ns/op 1.4250 ns/op 1.10
Array 250000 set(125000) 1.5760 ns/op 1.4000 ns/op 1.13
Array 250000 iterate all - loop 150.99 us/op 144.55 us/op 1.04
effectiveBalanceIncrements clone Uint8Array 300000 62.201 us/op 96.911 us/op 0.64
effectiveBalanceIncrements clone MutableVector 300000 1.1050 us/op 952.00 ns/op 1.16
effectiveBalanceIncrements rw all Uint8Array 300000 247.30 us/op 315.84 us/op 0.78
effectiveBalanceIncrements rw all MutableVector 300000 189.38 ms/op 253.36 ms/op 0.75
phase0 afterProcessEpoch - 250000 vs - 7PWei 191.47 ms/op 203.58 ms/op 0.94
phase0 beforeProcessEpoch - 250000 vs - 7PWei 62.946 ms/op 78.702 ms/op 0.80
altair processEpoch - mainnet_e81889 560.67 ms/op 666.50 ms/op 0.84
mainnet_e81889 - altair beforeProcessEpoch 82.004 ms/op 192.76 ms/op 0.43
mainnet_e81889 - altair processJustificationAndFinalization 17.383 us/op 66.263 us/op 0.26
mainnet_e81889 - altair processInactivityUpdates 8.9789 ms/op 11.495 ms/op 0.78
mainnet_e81889 - altair processRewardsAndPenalties 140.26 ms/op 107.15 ms/op 1.31
mainnet_e81889 - altair processRegistryUpdates 2.6240 us/op 14.043 us/op 0.19
mainnet_e81889 - altair processSlashings 585.00 ns/op 4.1600 us/op 0.14
mainnet_e81889 - altair processEth1DataReset 625.00 ns/op 4.2990 us/op 0.15
mainnet_e81889 - altair processEffectiveBalanceUpdates 2.6618 ms/op 2.6125 ms/op 1.02
mainnet_e81889 - altair processSlashingsReset 4.0050 us/op 26.057 us/op 0.15
mainnet_e81889 - altair processRandaoMixesReset 4.3360 us/op 26.230 us/op 0.17
mainnet_e81889 - altair processHistoricalRootsUpdate 716.00 ns/op 4.6600 us/op 0.15
mainnet_e81889 - altair processParticipationFlagUpdates 5.4500 us/op 16.830 us/op 0.32
mainnet_e81889 - altair processSyncCommitteeUpdates 814.00 ns/op 3.7130 us/op 0.22
mainnet_e81889 - altair afterProcessEpoch 220.71 ms/op 216.12 ms/op 1.02
phase0 processEpoch - mainnet_e58758 504.78 ms/op 637.70 ms/op 0.79
mainnet_e58758 - phase0 beforeProcessEpoch 187.59 ms/op 292.59 ms/op 0.64
mainnet_e58758 - phase0 processJustificationAndFinalization 18.235 us/op 61.067 us/op 0.30
mainnet_e58758 - phase0 processRewardsAndPenalties 101.08 ms/op 158.23 ms/op 0.64
mainnet_e58758 - phase0 processRegistryUpdates 8.3810 us/op 34.291 us/op 0.24
mainnet_e58758 - phase0 processSlashings 706.00 ns/op 3.5200 us/op 0.20
mainnet_e58758 - phase0 processEth1DataReset 602.00 ns/op 4.0400 us/op 0.15
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.6263 ms/op 2.5902 ms/op 0.63
mainnet_e58758 - phase0 processSlashingsReset 4.2830 us/op 16.351 us/op 0.26
mainnet_e58758 - phase0 processRandaoMixesReset 4.1970 us/op 25.359 us/op 0.17
mainnet_e58758 - phase0 processHistoricalRootsUpdate 649.00 ns/op 4.4800 us/op 0.14
mainnet_e58758 - phase0 processParticipationRecordUpdates 3.8870 us/op 24.205 us/op 0.16
mainnet_e58758 - phase0 afterProcessEpoch 164.54 ms/op 175.62 ms/op 0.94
phase0 processEffectiveBalanceUpdates - 250000 normalcase 2.1270 ms/op 2.5178 ms/op 0.84
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 2.4986 ms/op 2.9555 ms/op 0.85
altair processInactivityUpdates - 250000 normalcase 40.903 ms/op 46.650 ms/op 0.88
altair processInactivityUpdates - 250000 worstcase 33.127 ms/op 57.474 ms/op 0.58
phase0 processRegistryUpdates - 250000 normalcase 7.1860 us/op 27.649 us/op 0.26
phase0 processRegistryUpdates - 250000 badcase_full_deposits 382.68 us/op 577.91 us/op 0.66
phase0 processRegistryUpdates - 250000 worstcase 0.5 201.07 ms/op 251.99 ms/op 0.80
altair processRewardsAndPenalties - 250000 normalcase 73.551 ms/op 156.55 ms/op 0.47
altair processRewardsAndPenalties - 250000 worstcase 79.551 ms/op 98.676 ms/op 0.81
phase0 getAttestationDeltas - 250000 normalcase 11.182 ms/op 16.620 ms/op 0.67
phase0 getAttestationDeltas - 250000 worstcase 13.939 ms/op 16.981 ms/op 0.82
phase0 processSlashings - 250000 worstcase 5.0635 ms/op 6.9061 ms/op 0.73
altair processSyncCommitteeUpdates - 250000 301.82 ms/op 348.13 ms/op 0.87
BeaconState.hashTreeRoot - No change 559.00 ns/op 629.00 ns/op 0.89
BeaconState.hashTreeRoot - 1 full validator 74.288 us/op 84.038 us/op 0.88
BeaconState.hashTreeRoot - 32 full validator 652.80 us/op 915.51 us/op 0.71
BeaconState.hashTreeRoot - 512 full validator 7.6689 ms/op 8.2938 ms/op 0.92
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 91.050 us/op 130.73 us/op 0.70
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.3418 ms/op 1.5667 ms/op 0.86
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 20.295 ms/op 20.176 ms/op 1.01
BeaconState.hashTreeRoot - 1 balances 70.721 us/op 80.413 us/op 0.88
BeaconState.hashTreeRoot - 32 balances 632.19 us/op 757.98 us/op 0.83
BeaconState.hashTreeRoot - 512 balances 6.4227 ms/op 7.6368 ms/op 0.84
BeaconState.hashTreeRoot - 250000 balances 101.93 ms/op 112.80 ms/op 0.90
aggregationBits - 2048 els - zipIndexesInBitList 31.049 us/op 42.017 us/op 0.74
regular array get 100000 times 61.666 us/op 58.597 us/op 1.05
wrappedArray get 100000 times 61.494 us/op 59.233 us/op 1.04
arrayWithProxy get 100000 times 28.762 ms/op 35.845 ms/op 0.80
ssz.Root.equals 522.00 ns/op 637.00 ns/op 0.82
byteArrayEquals 511.00 ns/op 605.00 ns/op 0.84
shuffle list - 16384 els 11.522 ms/op 12.685 ms/op 0.91
shuffle list - 250000 els 169.02 ms/op 180.10 ms/op 0.94
processSlot - 1 slots 14.463 us/op 18.951 us/op 0.76
processSlot - 32 slots 2.0429 ms/op 2.3159 ms/op 0.88
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 429.53 us/op 432.17 us/op 0.99
getCommitteeAssignments - req 1 vs - 250000 vc 5.4025 ms/op 5.5493 ms/op 0.97
getCommitteeAssignments - req 100 vs - 250000 vc 7.8451 ms/op 8.1520 ms/op 0.96
getCommitteeAssignments - req 1000 vs - 250000 vc 8.4365 ms/op 8.6807 ms/op 0.97
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 8.8000 ns/op 10.670 ns/op 0.82
state getBlockRootAtSlot - 250000 vs - 7PWei 1.1498 us/op 1.3183 us/op 0.87
computeProposers - vc 250000 18.025 ms/op 20.449 ms/op 0.88
computeEpochShuffling - vc 250000 172.43 ms/op 187.04 ms/op 0.92
getNextSyncCommittee - vc 250000 300.30 ms/op 343.07 ms/op 0.88

by benchmarkbot/action

@@ -79,6 +80,8 @@ type ValidatorData = {
*/
export class ValidatorStore {
private readonly validators = new Map<PubkeyHex, ValidatorData>();
private readonly validatorRegistrationCache = new ValidatorRegistrationCache();
Copy link
Member

Choose a reason for hiding this comment

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

Can you include a jsdoc comment here or on the class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not add this inside ValidatorData so it gets automatically pruned when removing validators?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved

@g11tech g11tech enabled auto-merge (squash) August 26, 2022 10:08
fromHexString(feeRecipient),
slot
);
return validatorStore.getValidatorRegistration(pubkeyHex, feeRecipient, slot);
Copy link
Contributor

Choose a reason for hiding this comment

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

the FB team requested not to create/send new registration objects unless params change.

@g11tech I still see we send every validator registration per epoch, is it expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, they also only keep a registration for 2 epochs, so its recommended to refresh every epoch 👍

export class ValidatorRegistrationCache {
private readonly validatorRegistrationMap = new Map<
string,
{validatorRegistration: bellatrix.SignedValidatorRegistrationV1; fullKey: string}
Copy link
Contributor

Choose a reason for hiding this comment

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

Add alias on type string such that

type PubkeyHex = string
/** `${feeRecipient}-${gasLimit}` */
type AttributesKey = string

Copy link
Contributor

Choose a reason for hiding this comment

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

Since fullKey is nested by first level of pubkey, does it really need to include the pubkey?

Copy link
Contributor

Choose a reason for hiding this comment

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

If you add this cache inside ValidatorData you don't need the 2d Map. And then you can prune by number of attribute combinations which is what makes more sense. pubkeys are naturally bounded already

@g11tech g11tech disabled auto-merge August 31, 2022 20:31
@g11tech g11tech force-pushed the g11tech/reuse-builder-val-reg branch from d8c06d3 to 45fab0b Compare September 2, 2022 18:34
@philknows philknows modified the milestones: v1.0.0 pre-merge, v1.1.0 Sep 2, 2022
wemeetagain
wemeetagain previously approved these changes Sep 2, 2022
@g11tech g11tech merged commit 47d1529 into unstable Sep 2, 2022
@g11tech g11tech deleted the g11tech/reuse-builder-val-reg branch September 2, 2022 19:40
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.

5 participants