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

fix: improve performance of getExpectedWithdrawals #7045

Merged
merged 3 commits into from
Sep 4, 2024

Conversation

twoeths
Copy link
Contributor

@twoeths twoeths commented Aug 23, 2024

Motivation

  • improve performance of getExpectedWithdrawals()

Description

  • for EIP-7002 withdrawals, only call getAllReadonly() conditionally due to its big length limit
  • for capella withdrawals, improve performance by embedding logics of isFullyWithdrawableValidator() and isPartiallyWithdrawableValidator()
    • these functions are now moved since they are not in use
    • this also match the current implementation
  • refactor partialWithdrawalsCount to eip7002WithdrawalsCount to make it more meaningful. partialWithdrawalsCount sounds link to the capella withdrawal

Note

  • some benchmark may still fails since in electra, max effective balance is per validator and the complexity of hasWithdrawableCredentials but the test time is in us so should not be an issue. I don't see we can improve it due to spec change.

Copy link

codecov bot commented Aug 23, 2024

Codecov Report

Attention: Patch coverage is 44.44444% with 15 lines in your changes missing coverage. Please review.

Project coverage is 49.31%. Comparing base (a7286bd) to head (91e0235).
Report is 4 commits behind head on unstable.

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #7045      +/-   ##
============================================
- Coverage     49.37%   49.31%   -0.06%     
============================================
  Files           589      592       +3     
  Lines         39233    39275      +42     
  Branches       2246     2250       +4     
============================================
  Hits          19370    19370              
- Misses        19822    19864      +42     
  Partials         41       41              

@twoeths twoeths marked this pull request as ready for review August 23, 2024 09:11
@twoeths twoeths requested a review from a team as a code owner August 23, 2024 09:11
@twoeths twoeths force-pushed the te/improve_get_expected_withdrawals branch from 8326976 to a8ee8c7 Compare August 24, 2024 09:05
} from "../util/index.js";

export function processWithdrawals(
fork: ForkSeq,
state: CachedBeaconStateCapella | CachedBeaconStateElectra,
payload: capella.FullOrBlindedExecutionPayload
): void {
const {withdrawals: expectedWithdrawals, partialWithdrawalsCount} = getExpectedWithdrawals(fork, state);
const {withdrawals: expectedWithdrawals, executionWithdrawalsCount} = getExpectedWithdrawals(fork, state);
Copy link
Member

Choose a reason for hiding this comment

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

refactor partialWithdrawalsCount to eip7002WithdrawalsCount to make it more meaningful. partialWithdrawalsCount sounds link to the capella withdrawal

On second thought, I am not sure about this rename. Partial withdrawals is a term introduced in Electra and also matches naming used in the spec

def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None:
    expected_withdrawals, partial_withdrawals_count = get_expected_withdrawals(state)  # [Modified in Electra:EIP7251]

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 see, the one from spec is also confusing because we already have full withdrawals and partial withdrawals since capella
how about electraPartialWithdrawalsCount?

Copy link
Member

Choose a reason for hiding this comment

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

But in capella, there was no difference in handling full vs. partial withdrawal, they were both considered as a withdrawal just with a different amount.

I don't see us using the term "partial withdrawal" on unstable branch, so I am wondering if we even need the electra prefix to differentiate in the code

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 reverted the change, added comments instead

Copy link
Contributor

@ensi321 ensi321 Aug 29, 2024

Choose a reason for hiding this comment

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

Partial withdrawals is a term introduced in Electra and also matches naming used in the spec

I believe the term is introduced in Capella. Back then the definition is straightforward:
Partial withdrawal: A withdrawal with amount < 32eth that's generated from withdrawal sweep
Full withdrawal: A withdrawal with amount equals to entire validator's balance generated from withdrawal sweep (underlying reason could be being slashed, voluntary exit etc.)

In Electra, we have EL triggered partial withdrawal aka withdrawal request aka execution withdrawal aka execution request withdrawal. The associated field in beacon state is pending_partial_withdrawals.

EIP-7002's partial withdrawal is enhanced to support full withdrawal in maxEB when the amount is set to 0. But the associate spec (eg. state.pending_partial_withdrawals, partial_withdrawals_count in get_expected_withdrawal) are not updated.

So @twoeths's motive to rename this is reasonable. Something like execution_withdrawals_count sound pretty reasonable to me. However we should change the spec (and it's a good idea) first before updating the related naming in Lodestar though.

Copy link
Member

Choose a reason for hiding this comment

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

Something like execution_withdrawals_count sound pretty reasonable to me

yeah that was my first suggestion (#7045 (comment)) and initial thought but after reading up on spec I wasn't sure it's a good rename.

However we should change the spec (and it's a good idea) first before updating the related naming in Lodestar though.

sounds reasonable to suggest this rename on the spec as well

Copy link
Contributor

@ensi321 ensi321 Sep 2, 2024

Choose a reason for hiding this comment

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

EIP-7002's partial withdrawal is enhanced to support full withdrawal in maxEB when the amount is set to 0. But the associate spec (eg. state.pending_partial_withdrawals, partial_withdrawals_count in get_expected_withdrawal) are not updated.

I was wrong. Execution requests with 0 amount are filtered during process_withdrawal_request and will not be appended to state.pending_partial_withdrawals so the naming in the spec is fine (including partial_withdrawals_count in get_expected_withdrawals.

refactor partialWithdrawalsCount to eip7002WithdrawalsCount to make it more meaningful. partialWithdrawalsCount sounds link to the capella withdrawal

In Capella spec, there was never a direct mention of partial withdrawal. The closest to this is is_**partially_withdrawable**_validator to indicate a validator can have amount < 32 withdrawn as part of the withdrawal sweep process. But the term partial withdrawal indeed was used extensively in Capella spec tests. We can change those instead.

@twoeths twoeths force-pushed the te/improve_get_expected_withdrawals branch from a0eb1c3 to d87d585 Compare August 29, 2024 01:35
Copy link
Contributor

@ensi321 ensi321 left a comment

Choose a reason for hiding this comment

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

General approach looks good to me! Regarding the comments on 7002 pending partial withdrawal naming I would suggest replace them with todos. I will open a consensus specs PR to rename the variables and then we can come back and address the todos.

Comment on lines +103 to +106
const allPendingPartialWithdrawals =
stateElectra.pendingPartialWithdrawals.length <= MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP
? stateElectra.pendingPartialWithdrawals.getAllReadonly()
: null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const allPendingPartialWithdrawals =
stateElectra.pendingPartialWithdrawals.length <= MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP
? stateElectra.pendingPartialWithdrawals.getAllReadonly()
: null;
const numPendingPartialWithdrawals = stateElectra.pendingPartialWithdrawals.length;
const allPendingPartialWithdrawals =
numPendingPartialWithdrawals <= MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP
? stateElectra.pendingPartialWithdrawals.getAllReadonly()
: Array.from(
{ length: numPendingPartialWithdrawals },
(_, i) => stateElectra.pendingPartialWithdrawals.getReadonly(i)
);

Copy link
Contributor

Choose a reason for hiding this comment

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

See if this makes sense. I think it's cleaner this way cuz we don't need to set allPendingPartialWithdrawals to null, and no more conditional assignment for withdrawal in the for loop

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that'd actually make it worse than the initial version because getAllReadonly() is way more performant than calling getReadonly(i) n times especially if n is big

packages/state-transition/src/block/processWithdrawals.ts Outdated Show resolved Hide resolved
@wemeetagain wemeetagain changed the base branch from electra-fork-rebasejul30 to unstable August 29, 2024 13:24
Copy link
Contributor

github-actions bot commented Sep 2, 2024

⚠️ Performance Alert ⚠️

Possible performance regression was detected for some benchmarks.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold.

Benchmark suite Current: c5f77dd Previous: 19ac678 Ratio
bitArray.getTrueBitIndexes() bitLen 248 6.3500 us/op 2.0690 us/op 3.07
bitArray.getTrueBitIndexes() bitLen 512 12.460 us/op 3.7920 us/op 3.29
Set add up to 256 items then delete first 23.276 us/op 7.2082 us/op 3.23
forkChoice updateHead vc 100000 bc 64 eq 0 1.9064 ms/op 406.49 us/op 4.69
forkChoice updateHead vc 600000 bc 64 eq 0 9.4379 ms/op 2.4888 ms/op 3.79
forkChoice updateHead vc 600000 bc 7200 eq 0 8.9051 ms/op 2.8583 ms/op 3.12
Full benchmark results
Benchmark suite Current: c5f77dd Previous: 19ac678 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.9688 ms/op 2.8321 ms/op 0.70
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 55.864 us/op 67.494 us/op 0.83
BLS verify - blst 906.36 us/op 848.04 us/op 1.07
BLS verifyMultipleSignatures 3 - blst 1.2604 ms/op 1.3035 ms/op 0.97
BLS verifyMultipleSignatures 8 - blst 1.9161 ms/op 1.8701 ms/op 1.02
BLS verifyMultipleSignatures 32 - blst 5.7419 ms/op 5.3396 ms/op 1.08
BLS verifyMultipleSignatures 64 - blst 10.755 ms/op 9.8476 ms/op 1.09
BLS verifyMultipleSignatures 128 - blst 17.166 ms/op 17.476 ms/op 0.98
BLS deserializing 10000 signatures 686.05 ms/op 637.59 ms/op 1.08
BLS deserializing 100000 signatures 6.7823 s/op 6.3941 s/op 1.06
BLS verifyMultipleSignatures - same message - 3 - blst 928.99 us/op 967.98 us/op 0.96
BLS verifyMultipleSignatures - same message - 8 - blst 1.0973 ms/op 1.0840 ms/op 1.01
BLS verifyMultipleSignatures - same message - 32 - blst 1.7028 ms/op 1.6580 ms/op 1.03
BLS verifyMultipleSignatures - same message - 64 - blst 2.6379 ms/op 2.4772 ms/op 1.06
BLS verifyMultipleSignatures - same message - 128 - blst 4.3541 ms/op 4.0416 ms/op 1.08
BLS aggregatePubkeys 32 - blst 19.891 us/op 18.894 us/op 1.05
BLS aggregatePubkeys 128 - blst 70.848 us/op 64.499 us/op 1.10
notSeenSlots=1 numMissedVotes=1 numBadVotes=10 75.147 ms/op 61.472 ms/op 1.22
notSeenSlots=1 numMissedVotes=0 numBadVotes=4 57.318 ms/op 57.203 ms/op 1.00
notSeenSlots=2 numMissedVotes=1 numBadVotes=10 37.799 ms/op 31.743 ms/op 1.19
getSlashingsAndExits - default max 132.68 us/op 86.169 us/op 1.54
getSlashingsAndExits - 2k 318.80 us/op 304.34 us/op 1.05
proposeBlockBody type=full, size=empty 5.7900 ms/op 5.0533 ms/op 1.15
isKnown best case - 1 super set check 303.00 ns/op 511.00 ns/op 0.59
isKnown normal case - 2 super set checks 325.00 ns/op 500.00 ns/op 0.65
isKnown worse case - 16 super set checks 301.00 ns/op 507.00 ns/op 0.59
InMemoryCheckpointStateCache - add get delete 3.9830 us/op 3.1310 us/op 1.27
updateUnfinalizedPubkeys - updating 10 pubkeys 1.2513 ms/op 448.06 us/op 2.79
updateUnfinalizedPubkeys - updating 100 pubkeys 2.6408 ms/op 2.2140 ms/op 1.19
updateUnfinalizedPubkeys - updating 1000 pubkeys 55.300 ms/op 40.379 ms/op 1.37
validate api signedAggregateAndProof - struct 1.6879 ms/op 1.6546 ms/op 1.02
validate gossip signedAggregateAndProof - struct 1.5118 ms/op 1.5846 ms/op 0.95
validate gossip attestation - vc 640000 1.1035 ms/op 986.09 us/op 1.12
batch validate gossip attestation - vc 640000 - chunk 32 141.86 us/op 136.31 us/op 1.04
batch validate gossip attestation - vc 640000 - chunk 64 137.14 us/op 124.58 us/op 1.10
batch validate gossip attestation - vc 640000 - chunk 128 113.21 us/op 105.41 us/op 1.07
batch validate gossip attestation - vc 640000 - chunk 256 109.81 us/op 99.958 us/op 1.10
pickEth1Vote - no votes 1.1922 ms/op 861.83 us/op 1.38
pickEth1Vote - max votes 6.6475 ms/op 4.3587 ms/op 1.53
pickEth1Vote - Eth1Data hashTreeRoot value x2048 13.242 ms/op 10.193 ms/op 1.30
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 21.025 ms/op 13.310 ms/op 1.58
pickEth1Vote - Eth1Data fastSerialize value x2048 485.47 us/op 363.20 us/op 1.34
pickEth1Vote - Eth1Data fastSerialize tree x2048 2.6996 ms/op 2.0327 ms/op 1.33
bytes32 toHexString 479.00 ns/op 592.00 ns/op 0.81
bytes32 Buffer.toString(hex) 279.00 ns/op 446.00 ns/op 0.63
bytes32 Buffer.toString(hex) from Uint8Array 427.00 ns/op 538.00 ns/op 0.79
bytes32 Buffer.toString(hex) + 0x 268.00 ns/op 453.00 ns/op 0.59
Object access 1 prop 0.18000 ns/op 0.33000 ns/op 0.55
Map access 1 prop 0.14900 ns/op 0.33100 ns/op 0.45
Object get x1000 6.2640 ns/op 5.1880 ns/op 1.21
Map get x1000 7.2810 ns/op 6.1030 ns/op 1.19
Object set x1000 45.402 ns/op 22.634 ns/op 2.01
Map set x1000 34.399 ns/op 19.357 ns/op 1.78
Return object 10000 times 0.32210 ns/op 0.30150 ns/op 1.07
Throw Error 10000 times 3.5987 us/op 2.6919 us/op 1.34
toHex 184.03 ns/op 109.48 ns/op 1.68
Buffer.from 172.64 ns/op 104.16 ns/op 1.66
shared Buffer 111.06 ns/op 69.938 ns/op 1.59
fastMsgIdFn sha256 / 200 bytes 2.7340 us/op 2.0060 us/op 1.36
fastMsgIdFn h32 xxhash / 200 bytes 348.00 ns/op 419.00 ns/op 0.83
fastMsgIdFn h64 xxhash / 200 bytes 313.00 ns/op 449.00 ns/op 0.70
fastMsgIdFn sha256 / 1000 bytes 8.5010 us/op 5.8630 us/op 1.45
fastMsgIdFn h32 xxhash / 1000 bytes 483.00 ns/op 538.00 ns/op 0.90
fastMsgIdFn h64 xxhash / 1000 bytes 389.00 ns/op 514.00 ns/op 0.76
fastMsgIdFn sha256 / 10000 bytes 70.362 us/op 49.293 us/op 1.43
fastMsgIdFn h32 xxhash / 10000 bytes 2.0750 us/op 1.8950 us/op 1.09
fastMsgIdFn h64 xxhash / 10000 bytes 1.3310 us/op 1.3280 us/op 1.00
send data - 1000 256B messages 17.709 ms/op 9.6281 ms/op 1.84
send data - 1000 512B messages 19.703 ms/op 13.622 ms/op 1.45
send data - 1000 1024B messages 29.716 ms/op 20.433 ms/op 1.45
send data - 1000 1200B messages 32.517 ms/op 23.685 ms/op 1.37
send data - 1000 2048B messages 35.602 ms/op 30.508 ms/op 1.17
send data - 1000 4096B messages 35.565 ms/op 27.505 ms/op 1.29
send data - 1000 16384B messages 79.944 ms/op 72.192 ms/op 1.11
send data - 1000 65536B messages 281.19 ms/op 246.77 ms/op 1.14
enrSubnets - fastDeserialize 64 bits 1.6450 us/op 1.1560 us/op 1.42
enrSubnets - ssz BitVector 64 bits 521.00 ns/op 521.00 ns/op 1.00
enrSubnets - fastDeserialize 4 bits 232.00 ns/op 342.00 ns/op 0.68
enrSubnets - ssz BitVector 4 bits 502.00 ns/op 527.00 ns/op 0.95
prioritizePeers score -10:0 att 32-0.1 sync 2-0 226.63 us/op 108.45 us/op 2.09
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 256.95 us/op 133.26 us/op 1.93
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 370.95 us/op 187.65 us/op 1.98
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 527.51 us/op 330.36 us/op 1.60
prioritizePeers score 0:0 att 64-1 sync 4-1 1.0164 ms/op 400.94 us/op 2.53
array of 16000 items push then shift 1.8546 us/op 1.2120 us/op 1.53
LinkedList of 16000 items push then shift 12.152 ns/op 7.1240 ns/op 1.71
array of 16000 items push then pop 183.11 ns/op 79.404 ns/op 2.31
LinkedList of 16000 items push then pop 10.393 ns/op 6.0520 ns/op 1.72
array of 24000 items push then shift 3.0463 us/op 1.7675 us/op 1.72
LinkedList of 24000 items push then shift 10.763 ns/op 6.7080 ns/op 1.60
array of 24000 items push then pop 225.11 ns/op 102.47 ns/op 2.20
LinkedList of 24000 items push then pop 9.4600 ns/op 6.0500 ns/op 1.56
intersect bitArray bitLen 8 8.8290 ns/op 5.1640 ns/op 1.71
intersect array and set length 8 115.52 ns/op 35.474 ns/op 3.26
intersect bitArray bitLen 128 33.839 ns/op 25.498 ns/op 1.33
intersect array and set length 128 1.3093 us/op 573.44 ns/op 2.28
bitArray.getTrueBitIndexes() bitLen 128 3.4350 us/op 1.3960 us/op 2.46
bitArray.getTrueBitIndexes() bitLen 248 6.3500 us/op 2.0690 us/op 3.07
bitArray.getTrueBitIndexes() bitLen 512 12.460 us/op 3.7920 us/op 3.29
Buffer.concat 32 items 1.5760 us/op 1.0110 us/op 1.56
Uint8Array.set 32 items 2.8210 us/op 2.0080 us/op 1.40
Buffer.copy 3.3070 us/op 1.8130 us/op 1.82
Uint8Array.set - with subarray 4.7790 us/op 1.8720 us/op 2.55
Uint8Array.set - without subarray 2.7210 us/op 1.4190 us/op 1.92
getUint32 - dataview 399.00 ns/op 406.00 ns/op 0.98
getUint32 - manual 369.00 ns/op 332.00 ns/op 1.11
Set add up to 64 items then delete first 3.8208 us/op 1.7552 us/op 2.18
OrderedSet add up to 64 items then delete first 6.0422 us/op 2.7300 us/op 2.21
Set add up to 64 items then delete last 3.7931 us/op 2.0480 us/op 1.85
OrderedSet add up to 64 items then delete last 6.4296 us/op 3.1501 us/op 2.04
Set add up to 64 items then delete middle 4.1923 us/op 2.0454 us/op 2.05
OrderedSet add up to 64 items then delete middle 7.9100 us/op 4.5576 us/op 1.74
Set add up to 128 items then delete first 9.2714 us/op 3.9423 us/op 2.35
OrderedSet add up to 128 items then delete first 14.217 us/op 5.8989 us/op 2.41
Set add up to 128 items then delete last 9.1864 us/op 3.9290 us/op 2.34
OrderedSet add up to 128 items then delete last 13.403 us/op 6.1054 us/op 2.20
Set add up to 128 items then delete middle 7.9311 us/op 3.9268 us/op 2.02
OrderedSet add up to 128 items then delete middle 19.852 us/op 11.927 us/op 1.66
Set add up to 256 items then delete first 23.276 us/op 7.2082 us/op 3.23
OrderedSet add up to 256 items then delete first 29.556 us/op 11.164 us/op 2.65
Set add up to 256 items then delete last 21.109 us/op 7.2220 us/op 2.92
OrderedSet add up to 256 items then delete last 23.951 us/op 11.530 us/op 2.08
Set add up to 256 items then delete middle 15.157 us/op 7.1636 us/op 2.12
OrderedSet add up to 256 items then delete middle 55.210 us/op 32.853 us/op 1.68
transfer serialized Status (84 B) 1.6070 us/op 1.5540 us/op 1.03
copy serialized Status (84 B) 1.3580 us/op 1.3360 us/op 1.02
transfer serialized SignedVoluntaryExit (112 B) 1.6070 us/op 1.6770 us/op 0.96
copy serialized SignedVoluntaryExit (112 B) 1.3950 us/op 1.4590 us/op 0.96
transfer serialized ProposerSlashing (416 B) 1.8710 us/op 2.5100 us/op 0.75
copy serialized ProposerSlashing (416 B) 1.7030 us/op 2.5390 us/op 0.67
transfer serialized Attestation (485 B) 1.7520 us/op 2.3670 us/op 0.74
copy serialized Attestation (485 B) 2.2050 us/op 2.4590 us/op 0.90
transfer serialized AttesterSlashing (33232 B) 3.0580 us/op 2.7370 us/op 1.12
copy serialized AttesterSlashing (33232 B) 15.323 us/op 5.0920 us/op 3.01
transfer serialized Small SignedBeaconBlock (128000 B) 2.5600 us/op 2.7930 us/op 0.92
copy serialized Small SignedBeaconBlock (128000 B) 30.554 us/op 14.499 us/op 2.11
transfer serialized Avg SignedBeaconBlock (200000 B) 4.4460 us/op 2.5670 us/op 1.73
copy serialized Avg SignedBeaconBlock (200000 B) 47.176 us/op 12.072 us/op 3.91
transfer serialized BlobsSidecar (524380 B) 3.6950 us/op 2.5980 us/op 1.42
copy serialized BlobsSidecar (524380 B) 226.94 us/op 102.70 us/op 2.21
transfer serialized Big SignedBeaconBlock (1000000 B) 7.1340 us/op 3.3070 us/op 2.16
copy serialized Big SignedBeaconBlock (1000000 B) 559.16 us/op 137.54 us/op 4.07
pass gossip attestations to forkchoice per slot 3.8366 ms/op 2.4148 ms/op 1.59
forkChoice updateHead vc 100000 bc 64 eq 0 1.9064 ms/op 406.49 us/op 4.69
forkChoice updateHead vc 600000 bc 64 eq 0 9.4379 ms/op 2.4888 ms/op 3.79
forkChoice updateHead vc 1000000 bc 64 eq 0 7.5768 ms/op 4.0793 ms/op 1.86
forkChoice updateHead vc 600000 bc 320 eq 0 4.7880 ms/op 2.3563 ms/op 2.03
forkChoice updateHead vc 600000 bc 1200 eq 0 5.5997 ms/op 2.3778 ms/op 2.36
forkChoice updateHead vc 600000 bc 7200 eq 0 8.9051 ms/op 2.8583 ms/op 3.12
forkChoice updateHead vc 600000 bc 64 eq 1000 12.112 ms/op 9.1681 ms/op 1.32
forkChoice updateHead vc 600000 bc 64 eq 10000 12.383 ms/op 9.0124 ms/op 1.37
forkChoice updateHead vc 600000 bc 64 eq 300000 27.058 ms/op 10.988 ms/op 2.46
computeDeltas 500000 validators 300 proto nodes 6.5826 ms/op 2.9131 ms/op 2.26
computeDeltas 500000 validators 1200 proto nodes 6.8187 ms/op 2.9822 ms/op 2.29
computeDeltas 500000 validators 7200 proto nodes 5.2161 ms/op 3.0487 ms/op 1.71
computeDeltas 750000 validators 300 proto nodes 7.1943 ms/op 4.6492 ms/op 1.55
computeDeltas 750000 validators 1200 proto nodes 7.2951 ms/op 4.5435 ms/op 1.61
computeDeltas 750000 validators 7200 proto nodes 8.0751 ms/op 4.6144 ms/op 1.75
computeDeltas 1400000 validators 300 proto nodes 12.341 ms/op 8.7679 ms/op 1.41
computeDeltas 1400000 validators 1200 proto nodes 10.845 ms/op 8.8281 ms/op 1.23
computeDeltas 1400000 validators 7200 proto nodes 10.866 ms/op 8.7140 ms/op 1.25
computeDeltas 2100000 validators 300 proto nodes 16.026 ms/op 13.373 ms/op 1.20
computeDeltas 2100000 validators 1200 proto nodes 15.946 ms/op 13.379 ms/op 1.19
computeDeltas 2100000 validators 7200 proto nodes 15.528 ms/op 13.010 ms/op 1.19
altair processAttestation - 250000 vs - 7PWei normalcase 1.8544 ms/op 1.4445 ms/op 1.28
altair processAttestation - 250000 vs - 7PWei worstcase 2.5665 ms/op 2.1422 ms/op 1.20
altair processAttestation - setStatus - 1/6 committees join 87.712 us/op 79.887 us/op 1.10
altair processAttestation - setStatus - 1/3 committees join 172.33 us/op 144.41 us/op 1.19
altair processAttestation - setStatus - 1/2 committees join 243.76 us/op 211.25 us/op 1.15
altair processAttestation - setStatus - 2/3 committees join 317.89 us/op 277.98 us/op 1.14
altair processAttestation - setStatus - 4/5 committees join 458.55 us/op 389.94 us/op 1.18
altair processAttestation - setStatus - 100% committees join 557.41 us/op 468.08 us/op 1.19
altair processBlock - 250000 vs - 7PWei normalcase 5.4182 ms/op 3.7004 ms/op 1.46
altair processBlock - 250000 vs - 7PWei normalcase hashState 27.495 ms/op 24.910 ms/op 1.10
altair processBlock - 250000 vs - 7PWei worstcase 39.679 ms/op 35.160 ms/op 1.13
altair processBlock - 250000 vs - 7PWei worstcase hashState 73.621 ms/op 67.930 ms/op 1.08
phase0 processBlock - 250000 vs - 7PWei normalcase 2.0522 ms/op 1.8277 ms/op 1.12
phase0 processBlock - 250000 vs - 7PWei worstcase 25.463 ms/op 21.938 ms/op 1.16
altair processEth1Data - 250000 vs - 7PWei normalcase 310.52 us/op 243.91 us/op 1.27
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15 5.8270 us/op 6.7210 us/op 0.87
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:219 40.382 us/op 38.024 us/op 1.06
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42 10.597 us/op 12.144 us/op 0.87
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18 5.9100 us/op 6.7360 us/op 0.88
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1020 176.43 us/op 149.58 us/op 1.18
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11777 1.3493 ms/op 953.99 us/op 1.41
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.9349 ms/op 1.3125 ms/op 1.47
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.8689 ms/op 1.3012 ms/op 1.44
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.6828 ms/op 3.0356 ms/op 1.21
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 1.9278 ms/op 1.3580 ms/op 1.42
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 3.8660 ms/op 3.0768 ms/op 1.26
Tree 40 250000 create 254.50 ms/op 183.32 ms/op 1.39
Tree 40 250000 get(125000) 139.50 ns/op 105.83 ns/op 1.32
Tree 40 250000 set(125000) 646.95 ns/op 584.64 ns/op 1.11
Tree 40 250000 toArray() 16.333 ms/op 12.865 ms/op 1.27
Tree 40 250000 iterate all - toArray() + loop 17.549 ms/op 9.6578 ms/op 1.82
Tree 40 250000 iterate all - get(i) 52.613 ms/op 43.002 ms/op 1.22
Array 250000 create 3.1353 ms/op 2.4141 ms/op 1.30
Array 250000 clone - spread 1.4325 ms/op 1.2351 ms/op 1.16
Array 250000 get(125000) 0.43000 ns/op 0.62200 ns/op 0.69
Array 250000 set(125000) 0.44300 ns/op 0.61400 ns/op 0.72
Array 250000 iterate all - loop 83.350 us/op 75.278 us/op 1.11
phase0 afterProcessEpoch - 250000 vs - 7PWei 89.876 ms/op 82.033 ms/op 1.10
Array.fill - length 1000000 3.6198 ms/op 2.5026 ms/op 1.45
Array push - length 1000000 16.808 ms/op 14.611 ms/op 1.15
Array.get 0.25708 ns/op 0.25809 ns/op 1.00
Uint8Array.get 0.41513 ns/op 0.32784 ns/op 1.27
phase0 beforeProcessEpoch - 250000 vs - 7PWei 15.910 ms/op 14.794 ms/op 1.08
altair processEpoch - mainnet_e81889 337.47 ms/op 276.46 ms/op 1.22
mainnet_e81889 - altair beforeProcessEpoch 17.617 ms/op 18.737 ms/op 0.94
mainnet_e81889 - altair processJustificationAndFinalization 18.630 us/op 9.3150 us/op 2.00
mainnet_e81889 - altair processInactivityUpdates 5.0842 ms/op 4.7977 ms/op 1.06
mainnet_e81889 - altair processRewardsAndPenalties 58.606 ms/op 54.563 ms/op 1.07
mainnet_e81889 - altair processRegistryUpdates 2.9900 us/op 1.9330 us/op 1.55
mainnet_e81889 - altair processSlashings 642.00 ns/op 760.00 ns/op 0.84
mainnet_e81889 - altair processEth1DataReset 466.00 ns/op 771.00 ns/op 0.60
mainnet_e81889 - altair processEffectiveBalanceUpdates 3.5597 ms/op 1.7678 ms/op 2.01
mainnet_e81889 - altair processSlashingsReset 4.3670 us/op 3.3310 us/op 1.31
mainnet_e81889 - altair processRandaoMixesReset 5.1050 us/op 4.1960 us/op 1.22
mainnet_e81889 - altair processHistoricalRootsUpdate 787.00 ns/op 575.00 ns/op 1.37
mainnet_e81889 - altair processParticipationFlagUpdates 1.9090 us/op 2.0970 us/op 0.91
mainnet_e81889 - altair processSyncCommitteeUpdates 669.00 ns/op 729.00 ns/op 0.92
mainnet_e81889 - altair afterProcessEpoch 94.164 ms/op 82.792 ms/op 1.14
capella processEpoch - mainnet_e217614 1.2228 s/op 1.2556 s/op 0.97
mainnet_e217614 - capella beforeProcessEpoch 68.606 ms/op 78.466 ms/op 0.87
mainnet_e217614 - capella processJustificationAndFinalization 17.831 us/op 18.625 us/op 0.96
mainnet_e217614 - capella processInactivityUpdates 18.041 ms/op 12.605 ms/op 1.43
mainnet_e217614 - capella processRewardsAndPenalties 248.54 ms/op 254.58 ms/op 0.98
mainnet_e217614 - capella processRegistryUpdates 22.141 us/op 14.403 us/op 1.54
mainnet_e217614 - capella processSlashings 461.00 ns/op 944.00 ns/op 0.49
mainnet_e217614 - capella processEth1DataReset 296.00 ns/op 879.00 ns/op 0.34
mainnet_e217614 - capella processEffectiveBalanceUpdates 14.629 ms/op 14.825 ms/op 0.99
mainnet_e217614 - capella processSlashingsReset 3.9920 us/op 3.4900 us/op 1.14
mainnet_e217614 - capella processRandaoMixesReset 4.0990 us/op 8.5700 us/op 0.48
mainnet_e217614 - capella processHistoricalRootsUpdate 461.00 ns/op 786.00 ns/op 0.59
mainnet_e217614 - capella processParticipationFlagUpdates 5.1630 us/op 2.0430 us/op 2.53
mainnet_e217614 - capella afterProcessEpoch 235.63 ms/op 208.76 ms/op 1.13
phase0 processEpoch - mainnet_e58758 463.11 ms/op 325.79 ms/op 1.42
mainnet_e58758 - phase0 beforeProcessEpoch 106.04 ms/op 91.970 ms/op 1.15
mainnet_e58758 - phase0 processJustificationAndFinalization 26.847 us/op 22.940 us/op 1.17
mainnet_e58758 - phase0 processRewardsAndPenalties 31.745 ms/op 33.206 ms/op 0.96
mainnet_e58758 - phase0 processRegistryUpdates 7.2110 us/op 8.2160 us/op 0.88
mainnet_e58758 - phase0 processSlashings 525.00 ns/op 982.00 ns/op 0.53
mainnet_e58758 - phase0 processEth1DataReset 292.00 ns/op 749.00 ns/op 0.39
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.9190 ms/op 904.00 us/op 2.12
mainnet_e58758 - phase0 processSlashingsReset 2.1500 us/op 5.0950 us/op 0.42
mainnet_e58758 - phase0 processRandaoMixesReset 6.1210 us/op 6.9090 us/op 0.89
mainnet_e58758 - phase0 processHistoricalRootsUpdate 583.00 ns/op 1.0630 us/op 0.55
mainnet_e58758 - phase0 processParticipationRecordUpdates 4.3300 us/op 6.3480 us/op 0.68
mainnet_e58758 - phase0 afterProcessEpoch 76.488 ms/op 75.695 ms/op 1.01
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.6919 ms/op 1.0299 ms/op 1.64
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 2.3083 ms/op 1.8412 ms/op 1.25
altair processInactivityUpdates - 250000 normalcase 17.532 ms/op 16.875 ms/op 1.04
altair processInactivityUpdates - 250000 worstcase 20.940 ms/op 17.897 ms/op 1.17
phase0 processRegistryUpdates - 250000 normalcase 9.0430 us/op 6.2260 us/op 1.45
phase0 processRegistryUpdates - 250000 badcase_full_deposits 433.14 us/op 204.89 us/op 2.11
phase0 processRegistryUpdates - 250000 worstcase 0.5 141.14 ms/op 124.66 ms/op 1.13
altair processRewardsAndPenalties - 250000 normalcase 48.114 ms/op 41.047 ms/op 1.17
altair processRewardsAndPenalties - 250000 worstcase 43.427 ms/op 40.325 ms/op 1.08
phase0 getAttestationDeltas - 250000 normalcase 7.9061 ms/op 7.8367 ms/op 1.01
phase0 getAttestationDeltas - 250000 worstcase 7.7416 ms/op 8.3045 ms/op 0.93
phase0 processSlashings - 250000 worstcase 120.97 us/op 96.218 us/op 1.26
altair processSyncCommitteeUpdates - 250000 119.99 ms/op 112.40 ms/op 1.07
BeaconState.hashTreeRoot - No change 258.00 ns/op 485.00 ns/op 0.53
BeaconState.hashTreeRoot - 1 full validator 115.66 us/op 102.89 us/op 1.12
BeaconState.hashTreeRoot - 32 full validator 929.67 us/op 1.2056 ms/op 0.77
BeaconState.hashTreeRoot - 512 full validator 13.068 ms/op 12.707 ms/op 1.03
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 139.84 us/op 163.61 us/op 0.85
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.6859 ms/op 1.9054 ms/op 0.88
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 22.421 ms/op 22.771 ms/op 0.98
BeaconState.hashTreeRoot - 1 balances 94.160 us/op 101.71 us/op 0.93
BeaconState.hashTreeRoot - 32 balances 870.31 us/op 1.0436 ms/op 0.83
BeaconState.hashTreeRoot - 512 balances 7.4266 ms/op 9.1315 ms/op 0.81
BeaconState.hashTreeRoot - 250000 balances 158.79 ms/op 154.59 ms/op 1.03
aggregationBits - 2048 els - zipIndexesInBitList 27.603 us/op 21.989 us/op 1.26
byteArrayEquals 32 54.558 ns/op 49.146 ns/op 1.11
Buffer.compare 32 17.534 ns/op 15.658 ns/op 1.12
byteArrayEquals 1024 1.5974 us/op 1.2916 us/op 1.24
Buffer.compare 1024 24.875 ns/op 23.384 ns/op 1.06
byteArrayEquals 16384 25.399 us/op 20.478 us/op 1.24
Buffer.compare 16384 178.46 ns/op 206.85 ns/op 0.86
byteArrayEquals 123687377 194.29 ms/op 153.71 ms/op 1.26
Buffer.compare 123687377 7.0011 ms/op 6.2576 ms/op 1.12
byteArrayEquals 32 - diff last byte 53.001 ns/op 47.822 ns/op 1.11
Buffer.compare 32 - diff last byte 17.456 ns/op 15.783 ns/op 1.11
byteArrayEquals 1024 - diff last byte 1.6089 us/op 1.2695 us/op 1.27
Buffer.compare 1024 - diff last byte 25.691 ns/op 23.918 ns/op 1.07
byteArrayEquals 16384 - diff last byte 25.493 us/op 20.394 us/op 1.25
Buffer.compare 16384 - diff last byte 194.10 ns/op 181.71 ns/op 1.07
byteArrayEquals 123687377 - diff last byte 192.73 ms/op 153.32 ms/op 1.26
Buffer.compare 123687377 - diff last byte 6.1543 ms/op 5.0693 ms/op 1.21
byteArrayEquals 32 - random bytes 5.0060 ns/op 5.0750 ns/op 0.99
Buffer.compare 32 - random bytes 16.711 ns/op 15.975 ns/op 1.05
byteArrayEquals 1024 - random bytes 5.0220 ns/op 5.0320 ns/op 1.00
Buffer.compare 1024 - random bytes 16.717 ns/op 15.847 ns/op 1.05
byteArrayEquals 16384 - random bytes 5.0170 ns/op 5.0220 ns/op 1.00
Buffer.compare 16384 - random bytes 16.681 ns/op 15.735 ns/op 1.06
byteArrayEquals 123687377 - random bytes 6.2700 ns/op 7.9400 ns/op 0.79
Buffer.compare 123687377 - random bytes 17.930 ns/op 18.810 ns/op 0.95
regular array get 100000 times 32.050 us/op 31.163 us/op 1.03
wrappedArray get 100000 times 36.637 us/op 31.342 us/op 1.17
arrayWithProxy get 100000 times 12.860 ms/op 10.485 ms/op 1.23
ssz.Root.equals 44.788 ns/op 44.735 ns/op 1.00
byteArrayEquals 44.318 ns/op 42.979 ns/op 1.03
Buffer.compare 10.082 ns/op 9.1590 ns/op 1.10
shuffle list - 16384 els 5.9429 ms/op 5.5541 ms/op 1.07
shuffle list - 250000 els 87.666 ms/op 82.730 ms/op 1.06
processSlot - 1 slots 14.767 us/op 12.760 us/op 1.16
processSlot - 32 slots 3.5765 ms/op 3.5015 ms/op 1.02
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 42.126 ms/op 37.301 ms/op 1.13
getCommitteeAssignments - req 1 vs - 250000 vc 2.0820 ms/op 1.8823 ms/op 1.11
getCommitteeAssignments - req 100 vs - 250000 vc 4.0326 ms/op 3.6017 ms/op 1.12
getCommitteeAssignments - req 1000 vs - 250000 vc 4.2828 ms/op 3.9432 ms/op 1.09
findModifiedValidators - 10000 modified validators 256.24 ms/op 267.56 ms/op 0.96
findModifiedValidators - 1000 modified validators 172.07 ms/op 182.76 ms/op 0.94
findModifiedValidators - 100 modified validators 160.66 ms/op 201.29 ms/op 0.80
findModifiedValidators - 10 modified validators 150.08 ms/op 172.95 ms/op 0.87
findModifiedValidators - 1 modified validators 171.99 ms/op 190.95 ms/op 0.90
findModifiedValidators - no difference 161.44 ms/op 187.88 ms/op 0.86
compare ViewDUs 3.2184 s/op 3.2009 s/op 1.01
compare each validator Uint8Array 1.6170 s/op 1.4094 s/op 1.15
compare ViewDU to Uint8Array 1.0667 s/op 1.1720 s/op 0.91
migrate state 1000000 validators, 24 modified, 0 new 572.83 ms/op 713.04 ms/op 0.80
migrate state 1000000 validators, 1700 modified, 1000 new 840.58 ms/op 932.08 ms/op 0.90
migrate state 1000000 validators, 3400 modified, 2000 new 1.0023 s/op 1.0690 s/op 0.94
migrate state 1500000 validators, 24 modified, 0 new 621.25 ms/op 628.50 ms/op 0.99
migrate state 1500000 validators, 1700 modified, 1000 new 904.56 ms/op 832.72 ms/op 1.09
migrate state 1500000 validators, 3400 modified, 2000 new 1.1634 s/op 938.73 ms/op 1.24
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.2800 ns/op 6.4400 ns/op 0.66
state getBlockRootAtSlot - 250000 vs - 7PWei 647.54 ns/op 774.91 ns/op 0.84
computeProposers - vc 250000 7.9085 ms/op 6.9285 ms/op 1.14
computeEpochShuffling - vc 250000 92.491 ms/op 79.670 ms/op 1.16
getNextSyncCommittee - vc 250000 122.32 ms/op 105.94 ms/op 1.15
computeSigningRoot for AttestationData 23.099 us/op 20.197 us/op 1.14
hash AttestationData serialized data then Buffer.toString(base64) 1.5594 us/op 1.1852 us/op 1.32
toHexString serialized data 848.57 ns/op 759.79 ns/op 1.12
Buffer.toString(base64) 182.96 ns/op 145.27 ns/op 1.26
nodejs block root to RootHex using toHex 143.15 ns/op 109.66 ns/op 1.31
nodejs block root to RootHex using toRootHex 96.686 ns/op 71.774 ns/op 1.35
browser block root to RootHex using the deprecated toHexString 227.13 ns/op 204.17 ns/op 1.11
browser block root to RootHex using toHex 180.60 ns/op 161.10 ns/op 1.12
browser block root to RootHex using toRootHex 166.88 ns/op 148.93 ns/op 1.12

by benchmarkbot/action

Copy link
Contributor

@ensi321 ensi321 left a comment

Choose a reason for hiding this comment

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

lgtm

Benchmark is failing but don't think it's related to this PR.

Spec naming will be followed up in ethereum/consensus-specs#3911

@twoeths twoeths merged commit 681bdcd into unstable Sep 4, 2024
25 of 26 checks passed
@twoeths twoeths deleted the te/improve_get_expected_withdrawals branch September 4, 2024 01:21
philknows pushed a commit that referenced this pull request Sep 11, 2024
* fix: improve performance of getExpectedWithdrawals

* chore: use isPostElectra variable

* chore: check pre-capella
@wemeetagain
Copy link
Member

🎉 This PR is included in v1.22.0 🎉

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.

4 participants