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

feat: verifySignatureSetsSameSigningRoot bls api #5734

Closed
wants to merge 8 commits into from

Conversation

twoeths
Copy link
Contributor

@twoeths twoeths commented Jul 7, 2023

Motivation

  • verifying signature sets of the same signing root is 6x to >10x faster than verifyMultipleSignatures() api
  • as a preparation for feat: verify attestation gossip messages in batch #5729 where we'll validate signature sets with same signing root
  • we want to leverage our worker pool to control canAcceptWork() (if we should process a gossip message or not)

Description

  • new verifyManySignatureSetsSameMessage() worker api
  • enhance verifySignatureSetsMaybeBatch() to add new param isSameMessage: boolean
  • separate QueueItem type (an item in "jobs" queue) and JobItem type (which contain a resolve/reject function of a promise)
/**
 * A job item we want to get a result for.
 */
export type JobItem<W = BlsWorkReq | SerializedSet, R = boolean> = {
  resolve: (result: R | PromiseLike<R>) => void;
  reject: (error?: Error) => void;
  addedTimeMs: number;
  workReq: W;
};

/**
 * An item in the queue. Could be BlsWorkReq or SerializedSet[] of the same message.
 */
export type QueueItem = JobItem<BlsWorkReq> | JobItem<SerializedSet>[];
  • an item in the queue could be a "multi sig sets" job item or an array of job item of same message signature set
  • verifySignatureSetsSameSigningRoot has "verifyOnMainThread" to verify on main thread or not, consumer can decide it later (in feat: verify attestation gossip messages in batch #5729)

part of #5416

Notes

@github-actions
Copy link
Contributor

github-actions bot commented Jul 7, 2023

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: c904b9b Previous: 85ff3cf Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 784.22 us/op 964.59 us/op 0.81
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 50.098 us/op 46.300 us/op 1.08
BLS verify - blst-native 1.3405 ms/op 1.2118 ms/op 1.11
BLS verifyMultipleSignatures 3 - blst-native 2.8172 ms/op 2.4652 ms/op 1.14
BLS verifyMultipleSignatures 8 - blst-native 6.2803 ms/op 5.3017 ms/op 1.18
BLS verifyMultipleSignatures 32 - blst-native 22.638 ms/op 19.120 ms/op 1.18
BLS verifyMultipleSignatures 64 - blst-native 44.151 ms/op
BLS verifyMultipleSignatures 128 - blst-native 87.257 ms/op
BLS verifyMultipleSignatures - same message - 3 - blst-native 1.5204 ms/op
BLS verifyMultipleSignatures - same message - 8 - blst-native 2.0756 ms/op
BLS verifyMultipleSignatures - same message - 32 - blst-native 4.1947 ms/op
BLS verifyMultipleSignatures - same message - 64 - blst-native 7.1129 ms/op
BLS verifyMultipleSignatures - same message - 128 - blst-native 13.139 ms/op
BLS aggregatePubkeys 32 - blst-native 26.507 us/op 25.729 us/op 1.03
BLS aggregatePubkeys 128 - blst-native 103.37 us/op 99.786 us/op 1.04
getAttestationsForBlock 67.794 ms/op 55.758 ms/op 1.22
isKnown best case - 1 super set check 267.00 ns/op 261.00 ns/op 1.02
isKnown normal case - 2 super set checks 258.00 ns/op 255.00 ns/op 1.01
isKnown worse case - 16 super set checks 255.00 ns/op 254.00 ns/op 1.00
CheckpointStateCache - add get delete 5.9460 us/op 5.6560 us/op 1.05
validate gossip signedAggregateAndProof - struct 2.9289 ms/op 2.7668 ms/op 1.06
validate gossip attestation - struct 1.3660 ms/op 1.3134 ms/op 1.04
pickEth1Vote - no votes 1.3670 ms/op 1.3030 ms/op 1.05
pickEth1Vote - max votes 11.462 ms/op 11.239 ms/op 1.02
pickEth1Vote - Eth1Data hashTreeRoot value x2048 9.5431 ms/op 9.2646 ms/op 1.03
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 16.405 ms/op 16.255 ms/op 1.01
pickEth1Vote - Eth1Data fastSerialize value x2048 776.02 us/op 709.80 us/op 1.09
pickEth1Vote - Eth1Data fastSerialize tree x2048 6.1397 ms/op 8.6182 ms/op 0.71
bytes32 toHexString 527.00 ns/op 565.00 ns/op 0.93
bytes32 Buffer.toString(hex) 395.00 ns/op 385.00 ns/op 1.03
bytes32 Buffer.toString(hex) from Uint8Array 593.00 ns/op 600.00 ns/op 0.99
bytes32 Buffer.toString(hex) + 0x 391.00 ns/op 391.00 ns/op 1.00
Object access 1 prop 0.18900 ns/op 0.17700 ns/op 1.07
Map access 1 prop 0.17300 ns/op 0.15900 ns/op 1.09
Object get x1000 6.6980 ns/op 6.6070 ns/op 1.01
Map get x1000 0.62200 ns/op 0.55700 ns/op 1.12
Object set x1000 71.864 ns/op 56.314 ns/op 1.28
Map set x1000 58.695 ns/op 46.958 ns/op 1.25
Return object 10000 times 0.24520 ns/op 0.23870 ns/op 1.03
Throw Error 10000 times 4.4423 us/op 4.2991 us/op 1.03
fastMsgIdFn sha256 / 200 bytes 3.6130 us/op 3.5400 us/op 1.02
fastMsgIdFn h32 xxhash / 200 bytes 336.00 ns/op 305.00 ns/op 1.10
fastMsgIdFn h64 xxhash / 200 bytes 476.00 ns/op 438.00 ns/op 1.09
fastMsgIdFn sha256 / 1000 bytes 11.973 us/op 11.644 us/op 1.03
fastMsgIdFn h32 xxhash / 1000 bytes 448.00 ns/op 444.00 ns/op 1.01
fastMsgIdFn h64 xxhash / 1000 bytes 556.00 ns/op 500.00 ns/op 1.11
fastMsgIdFn sha256 / 10000 bytes 106.99 us/op 103.64 us/op 1.03
fastMsgIdFn h32 xxhash / 10000 bytes 2.0710 us/op 1.9690 us/op 1.05
fastMsgIdFn h64 xxhash / 10000 bytes 1.5190 us/op 1.3980 us/op 1.09
enrSubnets - fastDeserialize 64 bits 1.5850 us/op 1.3490 us/op 1.17
enrSubnets - ssz BitVector 64 bits 617.00 ns/op 512.00 ns/op 1.21
enrSubnets - fastDeserialize 4 bits 206.00 ns/op 180.00 ns/op 1.14
enrSubnets - ssz BitVector 4 bits 583.00 ns/op 551.00 ns/op 1.06
prioritizePeers score -10:0 att 32-0.1 sync 2-0 119.07 us/op 112.02 us/op 1.06
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 161.48 us/op 147.46 us/op 1.10
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 203.21 us/op 178.82 us/op 1.14
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 380.29 us/op 332.27 us/op 1.14
prioritizePeers score 0:0 att 64-1 sync 4-1 418.09 us/op 406.36 us/op 1.03
array of 16000 items push then shift 1.7064 us/op 1.6588 us/op 1.03
LinkedList of 16000 items push then shift 9.6360 ns/op 9.0040 ns/op 1.07
array of 16000 items push then pop 114.01 ns/op 104.83 ns/op 1.09
LinkedList of 16000 items push then pop 9.1170 ns/op 8.6720 ns/op 1.05
array of 24000 items push then shift 2.4955 us/op 2.3785 us/op 1.05
LinkedList of 24000 items push then shift 9.3700 ns/op 9.0530 ns/op 1.04
array of 24000 items push then pop 97.322 ns/op 80.041 ns/op 1.22
LinkedList of 24000 items push then pop 10.245 ns/op 8.7600 ns/op 1.17
intersect bitArray bitLen 8 14.225 ns/op 13.234 ns/op 1.07
intersect array and set length 8 85.254 ns/op 81.915 ns/op 1.04
intersect bitArray bitLen 128 46.454 ns/op 43.836 ns/op 1.06
intersect array and set length 128 1.2488 us/op 1.1640 us/op 1.07
Buffer.concat 32 items 2.9470 us/op 2.9260 us/op 1.01
Uint8Array.set 32 items 2.6400 us/op 2.1990 us/op 1.20
transfer serialized Status (84 B) 2.3300 us/op 2.0360 us/op 1.14
copy serialized Status (84 B) 1.9540 us/op 1.6780 us/op 1.16
transfer serialized SignedVoluntaryExit (112 B) 2.4230 us/op 2.0950 us/op 1.16
copy serialized SignedVoluntaryExit (112 B) 1.9170 us/op 1.7040 us/op 1.13
transfer serialized ProposerSlashing (416 B) 2.5750 us/op 2.2350 us/op 1.15
copy serialized ProposerSlashing (416 B) 2.6010 us/op 2.0960 us/op 1.24
transfer serialized Attestation (485 B) 3.1370 us/op 2.3040 us/op 1.36
copy serialized Attestation (485 B) 2.7230 us/op 2.2280 us/op 1.22
transfer serialized AttesterSlashing (33232 B) 3.0660 us/op 2.4210 us/op 1.27
copy serialized AttesterSlashing (33232 B) 8.6710 us/op 5.5700 us/op 1.56
transfer serialized Small SignedBeaconBlock (128000 B) 3.2010 us/op 2.7760 us/op 1.15
copy serialized Small SignedBeaconBlock (128000 B) 21.268 us/op 15.060 us/op 1.41
transfer serialized Avg SignedBeaconBlock (200000 B) 3.7070 us/op 3.1090 us/op 1.19
copy serialized Avg SignedBeaconBlock (200000 B) 73.986 us/op 34.721 us/op 2.13
transfer serialized BlobsSidecar (524380 B) 3.9310 us/op 3.3750 us/op 1.16
copy serialized BlobsSidecar (524380 B) 174.66 us/op 167.19 us/op 1.04
transfer serialized Big SignedBeaconBlock (1000000 B) 3.8970 us/op 3.1670 us/op 1.23
copy serialized Big SignedBeaconBlock (1000000 B) 283.49 us/op 249.98 us/op 1.13
pass gossip attestations to forkchoice per slot 2.8355 ms/op 2.6945 ms/op 1.05
forkChoice updateHead vc 100000 bc 64 eq 0 2.3652 ms/op 2.1348 ms/op 1.11
forkChoice updateHead vc 600000 bc 64 eq 0 14.067 ms/op 14.622 ms/op 0.96
forkChoice updateHead vc 1000000 bc 64 eq 0 20.127 ms/op 18.588 ms/op 1.08
forkChoice updateHead vc 600000 bc 320 eq 0 17.537 ms/op 18.009 ms/op 0.97
forkChoice updateHead vc 600000 bc 1200 eq 0 88.742 ms/op 88.849 ms/op 1.00
forkChoice updateHead vc 600000 bc 64 eq 1000 21.604 ms/op 24.095 ms/op 0.90
forkChoice updateHead vc 600000 bc 64 eq 10000 24.305 ms/op 26.097 ms/op 0.93
forkChoice updateHead vc 600000 bc 64 eq 300000 32.908 ms/op 33.193 ms/op 0.99
computeDeltas 3.7193 ms/op 2.9440 ms/op 1.26
computeProposerBoostScoreFromBalances 1.9368 ms/op 1.7358 ms/op 1.12
altair processAttestation - 250000 vs - 7PWei normalcase 3.7153 ms/op 2.0776 ms/op 1.79
altair processAttestation - 250000 vs - 7PWei worstcase 5.1995 ms/op 3.1950 ms/op 1.63
altair processAttestation - setStatus - 1/6 committees join 172.74 us/op 134.98 us/op 1.28
altair processAttestation - setStatus - 1/3 committees join 369.97 us/op 270.84 us/op 1.37
altair processAttestation - setStatus - 1/2 committees join 410.94 us/op 360.56 us/op 1.14
altair processAttestation - setStatus - 2/3 committees join 534.59 us/op 456.75 us/op 1.17
altair processAttestation - setStatus - 4/5 committees join 771.83 us/op 639.79 us/op 1.21
altair processAttestation - setStatus - 100% committees join 981.00 us/op 751.49 us/op 1.31
altair processBlock - 250000 vs - 7PWei normalcase 21.162 ms/op 18.535 ms/op 1.14
altair processBlock - 250000 vs - 7PWei normalcase hashState 35.175 ms/op 27.304 ms/op 1.29
altair processBlock - 250000 vs - 7PWei worstcase 64.121 ms/op 46.156 ms/op 1.39
altair processBlock - 250000 vs - 7PWei worstcase hashState 86.059 ms/op 73.264 ms/op 1.17
phase0 processBlock - 250000 vs - 7PWei normalcase 4.3280 ms/op 1.9270 ms/op 2.25
phase0 processBlock - 250000 vs - 7PWei worstcase 42.156 ms/op 28.348 ms/op 1.49
altair processEth1Data - 250000 vs - 7PWei normalcase 708.43 us/op 461.91 us/op 1.53
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15 14.744 us/op 6.7880 us/op 2.17
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:219 39.402 us/op 22.032 us/op 1.79
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42 21.619 us/op 8.2410 us/op 2.62
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18 15.217 us/op 6.4990 us/op 2.34
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1020 133.51 us/op 77.850 us/op 1.71
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11777 867.19 us/op 637.56 us/op 1.36
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.2143 ms/op 873.74 us/op 1.39
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.2391 ms/op 853.11 us/op 1.45
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 2.8646 ms/op 2.4515 ms/op 1.17
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.1166 ms/op 1.5970 ms/op 1.33
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 5.2878 ms/op 3.7440 ms/op 1.41
Tree 40 250000 create 528.14 ms/op 308.63 ms/op 1.71
Tree 40 250000 get(125000) 211.84 ns/op 186.80 ns/op 1.13
Tree 40 250000 set(125000) 1.5371 us/op 969.55 ns/op 1.59
Tree 40 250000 toArray() 25.239 ms/op 19.307 ms/op 1.31
Tree 40 250000 iterate all - toArray() + loop 27.030 ms/op 18.877 ms/op 1.43
Tree 40 250000 iterate all - get(i) 79.916 ms/op 70.176 ms/op 1.14
MutableVector 250000 create 14.447 ms/op 11.380 ms/op 1.27
MutableVector 250000 get(125000) 7.0390 ns/op 6.4260 ns/op 1.10
MutableVector 250000 set(125000) 423.60 ns/op 274.44 ns/op 1.54
MutableVector 250000 toArray() 4.5808 ms/op 2.9633 ms/op 1.55
MutableVector 250000 iterate all - toArray() + loop 6.1031 ms/op 3.4687 ms/op 1.76
MutableVector 250000 iterate all - get(i) 1.6587 ms/op 1.4946 ms/op 1.11
Array 250000 create 4.4997 ms/op 3.1570 ms/op 1.43
Array 250000 clone - spread 3.3978 ms/op 1.3152 ms/op 2.58
Array 250000 get(125000) 1.6090 ns/op 0.64800 ns/op 2.48
Array 250000 set(125000) 1.8020 ns/op 0.72300 ns/op 2.49
Array 250000 iterate all - loop 145.93 us/op 88.100 us/op 1.66
effectiveBalanceIncrements clone Uint8Array 300000 59.771 us/op 85.219 us/op 0.70
effectiveBalanceIncrements clone MutableVector 300000 484.00 ns/op 334.00 ns/op 1.45
effectiveBalanceIncrements rw all Uint8Array 300000 193.19 us/op 165.80 us/op 1.17
effectiveBalanceIncrements rw all MutableVector 300000 170.57 ms/op 77.137 ms/op 2.21
phase0 afterProcessEpoch - 250000 vs - 7PWei 125.52 ms/op 113.54 ms/op 1.11
phase0 beforeProcessEpoch - 250000 vs - 7PWei 57.232 ms/op 34.244 ms/op 1.67
altair processEpoch - mainnet_e81889 375.93 ms/op 289.32 ms/op 1.30
mainnet_e81889 - altair beforeProcessEpoch 57.287 ms/op 47.676 ms/op 1.20
mainnet_e81889 - altair processJustificationAndFinalization 24.544 us/op 17.138 us/op 1.43
mainnet_e81889 - altair processInactivityUpdates 7.5549 ms/op 5.1540 ms/op 1.47
mainnet_e81889 - altair processRewardsAndPenalties 78.075 ms/op 54.778 ms/op 1.43
mainnet_e81889 - altair processRegistryUpdates 3.0860 us/op 2.6040 us/op 1.19
mainnet_e81889 - altair processSlashings 673.00 ns/op 625.00 ns/op 1.08
mainnet_e81889 - altair processEth1DataReset 822.00 ns/op 623.00 ns/op 1.32
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.5458 ms/op 1.1894 ms/op 1.30
mainnet_e81889 - altair processSlashingsReset 4.1480 us/op 4.9550 us/op 0.84
mainnet_e81889 - altair processRandaoMixesReset 4.7050 us/op 4.6060 us/op 1.02
mainnet_e81889 - altair processHistoricalRootsUpdate 1.2890 us/op 809.00 ns/op 1.59
mainnet_e81889 - altair processParticipationFlagUpdates 4.6750 us/op 2.6510 us/op 1.76
mainnet_e81889 - altair processSyncCommitteeUpdates 676.00 ns/op 994.00 ns/op 0.68
mainnet_e81889 - altair afterProcessEpoch 134.70 ms/op 123.98 ms/op 1.09
phase0 processEpoch - mainnet_e58758 421.13 ms/op 350.86 ms/op 1.20
mainnet_e58758 - phase0 beforeProcessEpoch 172.06 ms/op 108.12 ms/op 1.59
mainnet_e58758 - phase0 processJustificationAndFinalization 28.042 us/op 20.203 us/op 1.39
mainnet_e58758 - phase0 processRewardsAndPenalties 73.591 ms/op 45.455 ms/op 1.62
mainnet_e58758 - phase0 processRegistryUpdates 11.255 us/op 8.8180 us/op 1.28
mainnet_e58758 - phase0 processSlashings 778.00 ns/op 575.00 ns/op 1.35
mainnet_e58758 - phase0 processEth1DataReset 1.1330 us/op 601.00 ns/op 1.89
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.3148 ms/op 1.0064 ms/op 1.31
mainnet_e58758 - phase0 processSlashingsReset 6.4420 us/op 3.8740 us/op 1.66
mainnet_e58758 - phase0 processRandaoMixesReset 9.5550 us/op 5.6690 us/op 1.69
mainnet_e58758 - phase0 processHistoricalRootsUpdate 2.0720 us/op 879.00 ns/op 2.36
mainnet_e58758 - phase0 processParticipationRecordUpdates 8.7080 us/op 5.4550 us/op 1.60
mainnet_e58758 - phase0 afterProcessEpoch 109.71 ms/op 100.72 ms/op 1.09
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.3216 ms/op 1.2285 ms/op 1.08
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 2.4642 ms/op 1.4298 ms/op 1.72
altair processInactivityUpdates - 250000 normalcase 37.170 ms/op 20.800 ms/op 1.79
altair processInactivityUpdates - 250000 worstcase 33.216 ms/op 21.911 ms/op 1.52
phase0 processRegistryUpdates - 250000 normalcase 12.936 us/op 7.3780 us/op 1.75
phase0 processRegistryUpdates - 250000 badcase_full_deposits 444.70 us/op 267.63 us/op 1.66
phase0 processRegistryUpdates - 250000 worstcase 0.5 189.03 ms/op 121.86 ms/op 1.55
altair processRewardsAndPenalties - 250000 normalcase 82.285 ms/op 52.819 ms/op 1.56
altair processRewardsAndPenalties - 250000 worstcase 77.613 ms/op 57.830 ms/op 1.34
phase0 getAttestationDeltas - 250000 normalcase 10.548 ms/op 6.5394 ms/op 1.61
phase0 getAttestationDeltas - 250000 worstcase 11.180 ms/op 6.6672 ms/op 1.68
phase0 processSlashings - 250000 worstcase 4.7334 ms/op 3.4308 ms/op 1.38
altair processSyncCommitteeUpdates - 250000 217.80 ms/op 173.89 ms/op 1.25
BeaconState.hashTreeRoot - No change 290.00 ns/op 254.00 ns/op 1.14
BeaconState.hashTreeRoot - 1 full validator 62.761 us/op 52.707 us/op 1.19
BeaconState.hashTreeRoot - 32 full validator 674.53 us/op 514.05 us/op 1.31
BeaconState.hashTreeRoot - 512 full validator 6.1204 ms/op 5.7423 ms/op 1.07
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 70.908 us/op 63.472 us/op 1.12
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 968.77 us/op 894.11 us/op 1.08
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 14.244 ms/op 10.951 ms/op 1.30
BeaconState.hashTreeRoot - 1 balances 54.967 us/op 49.585 us/op 1.11
BeaconState.hashTreeRoot - 32 balances 502.77 us/op 438.20 us/op 1.15
BeaconState.hashTreeRoot - 512 balances 5.5557 ms/op 4.2530 ms/op 1.31
BeaconState.hashTreeRoot - 250000 balances 90.989 ms/op 73.049 ms/op 1.25
aggregationBits - 2048 els - zipIndexesInBitList 23.417 us/op 16.767 us/op 1.40
regular array get 100000 times 46.222 us/op 42.284 us/op 1.09
wrappedArray get 100000 times 35.344 us/op 32.522 us/op 1.09
arrayWithProxy get 100000 times 17.587 ms/op 15.337 ms/op 1.15
ssz.Root.equals 959.00 ns/op 545.00 ns/op 1.76
byteArrayEquals 1.0270 us/op 541.00 ns/op 1.90
shuffle list - 16384 els 7.5573 ms/op 6.9147 ms/op 1.09
shuffle list - 250000 els 110.66 ms/op 101.79 ms/op 1.09
processSlot - 1 slots 11.595 us/op 9.4600 us/op 1.23
processSlot - 32 slots 1.5894 ms/op 1.3229 ms/op 1.20
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 45.843 ms/op 33.305 ms/op 1.38
getCommitteeAssignments - req 1 vs - 250000 vc 3.2220 ms/op 2.7344 ms/op 1.18
getCommitteeAssignments - req 100 vs - 250000 vc 4.5145 ms/op 3.9765 ms/op 1.14
getCommitteeAssignments - req 1000 vs - 250000 vc 4.8838 ms/op 4.3839 ms/op 1.11
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 5.2900 ns/op 4.8200 ns/op 1.10
state getBlockRootAtSlot - 250000 vs - 7PWei 1.2405 us/op 901.36 ns/op 1.38
computeProposers - vc 250000 12.297 ms/op 10.468 ms/op 1.17
computeEpochShuffling - vc 250000 114.90 ms/op 99.493 ms/op 1.15
getNextSyncCommittee - vc 250000 196.18 ms/op 171.03 ms/op 1.15
computeSigningRoot for AttestationData 15.113 us/op 13.145 us/op 1.15
hash AttestationData serialized data then Buffer.toString(base64) 2.6799 us/op 2.3410 us/op 1.14
toHexString serialized data 1.1850 us/op 1.0388 us/op 1.14
Buffer.toString(base64) 354.68 ns/op 316.02 ns/op 1.12

by benchmarkbot/action

@twoeths twoeths marked this pull request as ready for review July 7, 2023 08:45
@twoeths twoeths requested a review from a team as a code owner July 7, 2023 08:45
@wemeetagain
Copy link
Member

verifySignatureSetsSameSigningRoot has "verifyOnMainThread" to verify on main thread or not

Not sure that we'd ever want to verify on the main thread?

@twoeths
Copy link
Contributor Author

twoeths commented Jul 7, 2023

verifySignatureSetsSameSigningRoot has "verifyOnMainThread" to verify on main thread or not

Not sure that we'd ever want to verify on the main thread?

@wemeetagain I think the theory of not to do heavy operations on main thread is because normally main thread is for I/O operation. Now we do I/O operations on worker thread, we can test verifying signatures (the 1st round) on main thread (and leave all fallback verifications on worker thread), this is when useWorker=true. The network processor is designed not to do anything when we receive/process gossip block already

I tested verifyOnMainThread=true with useWorker=false (no network thread), it takes 15% of cpu profile and mesh peers range from 2 to 6 which is not too bad (verification time of an attestation is <10ms). I'm not sure verifyOnMainThread=true works fine with useWorker=true but would like to give us a chance to test that

@twoeths
Copy link
Contributor Author

twoeths commented Jul 9, 2023

another use case for verifyOnMainThread=true is #5739

Copy link
Member

@matthewkeil matthewkeil left a comment

Choose a reason for hiding this comment

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

I am curious what you think about simplifying the API back to:

type WorkerApi = {
  verifyManySignatureSets(workReqArr: BlsWorkReq[]): Promise<BlsWorkResult>;
};

That way there is only a single api from the chain code perspective and the decision making about when and to check messages for being the same and to verify accordingly all happens within the IBlsVerifier. We would be able to achieve the grouping of similar attestations across multiple gossip messages and I think it will simplify the worker API.

If you don't think this is a good idea let me know and I will come back and finish the review with the code as-is.

@philknows philknows added this to the v1.10.0 milestone Jul 11, 2023
opts?: Pick<VerifySignatureOpts, "verifyOnMainThread">
): Promise<boolean[]> {
if (opts?.verifyOnMainThread && !this.blsVerifyAllMultiThread) {
const isSameMessage = true;
Copy link
Member

Choose a reason for hiding this comment

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

What do you think about a metric for main thread time similar to the other case?

Copy link
Member

Choose a reason for hiding this comment

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

Should we also be counting the sets and keys to see what kind of gains we get under load?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for reminding this, all metrics are available, I only need to add "api" label there

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we also be counting the sets and keys to see what kind of gains we get under load?

we counted the api call, regarding the gain we can count on bls.test.ts perf test

@twoeths
Copy link
Contributor Author

twoeths commented Jul 11, 2023

I am curious what you think about simplifying the API back to:

type WorkerApi = {
  verifyManySignatureSets(workReqArr: BlsWorkReq[]): Promise<BlsWorkResult>;
};

That way there is only a single api from the chain code perspective and the decision making about when and to check messages for being the same and to verify accordingly all happens within the IBlsVerifier. We would be able to achieve the grouping of similar attestations across multiple gossip messages and I think it will simplify the worker API.

If you don't think this is a good idea let me know and I will come back and finish the review with the code as-is.

@matthewkeil thanks for looking into this PR. As discussed, the part of filtering signature sets with the same message is done in #5729 so we really need a new api here. I'm happy if you have any suggestions or simpler way to achieve this.

Copy link
Member

@matthewkeil matthewkeil left a comment

Choose a reason for hiding this comment

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

Thanks for taking the time to chat about this. Ill definitely spend some more time looking through the draft PR implementing this over the week!! Awesome idea 🚀 for optimization of the gossip work

@matthewkeil matthewkeil self-requested a review July 11, 2023 09:06
@philknows philknows modified the milestones: v1.10.0, v1.11.0 Jul 11, 2023
@dapplion
Copy link
Contributor

@tuyennhv I think I found a simpler approach extending your idea. It re-uses the existing queue, such that:

  • same message batch are lazily aggregated and sent to the worker
  • on failure are put back into the queue
  • plus nice metrics and use of enums to split job types

Please take a look and consider incorporating

https://github.com/ChainSafe/lodestar/compare/tuyen/verifyManySignatureSetsSameMessage-lion-take?expand=1

@twoeths
Copy link
Contributor Author

twoeths commented Jul 12, 2023

@tuyennhv I think I found a simpler approach extending your idea. It re-uses the existing queue, such that:

  • same message batch are lazily aggregated and sent to the worker
  • on failure are put back into the queue
  • plus nice metrics and use of enums to split job types

Please take a look and consider incorporating

https://github.com/ChainSafe/lodestar/compare/tuyen/verifyManySignatureSetsSameMessage-lion-take?expand=1

@dapplion that's great, it looks really simpler, I created #5747

closing this PR for now

@twoeths twoeths closed this Jul 12, 2023
@twoeths twoeths deleted the tuyen/verifyManySignatureSetsSameMessage branch December 14, 2023 04:25
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