Merge branch 'unstable' into feat_eip-7688

This commit is contained in:
Etan Kissling 2024-09-21 14:44:53 +02:00
commit af75741f2a
No known key found for this signature in database
GPG Key ID: B21DA824C5A3D03D
146 changed files with 6937 additions and 3390 deletions

View File

@ -320,7 +320,7 @@ jobs:
ref: unstable ref: unstable
- name: Download artefacts - name: Download artefacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4.1.7
- name: Create release notes - name: Create release notes
run: | run: |

View File

@ -349,7 +349,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Download artefacts - name: Download artefacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4.1.7
- name: Create release notes - name: Create release notes
run: | run: |
cat > release_notes.md <<EOF cat > release_notes.md <<EOF

View File

@ -7,9 +7,12 @@ AllTests-mainnet
OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 1/1 Fail: 0/1 Skip: 0/1
## Attestation pool electra processing [Preset: mainnet] ## Attestation pool electra processing [Preset: mainnet]
```diff ```diff
+ Aggregated attestations with disjoint comittee bits into a single on-chain aggregate [Pres OK
+ Attestations with disjoint comittee bits and equal data into single on-chain aggregate [Pr OK
+ Can add and retrieve simple electra attestations [Preset: mainnet] OK + Can add and retrieve simple electra attestations [Preset: mainnet] OK
+ Working with electra aggregates [Preset: mainnet] OK
``` ```
OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 4/4 Fail: 0/4 Skip: 0/4
## Attestation pool processing [Preset: mainnet] ## Attestation pool processing [Preset: mainnet]
```diff ```diff
+ Attestation from different branch [Preset: mainnet] OK + Attestation from different branch [Preset: mainnet] OK
@ -174,6 +177,19 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
+ Tail block only in common OK + Tail block only in common OK
``` ```
OK: 2/2 Fail: 0/2 Skip: 0/2 OK: 2/2 Fail: 0/2 Skip: 0/2
## EF - EIP7594 - Networking [Preset: mainnet]
```diff
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
```
OK: 9/9 Fail: 0/9 Skip: 0/9
## EF - KZG ## EF - KZG
```diff ```diff
+ KZG - Blob to KZG commitment - blob_to_kzg_commitment_case_invalid_blob_59d64ff6b4648fad OK + KZG - Blob to KZG commitment - blob_to_kzg_commitment_case_invalid_blob_59d64ff6b4648fad OK
@ -431,6 +447,66 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
+ KZG - Verify blob KZG proof batch - verify_blob_kzg_proof_batch_case_proof_length_differen OK + KZG - Verify blob KZG proof batch - verify_blob_kzg_proof_batch_case_proof_length_differen OK
``` ```
OK: 253/253 Fail: 0/253 Skip: 0/253 OK: 253/253 Fail: 0/253 Skip: 0/253
## EF - KZG - EIP7594
```diff
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_invalid_blob_26555bdcbf OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_invalid_blob_79fb3cb1ef OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_invalid_blob_7e99dea889 OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_invalid_blob_9d88c33852 OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_valid_419245fbfe69f145 OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_valid_4aedd1a2a3933c3e OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_valid_6e773f256383918c OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_valid_b0731ef77b166ca8 OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_valid_b81d309b22788820 OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_valid_ed8b5001151417d5 OK
+ KZG - Compute Cells And Proofs - compute_cells_and_kzg_proofs_case_valid_edeb8500a6507818 OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_all_cells_a OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_cell_047ee7 OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_cell_76ab46 OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_cell_77b669 OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_cell_c8e2ca OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_cell_index_ OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_duplicate_c OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_more_cell_i OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_more_cells_ OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_more_cells_ OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_invalid_more_than_h OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_valid_half_missing_ OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_valid_half_missing_ OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_valid_half_missing_ OK
+ KZG - Recover Cells And Kzg Proofs - recover_cells_and_kzg_proofs_case_valid_no_missing_a1 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_incorrect_cell_48bcbf OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_incorrect_commitment_ OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_incorrect_proof_ba29f OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_cell_bcb1b35c OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_cell_d89304ce OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_cell_d939faf6 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_cell_ef6ac828 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_cell_index_5d OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_commitment_4b OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_commitment_53 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_commitment_68 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_commitment_d3 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_missing_cell_ OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_missing_cell_ OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_missing_commi OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_missing_proof OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_proof_0424858 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_proof_48fa9d1 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_proof_8feaf47 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_invalid_proof_a9d14f0 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_0cfba0f22152206 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_3073caf43016db4 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_5211d9e9ff34c00 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_92c0b5242fa34ae OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_9fb9bff6fe1fb6b OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_d3f60d6d484ddb6 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_fd341ee5517e590 OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_multiple_blobs_ OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_same_cell_multi OK
+ KZG - Verify Cell Kzg Proof Batch - verify_cell_kzg_proof_batch_case_valid_zero_cells_fbbd OK
```
OK: 56/56 Fail: 0/56 Skip: 0/56
## EF - SSZ generic types ## EF - SSZ generic types
```diff ```diff
Testing basic_vector inputs - invalid Skip Testing basic_vector inputs - invalid Skip
@ -458,6 +534,17 @@ OK: 12/14 Fail: 0/14 Skip: 2/14
+ snapshot_cases OK + snapshot_cases OK
``` ```
OK: 5/5 Fail: 0/5 Skip: 0/5 OK: 5/5 Fail: 0/5 Skip: 0/5
## EIP-7594 Sampling Tests
```diff
+ EIP7594: Extended Sample Count OK
```
OK: 1/1 Fail: 0/1 Skip: 0/1
## EIP-7594 Unit Tests
```diff
+ EIP-7594: Compute Matrix OK
+ EIP:7594: Recover Matrix OK
```
OK: 2/2 Fail: 0/2 Skip: 0/2
## EL Configuration ## EL Configuration
```diff ```diff
+ Empty config file OK + Empty config file OK
@ -1041,4 +1128,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
OK: 9/9 Fail: 0/9 Skip: 0/9 OK: 9/9 Fail: 0/9 Skip: 0/9
---TOTAL--- ---TOTAL---
OK: 694/699 Fail: 0/699 Skip: 5/699 OK: 765/770 Fail: 0/770 Skip: 5/770

View File

@ -2396,6 +2396,61 @@ OK: 25/25 Fail: 0/25 Skip: 0/25
+ test_process_light_client_update_not_timeout OK + test_process_light_client_update_not_timeout OK
``` ```
OK: 4/4 Fail: 0/4 Skip: 0/4 OK: 4/4 Fail: 0/4 Skip: 0/4
## EF - EIP7594 - SSZ consensus objects [Preset: mainnet]
```diff
+ Testing AggregateAndProof OK
+ Testing Attestation OK
+ Testing AttestationData OK
+ Testing AttesterSlashing OK
+ Testing BLSToExecutionChange OK
+ Testing BeaconBlock OK
+ Testing BeaconBlockBody OK
+ Testing BeaconBlockHeader OK
+ Testing BeaconState OK
+ Testing BlobIdentifier OK
+ Testing BlobSidecar OK
+ Testing Checkpoint OK
+ Testing ContributionAndProof OK
+ Testing DataColumnIdentifier OK
+ Testing DataColumnSidecar OK
+ Testing Deposit OK
+ Testing DepositData OK
+ Testing DepositMessage OK
+ Testing Eth1Block OK
+ Testing Eth1Data OK
+ Testing ExecutionPayload OK
+ Testing ExecutionPayloadHeader OK
+ Testing Fork OK
+ Testing ForkData OK
+ Testing HistoricalBatch OK
+ Testing HistoricalSummary OK
+ Testing IndexedAttestation OK
+ Testing LightClientBootstrap OK
+ Testing LightClientFinalityUpdate OK
+ Testing LightClientHeader OK
+ Testing LightClientOptimisticUpdate OK
+ Testing LightClientUpdate OK
+ Testing MatrixEntry OK
+ Testing PendingAttestation OK
+ Testing PowBlock OK
+ Testing ProposerSlashing OK
+ Testing SignedAggregateAndProof OK
+ Testing SignedBLSToExecutionChange OK
+ Testing SignedBeaconBlock OK
+ Testing SignedBeaconBlockHeader OK
+ Testing SignedContributionAndProof OK
+ Testing SignedVoluntaryExit OK
+ Testing SigningData OK
+ Testing SyncAggregate OK
+ Testing SyncAggregatorSelectionData OK
+ Testing SyncCommittee OK
+ Testing SyncCommitteeContribution OK
+ Testing SyncCommitteeMessage OK
+ Testing Validator OK
+ Testing VoluntaryExit OK
+ Testing Withdrawal OK
```
OK: 51/51 Fail: 0/51 Skip: 0/51
## EF - Electra - Epoch Processing - Effective balance updates [Preset: mainnet] ## EF - Electra - Epoch Processing - Effective balance updates [Preset: mainnet]
```diff ```diff
+ Effective balance updates - effective_balance_hysteresis [Preset: mainnet] OK + Effective balance updates - effective_balance_hysteresis [Preset: mainnet] OK
@ -2859,6 +2914,7 @@ OK: 24/24 Fail: 0/24 Skip: 0/24
+ [Valid] EF - Electra - Operations - Withdrawal Request - activation_epoch_less_than_shar OK + [Valid] EF - Electra - Operations - Withdrawal Request - activation_epoch_less_than_shar OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request OK + [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_c OK + [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_c OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_f OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_source_address OK + [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_source_address OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_withdrawal_credential OK + [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_withdrawal_credential OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - insufficient_effective_balance OK + [Valid] EF - Electra - Operations - Withdrawal Request - insufficient_effective_balance OK
@ -2871,7 +2927,7 @@ OK: 24/24 Fail: 0/24 Skip: 0/24
+ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_on_exit_init OK + [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_on_exit_init OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - pending_withdrawals_consume_all OK + [Valid] EF - Electra - Operations - Withdrawal Request - pending_withdrawals_consume_all OK
``` ```
OK: 14/14 Fail: 0/14 Skip: 0/14 OK: 15/15 Fail: 0/15 Skip: 0/15
## EF - Electra - Operations - Withdrawals [Preset: mainnet] ## EF - Electra - Operations - Withdrawals [Preset: mainnet]
```diff ```diff
+ [Invalid] EF - Electra - Operations - Withdrawals - invalid_a_lot_fully_withdrawable_too_f OK + [Invalid] EF - Electra - Operations - Withdrawals - invalid_a_lot_fully_withdrawable_too_f OK
@ -3008,6 +3064,7 @@ OK: 34/34 Fail: 0/34 Skip: 0/34
+ Testing Eth1Data OK + Testing Eth1Data OK
+ Testing ExecutionPayload OK + Testing ExecutionPayload OK
+ Testing ExecutionPayloadHeader OK + Testing ExecutionPayloadHeader OK
+ Testing ExecutionRequests OK
+ Testing Fork OK + Testing Fork OK
+ Testing ForkData OK + Testing ForkData OK
+ Testing HistoricalBatch OK + Testing HistoricalBatch OK
@ -3037,6 +3094,7 @@ OK: 34/34 Fail: 0/34 Skip: 0/34
+ Testing StableBeaconState OK + Testing StableBeaconState OK
+ Testing StableExecutionPayload OK + Testing StableExecutionPayload OK
+ Testing StableExecutionPayloadHeader OK + Testing StableExecutionPayloadHeader OK
+ Testing StableExecutionRequests OK
+ Testing StableIndexedAttestation OK + Testing StableIndexedAttestation OK
+ Testing SyncAggregate OK + Testing SyncAggregate OK
+ Testing SyncAggregatorSelectionData OK + Testing SyncAggregatorSelectionData OK
@ -3048,7 +3106,7 @@ OK: 34/34 Fail: 0/34 Skip: 0/34
+ Testing Withdrawal OK + Testing Withdrawal OK
+ Testing WithdrawalRequest OK + Testing WithdrawalRequest OK
``` ```
OK: 61/61 Fail: 0/61 Skip: 0/61 OK: 63/63 Fail: 0/63 Skip: 0/63
## EF - Electra - Sanity - Blocks [Preset: mainnet] ## EF - Electra - Sanity - Blocks [Preset: mainnet]
```diff ```diff
+ [Invalid] EF - Electra - Sanity - Blocks - deposit_transition__invalid_eth1_deposits_overl OK + [Invalid] EF - Electra - Sanity - Blocks - deposit_transition__invalid_eth1_deposits_overl OK
@ -3713,4 +3771,4 @@ OK: 69/88 Fail: 0/88 Skip: 19/88
OK: 3/3 Fail: 0/3 Skip: 0/3 OK: 3/3 Fail: 0/3 Skip: 0/3
---TOTAL--- ---TOTAL---
OK: 2991/3011 Fail: 0/3011 Skip: 20/3011 OK: 3045/3065 Fail: 0/3065 Skip: 20/3065

View File

@ -2505,6 +2505,61 @@ OK: 30/30 Fail: 0/30 Skip: 0/30
+ test_process_light_client_update_not_timeout OK + test_process_light_client_update_not_timeout OK
``` ```
OK: 4/4 Fail: 0/4 Skip: 0/4 OK: 4/4 Fail: 0/4 Skip: 0/4
## EF - EIP7594 - SSZ consensus objects [Preset: minimal]
```diff
+ Testing AggregateAndProof OK
+ Testing Attestation OK
+ Testing AttestationData OK
+ Testing AttesterSlashing OK
+ Testing BLSToExecutionChange OK
+ Testing BeaconBlock OK
+ Testing BeaconBlockBody OK
+ Testing BeaconBlockHeader OK
+ Testing BeaconState OK
+ Testing BlobIdentifier OK
+ Testing BlobSidecar OK
+ Testing Checkpoint OK
+ Testing ContributionAndProof OK
+ Testing DataColumnIdentifier OK
+ Testing DataColumnSidecar OK
+ Testing Deposit OK
+ Testing DepositData OK
+ Testing DepositMessage OK
+ Testing Eth1Block OK
+ Testing Eth1Data OK
+ Testing ExecutionPayload OK
+ Testing ExecutionPayloadHeader OK
+ Testing Fork OK
+ Testing ForkData OK
+ Testing HistoricalBatch OK
+ Testing HistoricalSummary OK
+ Testing IndexedAttestation OK
+ Testing LightClientBootstrap OK
+ Testing LightClientFinalityUpdate OK
+ Testing LightClientHeader OK
+ Testing LightClientOptimisticUpdate OK
+ Testing LightClientUpdate OK
+ Testing MatrixEntry OK
+ Testing PendingAttestation OK
+ Testing PowBlock OK
+ Testing ProposerSlashing OK
+ Testing SignedAggregateAndProof OK
+ Testing SignedBLSToExecutionChange OK
+ Testing SignedBeaconBlock OK
+ Testing SignedBeaconBlockHeader OK
+ Testing SignedContributionAndProof OK
+ Testing SignedVoluntaryExit OK
+ Testing SigningData OK
+ Testing SyncAggregate OK
+ Testing SyncAggregatorSelectionData OK
+ Testing SyncCommittee OK
+ Testing SyncCommitteeContribution OK
+ Testing SyncCommitteeMessage OK
+ Testing Validator OK
+ Testing VoluntaryExit OK
+ Testing Withdrawal OK
```
OK: 51/51 Fail: 0/51 Skip: 0/51
## EF - Electra - Epoch Processing - Effective balance updates [Preset: minimal] ## EF - Electra - Epoch Processing - Effective balance updates [Preset: minimal]
```diff ```diff
+ Effective balance updates - effective_balance_hysteresis [Preset: minimal] OK + Effective balance updates - effective_balance_hysteresis [Preset: minimal] OK
@ -3005,6 +3060,7 @@ OK: 20/20 Fail: 0/20 Skip: 0/20
+ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request OK + [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_c OK + [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_c OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_f OK + [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_f OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - basic_withdrawal_request_with_f OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_source_address OK + [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_source_address OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_withdrawal_credential OK + [Valid] EF - Electra - Operations - Withdrawal Request - incorrect_withdrawal_credential OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - insufficient_effective_balance OK + [Valid] EF - Electra - Operations - Withdrawal Request - insufficient_effective_balance OK
@ -3023,7 +3079,7 @@ OK: 20/20 Fail: 0/20 Skip: 0/20
+ [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_request_with OK + [Valid] EF - Electra - Operations - Withdrawal Request - partial_withdrawal_request_with OK
+ [Valid] EF - Electra - Operations - Withdrawal Request - pending_withdrawals_consume_all OK + [Valid] EF - Electra - Operations - Withdrawal Request - pending_withdrawals_consume_all OK
``` ```
OK: 24/24 Fail: 0/24 Skip: 0/24 OK: 25/25 Fail: 0/25 Skip: 0/25
## EF - Electra - Operations - Withdrawals [Preset: minimal] ## EF - Electra - Operations - Withdrawals [Preset: minimal]
```diff ```diff
+ [Invalid] EF - Electra - Operations - Withdrawals - invalid_a_lot_fully_withdrawable_too_f OK + [Invalid] EF - Electra - Operations - Withdrawals - invalid_a_lot_fully_withdrawable_too_f OK
@ -3161,6 +3217,7 @@ OK: 34/34 Fail: 0/34 Skip: 0/34
+ Testing Eth1Data OK + Testing Eth1Data OK
+ Testing ExecutionPayload OK + Testing ExecutionPayload OK
+ Testing ExecutionPayloadHeader OK + Testing ExecutionPayloadHeader OK
+ Testing ExecutionRequests OK
+ Testing Fork OK + Testing Fork OK
+ Testing ForkData OK + Testing ForkData OK
+ Testing HistoricalBatch OK + Testing HistoricalBatch OK
@ -3190,6 +3247,7 @@ OK: 34/34 Fail: 0/34 Skip: 0/34
+ Testing StableBeaconState OK + Testing StableBeaconState OK
+ Testing StableExecutionPayload OK + Testing StableExecutionPayload OK
+ Testing StableExecutionPayloadHeader OK + Testing StableExecutionPayloadHeader OK
+ Testing StableExecutionRequests OK
+ Testing StableIndexedAttestation OK + Testing StableIndexedAttestation OK
+ Testing SyncAggregate OK + Testing SyncAggregate OK
+ Testing SyncAggregatorSelectionData OK + Testing SyncAggregatorSelectionData OK
@ -3201,7 +3259,7 @@ OK: 34/34 Fail: 0/34 Skip: 0/34
+ Testing Withdrawal OK + Testing Withdrawal OK
+ Testing WithdrawalRequest OK + Testing WithdrawalRequest OK
``` ```
OK: 61/61 Fail: 0/61 Skip: 0/61 OK: 63/63 Fail: 0/63 Skip: 0/63
## EF - Electra - Sanity - Blocks [Preset: minimal] ## EF - Electra - Sanity - Blocks [Preset: minimal]
```diff ```diff
+ [Invalid] EF - Electra - Sanity - Blocks - deposit_transition__invalid_eth1_deposits_overl OK + [Invalid] EF - Electra - Sanity - Blocks - deposit_transition__invalid_eth1_deposits_overl OK
@ -4050,4 +4108,4 @@ OK: 185/207 Fail: 0/207 Skip: 22/207
OK: 3/3 Fail: 0/3 Skip: 0/3 OK: 3/3 Fail: 0/3 Skip: 0/3
---TOTAL--- ---TOTAL---
OK: 3297/3320 Fail: 0/3320 Skip: 23/3320 OK: 3351/3374 Fail: 0/3374 Skip: 23/3374

View File

@ -560,8 +560,7 @@ proc new*(T: type BeaconChainDB,
static: doAssert LightClientDataFork.high == LightClientDataFork.Electra static: doAssert LightClientDataFork.high == LightClientDataFork.Electra
var blobs: array[BlobFork, KvStoreRef] var blobs: array[BlobFork, KvStoreRef]
if cfg.DENEB_FORK_EPOCH != FAR_FUTURE_EPOCH: blobs[BlobFork.Deneb] = kvStore db.openKvStore("deneb_blobs").expectDb()
blobs[BlobFork.Deneb] = kvStore db.openKvStore("deneb_blobs").expectDb()
if cfg.ELECTRA_FORK_EPOCH != FAR_FUTURE_EPOCH: if cfg.ELECTRA_FORK_EPOCH != FAR_FUTURE_EPOCH:
blobs[BlobFork.Electra] = kvStore db.openKvStore("electra_blobs").expectDb() blobs[BlobFork.Electra] = kvStore db.openKvStore("electra_blobs").expectDb()
static: doAssert BlobFork.high == BlobFork.Electra static: doAssert BlobFork.high == BlobFork.Electra

View File

@ -130,7 +130,7 @@ type
current_sync_committee*: SyncCommittee # [New in Altair] current_sync_committee*: SyncCommittee # [New in Altair]
next_sync_committee*: SyncCommittee # [New in Altair] next_sync_committee*: SyncCommittee # [New in Altair]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#beaconstate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#beaconstate
# Memory-representation-equivalent to a Bellatrix BeaconState for in-place SSZ # Memory-representation-equivalent to a Bellatrix BeaconState for in-place SSZ
# reading and writing # reading and writing
BellatrixBeaconStateNoImmutableValidators* = object BellatrixBeaconStateNoImmutableValidators* = object

View File

@ -27,7 +27,7 @@ type
## which blocks are valid - in particular, blocks are not valid if they ## which blocks are valid - in particular, blocks are not valid if they
## come from the future as seen from the local clock. ## come from the future as seen from the local clock.
## ##
## https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/fork-choice.md#fork-choice ## https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/fork-choice.md#fork-choice
## ##
# TODO consider NTP and network-adjusted timestamps as outlined here: # TODO consider NTP and network-adjusted timestamps as outlined here:
# https://ethresear.ch/t/network-adjusted-timestamps/4187 # https://ethresear.ch/t/network-adjusted-timestamps/4187

View File

@ -22,7 +22,7 @@ import
eth/p2p/discoveryv5/enr, eth/p2p/discoveryv5/enr,
json_serialization, web3/[primitives, confutils_defs], json_serialization, web3/[primitives, confutils_defs],
chronos/transports/common, chronos/transports/common,
kzg4844/kzg_ex, kzg4844/kzg,
./spec/[engine_authentication, keystore, network, crypto], ./spec/[engine_authentication, keystore, network, crypto],
./spec/datatypes/base, ./spec/datatypes/base,
./networking/network_metadata, ./networking/network_metadata,
@ -1500,11 +1500,11 @@ proc loadKzgTrustedSetup*(): Result[void, string] =
vendorDir & "/nim-kzg4844/kzg4844/csources/src/trusted_setup.txt") vendorDir & "/nim-kzg4844/kzg4844/csources/src/trusted_setup.txt")
static: doAssert const_preset in ["mainnet", "gnosis", "minimal"] static: doAssert const_preset in ["mainnet", "gnosis", "minimal"]
Kzg.loadTrustedSetupFromString(trustedSetup) loadTrustedSetupFromString(trustedSetup, 0)
proc loadKzgTrustedSetup*(trustedSetupPath: string): Result[void, string] = proc loadKzgTrustedSetup*(trustedSetupPath: string): Result[void, string] =
try: try:
Kzg.loadTrustedSetupFromString(readFile(trustedSetupPath)) loadTrustedSetupFromString(readFile(trustedSetupPath), 0)
except IOError as err: except IOError as err:
err(err.msg) err(err.msg)

View File

@ -104,7 +104,7 @@ type LightClientConf* = object
hidden hidden
desc: "Enable the Yamux multiplexer" desc: "Enable the Yamux multiplexer"
defaultValue: false defaultValue: false
name: "enable-yamux" .}: bool name: "debug-enable-yamux" .}: bool
agentString* {. agentString* {.
defaultValue: "nimbus", defaultValue: "nimbus",

View File

@ -5,10 +5,10 @@ This folder holds the various consensus object pools needed for a blockchain cli
Object in those pools have passed the "gossip validation" filter according Object in those pools have passed the "gossip validation" filter according
to specs: to specs:
- blocks: https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#beacon_block - blocks: https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#beacon_block
- aggregate attestations: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof - aggregate attestations: https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof
- unaggregated attestation: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id - unaggregated attestation: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
- voluntary exits: https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#voluntary_exit - voluntary exits: https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#voluntary_exit
- Attester slashings: https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#attester_slashing - Attester slashings: https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#attester_slashing
- Proposer slashings: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#proposer_slashing - Proposer slashings: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#proposer_slashing
After "gossip validation" the consensus objects can be rebroadcasted as they are optimistically good, however for internal processing further verification is needed. After "gossip validation" the consensus objects can be rebroadcasted as they are optimistically good, however for internal processing further verification is needed.

View File

@ -8,6 +8,7 @@
{.push raises: [].} {.push raises: [].}
import import
std/algorithm,
# Status libraries # Status libraries
metrics, metrics,
chronicles, stew/byteutils, chronicles, stew/byteutils,
@ -198,11 +199,16 @@ proc addForkChoiceVotes(
# hopefully the fork choice will heal itself over time. # hopefully the fork choice will heal itself over time.
error "Couldn't add attestation to fork choice, bug?", err = v.error() error "Couldn't add attestation to fork choice, bug?", err = v.error()
func candidateIdx(pool: AttestationPool, slot: Slot): Opt[int] = func candidateIdx(pool: AttestationPool, slot: Slot,
isElectra: bool = false): Opt[int] =
static: doAssert pool.phase0Candidates.len == pool.electraCandidates.len static: doAssert pool.phase0Candidates.len == pool.electraCandidates.len
let poolLength = if isElectra:
pool.electraCandidates.lenu64 else: pool.phase0Candidates.lenu64
if slot >= pool.startingSlot and if slot >= pool.startingSlot and
slot < (pool.startingSlot + pool.phase0Candidates.lenu64): slot < (pool.startingSlot + poolLength):
Opt.some(int(slot mod pool.phase0Candidates.lenu64)) Opt.some(int(slot mod poolLength))
else: else:
Opt.none(int) Opt.none(int)
@ -751,15 +757,6 @@ proc getAttestationsForBlock*(pool: var AttestationPool,
# #
# For each round, we'll look for the best attestation and add it to the result # For each round, we'll look for the best attestation and add it to the result
# then re-score the other candidates. # then re-score the other candidates.
var
prevEpoch = state.data.get_previous_epoch()
prevEpochSpace =
when not (state is phase0.HashedBeaconState):
MAX_ATTESTATIONS
else:
state.data.previous_epoch_attestations.maxLen -
state.data.previous_epoch_attestations.len()
var res: seq[phase0.Attestation] var res: seq[phase0.Attestation]
let totalCandidates = candidates.len() let totalCandidates = candidates.len()
while candidates.len > 0 and res.lenu64() < MAX_ATTESTATIONS: while candidates.len > 0 and res.lenu64() < MAX_ATTESTATIONS:
@ -775,12 +772,6 @@ proc getAttestationsForBlock*(pool: var AttestationPool,
candidates.del(candidate) # careful, `del` reorders candidates candidates.del(candidate) # careful, `del` reorders candidates
if entry[].data.target.epoch == prevEpoch:
if prevEpochSpace < 1:
continue # No need to rescore since we didn't add the attestation
prevEpochSpace -= 1
res.add(entry[].toAttestation(entry[].aggregates[j])) res.add(entry[].toAttestation(entry[].aggregates[j]))
# Update cache so that the new votes are taken into account when updating # Update cache so that the new votes are taken into account when updating
@ -888,6 +879,9 @@ proc getElectraAttestationsForBlock*(
# remain valid # remain valid
candidates.add((score, slot, addr entry, j)) candidates.add((score, slot, addr entry, j))
# Sort candidates by score use slot as a tie-breaker
candidates.sort()
# Using a greedy algorithm, select as many attestations as possible that will # Using a greedy algorithm, select as many attestations as possible that will
# fit in the block. # fit in the block.
# #
@ -902,34 +896,31 @@ proc getElectraAttestationsForBlock*(
# For each round, we'll look for the best attestation and add it to the result # For each round, we'll look for the best attestation and add it to the result
# then re-score the other candidates. # then re-score the other candidates.
var var
prevEpoch = state.data.get_previous_epoch() candidatesPerBlock: Table[(Eth2Digest, Slot), seq[electra.Attestation]]
prevEpochSpace = MAX_ATTESTATIONS_ELECTRA
var res: seq[electra.Attestation]
let totalCandidates = candidates.len() let totalCandidates = candidates.len()
while candidates.len > 0 and res.lenu64() < while candidates.len > 0 and candidatesPerBlock.lenu64() <
MAX_ATTESTATIONS_ELECTRA * MAX_COMMITTEES_PER_SLOT: MAX_ATTESTATIONS_ELECTRA * MAX_COMMITTEES_PER_SLOT:
let entryCacheKey = block: let entryCacheKey = block:
# Find the candidate with the highest score - slot is used as a let (_, _, entry, j) =
# tie-breaker so that more recent attestations are added first # Fast path for when all remaining candidates fit
if candidates.lenu64 < MAX_ATTESTATIONS_ELECTRA:
candidates[candidates.len - 1]
else:
# Get the candidate with the highest score
candidates.pop()
#TODO: Merge candidates per block structure with the candidates one
# and score possible on-chain attestations while collecting candidates
# (previous loop) and reavaluate cache key definition
let let
candidate = key = (entry.data.beacon_block_root, entry.data.slot)
# Fast path for when all remaining candidates fit newAtt = entry[].toElectraAttestation(entry[].aggregates[j])
if candidates.lenu64 < MAX_ATTESTATIONS_ELECTRA * MAX_COMMITTEES_PER_SLOT:
candidates.len - 1
else:
maxIndex(candidates)
(_, _, entry, j) = candidates[candidate]
candidates.del(candidate) # careful, `del` reorders candidates candidatesPerBlock.withValue(key, candidate):
candidate[].add newAtt
if entry[].data.target.epoch == prevEpoch: do:
if prevEpochSpace < 1: candidatesPerBlock[key] = @[newAtt]
continue # No need to rescore since we didn't add the attestation
prevEpochSpace -= 1
res.add(entry[].toElectraAttestation(entry[].aggregates[j]))
# Update cache so that the new votes are taken into account when updating # Update cache so that the new votes are taken into account when updating
# the score below # the score below
@ -953,35 +944,35 @@ proc getElectraAttestationsForBlock*(
# Only keep candidates that might add coverage # Only keep candidates that might add coverage
it.score > 0 it.score > 0
# TODO sort candidates by score - or really, rewrite the whole loop above ;) # Sort candidates by score use slot as a tie-breaker
var res2: seq[electra.Attestation] candidates.sort()
var perBlock: Table[(Eth2Digest, Slot), seq[electra.Attestation]]
for a in res: # Consolidate attestation aggregates with disjoint comittee bits into single
let key = (a.data.beacon_block_root, a.data.slot) # attestation
perBlock.mGetOrPut(key, newSeq[electra.Attestation](0)).add(a) var res: seq[electra.Attestation]
for a in candidatesPerBlock.values():
for a in perBlock.values(): if a.len > 1:
# TODO this will create on-chain aggregates that contain only one let
# committee index - this is obviously wrong but fixing requires att = compute_on_chain_aggregate(a).valueOr:
# a more significant rewrite - we should combine the best aggregates continue
# for each beacon block root res.add(att)
let x = compute_on_chain_aggregate(a).valueOr: #no on chain candidates
continue else:
res.add(a)
res2.add(x) if res.lenu64 == MAX_ATTESTATIONS_ELECTRA:
if res2.lenu64 == MAX_ATTESTATIONS_ELECTRA:
break break
let let
packingDur = Moment.now() - startPackingTick packingDur = Moment.now() - startPackingTick
debug "Packed attestations for block", debug "Packed attestations for block",
newBlockSlot, packingDur, totalCandidates, attestations = res2.len() newBlockSlot, packingDur, totalCandidates, attestations = res.len()
attestation_pool_block_attestation_packing_time.set( attestation_pool_block_attestation_packing_time.set(
packingDur.toFloatSeconds()) packingDur.toFloatSeconds())
res2 res
proc getElectraAttestationsForBlock*( proc getElectraAttestationsForBlock*(
pool: var AttestationPool, state: ForkedHashedBeaconState, pool: var AttestationPool, state: ForkedHashedBeaconState,
@ -992,7 +983,8 @@ proc getElectraAttestationsForBlock*(
else: else:
default(seq[electra.Attestation]) default(seq[electra.Attestation])
func bestValidation(aggregates: openArray[Phase0Validation]): (int, int) = func bestValidation(
aggregates: openArray[Phase0Validation | ElectraValidation]): (int, int) =
# Look for best validation based on number of votes in the aggregate # Look for best validation based on number of votes in the aggregate
doAssert aggregates.len() > 0, doAssert aggregates.len() > 0,
"updateAggregates should have created at least one aggregate" "updateAggregates should have created at least one aggregate"
@ -1007,6 +999,29 @@ func bestValidation(aggregates: openArray[Phase0Validation]): (int, int) =
bestIndex = i bestIndex = i
(bestIndex, best) (bestIndex, best)
func getElectraAggregatedAttestation*(
pool: var AttestationPool, slot: Slot,
attestationDataRoot: Eth2Digest, committeeIndex: CommitteeIndex):
Opt[electra.Attestation] =
let candidateIdx = pool.candidateIdx(slot)
if candidateIdx.isNone:
return Opt.none(electra.Attestation)
var res: Opt[electra.Attestation]
for _, entry in pool.electraCandidates[candidateIdx.get].mpairs():
if entry.data.index != committeeIndex.distinctBase:
continue
entry.updateAggregates()
let (bestIndex, best) = bestValidation(entry.aggregates)
if res.isNone() or best > res.get().aggregation_bits.countOnes():
res = Opt.some(entry.toElectraAttestation(entry.aggregates[bestIndex]))
res
func getAggregatedAttestation*( func getAggregatedAttestation*(
pool: var AttestationPool, slot: Slot, attestation_data_root: Eth2Digest): pool: var AttestationPool, slot: Slot, attestation_data_root: Eth2Digest):
Opt[phase0.Attestation] = Opt[phase0.Attestation] =

View File

@ -1178,7 +1178,7 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
# should have `previous_version` set to `current_version` while # should have `previous_version` set to `current_version` while
# this doesn't happen to be the case in network that go through # this doesn't happen to be the case in network that go through
# regular hard-fork upgrades. See for example: # regular hard-fork upgrades. See for example:
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#testing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#testing
if stateFork.current_version != configFork.current_version: if stateFork.current_version != configFork.current_version:
error "State from database does not match network, check --network parameter", error "State from database does not match network, check --network parameter",
tail = dag.tail, headRef, stateFork, configFork tail = dag.tail, headRef, stateFork, configFork
@ -1972,7 +1972,7 @@ proc pruneBlocksDAG(dag: ChainDAGRef) =
prunedHeads = hlen - dag.heads.len, prunedHeads = hlen - dag.heads.len,
dagPruneDur = Moment.now() - startTick dagPruneDur = Moment.now() - startTick
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/sync/optimistic.md#helpers # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/sync/optimistic.md#helpers
func is_optimistic*(dag: ChainDAGRef, bid: BlockId): bool = func is_optimistic*(dag: ChainDAGRef, bid: BlockId): bool =
let blck = let blck =
if bid.slot <= dag.finalizedHead.slot: if bid.slot <= dag.finalizedHead.slot:
@ -2676,7 +2676,7 @@ func aggregateAll*(
# Aggregation spec requires non-empty collection # Aggregation spec requires non-empty collection
# - https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04 # - https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04
# Consensus specs require at least one attesting index in attestation # Consensus specs require at least one attesting index in attestation
# - https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#is_valid_indexed_attestation # - https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#is_valid_indexed_attestation
return err("aggregate: no attesting keys") return err("aggregate: no attesting keys")
let let

View File

@ -53,7 +53,7 @@ iterator get_beacon_committee*(
committees_per_slot * SLOTS_PER_EPOCH committees_per_slot * SLOTS_PER_EPOCH
): yield (index_in_committee, idx) ): yield (index_in_committee, idx)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#get_beacon_committee # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_beacon_committee
func get_beacon_committee*( func get_beacon_committee*(
shufflingRef: ShufflingRef, slot: Slot, committee_index: CommitteeIndex): shufflingRef: ShufflingRef, slot: Slot, committee_index: CommitteeIndex):
seq[ValidatorIndex] = seq[ValidatorIndex] =
@ -283,7 +283,7 @@ func makeAttestationData*(
doAssert current_epoch == epochRef.epoch doAssert current_epoch == epochRef.epoch
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#attestation-data # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#attestation-data
AttestationData( AttestationData(
slot: slot, slot: slot,
index: committee_index.asUInt64, index: committee_index.asUInt64,

View File

@ -364,7 +364,7 @@ proc produceSyncAggregate*(
proc isEpochLeadTime*( proc isEpochLeadTime*(
pool: SyncCommitteeMsgPool, epochsToSyncPeriod: uint64): bool = pool: SyncCommitteeMsgPool, epochsToSyncPeriod: uint64): bool =
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#sync-committee-subnet-stability # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#sync-committee-subnet-stability
# This ensures a uniform distribution without requiring additional state: # This ensures a uniform distribution without requiring additional state:
# (1/4) = 1/4, 4 slots out # (1/4) = 1/4, 4 slots out
# (3/4) * (1/3) = 1/4, 3 slots out # (3/4) * (1/3) = 1/4, 3 slots out

View File

@ -220,7 +220,7 @@ proc restValidatorExit(config: BeaconNodeConf) {.async.} =
reason = exc.msg reason = exc.msg
quit 1 quit 1
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#voluntary-exits # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#voluntary-exits
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/beacon-chain.md#modified-process_voluntary_exit # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/beacon-chain.md#modified-process_voluntary_exit
let signingFork = try: let signingFork = try:
let response = await client.getSpecVC() let response = await client.getSpecVC()

View File

@ -15,6 +15,7 @@ import
web3, web3/[engine_api, primitives, conversions], web3, web3/[engine_api, primitives, conversions],
eth/common/eth_types, eth/common/eth_types,
results, results,
kzg4844/[kzg_abi, kzg],
stew/[assign2, byteutils, objects], stew/[assign2, byteutils, objects],
# Local modules: # Local modules:
../spec/[eth2_merkleization, forks], ../spec/[eth2_merkleization, forks],
@ -942,7 +943,7 @@ proc sendNewPayload*(
let let
startTime = Moment.now() startTime = Moment.now()
deadline = sleepAsync(NEWPAYLOAD_TIMEOUT) deadline = sleepAsync(NEWPAYLOAD_TIMEOUT)
payload = blck.body.execution_payload.asEngineExecutionPayload payload = blck.body.asEngineExecutionPayload
var var
responseProcessor = ELConsensusViolationDetector.init() responseProcessor = ELConsensusViolationDetector.init()

View File

@ -8,6 +8,7 @@
{.push raises: [].} {.push raises: [].}
import import
kzg4844/[kzg_abi, kzg],
../spec/datatypes/[bellatrix, capella, deneb, electra], ../spec/datatypes/[bellatrix, capella, deneb, electra],
web3/[engine_api, engine_api_types] web3/[engine_api, engine_api_types]
@ -196,18 +197,7 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4):
withdrawals: List[capella.Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD].init( withdrawals: List[capella.Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD].init(
mapIt(rpcExecutionPayload.withdrawals, it.asConsensusWithdrawal)), mapIt(rpcExecutionPayload.withdrawals, it.asConsensusWithdrawal)),
blob_gas_used: rpcExecutionPayload.blobGasUsed.uint64, blob_gas_used: rpcExecutionPayload.blobGasUsed.uint64,
excess_blob_gas: rpcExecutionPayload.excessBlobGas.uint64, excess_blob_gas: rpcExecutionPayload.excessBlobGas.uint64)
deposit_requests:
List[electra.DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD].init(
mapIt(rpcExecutionPayload.depositRequests, it.getDepositRequest)),
withdrawal_requests: List[electra.WithdrawalRequest,
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD].init(
mapIt(rpcExecutionPayload.withdrawalRequests,
it.getWithdrawalRequest)),
consolidation_requests: List[electra.ConsolidationRequest,
Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD].init(
mapIt(rpcExecutionPayload.consolidationRequests,
it.getConsolidationRequest)))
func asConsensusType*(payload: engine_api.GetPayloadV4Response): func asConsensusType*(payload: engine_api.GetPayloadV4Response):
electra.ExecutionPayloadForSigning = electra.ExecutionPayloadForSigning =
@ -228,8 +218,10 @@ func asConsensusType*(payload: engine_api.GetPayloadV4Response):
blobs: Blobs.init( blobs: Blobs.init(
payload.blobsBundle.blobs.mapIt(it.bytes)))) payload.blobsBundle.blobs.mapIt(it.bytes))))
func asEngineExecutionPayload*(executionPayload: bellatrix.ExecutionPayload): func asEngineExecutionPayload*(blockBody: bellatrix.BeaconBlockBody):
ExecutionPayloadV1 = ExecutionPayloadV1 =
template executionPayload(): untyped = blockBody.execution_payload
template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction = template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction =
TypedTransaction(tt.distinctBase) TypedTransaction(tt.distinctBase)
@ -257,8 +249,10 @@ template toEngineWithdrawal*(w: capella.Withdrawal): WithdrawalV1 =
address: Address(w.address.data), address: Address(w.address.data),
amount: Quantity(w.amount)) amount: Quantity(w.amount))
func asEngineExecutionPayload*(executionPayload: capella.ExecutionPayload): func asEngineExecutionPayload*(blockBody: capella.BeaconBlockBody):
ExecutionPayloadV2 = ExecutionPayloadV2 =
template executionPayload(): untyped = blockBody.execution_payload
template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction = template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction =
TypedTransaction(tt.distinctBase) TypedTransaction(tt.distinctBase)
engine_api.ExecutionPayloadV2( engine_api.ExecutionPayloadV2(
@ -279,8 +273,10 @@ func asEngineExecutionPayload*(executionPayload: capella.ExecutionPayload):
transactions: mapIt(executionPayload.transactions, it.getTypedTransaction), transactions: mapIt(executionPayload.transactions, it.getTypedTransaction),
withdrawals: mapIt(executionPayload.withdrawals, it.toEngineWithdrawal)) withdrawals: mapIt(executionPayload.withdrawals, it.toEngineWithdrawal))
func asEngineExecutionPayload*(executionPayload: deneb.ExecutionPayload): func asEngineExecutionPayload*(blockBody: deneb.BeaconBlockBody):
ExecutionPayloadV3 = ExecutionPayloadV3 =
template executionPayload(): untyped = blockBody.execution_payload
template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction = template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction =
TypedTransaction(tt.distinctBase) TypedTransaction(tt.distinctBase)
@ -304,8 +300,10 @@ func asEngineExecutionPayload*(executionPayload: deneb.ExecutionPayload):
blobGasUsed: Quantity(executionPayload.blob_gas_used), blobGasUsed: Quantity(executionPayload.blob_gas_used),
excessBlobGas: Quantity(executionPayload.excess_blob_gas)) excessBlobGas: Quantity(executionPayload.excess_blob_gas))
func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload): func asEngineExecutionPayload*(blockBody: electra.BeaconBlockBody):
ExecutionPayloadV4 = ExecutionPayloadV4 =
template executionPayload(): untyped = blockBody.execution_payload
template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction = template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction =
TypedTransaction(tt.distinctBase) TypedTransaction(tt.distinctBase)
@ -351,9 +349,9 @@ func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload):
withdrawals: mapIt(executionPayload.withdrawals, it.asEngineWithdrawal), withdrawals: mapIt(executionPayload.withdrawals, it.asEngineWithdrawal),
blobGasUsed: Quantity(executionPayload.blob_gas_used), blobGasUsed: Quantity(executionPayload.blob_gas_used),
excessBlobGas: Quantity(executionPayload.excess_blob_gas), excessBlobGas: Quantity(executionPayload.excess_blob_gas),
depositRequests: mapIt( depositRequests:
executionPayload.deposit_requests, it.getDepositRequest), mapIt(blockBody.execution_requests.deposits, it.getDepositRequest),
withdrawalRequests: mapIt( withdrawalRequests: mapIt(
executionPayload.withdrawal_requests, it.getWithdrawalRequest), blockBody.execution_requests.withdrawals, it.getWithdrawalRequest),
consolidationRequests: mapIt( consolidationRequests: mapIt(
executionPayload.consolidation_requests, it.getConsolidationRequest)) blockBody.execution_requests.consolidations, it.getConsolidationRequest))

View File

@ -7,7 +7,7 @@
{.push raises: [].} {.push raises: [].}
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/tests/core/pyspec/eth2spec/utils/merkle_minimal.py # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/tests/core/pyspec/eth2spec/utils/merkle_minimal.py
# Merkle tree helpers # Merkle tree helpers
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -109,7 +109,7 @@ proc update_justified(
self.update_justified(dag, blck, justified.epoch) self.update_justified(dag, blck, justified.epoch)
ok() ok()
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/fork-choice.md#update_checkpoints # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/fork-choice.md#update_checkpoints
proc update_checkpoints( proc update_checkpoints(
self: var Checkpoints, dag: ChainDAGRef, self: var Checkpoints, dag: ChainDAGRef,
checkpoints: FinalityCheckpoints): FcResult[void] = checkpoints: FinalityCheckpoints): FcResult[void] =
@ -373,7 +373,7 @@ proc get_head*(self: var ForkChoice,
self.checkpoints.justified.balances, self.checkpoints.justified.balances,
self.checkpoints.proposer_boost_root) self.checkpoints.proposer_boost_root)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/fork_choice/safe-block.md#get_safe_beacon_block_root # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/fork_choice/safe-block.md#get_safe_beacon_block_root
func get_safe_beacon_block_root*(self: ForkChoice): Eth2Digest = func get_safe_beacon_block_root*(self: ForkChoice): Eth2Digest =
# Use most recent justified block as a stopgap # Use most recent justified block as a stopgap
self.checkpoints.justified.checkpoint.root self.checkpoints.justified.checkpoint.root

View File

@ -71,9 +71,6 @@ func len*(nodes: ProtoNodes): int =
func add(nodes: var ProtoNodes, node: ProtoNode) = func add(nodes: var ProtoNodes, node: ProtoNode) =
nodes.buf.add node nodes.buf.add node
func isPreviousEpochJustified(self: ProtoArray): bool =
self.checkpoints.justified.epoch + 1 == self.currentEpoch
# Forward declarations # Forward declarations
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------

View File

@ -14,7 +14,7 @@ Gossip validation is different from consensus verification in particular for blo
- Attestations (unaggregated): https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#attestation-subnets - Attestations (unaggregated): https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#attestation-subnets
- Voluntary exits: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/phase0/p2p-interface.md#voluntary_exit - Voluntary exits: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/phase0/p2p-interface.md#voluntary_exit
- Proposer slashings: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#proposer_slashing - Proposer slashings: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#proposer_slashing
- Attester slashing: https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#attester_slashing - Attester slashing: https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#attester_slashing
There are multiple consumers of validated consensus objects: There are multiple consumers of validated consensus objects:
- a `ValidationResult.Accept` output triggers rebroadcasting in libp2p - a `ValidationResult.Accept` output triggers rebroadcasting in libp2p

View File

@ -587,8 +587,8 @@ proc storeBlock(
if NewPayloadStatus.noResponse == payloadStatus: if NewPayloadStatus.noResponse == payloadStatus:
# When the execution layer is not available to verify the payload, we do the # When the execution layer is not available to verify the payload, we do the
# required checks on the CL instead and proceed as if the EL was syncing # required checks on the CL instead and proceed as if the EL was syncing
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#verify_and_notify_new_payload # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#verify_and_notify_new_payload
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/deneb/beacon-chain.md#modified-verify_and_notify_new_payload # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/beacon-chain.md#modified-verify_and_notify_new_payload
when typeof(signedBlock).kind >= ConsensusFork.Bellatrix: when typeof(signedBlock).kind >= ConsensusFork.Bellatrix:
if signedBlock.message.is_execution_block: if signedBlock.message.is_execution_block:
template payload(): auto = signedBlock.message.body.execution_payload template payload(): auto = signedBlock.message.body.execution_payload
@ -898,7 +898,7 @@ proc processBlock(
# - MUST NOT optimistically import the block. # - MUST NOT optimistically import the block.
# - MUST NOT apply the block to the fork choice store. # - MUST NOT apply the block to the fork choice store.
# - MAY queue the block for later processing. # - MAY queue the block for later processing.
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/sync/optimistic.md#execution-engine-errors # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/sync/optimistic.md#execution-engine-errors
await sleepAsync(chronos.seconds(1)) await sleepAsync(chronos.seconds(1))
self[].enqueueBlock( self[].enqueueBlock(
entry.src, entry.blck, entry.blobs, entry.resfut, entry.maybeFinalized, entry.src, entry.blck, entry.blobs, entry.resfut, entry.maybeFinalized,

View File

@ -11,6 +11,7 @@ import
# Status # Status
chronicles, chronos, metrics, chronicles, chronos, metrics,
results, results,
kzg4844/[kzg, kzg_abi],
stew/byteutils, stew/byteutils,
# Internals # Internals
../spec/[ ../spec/[
@ -93,7 +94,7 @@ func check_propagation_slot_range(
return ok(msgSlot) return ok(msgSlot)
if consensusFork < ConsensusFork.Deneb: if consensusFork < ConsensusFork.Deneb:
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/p2p-interface.md#configuration # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#configuration
# The spec value of ATTESTATION_PROPAGATION_SLOT_RANGE is 32, but it can # The spec value of ATTESTATION_PROPAGATION_SLOT_RANGE is 32, but it can
# retransmit attestations on the cusp of being out of spec, and which by # retransmit attestations on the cusp of being out of spec, and which by
# the time they reach their destination might be out of spec. # the time they reach their destination might be out of spec.
@ -275,10 +276,6 @@ template checkedReject(
pool: ValidatorChangePool, error: ValidationError): untyped = pool: ValidatorChangePool, error: ValidationError): untyped =
pool.dag.checkedReject(error) pool.dag.checkedReject(error)
template checkedResult(
pool: ValidatorChangePool, error: ValidationError): untyped =
pool.dag.checkedResult(error)
template validateBeaconBlockBellatrix( template validateBeaconBlockBellatrix(
signed_beacon_block: phase0.SignedBeaconBlock | altair.SignedBeaconBlock, signed_beacon_block: phase0.SignedBeaconBlock | altair.SignedBeaconBlock,
parent: BlockRef): untyped = parent: BlockRef): untyped =
@ -303,7 +300,7 @@ template validateBeaconBlockBellatrix(
# #
# `is_merge_transition_complete(state)` tests for # `is_merge_transition_complete(state)` tests for
# `state.latest_execution_payload_header != ExecutionPayloadHeader()`, while # `state.latest_execution_payload_header != ExecutionPayloadHeader()`, while
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#block-processing
# shows that `state.latest_execution_payload_header` being default or not is # shows that `state.latest_execution_payload_header` being default or not is
# exactly equivalent to whether that block's execution payload is default or # exactly equivalent to whether that block's execution payload is default or
# not, so test cached block information rather than reconstructing a state. # not, so test cached block information rather than reconstructing a state.
@ -458,7 +455,7 @@ proc validateBlobSidecar*(
# [REJECT] The sidecar's blob is valid as verified by `verify_blob_kzg_proof( # [REJECT] The sidecar's blob is valid as verified by `verify_blob_kzg_proof(
# blob_sidecar.blob, blob_sidecar.kzg_commitment, blob_sidecar.kzg_proof)`. # blob_sidecar.blob, blob_sidecar.kzg_commitment, blob_sidecar.kzg_proof)`.
block: block:
let ok = verifyProof( let ok = verifyBlobKzgProof(
KzgBlob(bytes: blob_sidecar.blob), KzgBlob(bytes: blob_sidecar.blob),
blob_sidecar.kzg_commitment, blob_sidecar.kzg_commitment,
blob_sidecar.kzg_proof).valueOr: blob_sidecar.kzg_proof).valueOr:
@ -482,7 +479,7 @@ proc validateBlobSidecar*(
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/p2p-interface.md#beacon_block # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/p2p-interface.md#beacon_block
proc validateBeaconBlock*( proc validateBeaconBlock*(
dag: ChainDAGRef, quarantine: ref Quarantine, dag: ChainDAGRef, quarantine: ref Quarantine,
signed_beacon_block: phase0.SignedBeaconBlock | altair.SignedBeaconBlock | bellatrix.SignedBeaconBlock | capella.SignedBeaconBlock | deneb.SignedBeaconBlock, signed_beacon_block: ForkySignedBeaconBlock,
wallTime: BeaconTime, flags: UpdateFlags): Result[void, ValidationError] = wallTime: BeaconTime, flags: UpdateFlags): Result[void, ValidationError] =
# In general, checks are ordered from cheap to expensive. Especially, crypto # In general, checks are ordered from cheap to expensive. Especially, crypto
# verification could be quite a bit more expensive than the rest. This is an # verification could be quite a bit more expensive than the rest. This is an
@ -672,13 +669,6 @@ proc validateBeaconBlock*(
ok() ok()
proc validateBeaconBlock*(
dag: ChainDAGRef, quarantine: ref Quarantine,
signed_beacon_block: electra.SignedBeaconBlock,
wallTime: BeaconTime, flags: UpdateFlags): Result[void, ValidationError] =
debugComment "it's sometimes not"
ok()
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#beacon_aggregate_and_proof # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#beacon_aggregate_and_proof
proc validateAttestation*( proc validateAttestation*(
@ -896,11 +886,9 @@ proc validateAttestation*(
attestation = shortLog(attestation), target = shortLog(target) attestation = shortLog(attestation), target = shortLog(target)
return errIgnore("Attestation: no shuffling") return errIgnore("Attestation: no shuffling")
let let attesting_index = get_attesting_indices_one(
fork = pool.dag.forkAtEpoch(attestation.data.slot.epoch) shufflingRef, slot, attestation.committee_bits,
attesting_index = get_attesting_indices_one( attestation.aggregation_bits, false)
shufflingRef, slot, attestation.committee_bits,
attestation.aggregation_bits, false)
# The number of aggregation bits matches the committee size, which ensures # The number of aggregation bits matches the committee size, which ensures
# this condition holds. # this condition holds.
@ -1176,18 +1164,15 @@ proc validateAggregate*(
"Attestation: committee index not within expected range") "Attestation: committee index not within expected range")
idx.get() idx.get()
let let
fork = pool.dag.forkAtEpoch(aggregate.data.slot.epoch)
attesting_indices = get_attesting_indices( attesting_indices = get_attesting_indices(
shufflingRef, slot, committee_index, aggregate.aggregation_bits, false) shufflingRef, slot, committee_index, aggregate.aggregation_bits, false)
let
sig = sig =
aggregate.signature.load().valueOr: aggregate.signature.load().valueOr:
return pool.checkedReject("Aggregate: unable to load signature") return pool.checkedReject("Aggregate: unable to load signature")
ok((attesting_indices, sig)) ok((attesting_indices, sig))
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/p2p-interface.md#bls_to_execution_change # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/p2p-interface.md#bls_to_execution_change
proc validateBlsToExecutionChange*( proc validateBlsToExecutionChange*(
pool: ValidatorChangePool, batchCrypto: ref BatchCrypto, pool: ValidatorChangePool, batchCrypto: ref BatchCrypto,
signed_address_change: SignedBLSToExecutionChange, signed_address_change: SignedBLSToExecutionChange,

View File

@ -94,7 +94,7 @@ typedef struct ETHConsensusConfig ETHConsensusConfig;
* based on the given `config.yaml` file content - If successful. * based on the given `config.yaml` file content - If successful.
* @return `NULL` - If the given `config.yaml` is malformed or incompatible. * @return `NULL` - If the given `config.yaml` is malformed or incompatible.
* *
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/configs/README.md * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/configs/README.md
*/ */
ETH_RESULT_USE_CHECK ETH_RESULT_USE_CHECK
ETHConsensusConfig *_Nullable ETHConsensusConfigCreateFromYaml(const char *configFileContent); ETHConsensusConfig *_Nullable ETHConsensusConfigCreateFromYaml(const char *configFileContent);
@ -150,10 +150,10 @@ typedef struct ETHBeaconState ETHBeaconState;
* @return `NULL` - If the given `sszBytes` is malformed. * @return `NULL` - If the given `sszBytes` is malformed.
* *
* @see https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#beaconstate * @see https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#beaconstate
* @see https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#beaconstate * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#beaconstate
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#beaconstate * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#beaconstate
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#beaconstate * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#beaconstate
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/configs/README.md * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/configs/README.md
*/ */
ETH_RESULT_USE_CHECK ETH_RESULT_USE_CHECK
ETHBeaconState *_Nullable ETHBeaconStateCreateFromSsz( ETHBeaconState *_Nullable ETHBeaconStateCreateFromSsz(
@ -271,7 +271,7 @@ void ETHBeaconClockDestroy(ETHBeaconClock *beaconClock);
* @return Slot number for the current wall clock time - If genesis has occurred. * @return Slot number for the current wall clock time - If genesis has occurred.
* @return `0` - If genesis is still pending. * @return `0` - If genesis is still pending.
* *
* @see https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#custom-types * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#custom-types
*/ */
ETH_RESULT_USE_CHECK ETH_RESULT_USE_CHECK
int ETHBeaconClockGetSlot(const ETHBeaconClock *beaconClock); int ETHBeaconClockGetSlot(const ETHBeaconClock *beaconClock);
@ -325,8 +325,8 @@ typedef struct ETHLightClientStore ETHLightClientStore;
* *
* @see https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.1#/Beacon/getLightClientBootstrap * @see https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.1#/Beacon/getLightClientBootstrap
* @see https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.1#/Events/eventstream * @see https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.1#/Events/eventstream
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/light-client.md * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/light-client.md
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/weak-subjectivity.md#weak-subjectivity-period * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/weak-subjectivity.md#weak-subjectivity-period
*/ */
ETH_RESULT_USE_CHECK ETH_RESULT_USE_CHECK
ETHLightClientStore *_Nullable ETHLightClientStoreCreateFromBootstrap( ETHLightClientStore *_Nullable ETHLightClientStoreCreateFromBootstrap(
@ -579,7 +579,7 @@ typedef struct ETHLightClientHeader ETHLightClientHeader;
* *
* @return Latest finalized header. * @return Latest finalized header.
* *
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/light-client/sync-protocol.md#modified-lightclientheader * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/light-client/sync-protocol.md#modified-lightclientheader
*/ */
ETH_RESULT_USE_CHECK ETH_RESULT_USE_CHECK
const ETHLightClientHeader *ETHLightClientStoreGetFinalizedHeader( const ETHLightClientHeader *ETHLightClientStoreGetFinalizedHeader(
@ -598,7 +598,7 @@ const ETHLightClientHeader *ETHLightClientStoreGetFinalizedHeader(
* @return Whether or not the next sync committee is currently known. * @return Whether or not the next sync committee is currently known.
* *
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#is_next_sync_committee_known
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/light-client.md * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/light-client.md
*/ */
ETH_RESULT_USE_CHECK ETH_RESULT_USE_CHECK
bool ETHLightClientStoreIsNextSyncCommitteeKnown(const ETHLightClientStore *store); bool ETHLightClientStoreIsNextSyncCommitteeKnown(const ETHLightClientStore *store);
@ -672,7 +672,7 @@ void ETHLightClientHeaderDestroy(ETHLightClientHeader *header);
* *
* @return Pointer to a copy of the given header's beacon block root. * @return Pointer to a copy of the given header's beacon block root.
* *
* @see https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#hash_tree_root * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#hash_tree_root
*/ */
ETH_RESULT_USE_CHECK ETH_RESULT_USE_CHECK
ETHRoot *ETHLightClientHeaderCopyBeaconRoot( ETHRoot *ETHLightClientHeaderCopyBeaconRoot(
@ -695,7 +695,7 @@ typedef struct ETHBeaconBlockHeader ETHBeaconBlockHeader;
* *
* @return Beacon block header. * @return Beacon block header.
* *
* @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#beaconblockheader * @see https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#beaconblockheader
*/ */
ETH_RESULT_USE_CHECK ETH_RESULT_USE_CHECK
const ETHBeaconBlockHeader *ETHLightClientHeaderGetBeacon( const ETHBeaconBlockHeader *ETHLightClientHeaderGetBeacon(
@ -1103,6 +1103,81 @@ ETH_RESULT_USE_CHECK
const ETHWithdrawals *ETHExecutionBlockHeaderGetWithdrawals( const ETHWithdrawals *ETHExecutionBlockHeaderGetWithdrawals(
const ETHExecutionBlockHeader *executionBlockHeader); const ETHExecutionBlockHeader *executionBlockHeader);
/**
* Obtains the requests MPT root of a given execution block header.
*
* - The returned value is allocated in the given execution block header.
* It must neither be released nor written to, and the execution block
* header must not be released while the returned value is in use.
*
* @param executionBlockHeader Execution block header.
*
* @return Execution requests root.
*/
ETH_RESULT_USE_CHECK
const ETHRoot *ETHExecutionBlockHeaderGetRequestsRoot(
const ETHExecutionBlockHeader *executionBlockHeader);
/**
* Deposit request sequence.
*/
typedef struct ETHDepositRequests ETHDepositRequests;
/**
* Obtains the deposit request sequence of a given execution block header.
*
* - The returned value is allocated in the given execution block header.
* It must neither be released nor written to, and the execution block
* header must not be released while the returned value is in use.
*
* @param executionBlockHeader Execution block header.
*
* @return Deposit request sequence.
*/
ETH_RESULT_USE_CHECK
const ETHDepositRequests *ETHExecutionBlockHeaderGetDepositRequests(
const ETHExecutionBlockHeader *executionBlockHeader);
/**
* Withdrawal request sequence.
*/
typedef struct ETHWithdrawalRequests ETHWithdrawalRequests;
/**
* Obtains the withdrawal request sequence of a given execution block header.
*
* - The returned value is allocated in the given execution block header.
* It must neither be released nor written to, and the execution block
* header must not be released while the returned value is in use.
*
* @param executionBlockHeader Execution block header.
*
* @return Withdrawal request sequence.
*/
ETH_RESULT_USE_CHECK
const ETHWithdrawalRequests *ETHExecutionBlockHeaderGetWithdrawalRequests(
const ETHExecutionBlockHeader *executionBlockHeader);
/**
* Consolidation request sequence.
*/
typedef struct ETHConsolidationRequests ETHConsolidationRequests;
/**
* Obtains the consolidation request sequence of a given execution block header.
*
* - The returned value is allocated in the given execution block header.
* It must neither be released nor written to, and the execution block
* header must not be released while the returned value is in use.
*
* @param executionBlockHeader Execution block header.
*
* @return Consolidation request sequence.
*/
ETH_RESULT_USE_CHECK
const ETHConsolidationRequests *ETHExecutionBlockHeaderGetConsolidationRequests(
const ETHExecutionBlockHeader *executionBlockHeader);
/** /**
* Transaction sequence. * Transaction sequence.
*/ */
@ -1373,9 +1448,9 @@ typedef struct ETHAccessTuple ETHAccessTuple;
* Obtains an individual access tuple by sequential index * Obtains an individual access tuple by sequential index
* in a transaction access list. * in a transaction access list.
* *
* - The returned value is allocated in the given transaction access list. * - The returned value is allocated in the given access list.
* It must neither be released nor written to, and the transaction * It must neither be released nor written to, and the access list
* access list must not be released while the returned value is in use. * must not be released while the returned value is in use.
* *
* @param accessList Transaction access list. * @param accessList Transaction access list.
* @param accessTupleIndex Sequential access tuple index. * @param accessTupleIndex Sequential access tuple index.
@ -1477,6 +1552,139 @@ const ETHRoot *ETHTransactionGetBlobVersionedHash(
const ETHTransaction *transaction, const ETHTransaction *transaction,
int versionedHashIndex); int versionedHashIndex);
/**
* Transaction authorization list.
*/
typedef struct ETHAuthorizationList ETHAuthorizationList;
/**
* Obtains the authorization list of a transaction.
*
* - The returned value is allocated in the given transaction.
* It must neither be released nor written to, and the transaction
* must not be released while the returned value is in use.
*
* @param transaction Transaction.
*
* @return Transaction authorization list.
*/
ETH_RESULT_USE_CHECK
const ETHAuthorizationList *ETHTransactionGetAuthorizationList(const ETHTransaction *transaction);
/**
* Indicates the total number of authorization tuples
* in a transaction authorization list.
*
* - Individual authorization tuples may be inspected using
* `ETHAuthorizationListGet`.
*
* @param authorizationList Transaction authorization list.
*
* @return Number of available authorization tuples.
*/
ETH_RESULT_USE_CHECK
int ETHAuthorizationListGetCount(const ETHAuthorizationList *authorizationList);
/**
* Authorization tuple.
*/
typedef struct ETHAuthorizationTuple ETHAuthorizationTuple;
/**
* Obtains an individual authorization tuple by sequential index
* in a transaction authorization list.
*
* - The returned value is allocated in the given authorization list.
* It must neither be released nor written to, and the authorization list
* must not be released while the returned value is in use.
*
* @param authorizationList Transaction authorization list.
* @param authorizationIndex Sequential authorization tuple index.
*
* @return Authorization tuple.
*/
ETH_RESULT_USE_CHECK
const ETHAuthorizationTuple *ETHAuthorizationListGet(
const ETHAuthorizationList *authorizationList,
int authorizationIndex);
/**
* Obtains the chain ID of an authorization tuple.
*
* - The returned value is allocated in the given authorization tuple.
* It must neither be released nor written to, and the authorization tuple
* must not be released while the returned value is in use.
*
* @param authorizationTuple Authorization tuple.
*
* @return Chain ID.
*/
ETH_RESULT_USE_CHECK
const ETHUInt256 *ETHAuthorizationTupleGetChainId(
const ETHAuthorizationTuple *authorizationTuple);
/**
* Obtains the address of an authorization tuple.
*
* - The returned value is allocated in the given authorization tuple.
* It must neither be released nor written to, and the authorization tuple
* must not be released while the returned value is in use.
*
* @param authorizationTuple Authorization tuple.
*
* @return Address.
*/
ETH_RESULT_USE_CHECK
const ETHExecutionAddress *ETHAuthorizationTupleGetAddress(
const ETHAuthorizationTuple *authorizationTuple);
/**
* Obtains the nonce of an authorization tuple.
*
* - The returned value is allocated in the given authorization tuple.
* It must neither be released nor written to, and the authorization tuple
* must not be released while the returned value is in use.
*
* @param authorizationTuple Authorization tuple.
*
* @return Nonce.
*/
ETH_RESULT_USE_CHECK
const uint64_t *ETHAuthorizationTupleGetNonce(
const ETHAuthorizationTuple *authorizationTuple);
/**
* Obtains the authority execution address of an authorization tuple.
*
* - The returned value is allocated in the given authorization tuple.
* It must neither be released nor written to, and the authorization tuple
* must not be released while the returned value is in use.
*
* @param authorizationTuple Authorization tuple.
*
* @return Authority execution address.
*/
ETH_RESULT_USE_CHECK
const ETHExecutionAddress *ETHAuthorizationTupleGetAuthority(
const ETHAuthorizationTuple *authorizationTuple);
/**
* Obtains the signature of a authorization tuple.
*
* - The returned value is allocated in the given authorization tuple.
* It must neither be released nor written to, and the authorization tuple
* must not be released while the returned value is in use.
*
* @param authorizationTuple Authorization tuple.
* @param[out] numBytes Length of buffer.
*
* @return Buffer with signature.
*/
ETH_RESULT_USE_CHECK
const void *ETHAuthorizationTupleGetSignatureBytes(
const ETHAuthorizationTuple *authorizationTuple,
int *numBytes);
/** /**
* Obtains the signature of a transaction. * Obtains the signature of a transaction.
* *
@ -1896,6 +2104,354 @@ const void *ETHWithdrawalGetBytes(
const ETHWithdrawal *withdrawal, const ETHWithdrawal *withdrawal,
int *numBytes); int *numBytes);
/**
* Indicates the total number of deposit requests
* in a deposit request sequence.
*
* - Individual deposit requests may be inspected using
* `ETHDepositRequestsGet`.
*
* @param requests Deposit request sequence.
*
* @return Number of available deposit requestss.
*/
ETH_RESULT_USE_CHECK
int ETHDepositRequestsGetCount(const ETHDepositRequests *requests);
/**
* Deposit request.
*/
typedef struct ETHDepositRequest ETHDepositRequest;
/**
* Obtains an individual deposit request by sequential index
* in a deposit request sequence.
*
* - The returned value is allocated in the given request sequence.
* It must neither be released nor written to, and the request
* sequence must not be released while the returned value is in use.
*
* @param requests Deposit request sequence.
* @param requestIndex Sequential deposit request index.
*
* @return Deposit request.
*/
ETH_RESULT_USE_CHECK
const ETHDepositRequest *ETHDepositRequestsGet(
const ETHDepositRequests *requests,
int requestIndex);
/**
* Validator pubkey.
*/
typedef struct {
uint8_t bytes[48];
} ETHValidatorPubkey;
/**
* Obtains the pubkey of a deposit request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Deposit request.
*
* @return Pubkey.
*/
ETH_RESULT_USE_CHECK
const ETHValidatorPubkey *ETHDepositRequestGetPubkey(
const ETHDepositRequest *request);
/**
* Withdrawal credentials.
*/
typedef struct {
uint8_t bytes[32];
} ETHWithdrawalCredentials;
/**
* Obtains the withdrawal credentials of a deposit request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Deposit request.
*
* @return Withdrawal credentials.
*/
ETH_RESULT_USE_CHECK
const ETHWithdrawalCredentials *ETHDepositRequestGetWithdrawalCredentials(
const ETHDepositRequest *request);
/**
* Obtains the amount of a deposit request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Deposit request.
*
* @return Amount.
*/
ETH_RESULT_USE_CHECK
const uint64_t *ETHDepositRequestGetAmount(
const ETHDepositRequest *request);
/**
* Validator signature.
*/
typedef struct {
uint8_t bytes[96];
} ETHValidatorSignature;
/**
* Obtains the signature of a deposit request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Deposit request.
*
* @return Signature.
*/
ETH_RESULT_USE_CHECK
const ETHValidatorSignature *ETHDepositRequestGetSignature(
const ETHDepositRequest *request);
/**
* Obtains the index of a deposit request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Deposit request.
*
* @return Index.
*/
ETH_RESULT_USE_CHECK
const uint64_t *ETHDepositRequestGetIndex(
const ETHDepositRequest *request);
/**
* Obtains the raw byte representation of a deposit request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Deposit request.
* @param[out] numBytes Length of buffer.
*
* @return Buffer with raw deposit request data.
*/
ETH_RESULT_USE_CHECK
const void *ETHDepositRequestGetBytes(
const ETHDepositRequest *request,
int *numBytes);
/**
* Indicates the total number of withdrawal requests
* in a withdrawal request sequence.
*
* - Individual withdrawal requests may be inspected using
* `ETHWithdrawalRequestsGet`.
*
* @param requests Withdrawal request sequence.
*
* @return Number of available withdrawal requestss.
*/
ETH_RESULT_USE_CHECK
int ETHWithdrawalRequestsGetCount(const ETHWithdrawalRequests *requests);
/**
* Withdrawal request.
*/
typedef struct ETHWithdrawalRequest ETHWithdrawalRequest;
/**
* Obtains an individual withdrawal request by sequential index
* in a withdrawal request sequence.
*
* - The returned value is allocated in the given request sequence.
* It must neither be released nor written to, and the request
* sequence must not be released while the returned value is in use.
*
* @param requests Withdrawal request sequence.
* @param requestIndex Sequential withdrawal request index.
*
* @return Withdrawal request.
*/
ETH_RESULT_USE_CHECK
const ETHWithdrawalRequest *ETHWithdrawalRequestsGet(
const ETHWithdrawalRequests *requests,
int requestIndex);
/**
* Obtains the source address of a withdrawal request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Withdrawal request.
*
* @return Source address.
*/
ETH_RESULT_USE_CHECK
const ETHExecutionAddress *ETHWithdrawalRequestGetSourceAddress(
const ETHWithdrawalRequest *request);
/**
* Obtains the validator pubkey of a withdrawal request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Withdrawal request.
*
* @return Validator pubkey.
*/
ETH_RESULT_USE_CHECK
const ETHValidatorPubkey *ETHWithdrawalRequestGetValidatorPubkey(
const ETHWithdrawalRequest *request);
/**
* Obtains the amount of a withdrawal request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Withdrawal request.
*
* @return Amount.
*/
ETH_RESULT_USE_CHECK
const uint64_t *ETHWithdrawalRequestGetAmount(
const ETHWithdrawalRequest *request);
/**
* Obtains the raw byte representation of a withdrawal request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Withdrawal request.
* @param[out] numBytes Length of buffer.
*
* @return Buffer with raw withdrawal request data.
*/
ETH_RESULT_USE_CHECK
const void *ETHWithdrawalRequestGetBytes(
const ETHWithdrawalRequest *request,
int *numBytes);
/**
* Indicates the total number of consolidation requests
* in a consolidation request sequence.
*
* - Individual consolidation requests may be inspected using
* `ETHConsolidationRequestsGet`.
*
* @param requests Consolidation request sequence.
*
* @return Number of available consolidation requestss.
*/
ETH_RESULT_USE_CHECK
int ETHConsolidationRequestsGetCount(const ETHConsolidationRequests *requests);
/**
* Consolidation request.
*/
typedef struct ETHConsolidationRequest ETHConsolidationRequest;
/**
* Obtains an individual consolidation request by sequential index
* in a consolidation request sequence.
*
* - The returned value is allocated in the given request sequence.
* It must neither be released nor written to, and the request
* sequence must not be released while the returned value is in use.
*
* @param requests Consolidation request sequence.
* @param requestIndex Sequential consolidation request index.
*
* @return Consolidation request.
*/
ETH_RESULT_USE_CHECK
const ETHConsolidationRequest *ETHConsolidationRequestsGet(
const ETHConsolidationRequests *requests,
int requestIndex);
/**
* Obtains the source address of a consolidation request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Consolidation request.
*
* @return Source address.
*/
ETH_RESULT_USE_CHECK
const ETHExecutionAddress *ETHConsolidationRequestGetSourceAddress(
const ETHConsolidationRequest *request);
/**
* Obtains the source pubkey of a consolidation request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Consolidation request.
*
* @return Source pubkey.
*/
ETH_RESULT_USE_CHECK
const ETHValidatorPubkey *ETHConsolidationRequestGetSourcePubkey(
const ETHConsolidationRequest *request);
/**
* Obtains the target pubkey of a consolidation request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Consolidation request.
*
* @return Target pubkey.
*/
ETH_RESULT_USE_CHECK
const ETHValidatorPubkey *ETHConsolidationRequestGetTargetPubkey(
const ETHConsolidationRequest *request);
/**
* Obtains the raw byte representation of a consolidation request.
*
* - The returned value is allocated in the given request.
* It must neither be released nor written to, and the request
* must not be released while the returned value is in use.
*
* @param request Consolidation request.
* @param[out] numBytes Length of buffer.
*
* @return Buffer with raw consolidation request data.
*/
ETH_RESULT_USE_CHECK
const void *ETHConsolidationRequestGetBytes(
const ETHConsolidationRequest *request,
int *numBytes);
#if __has_feature(nullability) #if __has_feature(nullability)
#pragma clang assume_nonnull end #pragma clang assume_nonnull end
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -417,6 +417,111 @@ int main(void)
printf("\n"); printf("\n");
} }
const ETHRoot *executionRequestsRoot =
ETHExecutionBlockHeaderGetRequestsRoot(executionBlockHeader);
printf(" - requests_root: ");
printHexString(executionRequestsRoot, sizeof *executionRequestsRoot);
printf("\n");
const ETHDepositRequests *depositRequests =
ETHExecutionBlockHeaderGetDepositRequests(executionBlockHeader);
int numRequests = ETHDepositRequestsGetCount(depositRequests);
printf(" - deposit_requests:\n");
for (int requestIndex = 0; requestIndex < numRequests; requestIndex++) {
const ETHDepositRequest *request =
ETHDepositRequestsGet(depositRequests, requestIndex);
const uint64_t *index = ETHDepositRequestGetIndex(request);
printf(" - index: %" PRIu64 "\n", *index);
const ETHValidatorPubkey *pubkey = ETHDepositRequestGetPubkey(request);
printf(" - pubkey: ");
printHexString(pubkey, sizeof *pubkey);
printf("\n");
const ETHWithdrawalCredentials *withdrawalCredentials =
ETHDepositRequestGetWithdrawalCredentials(request);
printf(" - pubkey: ");
printHexString(withdrawalCredentials, sizeof *withdrawalCredentials);
printf("\n");
const uint64_t *amount = ETHDepositRequestGetAmount(request);
printf(" - amount: %" PRIu64 "\n", *amount);
const ETHValidatorSignature *signature = ETHDepositRequestGetSignature(request);
printf(" - signature: ");
printHexString(signature, sizeof *signature);
printf("\n");
int numBytes;
const void *bytes = ETHDepositRequestGetBytes(request, &numBytes);
printf(" - bytes: ");
printHexString(bytes, numBytes);
printf("\n");
}
const ETHWithdrawalRequests *withdrawalRequests =
ETHExecutionBlockHeaderGetWithdrawalRequests(executionBlockHeader);
numRequests = ETHWithdrawalRequestsGetCount(withdrawalRequests);
printf(" - withdrawal_requests:\n");
for (int requestIndex = 0; requestIndex < numRequests; requestIndex++) {
const ETHWithdrawalRequest *request =
ETHWithdrawalRequestsGet(withdrawalRequests, requestIndex);
printf(" - index: %d\n", requestIndex);
const ETHExecutionAddress *sourceAddress = ETHWithdrawalRequestGetSourceAddress(request);
printf(" - source_address: ");
printHexString(sourceAddress, sizeof *sourceAddress);
printf("\n");
const ETHValidatorPubkey *validatorPubkey = ETHWithdrawalRequestGetValidatorPubkey(request);
printf(" - validator_pubkey: ");
printHexString(validatorPubkey, sizeof *validatorPubkey);
printf("\n");
const uint64_t *amount = ETHWithdrawalRequestGetAmount(request);
printf(" - amount: %" PRIu64 "\n", *amount);
int numBytes;
const void *bytes = ETHWithdrawalRequestGetBytes(request, &numBytes);
printf(" - bytes: ");
printHexString(bytes, numBytes);
printf("\n");
}
const ETHConsolidationRequests *consolidationRequests =
ETHExecutionBlockHeaderGetConsolidationRequests(executionBlockHeader);
numRequests = ETHConsolidationRequestsGetCount(consolidationRequests);
printf(" - consolidation_requests:\n");
for (int requestIndex = 0; requestIndex < numRequests; requestIndex++) {
const ETHConsolidationRequest *request =
ETHConsolidationRequestsGet(consolidationRequests, requestIndex);
printf(" - index: %d\n", requestIndex);
const ETHExecutionAddress *sourceAddress = ETHConsolidationRequestGetSourceAddress(request);
printf(" - source_address: ");
printHexString(sourceAddress, sizeof *sourceAddress);
printf("\n");
const ETHValidatorPubkey *sourcePubkey = ETHConsolidationRequestGetSourcePubkey(request);
printf(" - source_pubkey: ");
printHexString(sourcePubkey, sizeof *sourcePubkey);
printf("\n");
const ETHValidatorPubkey *targetPubkey = ETHConsolidationRequestGetTargetPubkey(request);
printf(" - target_pubkey: ");
printHexString(targetPubkey, sizeof *targetPubkey);
printf("\n");
int numBytes;
const void *bytes = ETHConsolidationRequestGetBytes(request, &numBytes);
printf(" - bytes: ");
printHexString(bytes, numBytes);
printf("\n");
}
ETHExecutionBlockHeaderDestroy(executionBlockHeader); ETHExecutionBlockHeaderDestroy(executionBlockHeader);
ETHRoot sampleTransactionsRoot = {{ ETHRoot sampleTransactionsRoot = {{
@ -539,6 +644,42 @@ int main(void)
printf("\n"); printf("\n");
} }
const ETHAuthorizationList *transactionAuthorizationList =
ETHTransactionGetAuthorizationList(transaction);
printf(" - authorization_list:\n");
int numAuthorizationTuples = ETHAuthorizationListGetCount(transactionAuthorizationList);
for (int tupleIndex = 0; tupleIndex < numAuthorizationTuples; tupleIndex++) {
const ETHAuthorizationTuple *authorizationTuple =
ETHAuthorizationListGet(transactionAuthorizationList, tupleIndex);
const ETHExecutionAddress *address =
ETHAuthorizationTupleGetAddress(authorizationTuple);
printf(" - ");
printHexString(address, sizeof *address);
printf("\n");
const ETHUInt256 *chainId = ETHAuthorizationTupleGetChainId(authorizationTuple);
printf(" - chain_id: ");
printHexStringReversed(chainId, sizeof *chainId);
printf("\n");
const uint64_t *nonce = ETHAuthorizationTupleGetNonce(authorizationTuple);
printf(" - nonce: %" PRIu64 "\n", *nonce);
const ETHExecutionAddress *authority =
ETHAuthorizationTupleGetAuthority(authorizationTuple);
printf(" - authority: ");
printHexString(authority, sizeof *authority);
printf("\n");
int numSignatureBytes;
const void *signatureBytes =
ETHAuthorizationTupleGetSignatureBytes(authorizationTuple, &numSignatureBytes);
printf(" - signature: ");
printHexString(signatureBytes, numSignatureBytes);
printf("\n");
}
int numTransactionSignatureBytes; int numTransactionSignatureBytes;
const void *transactionSignatureBytes = const void *transactionSignatureBytes =
ETHTransactionGetSignatureBytes(transaction, &numTransactionSignatureBytes); ETHTransactionGetSignatureBytes(transaction, &numTransactionSignatureBytes);

View File

@ -176,7 +176,7 @@ type
MounterProc* = proc(network: Eth2Node) {.gcsafe, raises: [].} MounterProc* = proc(network: Eth2Node) {.gcsafe, raises: [].}
MessageContentPrinter* = proc(msg: pointer): string {.gcsafe, raises: [].} MessageContentPrinter* = proc(msg: pointer): string {.gcsafe, raises: [].}
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/p2p-interface.md#goodbye # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#goodbye
DisconnectionReason* = enum DisconnectionReason* = enum
# might see other values on the wire! # might see other values on the wire!
ClientShutDown = 1 ClientShutDown = 1
@ -2234,7 +2234,7 @@ proc getPersistentNetKeys*(
func gossipId( func gossipId(
data: openArray[byte], phase0Prefix, topic: string): seq[byte] = data: openArray[byte], phase0Prefix, topic: string): seq[byte] =
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#topics-and-messages # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#topics-and-messages
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/p2p-interface.md#topics-and-messages # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/p2p-interface.md#topics-and-messages
const MESSAGE_DOMAIN_VALID_SNAPPY = [0x01'u8, 0x00, 0x00, 0x00] const MESSAGE_DOMAIN_VALID_SNAPPY = [0x01'u8, 0x00, 0x00, 0x00]
let messageDigest = withEth2Hash: let messageDigest = withEth2Hash:
h.update(MESSAGE_DOMAIN_VALID_SNAPPY) h.update(MESSAGE_DOMAIN_VALID_SNAPPY)
@ -2555,8 +2555,8 @@ proc updateStabilitySubnetMetadata*(node: Eth2Node, attnets: AttnetBits) =
node.metadata.seq_number += 1 node.metadata.seq_number += 1
node.metadata.attnets = attnets node.metadata.attnets = attnets
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/p2p-interface.md#attestation-subnet-subscription # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#attestation-subnet-subscription
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/p2p-interface.md#attestation-subnet-bitfield # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#attestation-subnet-bitfield
let res = node.discovery.updateRecord({ let res = node.discovery.updateRecord({
enrAttestationSubnetsField: SSZ.encode(node.metadata.attnets) enrAttestationSubnetsField: SSZ.encode(node.metadata.attnets)
}) })
@ -2568,7 +2568,7 @@ proc updateStabilitySubnetMetadata*(node: Eth2Node, attnets: AttnetBits) =
debug "Stability subnets changed; updated ENR attnets", attnets debug "Stability subnets changed; updated ENR attnets", attnets
proc updateSyncnetsMetadata*(node: Eth2Node, syncnets: SyncnetBits) = proc updateSyncnetsMetadata*(node: Eth2Node, syncnets: SyncnetBits) =
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#sync-committee-subnet-stability # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#sync-committee-subnet-stability
if node.metadata.syncnets == syncnets: if node.metadata.syncnets == syncnets:
return return
@ -2610,7 +2610,7 @@ proc broadcastAttestation*(
attestation: phase0.Attestation | electra.Attestation): attestation: phase0.Attestation | electra.Attestation):
Future[SendResult] {.async: (raises: [CancelledError], raw: true).} = Future[SendResult] {.async: (raises: [CancelledError], raw: true).} =
# Regardless of the contents of the attestation, # Regardless of the contents of the attestation,
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/altair/p2p-interface.md#transitioning-the-gossip # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/p2p-interface.md#transitioning-the-gossip
# implies that pre-fork, messages using post-fork digests might be # implies that pre-fork, messages using post-fork digests might be
# ignored, whilst post-fork, there is effectively a seen_ttl-based # ignored, whilst post-fork, there is effectively a seen_ttl-based
# timer unsubscription point that means no new pre-fork-forkdigest # timer unsubscription point that means no new pre-fork-forkdigest
@ -2648,7 +2648,8 @@ proc broadcastBlsToExecutionChange*(
node.broadcast(topic, bls_to_execution_change) node.broadcast(topic, bls_to_execution_change)
proc broadcastAggregateAndProof*( proc broadcastAggregateAndProof*(
node: Eth2Node, proof: phase0.SignedAggregateAndProof): node: Eth2Node,
proof: phase0.SignedAggregateAndProof | electra.SignedAggregateAndProof):
Future[SendResult] {.async: (raises: [CancelledError], raw: true).} = Future[SendResult] {.async: (raises: [CancelledError], raw: true).} =
let topic = getAggregateAndProofsTopic( let topic = getAggregateAndProofsTopic(
node.forkDigestAtEpoch(node.getWallEpoch)) node.forkDigestAtEpoch(node.getWallEpoch))

View File

@ -269,7 +269,7 @@ when const_preset == "gnosis":
for network in [gnosisMetadata, chiadoMetadata]: for network in [gnosisMetadata, chiadoMetadata]:
doAssert network.cfg.DENEB_FORK_EPOCH < FAR_FUTURE_EPOCH doAssert network.cfg.DENEB_FORK_EPOCH < FAR_FUTURE_EPOCH
doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH
static: doAssert ConsensusFork.high == ConsensusFork.Electra doAssert ConsensusFork.high == ConsensusFork.Electra
elif const_preset == "mainnet": elif const_preset == "mainnet":
when incbinEnabled: when incbinEnabled:
@ -321,7 +321,7 @@ elif const_preset == "mainnet":
for network in [mainnetMetadata, sepoliaMetadata, holeskyMetadata]: for network in [mainnetMetadata, sepoliaMetadata, holeskyMetadata]:
doAssert network.cfg.DENEB_FORK_EPOCH < FAR_FUTURE_EPOCH doAssert network.cfg.DENEB_FORK_EPOCH < FAR_FUTURE_EPOCH
doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH
static: doAssert ConsensusFork.high == ConsensusFork.Electra doAssert ConsensusFork.high == ConsensusFork.Electra
proc getMetadataForNetwork*(networkName: string): Eth2NetworkMetadata = proc getMetadataForNetwork*(networkName: string): Eth2NetworkMetadata =
template loadRuntimeMetadata(): auto = template loadRuntimeMetadata(): auto =

View File

@ -1781,6 +1781,7 @@ proc installRestHandlers(restServer: RestServerRef, node: BeaconNode) =
restServer.router.installNimbusApiHandlers(node) restServer.router.installNimbusApiHandlers(node)
restServer.router.installNodeApiHandlers(node) restServer.router.installNodeApiHandlers(node)
restServer.router.installValidatorApiHandlers(node) restServer.router.installValidatorApiHandlers(node)
restServer.router.installRewardsApiHandlers(node)
if node.dag.lcDataStore.serve: if node.dag.lcDataStore.serve:
restServer.router.installLightClientApiHandlers(node) restServer.router.installLightClientApiHandlers(node)
@ -1796,7 +1797,7 @@ proc installMessageValidators(node: BeaconNode) =
let digest = forkDigests[].atConsensusFork(consensusFork) let digest = forkDigests[].atConsensusFork(consensusFork)
# beacon_block # beacon_block
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/p2p-interface.md#beacon_block # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#beacon_block
node.network.addValidator( node.network.addValidator(
getBeaconBlocksTopic(digest), proc ( getBeaconBlocksTopic(digest), proc (
signedBlock: consensusFork.SignedBeaconBlock signedBlock: consensusFork.SignedBeaconBlock
@ -1869,7 +1870,7 @@ proc installMessageValidators(node: BeaconNode) =
MsgSource.gossip, attesterSlashing))) MsgSource.gossip, attesterSlashing)))
# proposer_slashing # proposer_slashing
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#proposer_slashing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#proposer_slashing
node.network.addValidator( node.network.addValidator(
getProposerSlashingsTopic(digest), proc ( getProposerSlashingsTopic(digest), proc (
proposerSlashing: ProposerSlashing proposerSlashing: ProposerSlashing
@ -1913,7 +1914,7 @@ proc installMessageValidators(node: BeaconNode) =
MsgSource.gossip, msg))) MsgSource.gossip, msg)))
when consensusFork >= ConsensusFork.Capella: when consensusFork >= ConsensusFork.Capella:
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/p2p-interface.md#bls_to_execution_change # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/p2p-interface.md#bls_to_execution_change
node.network.addAsyncValidator( node.network.addAsyncValidator(
getBlsToExecutionChangeTopic(digest), proc ( getBlsToExecutionChangeTopic(digest), proc (
msg: SignedBLSToExecutionChange msg: SignedBLSToExecutionChange
@ -2287,7 +2288,7 @@ proc doRunBeaconNode(config: var BeaconNodeConf, rng: ref HmacDrbgContext) {.rai
bnStatus = BeaconNodeStatus.Stopping bnStatus = BeaconNodeStatus.Stopping
c_signal(ansi_c.SIGTERM, SIGTERMHandler) c_signal(ansi_c.SIGTERM, SIGTERMHandler)
if metadata.cfg.DENEB_FORK_EPOCH != FAR_FUTURE_EPOCH: block:
let res = let res =
if config.trustedSetupFile.isNone: if config.trustedSetupFile.isNone:
conf.loadKzgTrustedSetup() conf.loadKzgTrustedSetup()

View File

@ -19,10 +19,10 @@ import
rest_utils, rest_utils,
rest_beacon_api, rest_builder_api, rest_config_api, rest_debug_api, rest_beacon_api, rest_builder_api, rest_config_api, rest_debug_api,
rest_event_api, rest_key_management_api, rest_light_client_api, rest_event_api, rest_key_management_api, rest_light_client_api,
rest_nimbus_api, rest_node_api, rest_validator_api] rest_nimbus_api, rest_node_api, rest_validator_api, rest_rewards_api]
export export
rest_utils, rest_utils,
rest_beacon_api, rest_builder_api, rest_config_api, rest_debug_api, rest_beacon_api, rest_builder_api, rest_config_api, rest_debug_api,
rest_event_api, rest_key_management_api, rest_light_client_api, rest_event_api, rest_key_management_api, rest_light_client_api,
rest_nimbus_api, rest_node_api, rest_validator_api rest_nimbus_api, rest_node_api, rest_validator_api, rest_rewards_api

View File

@ -92,7 +92,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) =
MAX_VOLUNTARY_EXITS: MAX_VOLUNTARY_EXITS:
Base10.toString(MAX_VOLUNTARY_EXITS), Base10.toString(MAX_VOLUNTARY_EXITS),
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/mainnet/altair.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/mainnet/altair.yaml
INACTIVITY_PENALTY_QUOTIENT_ALTAIR: INACTIVITY_PENALTY_QUOTIENT_ALTAIR:
Base10.toString(INACTIVITY_PENALTY_QUOTIENT_ALTAIR), Base10.toString(INACTIVITY_PENALTY_QUOTIENT_ALTAIR),
MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR: MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR:
@ -108,7 +108,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) =
UPDATE_TIMEOUT: UPDATE_TIMEOUT:
Base10.toString(UPDATE_TIMEOUT), Base10.toString(UPDATE_TIMEOUT),
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/mainnet/bellatrix.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/mainnet/bellatrix.yaml
INACTIVITY_PENALTY_QUOTIENT_BELLATRIX: INACTIVITY_PENALTY_QUOTIENT_BELLATRIX:
Base10.toString(INACTIVITY_PENALTY_QUOTIENT_BELLATRIX), Base10.toString(INACTIVITY_PENALTY_QUOTIENT_BELLATRIX),
MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX: MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX:
@ -124,7 +124,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) =
MAX_EXTRA_DATA_BYTES: MAX_EXTRA_DATA_BYTES:
Base10.toString(uint64(MAX_EXTRA_DATA_BYTES)), Base10.toString(uint64(MAX_EXTRA_DATA_BYTES)),
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/mainnet/capella.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/mainnet/capella.yaml
MAX_BLS_TO_EXECUTION_CHANGES: MAX_BLS_TO_EXECUTION_CHANGES:
Base10.toString(uint64(MAX_BLS_TO_EXECUTION_CHANGES)), Base10.toString(uint64(MAX_BLS_TO_EXECUTION_CHANGES)),
MAX_WITHDRAWALS_PER_PAYLOAD: MAX_WITHDRAWALS_PER_PAYLOAD:

View File

@ -24,6 +24,12 @@ const
"Beacon node is currently syncing and not serving request on that endpoint" "Beacon node is currently syncing and not serving request on that endpoint"
BlockNotFoundError* = BlockNotFoundError* =
"Block header/data has not been found" "Block header/data has not been found"
BlockParentUnknownError* =
"Block parent unknown"
BlockOlderThanParentError* =
"Block older than parent block"
BlockInvalidError* =
"Invalid block"
EmptyRequestBodyError* = EmptyRequestBodyError* =
"Empty request body" "Empty request body"
InvalidRequestBodyError* = InvalidRequestBodyError* =
@ -259,3 +265,7 @@ const
"Path not found" "Path not found"
FileReadError* = FileReadError* =
"Error reading file" "Error reading file"
ParentBlockMissingStateError* =
"Unable to load state for parent block, database corrupt?"
RewardOverflowError* =
"Reward value overflow"

View File

@ -0,0 +1,245 @@
# beacon_chain
# Copyright (c) 2018-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
import
std/[typetraits, sets],
stew/base10,
chronicles, metrics,
./rest_utils,
../beacon_node,
../consensus_object_pools/[blockchain_dag, spec_cache, validator_change_pool],
../spec/[forks, state_transition]
export rest_utils
logScope: topics = "rest_rewardsapi"
func isGenesis(node: BeaconNode,
blockId: BlockIdent,
genesisBsid: BlockSlotId): bool =
case blockId.kind
of BlockQueryKind.Named:
case blockId.value
of BlockIdentType.Genesis:
true
of BlockIdentType.Head:
node.dag.head.bid.slot == GENESIS_SLOT
of BlockIdentType.Finalized:
node.dag.finalizedHead.slot == GENESIS_SLOT
of BlockQueryKind.Slot:
blockId.slot == GENESIS_SLOT
of BlockQueryKind.Root:
blockId.root == genesisBsid.bid.root
proc installRewardsApiHandlers*(router: var RestRouter, node: BeaconNode) =
let
genesisBlockRewardsResponse =
RestApiResponse.prepareJsonResponseFinalized(
(
proposer_index: "0", total: "0", attestations: "0",
sync_aggregate: "0", proposer_slashings: "0", attester_slashings: "0"
),
Opt.some(false),
true,
)
genesisBsid = node.dag.getBlockIdAtSlot(GENESIS_SLOT).get()
# https://ethereum.github.io/beacon-APIs/#/Rewards/getBlockRewards
router.api2(MethodGet, "/eth/v1/beacon/rewards/blocks/{block_id}") do (
block_id: BlockIdent) -> RestApiResponse:
let
bident = block_id.valueOr:
return RestApiResponse.jsonError(Http400, InvalidBlockIdValueError,
$error)
if node.isGenesis(bident, genesisBsid):
return RestApiResponse.response(
genesisBlockRewardsResponse, Http200, "application/json")
let
bdata = node.getForkedBlock(bident).valueOr:
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
bid = BlockId(slot: bdata.slot, root: bdata.root)
targetBlock =
withBlck(bdata):
let parentBid =
node.dag.getBlockId(forkyBlck.message.parent_root).valueOr:
return RestApiResponse.jsonError(Http404, BlockParentUnknownError)
if parentBid.slot >= forkyBlck.message.slot:
return RestApiResponse.jsonError(Http404, BlockOlderThanParentError)
BlockSlotId.init(parentBid, forkyBlck.message.slot)
var
cache = StateCache()
tmpState = assignClone(node.dag.headState)
if not updateState(
node.dag, tmpState[], targetBlock, false, cache):
return RestApiResponse.jsonError(Http404, ParentBlockMissingStateError)
func rollbackProc(state: var ForkedHashedBeaconState) {.
gcsafe, noSideEffect, raises: [].} =
discard
let
rewards =
withBlck(bdata):
state_transition_block(
node.dag.cfg, tmpState[], forkyBlck,
cache, node.dag.updateFlags, rollbackProc).valueOr:
return RestApiResponse.jsonError(Http400, BlockInvalidError)
total = rewards.attestations + rewards.sync_aggregate +
rewards.proposer_slashings + rewards.attester_slashings
proposerIndex =
withBlck(bdata):
forkyBlck.message.proposer_index
RestApiResponse.jsonResponseFinalized(
(
proposer_index: Base10.toString(uint64(proposerIndex)),
total: Base10.toString(uint64(total)),
attestations: Base10.toString(uint64(rewards.attestations)),
sync_aggregate: Base10.toString(uint64(rewards.sync_aggregate)),
proposer_slashings: Base10.toString(uint64(rewards.proposer_slashings)),
attester_slashings: Base10.toString(uint64(rewards.attester_slashings))
),
node.getBlockOptimistic(bdata),
node.dag.isFinalized(bid)
)
# https://ethereum.github.io/beacon-APIs/#/Rewards/getSyncCommitteeRewards
router.api2(
MethodPost, "/eth/v1/beacon/rewards/sync_committee/{block_id}") do (
block_id: BlockIdent,
contentBody: Option[ContentBody]) -> RestApiResponse:
let
idents =
block:
if contentBody.isNone():
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
let res = decodeBody(seq[ValidatorIdent], contentBody.get()).valueOr:
return RestApiResponse.jsonError(
Http400, InvalidRequestBodyError, $error)
res
bident = block_id.valueOr:
return RestApiResponse.jsonError(Http400, InvalidBlockIdValueError,
$error)
bdata = node.getForkedBlock(bident).valueOr:
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
bid = BlockId(slot: bdata.slot, root: bdata.root)
sync_aggregate =
withBlck(bdata):
when consensusFork > ConsensusFork.Phase0:
forkyBlck.message.body.sync_aggregate
else:
default(TrustedSyncAggregate)
targetBlock =
withBlck(bdata):
if node.isGenesis(bident, genesisBsid):
genesisBsid
else:
let parentBid =
node.dag.getBlockId(forkyBlck.message.parent_root).valueOr:
return RestApiResponse.jsonError(
Http404, BlockParentUnknownError)
if parentBid.slot >= forkyBlck.message.slot:
return RestApiResponse.jsonError(
Http404, BlockOlderThanParentError)
BlockSlotId.init(parentBid, forkyBlck.message.slot)
var
cache = StateCache()
tmpState = assignClone(node.dag.headState)
if not updateState(
node.dag, tmpState[], targetBlock, false, cache):
return RestApiResponse.jsonError(Http404, ParentBlockMissingStateError)
let response =
withState(tmpState[]):
let total_active_balance =
get_total_active_balance(forkyState.data, cache)
var resp: seq[RestSyncCommitteeReward]
when consensusFork > ConsensusFork.Phase0:
let
keys =
block:
var res: HashSet[ValidatorPubKey]
for item in idents:
case item.kind
of ValidatorQueryKind.Index:
let vindex = item.index.toValidatorIndex().valueOr:
case error
of ValidatorIndexError.TooHighValue:
return RestApiResponse.jsonError(
Http400, TooHighValidatorIndexValueError)
of ValidatorIndexError.UnsupportedValue:
return RestApiResponse.jsonError(
Http500, UnsupportedValidatorIndexValueError)
if uint64(vindex) >= lenu64(forkyState.data.validators):
return RestApiResponse.jsonError(
Http400, ValidatorNotFoundError)
res.incl(forkyState.data.validators.item(vindex).pubkey)
of ValidatorQueryKind.Key:
res.incl(item.key)
res
committeeKeys =
toHashSet(forkyState.data.current_sync_committee.pubkeys.data)
pubkeyIndices =
block:
var res: Table[ValidatorPubKey, ValidatorIndex]
for vindex in forkyState.data.validators.vindices:
let pubkey = forkyState.data.validators.item(vindex).pubkey
if pubkey in committeeKeys:
res[pubkey] = vindex
res
reward =
block:
let res = uint64(get_participant_reward(total_active_balance))
if res > uint64(high(int64)):
return RestApiResponse.jsonError(
Http500, RewardOverflowError)
res
for i in 0 ..< min(
len(forkyState.data.current_sync_committee.pubkeys),
len(sync_aggregate.sync_committee_bits)):
let
pubkey = forkyState.data.current_sync_committee.pubkeys.data[i]
vindex =
try:
pubkeyIndices[pubkey]
except KeyError:
raiseAssert "Unknown sync committee pubkey encountered!"
vreward =
if sync_aggregate.sync_committee_bits[i]:
cast[int64](reward)
else:
-cast[int64](reward)
if (len(idents) == 0) or (pubkey in keys):
resp.add(RestSyncCommitteeReward(
validator_index: RestValidatorIndex(vindex),
reward: RestReward(vreward)))
resp
RestApiResponse.jsonResponseFinalized(
response,
node.getBlockOptimistic(bdata),
node.dag.isFinalized(bid)
)

View File

@ -804,6 +804,58 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
res.get() res.get()
RestApiResponse.jsonResponse(attestation) RestApiResponse.jsonResponse(attestation)
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getPoolAttestationsV2
router.api2(MethodGet, "/eth/v2/validator/aggregate_attestation") do (
attestation_data_root: Option[Eth2Digest],
committee_index: Option[CommitteeIndex],
slot: Option[Slot]) -> RestApiResponse:
let qslot =
block:
if slot.isNone():
return RestApiResponse.jsonError(Http400, MissingSlotValueError)
let res = slot.get()
if res.isErr():
return RestApiResponse.jsonError(Http400, InvalidSlotValueError,
$res.error())
res.get()
let committee_index =
block:
if committee_index.isNone():
return RestApiResponse.jsonError(Http400,
MissingCommitteeIndexValueError)
let res = committee_index.get()
if res.isErr():
return RestApiResponse.jsonError(Http400,
InvalidCommitteeIndexValueError,
$res.error())
res.get()
let root =
block:
if attestation_data_root.isNone():
return RestApiResponse.jsonError(Http400,
MissingAttestationDataRootValueError)
let res = attestation_data_root.get()
if res.isErr():
return RestApiResponse.jsonError(Http400,
InvalidAttestationDataRootValueError, $res.error())
res.get()
let phase0_attestations =
node.attestationPool[].getAggregatedAttestation(qslot, root)
if phase0_attestations.isSome():
return RestApiResponse.jsonResponse(phase0_attestations.get())
let electra_attestations =
node.attestationPool[].getElectraAggregatedAttestation(qslot,
root,
committee_index)
if electra_attestations.isSome():
return RestApiResponse.jsonResponse(electra_attestations.get())
RestApiResponse.jsonError(Http400, UnableToGetAggregatedAttestationError)
# https://ethereum.github.io/beacon-APIs/#/Validator/publishAggregateAndProofs # https://ethereum.github.io/beacon-APIs/#/Validator/publishAggregateAndProofs
router.api2(MethodPost, "/eth/v1/validator/aggregate_and_proofs") do ( router.api2(MethodPost, "/eth/v1/validator/aggregate_and_proofs") do (
contentBody: Option[ContentBody]) -> RestApiResponse: contentBody: Option[ContentBody]) -> RestApiResponse:
@ -838,6 +890,48 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
"Unexpected server failure, while sending aggregate and proof") "Unexpected server failure, while sending aggregate and proof")
RestApiResponse.jsonMsgResponse(AggregateAndProofValidationSuccess) RestApiResponse.jsonMsgResponse(AggregateAndProofValidationSuccess)
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Validator/publishAggregateAndProofsV2
router.api2(MethodPost, "/eth/v2/validator/aggregate_and_proofs") do (
contentBody: Option[ContentBody]) -> RestApiResponse:
if contentBody.isNone():
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
let
headerVersion = request.headers.getString("Eth-Consensus-Version")
consensusVersion = ConsensusFork.init(headerVersion)
if consensusVersion.isNone():
return RestApiResponse.jsonError(Http400, FailedToObtainConsensusForkError)
var proofs: seq[Future[SendResult]]
template addDecodedProofs(ProofType: untyped) =
let dres = decodeBody(seq[ProofType], contentBody.get())
if dres.isErr():
return RestApiResponse.jsonError(Http400,
InvalidAggregateAndProofObjectError,
$dres.error())
for proof in dres.get():
proofs.add(node.router.routeSignedAggregateAndProof(proof))
case consensusVersion.get():
of ConsensusFork.Phase0 .. ConsensusFork.Deneb:
addDecodedProofs(phase0.SignedAggregateAndProof)
of ConsensusFork.Electra:
addDecodedProofs(electra.SignedAggregateAndProof)
await allFutures(proofs)
for future in proofs:
if future.completed():
let res = future.value()
if res.isErr():
return RestApiResponse.jsonError(Http400,
AggregateAndProofValidationError,
$res.error())
else:
return RestApiResponse.jsonError(Http500,
"Unexpected server failure, while sending aggregate and proof")
RestApiResponse.jsonMsgResponse(AggregateAndProofValidationSuccess)
# https://ethereum.github.io/beacon-APIs/#/Validator/prepareBeaconCommitteeSubnet # https://ethereum.github.io/beacon-APIs/#/Validator/prepareBeaconCommitteeSubnet
router.api2(MethodPost, router.api2(MethodPost,
"/eth/v1/validator/beacon_committee_subscriptions") do ( "/eth/v1/validator/beacon_committee_subscriptions") do (

View File

@ -43,7 +43,7 @@ const
GENESIS_SLOT* = Slot(0) GENESIS_SLOT* = Slot(0)
GENESIS_EPOCH* = Epoch(0) # compute_epoch_at_slot(GENESIS_SLOT) GENESIS_EPOCH* = Epoch(0) # compute_epoch_at_slot(GENESIS_SLOT)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/fork-choice.md#constant # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/fork-choice.md#constant
INTERVALS_PER_SLOT* = 3 INTERVALS_PER_SLOT* = 3
FAR_FUTURE_BEACON_TIME* = BeaconTime(ns_since_genesis: int64.high()) FAR_FUTURE_BEACON_TIME* = BeaconTime(ns_since_genesis: int64.high())
@ -133,22 +133,22 @@ template `+`*(a: TimeDiff, b: Duration): TimeDiff =
const const
# Offsets from the start of the slot to when the corresponding message should # Offsets from the start of the slot to when the corresponding message should
# be sent # be sent
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#attesting # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#attesting
attestationSlotOffset* = TimeDiff(nanoseconds: attestationSlotOffset* = TimeDiff(nanoseconds:
NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT) NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#broadcast-aggregate # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#broadcast-aggregate
aggregateSlotOffset* = TimeDiff(nanoseconds: aggregateSlotOffset* = TimeDiff(nanoseconds:
NANOSECONDS_PER_SLOT.int64 * 2 div INTERVALS_PER_SLOT) NANOSECONDS_PER_SLOT.int64 * 2 div INTERVALS_PER_SLOT)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#prepare-sync-committee-message # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#prepare-sync-committee-message
syncCommitteeMessageSlotOffset* = TimeDiff(nanoseconds: syncCommitteeMessageSlotOffset* = TimeDiff(nanoseconds:
NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT) NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#broadcast-sync-committee-contribution # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#broadcast-sync-committee-contribution
syncContributionSlotOffset* = TimeDiff(nanoseconds: syncContributionSlotOffset* = TimeDiff(nanoseconds:
NANOSECONDS_PER_SLOT.int64 * 2 div INTERVALS_PER_SLOT) NANOSECONDS_PER_SLOT.int64 * 2 div INTERVALS_PER_SLOT)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/p2p-interface.md#sync-committee # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/p2p-interface.md#sync-committee
lightClientFinalityUpdateSlotOffset* = TimeDiff(nanoseconds: lightClientFinalityUpdateSlotOffset* = TimeDiff(nanoseconds:
NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT) NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/p2p-interface.md#sync-committee # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/p2p-interface.md#sync-committee
lightClientOptimisticUpdateSlotOffset* = TimeDiff(nanoseconds: lightClientOptimisticUpdateSlotOffset* = TimeDiff(nanoseconds:
NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT) NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT)
@ -188,7 +188,7 @@ func epoch*(slot: Slot): Epoch = # aka compute_epoch_at_slot
if slot == FAR_FUTURE_SLOT: FAR_FUTURE_EPOCH if slot == FAR_FUTURE_SLOT: FAR_FUTURE_EPOCH
else: Epoch(slot div SLOTS_PER_EPOCH) else: Epoch(slot div SLOTS_PER_EPOCH)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/fork-choice.md#compute_slots_since_epoch_start # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/fork-choice.md#compute_slots_since_epoch_start
func since_epoch_start*(slot: Slot): uint64 = # aka compute_slots_since_epoch_start func since_epoch_start*(slot: Slot): uint64 = # aka compute_slots_since_epoch_start
## How many slots since the beginning of the epoch (`[0..SLOTS_PER_EPOCH-1]`) ## How many slots since the beginning of the epoch (`[0..SLOTS_PER_EPOCH-1]`)
(slot mod SLOTS_PER_EPOCH) (slot mod SLOTS_PER_EPOCH)
@ -196,7 +196,7 @@ func since_epoch_start*(slot: Slot): uint64 = # aka compute_slots_since_epoch_st
template is_epoch*(slot: Slot): bool = template is_epoch*(slot: Slot): bool =
slot.since_epoch_start == 0 slot.since_epoch_start == 0
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#compute_start_slot_at_epoch # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#compute_start_slot_at_epoch
func start_slot*(epoch: Epoch): Slot = # aka compute_start_slot_at_epoch func start_slot*(epoch: Epoch): Slot = # aka compute_start_slot_at_epoch
## Return the start slot of ``epoch``. ## Return the start slot of ``epoch``.
const maxEpoch = Epoch(FAR_FUTURE_SLOT div SLOTS_PER_EPOCH) const maxEpoch = Epoch(FAR_FUTURE_SLOT div SLOTS_PER_EPOCH)
@ -216,7 +216,7 @@ iterator slots*(epoch: Epoch): Slot =
for slot in start_slot ..< start_slot + SLOTS_PER_EPOCH: for slot in start_slot ..< start_slot + SLOTS_PER_EPOCH:
yield slot yield slot
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#sync-committee # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#sync-committee
template sync_committee_period*(epoch: Epoch): SyncCommitteePeriod = template sync_committee_period*(epoch: Epoch): SyncCommitteePeriod =
if epoch == FAR_FUTURE_EPOCH: FAR_FUTURE_PERIOD if epoch == FAR_FUTURE_EPOCH: FAR_FUTURE_PERIOD
else: SyncCommitteePeriod(epoch div EPOCHS_PER_SYNC_COMMITTEE_PERIOD) else: SyncCommitteePeriod(epoch div EPOCHS_PER_SYNC_COMMITTEE_PERIOD)

View File

@ -80,13 +80,13 @@ func get_validator_from_deposit*(
effective_balance: 0.Gwei # [Modified in Electra:EIP7251] effective_balance: 0.Gwei # [Modified in Electra:EIP7251]
) )
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#compute_activation_exit_epoch # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#compute_activation_exit_epoch
func compute_activation_exit_epoch*(epoch: Epoch): Epoch = func compute_activation_exit_epoch*(epoch: Epoch): Epoch =
## Return the epoch during which validator activations and exits initiated in ## Return the epoch during which validator activations and exits initiated in
## ``epoch`` take effect. ## ``epoch`` take effect.
epoch + 1 + MAX_SEED_LOOKAHEAD epoch + 1 + MAX_SEED_LOOKAHEAD
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#get_validator_churn_limit # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_validator_churn_limit
func get_validator_churn_limit*( func get_validator_churn_limit*(
cfg: RuntimeConfig, state: ForkyBeaconState, cache: var StateCache): cfg: RuntimeConfig, state: ForkyBeaconState, cache: var StateCache):
uint64 = uint64 =
@ -96,7 +96,7 @@ func get_validator_churn_limit*(
count_active_validators( count_active_validators(
state, state.get_current_epoch(), cache) div cfg.CHURN_LIMIT_QUOTIENT) state, state.get_current_epoch(), cache) div cfg.CHURN_LIMIT_QUOTIENT)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/deneb/beacon-chain.md#new-get_validator_activation_churn_limit # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/beacon-chain.md#new-get_validator_activation_churn_limit
func get_validator_activation_churn_limit*( func get_validator_activation_churn_limit*(
cfg: RuntimeConfig, state: deneb.BeaconState | electra.BeaconState, cfg: RuntimeConfig, state: deneb.BeaconState | electra.BeaconState,
cache: var StateCache): uint64 = cache: var StateCache): uint64 =
@ -270,7 +270,7 @@ func compute_consolidation_epoch_and_update_churn*(
state.earliest_consolidation_epoch state.earliest_consolidation_epoch
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/electra/beacon-chain.md#modified-initiate_validator_exit # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#modified-initiate_validator_exit
func initiate_validator_exit*( func initiate_validator_exit*(
cfg: RuntimeConfig, state: var electra.BeaconState, cfg: RuntimeConfig, state: var electra.BeaconState,
index: ValidatorIndex, exit_queue_info: ExitQueueInfo, index: ValidatorIndex, exit_queue_info: ExitQueueInfo,
@ -301,7 +301,7 @@ from ./datatypes/deneb import BeaconState
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#modified-slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#updated-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#updated-slash_validator
func get_slashing_penalty*( func get_slashing_penalty*(
state: ForkyBeaconState, validator_effective_balance: Gwei): Gwei = state: ForkyBeaconState, validator_effective_balance: Gwei): Gwei =
@ -317,9 +317,9 @@ func get_slashing_penalty*(
else: else:
{.fatal: "invalid BeaconState type".} {.fatal: "invalid BeaconState type".}
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#modified-slash_validator
func get_whistleblower_reward*( func get_whistleblower_reward*(
state: phase0.BeaconState | altair.BeaconState | bellatrix.BeaconState | state: phase0.BeaconState | altair.BeaconState | bellatrix.BeaconState |
capella.BeaconState | deneb.BeaconState, capella.BeaconState | deneb.BeaconState,
@ -332,8 +332,8 @@ func get_whistleblower_reward*(
validator_effective_balance div WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA validator_effective_balance div WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#modified-slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#modified-slash_validator
func get_proposer_reward(state: ForkyBeaconState, whistleblower_reward: Gwei): Gwei = func get_proposer_reward(state: ForkyBeaconState, whistleblower_reward: Gwei): Gwei =
when state is phase0.BeaconState: when state is phase0.BeaconState:
whistleblower_reward div PROPOSER_REWARD_QUOTIENT whistleblower_reward div PROPOSER_REWARD_QUOTIENT
@ -346,7 +346,7 @@ func get_proposer_reward(state: ForkyBeaconState, whistleblower_reward: Gwei): G
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-slash_validator
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#modified-slash_validator
proc slash_validator*( proc slash_validator*(
cfg: RuntimeConfig, state: var ForkyBeaconState, cfg: RuntimeConfig, state: var ForkyBeaconState,
slashed_index: ValidatorIndex, pre_exit_queue_info: ExitQueueInfo, slashed_index: ValidatorIndex, pre_exit_queue_info: ExitQueueInfo,
@ -407,7 +407,7 @@ func get_initial_beacon_block*(state: phase0.HashedBeaconState):
phase0.TrustedSignedBeaconBlock( phase0.TrustedSignedBeaconBlock(
message: message, root: hash_tree_root(message)) message: message, root: hash_tree_root(message))
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#initialize-state-for-pure-altair-testnets-and-test-vectors # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#initialize-state-for-pure-altair-testnets-and-test-vectors
func get_initial_beacon_block*(state: altair.HashedBeaconState): func get_initial_beacon_block*(state: altair.HashedBeaconState):
altair.TrustedSignedBeaconBlock = altair.TrustedSignedBeaconBlock =
# The genesis block is implicitly trusted # The genesis block is implicitly trusted
@ -419,7 +419,7 @@ func get_initial_beacon_block*(state: altair.HashedBeaconState):
altair.TrustedSignedBeaconBlock( altair.TrustedSignedBeaconBlock(
message: message, root: hash_tree_root(message)) message: message, root: hash_tree_root(message))
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#testing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#testing
func get_initial_beacon_block*(state: bellatrix.HashedBeaconState): func get_initial_beacon_block*(state: bellatrix.HashedBeaconState):
bellatrix.TrustedSignedBeaconBlock = bellatrix.TrustedSignedBeaconBlock =
# The genesis block is implicitly trusted # The genesis block is implicitly trusted
@ -624,7 +624,7 @@ func get_attesting_indices*(
toSeq(get_attesting_indices_iter(state, data, aggregation_bits, cache)) toSeq(get_attesting_indices_iter(state, data, aggregation_bits, cache))
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#get_attesting_indices # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_attesting_indices
func get_attesting_indices*( func get_attesting_indices*(
state: ForkyBeaconState, data: AttestationData, state: ForkyBeaconState, data: AttestationData,
aggregation_bits: ElectraCommitteeValidatorsBits, committee_bits: auto, aggregation_bits: ElectraCommitteeValidatorsBits, committee_bits: auto,
@ -741,7 +741,7 @@ func check_attestation_target_epoch(
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#attestations # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#attestations
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-process_attestation # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#modified-process_attestation
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/deneb/beacon-chain.md#modified-process_attestation # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/beacon-chain.md#modified-process_attestation
func check_attestation_inclusion( func check_attestation_inclusion(
consensusFork: static ConsensusFork, attestation_slot: Slot, consensusFork: static ConsensusFork, attestation_slot: Slot,
current_slot: Slot): Result[void, cstring] = current_slot: Slot): Result[void, cstring] =
@ -770,7 +770,7 @@ func check_attestation_index(
Result[CommitteeIndex, cstring] = Result[CommitteeIndex, cstring] =
check_attestation_index(data.index, committees_per_slot) check_attestation_index(data.index, committees_per_slot)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#get_attestation_participation_flag_indices # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#get_attestation_participation_flag_indices
func get_attestation_participation_flag_indices( func get_attestation_participation_flag_indices(
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState, state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState,
data: AttestationData, inclusion_delay: uint64): set[TimelyFlag] = data: AttestationData, inclusion_delay: uint64): set[TimelyFlag] =
@ -843,7 +843,7 @@ func get_attestation_participation_flag_indices(
# TODO these duplicate some stuff in state_transition_epoch which uses TotalBalances # TODO these duplicate some stuff in state_transition_epoch which uses TotalBalances
# better to centralize around that if feasible # better to centralize around that if feasible
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#get_total_active_balance # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_total_active_balance
func get_total_active_balance*(state: ForkyBeaconState, cache: var StateCache): Gwei = func get_total_active_balance*(state: ForkyBeaconState, cache: var StateCache): Gwei =
## Return the combined effective balance of the active validators. ## Return the combined effective balance of the active validators.
## Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei ## Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei
@ -859,7 +859,7 @@ func get_total_active_balance*(state: ForkyBeaconState, cache: var StateCache):
cache.total_active_balance[epoch] = tab cache.total_active_balance[epoch] = tab
return tab return tab
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_base_reward_per_increment # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#get_base_reward_per_increment
func get_base_reward_per_increment_sqrt( func get_base_reward_per_increment_sqrt(
total_active_balance_sqrt: uint64): Gwei = total_active_balance_sqrt: uint64): Gwei =
EFFECTIVE_BALANCE_INCREMENT.Gwei * BASE_REWARD_FACTOR div EFFECTIVE_BALANCE_INCREMENT.Gwei * BASE_REWARD_FACTOR div
@ -1128,7 +1128,7 @@ proc process_attestation*(
ok(proposer_reward) ok(proposer_reward)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#get_next_sync_committee_indices # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#get_next_sync_committee_indices
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#modified-get_next_sync_committee_indices # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#modified-get_next_sync_committee_indices
func get_next_sync_committee_keys( func get_next_sync_committee_keys(
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState | state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
@ -1173,7 +1173,7 @@ func get_next_sync_committee_keys(
i += 1'u64 i += 1'u64
res res
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/beacon-chain.md#has_eth1_withdrawal_credential # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/beacon-chain.md#has_eth1_withdrawal_credential
func has_eth1_withdrawal_credential*(validator: Validator): bool = func has_eth1_withdrawal_credential*(validator: Validator): bool =
## Check if ``validator`` has an 0x01 prefixed "eth1" withdrawal credential. ## Check if ``validator`` has an 0x01 prefixed "eth1" withdrawal credential.
validator.withdrawal_credentials.data[0] == ETH1_ADDRESS_WITHDRAWAL_PREFIX validator.withdrawal_credentials.data[0] == ETH1_ADDRESS_WITHDRAWAL_PREFIX
@ -1195,7 +1195,7 @@ func has_execution_withdrawal_credential*(validator: Validator): bool =
has_compounding_withdrawal_credential(validator) or has_compounding_withdrawal_credential(validator) or
has_eth1_withdrawal_credential(validator) has_eth1_withdrawal_credential(validator)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/beacon-chain.md#is_fully_withdrawable_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/beacon-chain.md#is_fully_withdrawable_validator
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-is_fully_withdrawable_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#updated-is_fully_withdrawable_validator
func is_fully_withdrawable_validator( func is_fully_withdrawable_validator(
fork: static ConsensusFork, validator: Validator, balance: Gwei, fork: static ConsensusFork, validator: Validator, balance: Gwei,
@ -1249,14 +1249,13 @@ func get_active_balance*(
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/beacon-chain.md#new-queue_excess_active_balance # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/beacon-chain.md#new-queue_excess_active_balance
func queue_excess_active_balance( func queue_excess_active_balance(
state: var electra.BeaconState, index: ValidatorIndex) = state: var electra.BeaconState, index: uint64) =
let balance = state.balances.item(index) let balance = state.balances.item(index)
if balance > MIN_ACTIVATION_BALANCE.Gwei: if balance > MIN_ACTIVATION_BALANCE.Gwei:
let excess_balance = balance - MIN_ACTIVATION_BALANCE.Gwei let excess_balance = balance - MIN_ACTIVATION_BALANCE.Gwei
state.balances.mitem(index) = MIN_ACTIVATION_BALANCE.Gwei state.balances.mitem(index) = MIN_ACTIVATION_BALANCE.Gwei
debugComment "maybe check return value"
discard state.pending_balance_deposits.add( discard state.pending_balance_deposits.add(
PendingBalanceDeposit(index: index.uint64, amount: excess_balance) PendingBalanceDeposit(index: index, amount: excess_balance)
) )
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-switch_to_compounding_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-switch_to_compounding_validator
@ -1265,7 +1264,7 @@ func switch_to_compounding_validator*(
let validator = addr state.validators.mitem(index) let validator = addr state.validators.mitem(index)
if has_eth1_withdrawal_credential(validator[]): if has_eth1_withdrawal_credential(validator[]):
validator.withdrawal_credentials.data[0] = COMPOUNDING_WITHDRAWAL_PREFIX validator.withdrawal_credentials.data[0] = COMPOUNDING_WITHDRAWAL_PREFIX
queue_excess_active_balance(state, index) queue_excess_active_balance(state, index.uint64)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-get_pending_balance_to_withdraw # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-get_pending_balance_to_withdraw
func get_pending_balance_to_withdraw*( func get_pending_balance_to_withdraw*(
@ -1288,7 +1287,7 @@ template effective_balance_might_update*(
balance + DOWNWARD_THRESHOLD < effective_balance or balance + DOWNWARD_THRESHOLD < effective_balance or
effective_balance + UPWARD_THRESHOLD < balance effective_balance + UPWARD_THRESHOLD < balance
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#effective-balances-updates # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#effective-balances-updates
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/beacon-chain.md#updated-process_effective_balance_updates # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/beacon-chain.md#updated-process_effective_balance_updates
template get_effective_balance_update*( template get_effective_balance_update*(
consensusFork: static ConsensusFork, balance: Gwei, consensusFork: static ConsensusFork, balance: Gwei,
@ -1298,7 +1297,6 @@ template get_effective_balance_update*(
balance - balance mod EFFECTIVE_BALANCE_INCREMENT.Gwei, balance - balance mod EFFECTIVE_BALANCE_INCREMENT.Gwei,
MAX_EFFECTIVE_BALANCE.Gwei) MAX_EFFECTIVE_BALANCE.Gwei)
else: else:
debugComment "amortize validator read access"
let effective_balance_limit = let effective_balance_limit =
if has_compounding_withdrawal_credential(state.validators.item(vidx)): if has_compounding_withdrawal_credential(state.validators.item(vidx)):
MAX_EFFECTIVE_BALANCE_ELECTRA.Gwei MAX_EFFECTIVE_BALANCE_ELECTRA.Gwei
@ -1580,7 +1578,7 @@ proc initialize_hashed_beacon_state_from_eth1*(
cfg, eth1_block_hash, eth1_timestamp, deposits, flags)) cfg, eth1_block_hash, eth1_timestamp, deposits, flags))
result.root = hash_tree_root(result.data) result.root = hash_tree_root(result.data)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#testing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#testing
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#testing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#testing
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#testing # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#testing
proc initialize_beacon_state_from_eth1*( proc initialize_beacon_state_from_eth1*(
@ -1725,7 +1723,6 @@ func queue_entire_balance_and_reset_validator(
let validator = addr state.validators.mitem(index) let validator = addr state.validators.mitem(index)
validator[].effective_balance = 0.Gwei validator[].effective_balance = 0.Gwei
validator[].activation_eligibility_epoch = FAR_FUTURE_EPOCH validator[].activation_eligibility_epoch = FAR_FUTURE_EPOCH
debugComment "check hashlist add return"
discard state.pending_balance_deposits.add PendingBalanceDeposit( discard state.pending_balance_deposits.add PendingBalanceDeposit(
index: index, amount: balance) index: index, amount: balance)
@ -1933,7 +1930,7 @@ func upgrade_to_capella*(cfg: RuntimeConfig, pre: bellatrix.BeaconState):
# historical_summaries initialized to correct default automatically # historical_summaries initialized to correct default automatically
) )
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/deneb/fork.md#upgrading-the-state # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/fork.md#upgrading-the-state
func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState): func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState):
ref deneb.BeaconState = ref deneb.BeaconState =
let let
@ -2041,10 +2038,7 @@ func upgrade_to_electra*(
transactions_root: pre.latest_execution_payload_header.transactions_root, transactions_root: pre.latest_execution_payload_header.transactions_root,
withdrawals_root: pre.latest_execution_payload_header.withdrawals_root, withdrawals_root: pre.latest_execution_payload_header.withdrawals_root,
blob_gas_used: 0, blob_gas_used: 0,
excess_blob_gas: 0, excess_blob_gas: 0
deposit_requests_root: ZERO_HASH, # [New in Electra:EIP6110]
withdrawal_requests_root: ZERO_HASH, # [New in Electra:EIP7002],
consolidation_requests_root: ZERO_HASH # [New in Electra:EIP7251]
) )
var max_exit_epoch = FAR_FUTURE_EPOCH var max_exit_epoch = FAR_FUTURE_EPOCH
@ -2153,8 +2147,7 @@ func upgrade_to_electra*(
# churn # churn
for index, validator in post.validators: for index, validator in post.validators:
if has_compounding_withdrawal_credential(validator): if has_compounding_withdrawal_credential(validator):
debugComment "in theory truncating" queue_excess_active_balance(post[], index.uint64)
queue_excess_active_balance(post[], ValidatorIndex(index))
post post

View File

@ -220,7 +220,7 @@ func blsVerify*(
## to enforce correct usage. ## to enforce correct usage.
PublicKey(pubkey).verify(message, blscurve.Signature(signature)) PublicKey(pubkey).verify(message, blscurve.Signature(signature))
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#bls-signatures # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#bls-signatures
proc blsVerify*( proc blsVerify*(
pubkey: ValidatorPubKey, message: openArray[byte], pubkey: ValidatorPubKey, message: openArray[byte],
signature: CookedSig): bool = signature: CookedSig): bool =

View File

@ -40,7 +40,7 @@ static:
doAssert ord(TIMELY_HEAD_FLAG_INDEX) == 2 doAssert ord(TIMELY_HEAD_FLAG_INDEX) == 2
const const
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#incentivization-weights # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#incentivization-weights
TIMELY_SOURCE_WEIGHT* = 14 TIMELY_SOURCE_WEIGHT* = 14
TIMELY_TARGET_WEIGHT* = 26 TIMELY_TARGET_WEIGHT* = 26
TIMELY_HEAD_WEIGHT* = 14 TIMELY_HEAD_WEIGHT* = 14
@ -51,7 +51,7 @@ const
PARTICIPATION_FLAG_WEIGHTS*: array[TimelyFlag, uint64] = PARTICIPATION_FLAG_WEIGHTS*: array[TimelyFlag, uint64] =
[uint64 TIMELY_SOURCE_WEIGHT, TIMELY_TARGET_WEIGHT, TIMELY_HEAD_WEIGHT] [uint64 TIMELY_SOURCE_WEIGHT, TIMELY_TARGET_WEIGHT, TIMELY_HEAD_WEIGHT]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#misc # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#misc
TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE* = 16 TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE* = 16
SYNC_COMMITTEE_SUBNET_COUNT* = 4 SYNC_COMMITTEE_SUBNET_COUNT* = 4
@ -78,7 +78,7 @@ static: doAssert TIMELY_SOURCE_WEIGHT + TIMELY_TARGET_WEIGHT +
type type
### New types ### New types
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#synccommitteemessage # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#synccommitteemessage
SyncCommitteeMessage* = object SyncCommitteeMessage* = object
slot*: Slot slot*: Slot
## Slot to which this contribution pertains ## Slot to which this contribution pertains
@ -92,7 +92,7 @@ type
signature*: ValidatorSig signature*: ValidatorSig
## Signature by the validator over the block root of `slot` ## Signature by the validator over the block root of `slot`
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#synccommitteecontribution # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#synccommitteecontribution
SyncCommitteeAggregationBits* = SyncCommitteeAggregationBits* =
BitArray[SYNC_SUBCOMMITTEE_SIZE] BitArray[SYNC_SUBCOMMITTEE_SIZE]
@ -114,18 +114,18 @@ type
signature*: ValidatorSig signature*: ValidatorSig
## Signature by the validator(s) over the block root of `slot` ## Signature by the validator(s) over the block root of `slot`
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#contributionandproof # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#contributionandproof
ContributionAndProof* = object ContributionAndProof* = object
aggregator_index*: uint64 # `ValidatorIndex` after validation aggregator_index*: uint64 # `ValidatorIndex` after validation
contribution*: SyncCommitteeContribution contribution*: SyncCommitteeContribution
selection_proof*: ValidatorSig selection_proof*: ValidatorSig
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#signedcontributionandproof # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#signedcontributionandproof
SignedContributionAndProof* = object SignedContributionAndProof* = object
message*: ContributionAndProof message*: ContributionAndProof
signature*: ValidatorSig signature*: ValidatorSig
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#syncaggregatorselectiondata # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#syncaggregatorselectiondata
SyncAggregatorSelectionData* = object SyncAggregatorSelectionData* = object
slot*: Slot slot*: Slot
subcommittee_index*: uint64 # `SyncSubcommitteeIndex` after validation subcommittee_index*: uint64 # `SyncSubcommitteeIndex` after validation
@ -141,7 +141,7 @@ type
NextSyncCommitteeBranch* = NextSyncCommitteeBranch* =
array[log2trunc(NEXT_SYNC_COMMITTEE_GINDEX), Eth2Digest] array[log2trunc(NEXT_SYNC_COMMITTEE_GINDEX), Eth2Digest]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#lightclientheader # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/sync-protocol.md#lightclientheader
LightClientHeader* = object LightClientHeader* = object
beacon*: BeaconBlockHeader beacon*: BeaconBlockHeader
## Beacon block header ## Beacon block header
@ -188,7 +188,7 @@ type
# Slot at which the aggregate signature was created (untrusted) # Slot at which the aggregate signature was created (untrusted)
signature_slot*: Slot signature_slot*: Slot
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#lightclientoptimisticupdate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/sync-protocol.md#lightclientoptimisticupdate
LightClientOptimisticUpdate* = object LightClientOptimisticUpdate* = object
# Header attested to by the sync committee # Header attested to by the sync committee
attested_header*: LightClientHeader attested_header*: LightClientHeader

View File

@ -76,7 +76,7 @@ export
tables, results, endians2, json_serialization, sszTypes, beacon_time, crypto, tables, results, endians2, json_serialization, sszTypes, beacon_time, crypto,
digest, presets, kzg4844 digest, presets, kzg4844
const SPEC_VERSION* = "1.5.0-alpha.5" const SPEC_VERSION* = "1.5.0-alpha.6"
## Spec version we're aiming to be compatible with, right now ## Spec version we're aiming to be compatible with, right now
const const
@ -233,7 +233,7 @@ type
ForkDigest* = distinct array[4, byte] ForkDigest* = distinct array[4, byte]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#forkdata # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#forkdata
ForkData* = object ForkData* = object
current_version*: Version current_version*: Version
genesis_validators_root*: Eth2Digest genesis_validators_root*: Eth2Digest
@ -312,7 +312,7 @@ type
HashedValidatorPubKey* = object HashedValidatorPubKey* = object
value*: ptr HashedValidatorPubKeyItem value*: ptr HashedValidatorPubKeyItem
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#validator
Validator* = object Validator* = object
pubkeyData*{.serializedFieldName: "pubkey".}: HashedValidatorPubKey pubkeyData*{.serializedFieldName: "pubkey".}: HashedValidatorPubKey
@ -334,7 +334,7 @@ type
withdrawable_epoch*: Epoch withdrawable_epoch*: Epoch
## When validator can withdraw funds ## When validator can withdraw funds
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#pendingattestation # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#pendingattestation
PendingAttestation* = object PendingAttestation* = object
aggregation_bits*: CommitteeValidatorsBits aggregation_bits*: CommitteeValidatorsBits
data*: AttestationData data*: AttestationData
@ -343,7 +343,7 @@ type
proposer_index*: uint64 # `ValidatorIndex` after validation proposer_index*: uint64 # `ValidatorIndex` after validation
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#historicalbatch # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#historicalbatch
HistoricalBatch* = object HistoricalBatch* = object
block_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] block_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
state_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] state_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
@ -380,7 +380,7 @@ type
sync_committee_bits*: BitArray[SYNC_COMMITTEE_SIZE] sync_committee_bits*: BitArray[SYNC_COMMITTEE_SIZE]
sync_committee_signature*: TrustedSig sync_committee_signature*: TrustedSig
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#custom-types # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#custom-types
Transaction* = List[byte, Limit MAX_BYTES_PER_TRANSACTION] Transaction* = List[byte, Limit MAX_BYTES_PER_TRANSACTION]
ExecutionAddress* = object ExecutionAddress* = object
@ -389,14 +389,14 @@ type
BloomLogs* = object BloomLogs* = object
data*: array[BYTES_PER_LOGS_BLOOM, byte] data*: array[BYTES_PER_LOGS_BLOOM, byte]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#withdrawal # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/beacon-chain.md#withdrawal
Withdrawal* = object Withdrawal* = object
index*: WithdrawalIndex index*: WithdrawalIndex
validator_index*: uint64 validator_index*: uint64
address*: ExecutionAddress address*: ExecutionAddress
amount*: Gwei amount*: Gwei
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#depositrequest # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#depositrequest
DepositRequest* = object DepositRequest* = object
pubkey*: ValidatorPubKey pubkey*: ValidatorPubKey
withdrawal_credentials*: Eth2Digest withdrawal_credentials*: Eth2Digest
@ -422,7 +422,7 @@ type
from_bls_pubkey*: ValidatorPubKey from_bls_pubkey*: ValidatorPubKey
to_execution_address*: ExecutionAddress to_execution_address*: ExecutionAddress
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#signedblstoexecutionchange # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/beacon-chain.md#signedblstoexecutionchange
SignedBLSToExecutionChange* = object SignedBLSToExecutionChange* = object
message*: BLSToExecutionChange message*: BLSToExecutionChange
signature*: ValidatorSig signature*: ValidatorSig
@ -433,7 +433,7 @@ type
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#beaconblockbody # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#beaconblockbody
KzgCommitments* = List[KzgCommitment, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK] KzgCommitments* = List[KzgCommitment, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#historicalsummary # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/beacon-chain.md#historicalsummary
HistoricalSummary* = object HistoricalSummary* = object
# `HistoricalSummary` matches the components of the phase0 # `HistoricalSummary` matches the components of the phase0
# `HistoricalBatch` making the two hash_tree_root-compatible. # `HistoricalBatch` making the two hash_tree_root-compatible.
@ -445,13 +445,13 @@ type
index*: uint64 index*: uint64
amount*: Gwei amount*: Gwei
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#pendingpartialwithdrawal # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#pendingpartialwithdrawal
PendingPartialWithdrawal* = object PendingPartialWithdrawal* = object
index*: uint64 index*: uint64
amount*: Gwei amount*: Gwei
withdrawable_epoch*: Epoch withdrawable_epoch*: Epoch
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#pendingconsolidation # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#pendingconsolidation
PendingConsolidation* = object PendingConsolidation* = object
source_index*: uint64 source_index*: uint64
target_index*: uint64 target_index*: uint64
@ -472,7 +472,7 @@ type
pubkeys*: HashArray[Limit SYNC_COMMITTEE_SIZE, ValidatorPubKey] pubkeys*: HashArray[Limit SYNC_COMMITTEE_SIZE, ValidatorPubKey]
aggregate_pubkey*: ValidatorPubKey aggregate_pubkey*: ValidatorPubKey
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#beaconblockheader # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#beaconblockheader
BeaconBlockHeader* = object BeaconBlockHeader* = object
slot*: Slot slot*: Slot
proposer_index*: uint64 # `ValidatorIndex` after validation proposer_index*: uint64 # `ValidatorIndex` after validation
@ -480,7 +480,7 @@ type
state_root*: Eth2Digest state_root*: Eth2Digest
body_root*: Eth2Digest body_root*: Eth2Digest
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#signingdata # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#signingdata
SigningData* = object SigningData* = object
object_root*: Eth2Digest object_root*: Eth2Digest
domain*: Eth2Domain domain*: Eth2Domain
@ -509,7 +509,7 @@ type
sync_committees*: Table[SyncCommitteePeriod, SyncCommitteeCache] sync_committees*: Table[SyncCommitteePeriod, SyncCommitteeCache]
# This matches the mutable state of the Solidity deposit contract # This matches the mutable state of the Solidity deposit contract
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/solidity_deposit_contract/deposit_contract.sol # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/solidity_deposit_contract/deposit_contract.sol
DepositContractState* = object DepositContractState* = object
branch*: array[DEPOSIT_CONTRACT_TREE_DEPTH, Eth2Digest] branch*: array[DEPOSIT_CONTRACT_TREE_DEPTH, Eth2Digest]
deposit_count*: array[32, byte] # Uint256 deposit_count*: array[32, byte] # Uint256
@ -551,7 +551,7 @@ type
withdrawable_epoch*: Epoch withdrawable_epoch*: Epoch
## When validator can withdraw funds ## When validator can withdraw funds
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#validator
ValidatorStatusCapella* = object ValidatorStatusCapella* = object
# This is a validator without the expensive, immutable, append-only parts # This is a validator without the expensive, immutable, append-only parts
# serialized. They're represented in memory to allow in-place SSZ reading # serialized. They're represented in memory to allow in-place SSZ reading

View File

@ -35,7 +35,7 @@ const
NEWPAYLOAD_TIMEOUT* = 8.seconds NEWPAYLOAD_TIMEOUT* = 8.seconds
type type
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#executionpayload # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#executionpayload
ExecutionPayload* = object ExecutionPayload* = object
# Execution block header fields # Execution block header fields
parent_hash*: Eth2Digest parent_hash*: Eth2Digest
@ -63,7 +63,7 @@ type
executionPayload*: ExecutionPayload executionPayload*: ExecutionPayload
blockValue*: Wei blockValue*: Wei
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#executionpayloadheader # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#executionpayloadheader
ExecutionPayloadHeader* = object ExecutionPayloadHeader* = object
# Execution block header fields # Execution block header fields
parent_hash*: Eth2Digest parent_hash*: Eth2Digest
@ -93,7 +93,7 @@ type
parent_hash*: Eth2Digest parent_hash*: Eth2Digest
total_difficulty*: Eth2Digest # uint256 total_difficulty*: Eth2Digest # uint256
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#beaconstate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#beaconstate
BeaconState* = object BeaconState* = object
# Versioning # Versioning
genesis_time*: uint64 genesis_time*: uint64
@ -218,7 +218,7 @@ type
state_root*: Eth2Digest state_root*: Eth2Digest
body*: TrustedBeaconBlockBody body*: TrustedBeaconBlockBody
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#beaconblockbody # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#beaconblockbody
BeaconBlockBody* = object BeaconBlockBody* = object
randao_reveal*: ValidatorSig randao_reveal*: ValidatorSig
eth1_data*: Eth1Data eth1_data*: Eth1Data

View File

@ -32,7 +32,7 @@ const
# This index is rooted in `BeaconBlockBody`. # This index is rooted in `BeaconBlockBody`.
# The first member (`randao_reveal`) is 16, subsequent members +1 each. # The first member (`randao_reveal`) is 16, subsequent members +1 each.
# If there are ever more than 16 members in `BeaconBlockBody`, indices change! # If there are ever more than 16 members in `BeaconBlockBody`, indices change!
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/ssz/merkle-proofs.md # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/ssz/merkle-proofs.md
# execution_payload # execution_payload
EXECUTION_PAYLOAD_GINDEX* = 25.GeneralizedIndex EXECUTION_PAYLOAD_GINDEX* = 25.GeneralizedIndex
@ -96,7 +96,7 @@ type
ExecutionBranch* = ExecutionBranch* =
array[log2trunc(EXECUTION_PAYLOAD_GINDEX), Eth2Digest] array[log2trunc(EXECUTION_PAYLOAD_GINDEX), Eth2Digest]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/light-client/sync-protocol.md#modified-lightclientheader # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/light-client/sync-protocol.md#modified-lightclientheader
LightClientHeader* = object LightClientHeader* = object
beacon*: BeaconBlockHeader beacon*: BeaconBlockHeader
## Beacon block header ## Beacon block header
@ -330,7 +330,7 @@ type
state_root*: Eth2Digest state_root*: Eth2Digest
body*: TrustedBeaconBlockBody body*: TrustedBeaconBlockBody
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/beacon-chain.md#beaconblockbody # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/beacon-chain.md#beaconblockbody
BeaconBlockBody* = object BeaconBlockBody* = object
randao_reveal*: ValidatorSig randao_reveal*: ValidatorSig
eth1_data*: Eth1Data eth1_data*: Eth1Data
@ -644,13 +644,13 @@ func is_valid_light_client_header*(
get_subtree_index(EXECUTION_PAYLOAD_GINDEX), get_subtree_index(EXECUTION_PAYLOAD_GINDEX),
header.beacon.body_root) header.beacon.body_root)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/light-client/fork.md#upgrading-light-client-data
func upgrade_lc_header_to_capella*( func upgrade_lc_header_to_capella*(
pre: altair.LightClientHeader): LightClientHeader = pre: altair.LightClientHeader): LightClientHeader =
LightClientHeader( LightClientHeader(
beacon: pre.beacon) beacon: pre.beacon)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/light-client/fork.md#upgrading-light-client-data
func upgrade_lc_bootstrap_to_capella*( func upgrade_lc_bootstrap_to_capella*(
pre: altair.LightClientBootstrap): LightClientBootstrap = pre: altair.LightClientBootstrap): LightClientBootstrap =
LightClientBootstrap( LightClientBootstrap(
@ -658,7 +658,7 @@ func upgrade_lc_bootstrap_to_capella*(
current_sync_committee: pre.current_sync_committee, current_sync_committee: pre.current_sync_committee,
current_sync_committee_branch: pre.current_sync_committee_branch) current_sync_committee_branch: pre.current_sync_committee_branch)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/light-client/fork.md#upgrading-light-client-data # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/light-client/fork.md#upgrading-light-client-data
func upgrade_lc_update_to_capella*( func upgrade_lc_update_to_capella*(
pre: altair.LightClientUpdate): LightClientUpdate = pre: altair.LightClientUpdate): LightClientUpdate =
LightClientUpdate( LightClientUpdate(
@ -670,7 +670,7 @@ func upgrade_lc_update_to_capella*(
sync_aggregate: pre.sync_aggregate, sync_aggregate: pre.sync_aggregate,
signature_slot: pre.signature_slot) signature_slot: pre.signature_slot)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/light-client/fork.md#upgrading-light-client-data
func upgrade_lc_finality_update_to_capella*( func upgrade_lc_finality_update_to_capella*(
pre: altair.LightClientFinalityUpdate): LightClientFinalityUpdate = pre: altair.LightClientFinalityUpdate): LightClientFinalityUpdate =
LightClientFinalityUpdate( LightClientFinalityUpdate(
@ -680,7 +680,7 @@ func upgrade_lc_finality_update_to_capella*(
sync_aggregate: pre.sync_aggregate, sync_aggregate: pre.sync_aggregate,
signature_slot: pre.signature_slot) signature_slot: pre.signature_slot)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/light-client/fork.md#upgrading-light-client-data # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/light-client/fork.md#upgrading-light-client-data
func upgrade_lc_optimistic_update_to_capella*( func upgrade_lc_optimistic_update_to_capella*(
pre: altair.LightClientOptimisticUpdate): LightClientOptimisticUpdate = pre: altair.LightClientOptimisticUpdate): LightClientOptimisticUpdate =
LightClientOptimisticUpdate( LightClientOptimisticUpdate(

View File

@ -55,12 +55,9 @@ const
DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF* = DomainType([byte 0x08, 0x00, 0x00, 0x00]) DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF* = DomainType([byte 0x08, 0x00, 0x00, 0x00])
DOMAIN_CONTRIBUTION_AND_PROOF* = DomainType([byte 0x09, 0x00, 0x00, 0x00]) DOMAIN_CONTRIBUTION_AND_PROOF* = DomainType([byte 0x09, 0x00, 0x00, 0x00])
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#domain-types # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/beacon-chain.md#domain-types
DOMAIN_BLS_TO_EXECUTION_CHANGE* = DomainType([byte 0x0a, 0x00, 0x00, 0x00]) DOMAIN_BLS_TO_EXECUTION_CHANGE* = DomainType([byte 0x0a, 0x00, 0x00, 0x00])
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#domains
DOMAIN_CONSOLIDATION* = DomainType([byte 0x0b, 0x00, 0x00, 0x00])
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/fork-choice.md#configuration # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/fork-choice.md#configuration
PROPOSER_SCORE_BOOST*: uint64 = 40 PROPOSER_SCORE_BOOST*: uint64 = 40
REORG_HEAD_WEIGHT_THRESHOLD*: uint64 = 20 REORG_HEAD_WEIGHT_THRESHOLD*: uint64 = 20

View File

@ -31,7 +31,7 @@ from kzg4844 import KzgCommitment, KzgProof
export json_serialization, base, kzg4844 export json_serialization, base, kzg4844
const const
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/polynomial-commitments.md#constants # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/polynomial-commitments.md#constants
BYTES_PER_FIELD_ELEMENT = 32 BYTES_PER_FIELD_ELEMENT = 32
BLS_MODULUS* = "52435875175126190479447740508185965837690552500527637822603658699938581184513".u256 BLS_MODULUS* = "52435875175126190479447740508185965837690552500527637822603658699938581184513".u256
@ -55,7 +55,7 @@ type
KzgCommitmentInclusionProof* = KzgCommitmentInclusionProof* =
array[KZG_COMMITMENT_INCLUSION_PROOF_DEPTH, Eth2Digest] array[KZG_COMMITMENT_INCLUSION_PROOF_DEPTH, Eth2Digest]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/p2p-interface.md#blobsidecar # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/p2p-interface.md#blobsidecar
BlobSidecar* = object BlobSidecar* = object
index*: BlobIndex index*: BlobIndex
## Index of blob in block ## Index of blob in block
@ -77,12 +77,12 @@ type
kzg_commitment*: KzgCommitment kzg_commitment*: KzgCommitment
versioned_hash*: string # TODO should be string; VersionedHash not distinct versioned_hash*: string # TODO should be string; VersionedHash not distinct
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/deneb/p2p-interface.md#blobidentifier # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/p2p-interface.md#blobidentifier
BlobIdentifier* = object BlobIdentifier* = object
block_root*: Eth2Digest block_root*: Eth2Digest
index*: BlobIndex index*: BlobIndex
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#executionpayload # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/beacon-chain.md#executionpayload
ExecutionPayload* = object ExecutionPayload* = object
# Execution block header fields # Execution block header fields
parent_hash*: Eth2Digest parent_hash*: Eth2Digest
@ -159,7 +159,7 @@ type
## Execution payload header corresponding to `beacon.body_root` (from Capella onward) ## Execution payload header corresponding to `beacon.body_root` (from Capella onward)
execution_branch*: capella.ExecutionBranch execution_branch*: capella.ExecutionBranch
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#lightclientbootstrap # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/sync-protocol.md#lightclientbootstrap
LightClientBootstrap* = object LightClientBootstrap* = object
header*: LightClientHeader header*: LightClientHeader
## Header matching the requested beacon block root ## Header matching the requested beacon block root
@ -326,7 +326,7 @@ type
data*: BeaconState data*: BeaconState
root*: Eth2Digest # hash_tree_root(data) root*: Eth2Digest # hash_tree_root(data)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#beaconblock # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#beaconblock
BeaconBlock* = object BeaconBlock* = object
## For each slot, a proposer is chosen from the validator pool to propose ## For each slot, a proposer is chosen from the validator pool to propose
## a new block. Once the block as been proposed, it is transmitted to ## a new block. Once the block as been proposed, it is transmitted to
@ -467,7 +467,7 @@ type
bls_to_execution_changes*: SignedBLSToExecutionChangeList bls_to_execution_changes*: SignedBLSToExecutionChangeList
blob_kzg_commitments*: KzgCommitments # [New in Deneb] blob_kzg_commitments*: KzgCommitments # [New in Deneb]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#signedbeaconblock # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#signedbeaconblock
SignedBeaconBlock* = object SignedBeaconBlock* = object
message*: BeaconBlock message*: BeaconBlock
signature*: ValidatorSig signature*: ValidatorSig
@ -627,7 +627,7 @@ func kzg_commitment_inclusion_proof_gindex*(
BLOB_KZG_COMMITMENTS_FIRST_GINDEX + index BLOB_KZG_COMMITMENTS_FIRST_GINDEX + index
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/deneb/light-client/sync-protocol.md#modified-get_lc_execution_root # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/light-client/sync-protocol.md#modified-get_lc_execution_root
func get_lc_execution_root*( func get_lc_execution_root*(
header: LightClientHeader, cfg: RuntimeConfig): Eth2Digest = header: LightClientHeader, cfg: RuntimeConfig): Eth2Digest =
let epoch = header.beacon.slot.epoch let epoch = header.beacon.slot.epoch
@ -658,7 +658,7 @@ func get_lc_execution_root*(
ZERO_HASH ZERO_HASH
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/deneb/light-client/sync-protocol.md#modified-is_valid_light_client_header # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/light-client/sync-protocol.md#modified-is_valid_light_client_header
func is_valid_light_client_header*( func is_valid_light_client_header*(
header: LightClientHeader, cfg: RuntimeConfig): bool = header: LightClientHeader, cfg: RuntimeConfig): bool =
let epoch = header.beacon.slot.epoch let epoch = header.beacon.slot.epoch

View File

@ -0,0 +1,110 @@
# beacon_chain
# Copyright (c) 2022-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
import
std/[sequtils],
"."/[altair, base, deneb],
kzg4844/[kzg, kzg_abi]
from std/strutils import join
export base
const
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/polynomial-commitments-sampling.md#cells
FIELD_ELEMENTS_PER_EXT_BLOB* = 2 * kzg_abi.FIELD_ELEMENTS_PER_BLOB
# Number of field elements in a Reed-Solomon extended blob |
FIELD_ELEMENTS_PER_CELL* = 64 # Number of field elements in a cell |
BYTES_PER_CELL* = FIELD_ELEMENTS_PER_CELL * kzg_abi.BYTES_PER_FIELD_ELEMENT
# The number of bytes in a cell |
CELLS_PER_EXT_BLOB* = FIELD_ELEMENTS_PER_EXT_BLOB div FIELD_ELEMENTS_PER_CELL
# The number of cells in an extended blob |
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/p2p-interface.md#preset
KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH* = 4
type
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/_features/eip7594/polynomial-commitments-sampling.md#custom-types
BLSFieldElement* = KzgBytes32
G2Point* = array[96, byte]
PolynomialCoeff* = List[BLSFieldElement, FIELD_ELEMENTS_PER_EXT_BLOB]
Coset* = array[FIELD_ELEMENTS_PER_CELL, BLSFieldElement]
CosetEvals* = array[FIELD_ELEMENTS_PER_CELL, BLSFieldElement]
Cell* = KzgCell
Cells* = KzgCells
CellsAndProofs* = KzgCellsAndKzgProofs
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#custom-types
RowIndex* = uint64
ColumnIndex* = uint64
CellIndex* = uint64
const
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#data-size
NUMBER_OF_COLUMNS* = 128
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#networking
DATA_COLUMN_SIDECAR_SUBNET_COUNT* = 128
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#custody-setting
SAMPLES_PER_SLOT* = 8
CUSTODY_REQUIREMENT* = 4
type
DataColumn* = List[KzgCell, Limit(MAX_BLOB_COMMITMENTS_PER_BLOCK)]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#datacolumnsidecar
DataColumnSidecar* = object
index*: ColumnIndex # Index of column in extended matrix
column*: DataColumn
kzg_commitments*: KzgCommitments
kzg_proofs*: KzgProofs
signed_block_header*: SignedBeaconBlockHeader
kzg_commitments_inclusion_proof*:
array[KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH, Eth2Digest]
DataColumnSidecars* = seq[ref DataColumnSidecar]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/p2p-interface.md#datacolumnidentifier
DataColumnIdentifier* = object
block_root*: Eth2Digest
index*: ColumnIndex
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/_features/eip7594/das-core.md#matrixentry
MatrixEntry* = object
cell*: Cell
kzg_proof*: KzgProof
column_index*: ColumnIndex
row_index*: RowIndex
# Not in spec, defined in order to compute custody subnets
CscBits* = BitArray[DATA_COLUMN_SIDECAR_SUBNET_COUNT]
CscCount* = uint8
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/p2p-interface.md#metadata
MetaData* = object
seq_number*: uint64
attnets*: AttnetBits
syncnets*: SyncnetBits
custody_subnet_count*: CscCount
func shortLog*(v: DataColumnSidecar): auto =
(
index: v.index,
kzg_commitments: v.kzg_commitments.len,
kzg_proofs: v.kzg_proofs.len,
block_header: shortLog(v.signed_block_header.message),
)
func shortLog*(v: seq[DataColumnSidecar]): auto =
"[" & v.mapIt(shortLog(it)).join(", ") & "]"
func shortLog*(x: seq[DataColumnIdentifier]): string =
"[" & x.mapIt(shortLog(it.block_root) & "/" & $it.index).join(", ") & "]"

View File

@ -92,11 +92,11 @@ type
attestation_1*: TrustedIndexedAttestation # Modified in Electra:EIP7549] attestation_1*: TrustedIndexedAttestation # Modified in Electra:EIP7549]
attestation_2*: TrustedIndexedAttestation # Modified in Electra:EIP7549] attestation_2*: TrustedIndexedAttestation # Modified in Electra:EIP7549]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/p2p-interface.md#custom-types # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/p2p-interface.md#custom-types
KzgCommitmentInclusionProof* = KzgCommitmentInclusionProof* =
array[KZG_COMMITMENT_INCLUSION_PROOF_DEPTH_ELECTRA, Eth2Digest] array[KZG_COMMITMENT_INCLUSION_PROOF_DEPTH_ELECTRA, Eth2Digest]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/p2p-interface.md#blobsidecar # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/p2p-interface.md#blobsidecar
BlobSidecar* = object BlobSidecar* = object
index*: BlobIndex index*: BlobIndex
## Index of blob in block ## Index of blob in block
@ -108,7 +108,7 @@ type
kzg_commitment_inclusion_proof*: KzgCommitmentInclusionProof kzg_commitment_inclusion_proof*: KzgCommitmentInclusionProof
BlobSidecars* = seq[ref BlobSidecar] BlobSidecars* = seq[ref BlobSidecar]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#executionpayload # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/beacon-chain.md#executionpayload
ExecutionPayload* {.sszProfile: StableExecutionPayload.} = object ExecutionPayload* {.sszProfile: StableExecutionPayload.} = object
# Execution block header fields # Execution block header fields
parent_hash*: Eth2Digest parent_hash*: Eth2Digest
@ -133,21 +133,13 @@ type
withdrawals*: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD] withdrawals*: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]
blob_gas_used*: uint64 blob_gas_used*: uint64
excess_blob_gas*: uint64 excess_blob_gas*: uint64
deposit_requests*: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD]
## [New in Electra:EIP6110]
withdrawal_requests*:
List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD]
## [New in Electra:EIP7002:EIP7251]
consolidation_requests*:
List[ConsolidationRequest, Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD]
## [New in Electra:EIP7251]
ExecutionPayloadForSigning* = object ExecutionPayloadForSigning* = object
executionPayload*: ExecutionPayload executionPayload*: ExecutionPayload
blockValue*: Wei blockValue*: Wei
blobsBundle*: BlobsBundle blobsBundle*: BlobsBundle
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#executionpayloadheader # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/beacon-chain.md#executionpayloadheader
ExecutionPayloadHeader* {.sszProfile: StableExecutionPayloadHeader.} = object ExecutionPayloadHeader* {.sszProfile: StableExecutionPayloadHeader.} = object
# Execution block header fields # Execution block header fields
parent_hash*: Eth2Digest parent_hash*: Eth2Digest
@ -170,9 +162,6 @@ type
withdrawals_root*: Eth2Digest withdrawals_root*: Eth2Digest
blob_gas_used*: uint64 blob_gas_used*: uint64
excess_blob_gas*: uint64 excess_blob_gas*: uint64
deposit_requests_root*: Eth2Digest # [New in Electra:EIP6110]
withdrawal_requests_root*: Eth2Digest # [New in Electra:EIP7002:EIP7251]
consolidation_requests_root*: Eth2Digest # [New in Electra:EIP7251]
ExecutePayload* = proc( ExecutePayload* = proc(
execution_payload: ExecutionPayload): bool {.gcsafe, raises: [].} execution_payload: ExecutionPayload): bool {.gcsafe, raises: [].}
@ -180,7 +169,7 @@ type
ExecutionBranch* = ExecutionBranch* =
array[log2trunc(EXECUTION_PAYLOAD_GINDEX_ELECTRA), Eth2Digest] array[log2trunc(EXECUTION_PAYLOAD_GINDEX_ELECTRA), Eth2Digest]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/validator.md#aggregateandproof # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#aggregateandproof
AggregateAndProof* = object AggregateAndProof* = object
aggregator_index*: uint64 # `ValidatorIndex` after validation aggregator_index*: uint64 # `ValidatorIndex` after validation
aggregate*: Attestation aggregate*: Attestation
@ -209,7 +198,7 @@ type
## Execution payload header corresponding to `beacon.body_root` (from Capella onward) ## Execution payload header corresponding to `beacon.body_root` (from Capella onward)
execution_branch*: ExecutionBranch execution_branch*: ExecutionBranch
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/altair/light-client/sync-protocol.md#lightclientbootstrap # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/sync-protocol.md#lightclientbootstrap
LightClientBootstrap* = object LightClientBootstrap* = object
header*: LightClientHeader header*: LightClientHeader
## Header matching the requested beacon block root ## Header matching the requested beacon block root
@ -218,7 +207,7 @@ type
## Current sync committee corresponding to `header.beacon.state_root` ## Current sync committee corresponding to `header.beacon.state_root`
current_sync_committee_branch*: CurrentSyncCommitteeBranch current_sync_committee_branch*: CurrentSyncCommitteeBranch
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#lightclientupdate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/sync-protocol.md#lightclientupdate
LightClientUpdate* = object LightClientUpdate* = object
attested_header*: LightClientHeader attested_header*: LightClientHeader
## Header attested to by the sync committee ## Header attested to by the sync committee
@ -298,9 +287,20 @@ type
## (used to compute safety threshold) ## (used to compute safety threshold)
current_max_active_participants*: uint64 current_max_active_participants*: uint64
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#executionrequests
ExecutionRequests* {.sszProfile: StableExecutionRequests.} = object
deposits*:
List[DepositRequest,
Limit MAX_DEPOSIT_REQUESTS_PER_PAYLOAD] # [New in Electra:EIP6110]
withdrawals*:
List[WithdrawalRequest,
Limit MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD] # [New in Electra:EIP7002:EIP7251]
consolidations*:
List[ConsolidationRequest,
Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD] # [New in Electra:EIP7251]
# https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#beaconstate # https://github.com/ethereum/consensus-specs/blob/82133085a1295e93394ebdf71df8f2f6e0962588/specs/electra/beacon-chain.md#beaconstate
BeaconState* {. BeaconState* {.sszProfile: StableBeaconState.}= object
sszProfile: StableBeaconState.}= object
# Versioning # Versioning
genesis_time*: uint64 genesis_time*: uint64
genesis_validators_root*: Eth2Digest genesis_validators_root*: Eth2Digest
@ -394,7 +394,7 @@ type
data*: BeaconState data*: BeaconState
root*: Eth2Digest # hash_tree_root(data) root*: Eth2Digest # hash_tree_root(data)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#beaconblock # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#beaconblock
BeaconBlock* = object BeaconBlock* = object
## For each slot, a proposer is chosen from the validator pool to propose ## For each slot, a proposer is chosen from the validator pool to propose
## a new block. Once the block as been proposed, it is transmitted to ## a new block. Once the block as been proposed, it is transmitted to
@ -451,7 +451,7 @@ type
state_root*: Eth2Digest state_root*: Eth2Digest
body*: TrustedBeaconBlockBody body*: TrustedBeaconBlockBody
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#beaconblockbody # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#beaconblockbody
BeaconBlockBody* {.sszProfile: StableBeaconBlockBody.} = object BeaconBlockBody* {.sszProfile: StableBeaconBlockBody.} = object
randao_reveal*: ValidatorSig randao_reveal*: ValidatorSig
eth1_data*: Eth1Data eth1_data*: Eth1Data
@ -476,6 +476,7 @@ type
execution_payload*: electra.ExecutionPayload # [Modified in Electra:EIP6110:EIP7002] execution_payload*: electra.ExecutionPayload # [Modified in Electra:EIP6110:EIP7002]
bls_to_execution_changes*: SignedBLSToExecutionChangeList bls_to_execution_changes*: SignedBLSToExecutionChangeList
blob_kzg_commitments*: KzgCommitments blob_kzg_commitments*: KzgCommitments
execution_requests*: ExecutionRequests # [New in Electra]
SigVerifiedBeaconBlockBody* {. SigVerifiedBeaconBlockBody* {.
sszProfile: StableBeaconBlockBody.} = object sszProfile: StableBeaconBlockBody.} = object
@ -516,6 +517,7 @@ type
execution_payload*: ExecutionPayload # [Modified in Electra:EIP6110:EIP7002] execution_payload*: ExecutionPayload # [Modified in Electra:EIP6110:EIP7002]
bls_to_execution_changes*: SignedBLSToExecutionChangeList bls_to_execution_changes*: SignedBLSToExecutionChangeList
blob_kzg_commitments*: KzgCommitments blob_kzg_commitments*: KzgCommitments
execution_requests*: ExecutionRequests # [New in Electra]
TrustedBeaconBlockBody* {. TrustedBeaconBlockBody* {.
sszProfile: StableBeaconBlockBody.} = object sszProfile: StableBeaconBlockBody.} = object
@ -544,6 +546,7 @@ type
execution_payload*: ExecutionPayload # [Modified in Electra:EIP6110:EIP7002] execution_payload*: ExecutionPayload # [Modified in Electra:EIP6110:EIP7002]
bls_to_execution_changes*: SignedBLSToExecutionChangeList bls_to_execution_changes*: SignedBLSToExecutionChangeList
blob_kzg_commitments*: KzgCommitments blob_kzg_commitments*: KzgCommitments
execution_requests*: ExecutionRequests # [New in Electra]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#signedbeaconblock # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#signedbeaconblock
SignedBeaconBlock* = object SignedBeaconBlock* = object
@ -583,7 +586,7 @@ type
root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#attestation # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#attestation
Attestation* {.sszProfile: StableAttestation.} = object Attestation* {.sszProfile: StableAttestation.} = object
aggregation_bits*: ElectraCommitteeValidatorsBits aggregation_bits*: ElectraCommitteeValidatorsBits
data*: AttestationData data*: AttestationData
@ -713,7 +716,7 @@ func kzg_commitment_inclusion_proof_gindex*(
BLOB_KZG_COMMITMENTS_FIRST_GINDEX + index BLOB_KZG_COMMITMENTS_FIRST_GINDEX + index
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#normalize_merkle_branch # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/light-client/fork.md#normalize_merkle_branch
func normalize_merkle_branch*[N]( func normalize_merkle_branch*[N](
branch: array[N, Eth2Digest], branch: array[N, Eth2Digest],
gindex: static GeneralizedIndex): auto = gindex: static GeneralizedIndex): auto =
@ -797,7 +800,7 @@ func get_lc_execution_root*(
ZERO_HASH ZERO_HASH
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/sync-protocol.md#modified-execution_payload_gindex_at_slot # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/light-client/sync-protocol.md#modified-execution_payload_gindex_at_slot
func execution_payload_gindex_at_epoch( func execution_payload_gindex_at_epoch(
epoch: Epoch, cfg: RuntimeConfig): GeneralizedIndex = epoch: Epoch, cfg: RuntimeConfig): GeneralizedIndex =
doAssert epoch >= cfg.CAPELLA_FORK_EPOCH doAssert epoch >= cfg.CAPELLA_FORK_EPOCH
@ -807,18 +810,11 @@ func execution_payload_gindex_at_epoch(
return EXECUTION_PAYLOAD_GINDEX_ELECTRA return EXECUTION_PAYLOAD_GINDEX_ELECTRA
EXECUTION_PAYLOAD_GINDEX EXECUTION_PAYLOAD_GINDEX
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/sync-protocol.md#modified-is_valid_light_client_header # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/light-client/sync-protocol.md#modified-is_valid_light_client_header
func is_valid_light_client_header*( func is_valid_light_client_header*(
header: LightClientHeader, cfg: RuntimeConfig): bool = header: LightClientHeader, cfg: RuntimeConfig): bool =
let epoch = header.beacon.slot.epoch let epoch = header.beacon.slot.epoch
# [New in Electra:EIP6110:EIP7002:EIP7251]
if epoch < cfg.ELECTRA_FORK_EPOCH:
if not header.execution.deposit_requests_root.isZero or
not header.execution.withdrawal_requests_root.isZero or
not header.execution.consolidation_requests_root.isZero:
return false
if epoch < cfg.DENEB_FORK_EPOCH: if epoch < cfg.DENEB_FORK_EPOCH:
if header.execution.blob_gas_used != 0 or if header.execution.blob_gas_used != 0 or
header.execution.excess_blob_gas != 0: header.execution.excess_blob_gas != 0:
@ -826,7 +822,7 @@ func is_valid_light_client_header*(
if epoch < cfg.CAPELLA_FORK_EPOCH: if epoch < cfg.CAPELLA_FORK_EPOCH:
return return
header.execution == static(default(ExecutionPayloadHeader)) and header.execution == static(default(electra.ExecutionPayloadHeader)) and
header.execution_branch == static(default(ExecutionBranch)) header.execution_branch == static(default(ExecutionBranch))
is_valid_normalized_merkle_branch( is_valid_normalized_merkle_branch(
@ -835,7 +831,7 @@ func is_valid_light_client_header*(
execution_payload_gindex_at_epoch(epoch, cfg), execution_payload_gindex_at_epoch(epoch, cfg),
header.beacon.body_root) header.beacon.body_root)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/light-client/fork.md#upgrading-light-client-data # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/light-client/fork.md#upgrading-light-client-data
func upgrade_lc_header_to_electra*( func upgrade_lc_header_to_electra*(
pre: deneb.LightClientHeader): LightClientHeader = pre: deneb.LightClientHeader): LightClientHeader =
LightClientHeader( LightClientHeader(
@ -857,10 +853,7 @@ func upgrade_lc_header_to_electra*(
transactions_root: pre.execution.transactions_root, transactions_root: pre.execution.transactions_root,
withdrawals_root: pre.execution.withdrawals_root, withdrawals_root: pre.execution.withdrawals_root,
blob_gas_used: pre.execution.blob_gas_used, blob_gas_used: pre.execution.blob_gas_used,
excess_blob_gas: pre.execution.excess_blob_gas, excess_blob_gas: pre.execution.excess_blob_gas),
deposit_requests_root: ZERO_HASH, # [New in Electra:EIP6110]
withdrawal_requests_root: ZERO_HASH, # [New in Electra:EIP7002:EIP7251]
consolidation_requests_root: ZERO_HASH), # [New in Electra:EIP7251]
execution_branch: normalize_merkle_branch( execution_branch: normalize_merkle_branch(
pre.execution_branch, EXECUTION_PAYLOAD_GINDEX_ELECTRA)) pre.execution_branch, EXECUTION_PAYLOAD_GINDEX_ELECTRA))

View File

@ -75,7 +75,7 @@ type
current_justified_checkpoint*: Checkpoint current_justified_checkpoint*: Checkpoint
finalized_checkpoint*: Checkpoint finalized_checkpoint*: Checkpoint
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#get_total_balance # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_total_balance
TotalBalances* = object TotalBalances* = object
# The total effective balance of all active validators during the _current_ # The total effective balance of all active validators during the _current_
# epoch. # epoch.
@ -221,7 +221,7 @@ type
deposits*: List[Deposit, Limit MAX_DEPOSITS] deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS] voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#signedbeaconblock # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#signedbeaconblock
SignedBeaconBlock* = object SignedBeaconBlock* = object
message*: BeaconBlock message*: BeaconBlock
signature*: ValidatorSig signature*: ValidatorSig

View File

@ -18,6 +18,7 @@ const
MAX_ATTESTATION_FIELDS* = 8 MAX_ATTESTATION_FIELDS* = 8
MAX_INDEXED_ATTESTATION_FIELDS* = 8 MAX_INDEXED_ATTESTATION_FIELDS* = 8
MAX_EXECUTION_PAYLOAD_FIELDS* = 64 MAX_EXECUTION_PAYLOAD_FIELDS* = 64
MAX_EXECUTION_REQUESTS_FIELDS* = 16
MAX_BEACON_BLOCK_BODY_FIELDS* = 64 MAX_BEACON_BLOCK_BODY_FIELDS* = 64
MAX_BEACON_STATE_FIELDS* = 128 MAX_BEACON_STATE_FIELDS* = 128
@ -66,13 +67,6 @@ type
withdrawals*: Opt[List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]] withdrawals*: Opt[List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]]
blob_gas_used*: Opt[uint64] blob_gas_used*: Opt[uint64]
excess_blob_gas*: Opt[uint64] excess_blob_gas*: Opt[uint64]
deposit_requests*:
Opt[List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD]]
withdrawal_requests*:
Opt[List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD]]
consolidation_requests*:
Opt[List[ConsolidationRequest,
Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD]]
StableExecutionPayloadHeader* {. StableExecutionPayloadHeader* {.
sszStableContainer: MAX_EXECUTION_PAYLOAD_FIELDS.} = object sszStableContainer: MAX_EXECUTION_PAYLOAD_FIELDS.} = object
@ -97,9 +91,18 @@ type
withdrawals_root*: Opt[Eth2Digest] withdrawals_root*: Opt[Eth2Digest]
blob_gas_used*: Opt[uint64] blob_gas_used*: Opt[uint64]
excess_blob_gas*: Opt[uint64] excess_blob_gas*: Opt[uint64]
deposit_requests_root*: Opt[Eth2Digest]
withdrawal_requests_root*: Opt[Eth2Digest] StableExecutionRequests* {.
consolidation_requests_root*: Opt[Eth2Digest] sszStableContainer: MAX_EXECUTION_REQUESTS_FIELDS.} = object
deposits*:
Opt[List[DepositRequest,
Limit MAX_DEPOSIT_REQUESTS_PER_PAYLOAD]]
withdrawals*:
Opt[List[WithdrawalRequest,
Limit MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD]]
consolidations*:
Opt[List[ConsolidationRequest,
Limit MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD]]
StableBeaconBlockBody* {. StableBeaconBlockBody* {.
sszStableContainer: MAX_BEACON_BLOCK_BODY_FIELDS.} = object sszStableContainer: MAX_BEACON_BLOCK_BODY_FIELDS.} = object
@ -125,6 +128,7 @@ type
execution_payload*: Opt[StableExecutionPayload] execution_payload*: Opt[StableExecutionPayload]
bls_to_execution_changes*: Opt[SignedBLSToExecutionChangeList] bls_to_execution_changes*: Opt[SignedBLSToExecutionChangeList]
blob_kzg_commitments*: Opt[KzgCommitments] blob_kzg_commitments*: Opt[KzgCommitments]
execution_requests*: Opt[StableExecutionRequests]
StableBeaconState* {.sszStableContainer: MAX_BEACON_STATE_FIELDS.} = object StableBeaconState* {.sszStableContainer: MAX_BEACON_STATE_FIELDS.} = object
# Versioning # Versioning

View File

@ -0,0 +1,182 @@
# beacon_chain
# Copyright (c) 2018-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
# Uncategorized helper functions from the spec
import
std/algorithm,
results,
eth/p2p/discoveryv5/[node],
./[helpers, digest],
./datatypes/[eip7594]
func sortedColumnIndices*(columnsPerSubnet: ColumnIndex,
subnetIds: HashSet[uint64]):
seq[ColumnIndex] =
var res: seq[ColumnIndex] = @[]
for i in 0'u64 ..< columnsPerSubnet:
for subnetId in subnetIds:
let index = DATA_COLUMN_SIDECAR_SUBNET_COUNT * i + subnetId
res.add(ColumnIndex(index))
res.sort
res
func sortedColumnIndexList*(columnsPerSubnet: ColumnIndex,
subnetIds: HashSet[uint64]):
List[ColumnIndex, NUMBER_OF_COLUMNS] =
var
res: seq[ColumnIndex]
for i in 0'u64 ..< columnsPerSubnet:
for subnetId in subnetIds:
let index = DATA_COLUMN_SIDECAR_SUBNET_COUNT * i + subnetId
res.add(ColumnIndex(index))
res.sort()
List[ColumnIndex, NUMBER_OF_COLUMNS].init(res)
func get_custody_column_subnets*(node_id: NodeId,
custody_subnet_count: uint64):
HashSet[uint64] =
# Decouples the custody subnet computation part from
# `get_custody_columns`, in order to later use this subnet list
# in order to maintain subscription to specific column subnets.
var
subnet_ids: HashSet[uint64]
current_id = node_id
while subnet_ids.lenu64 < custody_subnet_count:
var
hashed_bytes: array[8, byte]
let
current_id_bytes = current_id.toBytesLE()
hashed_current_id = eth2digest(current_id_bytes)
hashed_bytes[0..7] = hashed_current_id.data.toOpenArray(0,7)
let subnet_id = bytes_to_uint64(hashed_bytes) mod
DATA_COLUMN_SIDECAR_SUBNET_COUNT
subnet_ids.incl(subnet_id)
if current_id == UInt256.high.NodeId:
# Overflow prevention
current_id = NodeId(StUint[256].zero)
current_id += NodeId(StUint[256].one)
subnet_ids
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#get_custody_columns
func get_custody_columns*(node_id: NodeId,
custody_subnet_count: uint64):
seq[ColumnIndex] =
let
subnet_ids =
get_custody_column_subnets(node_id, custody_subnet_count)
const
columns_per_subnet =
NUMBER_OF_COLUMNS div DATA_COLUMN_SIDECAR_SUBNET_COUNT
sortedColumnIndices(ColumnIndex(columns_per_subnet), subnet_ids)
func get_custody_column_list*(node_id: NodeId,
custody_subnet_count: uint64):
List[ColumnIndex, NUMBER_OF_COLUMNS] =
# Not in spec in the exact format, but it is useful in sorting custody columns
# before sending, data_column_sidecars_by_range requests
let
subnet_ids =
get_custody_column_subnets(node_id, custody_subnet_count)
const
columns_per_subnet =
NUMBER_OF_COLUMNS div DATA_COLUMN_SIDECAR_SUBNET_COUNT
sortedColumnIndexList(ColumnIndex(columns_per_subnet), subnet_ids)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#compute_matrix
proc compute_matrix*(blobs: seq[KzgBlob]): Result[seq[MatrixEntry], cstring] =
## `compute_matrix` helper demonstrates the relationship
## between blobs and the `MatrixEntries`
var extended_matrix: seq[MatrixEntry]
for blbIdx, blob in blobs.pairs:
let cellsAndProofs = computeCellsAndKzgProofs(blob)
if cellsAndProofs.isErr:
return err("Computing Extended Matrix: Issue computing cells and proofs")
for i in 0..<eip7594.CELLS_PER_EXT_BLOB:
extended_matrix.add(MatrixEntry(
cell: cellsAndProofs.get.cells[i],
kzg_proof: cellsAndProofs.get.proofs[i],
row_index: blbIdx.uint64,
column_index: i.uint64
))
ok(extended_matrix)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#recover_matrix
proc recover_matrix*(partial_matrix: seq[MatrixEntry],
blobCount: int):
Result[seq[MatrixEntry], cstring] =
## This helper demonstrates how to apply recover_cells_and_kzg_proofs
## The data structure for storing cells is implementation-dependent
var extended_matrix: seq[MatrixEntry]
for blob_index in 0..<blobCount:
var
cell_indices: seq[CellIndex]
cells: seq[Cell]
for e in partial_matrix:
if e.row_index == uint64(blob_index):
cell_indices.add(e.column_index)
cells.add(e.cell)
let recoveredCellsAndKzgProofs =
recoverCellsAndKzgProofs(cell_indices, cells)
if recoveredCellsAndKzgProofs.isErr:
return err("Issue in recovering cells and proofs")
for i in 0..<recoveredCellsAndKzgProofs.get.cells.len:
let
cell = recoveredCellsAndKzgProofs.get.cells[i]
proof = recoveredCellsAndKzgProofs.get.proofs[i]
extended_matrix.add(MatrixEntry(
cell: cell,
kzg_proof: proof,
row_index: blob_index.uint64,
column_index: i.uint64
))
ok(extended_matrix)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/_features/eip7594/peer-sampling.md#get_extended_sample_count
func get_extended_sample_count*(samples_per_slot: int,
allowed_failures: int):
int =
## `get_extended_sample_count` computes the number of samples we
## should query from peers, given the SAMPLES_PER_SLOT and
## the number of allowed failures
# If 50% of the columns are missing, we are able to reconstruct the data
# If 50% + 1 columns are missing, we cannot reconstruct the data
const worstCaseConditionCount = (NUMBER_OF_COLUMNS div 2) + 1
# Compute the false positive threshold
let falsePositiveThreshold =
hypergeom_cdf(0, NUMBER_OF_COLUMNS, worstCaseConditionCount, samples_per_slot)
# Finally, compute the extended sample count
for i in samples_per_slot .. NUMBER_OF_COLUMNS:
if hypergeom_cdf(
allowed_failures,
NUMBER_OF_COLUMNS,
worstCaseConditionCount, i) <= falsePositiveThreshold:
return i
NUMBER_OF_COLUMNS

View File

@ -15,15 +15,11 @@ import results, stew/[assign2, base10, byteutils, endians2], presto/common,
stint, chronicles stint, chronicles
import ".."/[eth2_ssz_serialization, forks, keystore], import ".."/[eth2_ssz_serialization, forks, keystore],
".."/../consensus_object_pools/block_pools_types, ".."/../consensus_object_pools/block_pools_types,
".."/datatypes/[phase0, altair, bellatrix],
".."/mev/[bellatrix_mev, capella_mev], ".."/mev/[bellatrix_mev, capella_mev],
".."/../validators/slashing_protection_common, ".."/../validators/slashing_protection_common,
"."/[rest_types, rest_keymanager_types] "."/[rest_types, rest_keymanager_types]
import nimcrypto/utils as ncrutils import nimcrypto/utils as ncrutils
from ".."/datatypes/capella import SignedBeaconBlock
from ".."/datatypes/deneb import BeaconState
export export
eth2_ssz_serialization, results, peerid, common, serialization, chronicles, eth2_ssz_serialization, results, peerid, common, serialization, chronicles,
json_serialization, net, sets, rest_types, slashing_protection_common, json_serialization, net, sets, rest_types, slashing_protection_common,
@ -71,6 +67,7 @@ RestJson.useDefaultSerializationFor(
EmptyBody, EmptyBody,
Eth1Data, Eth1Data,
EventBeaconBlockObject, EventBeaconBlockObject,
ExecutionRequests,
Fork, Fork,
GetBlockAttestationsResponse, GetBlockAttestationsResponse,
GetBlockHeaderResponse, GetBlockHeaderResponse,
@ -243,6 +240,7 @@ RestJson.useDefaultSerializationFor(
deneb_mev.ExecutionPayloadAndBlobsBundle, deneb_mev.ExecutionPayloadAndBlobsBundle,
deneb_mev.SignedBlindedBeaconBlock, deneb_mev.SignedBlindedBeaconBlock,
deneb_mev.SignedBuilderBid, deneb_mev.SignedBuilderBid,
electra.AggregateAndProof,
electra.Attestation, electra.Attestation,
electra.AttesterSlashing, electra.AttesterSlashing,
electra.BeaconBlock, electra.BeaconBlock,
@ -258,6 +256,7 @@ RestJson.useDefaultSerializationFor(
electra.LightClientHeader, electra.LightClientHeader,
electra.LightClientOptimisticUpdate, electra.LightClientOptimisticUpdate,
electra.LightClientUpdate, electra.LightClientUpdate,
electra.SignedAggregateAndProof,
electra.SignedBeaconBlock, electra.SignedBeaconBlock,
electra.TrustedAttestation, electra.TrustedAttestation,
electra_mev.BlindedBeaconBlock, electra_mev.BlindedBeaconBlock,
@ -310,7 +309,7 @@ template writeValue*(w: JsonWriter[RestJson], value: tuple) =
## TODO nim-json-serializations should allow setting up this policy per format ## TODO nim-json-serializations should allow setting up this policy per format
## ##
## This also means that when new fields are introduced to the object definitions ## This also means that when new fields are introduced to the object definitions
## below, one must use the `Option[T]` type. ## below, one must use the `Opt[T]` type.
const const
DecimalSet = {'0' .. '9'} DecimalSet = {'0' .. '9'}
@ -678,24 +677,28 @@ proc jsonResponseWOpt*(t: typedesc[RestApiResponse], data: auto,
default default
RestApiResponse.response(res, Http200, "application/json") RestApiResponse.response(res, Http200, "application/json")
proc prepareJsonResponseFinalized*(
t: typedesc[RestApiResponse], data: auto, exec: Opt[bool],
finalized: bool
): seq[byte] =
try:
var
stream = memoryOutput()
writer = JsonWriter[RestJson].init(stream)
writer.beginRecord()
if exec.isSome():
writer.writeField("execution_optimistic", exec.get())
writer.writeField("finalized", finalized)
writer.writeField("data", data)
writer.endRecord()
stream.getOutput(seq[byte])
except IOError:
default(seq[byte])
proc jsonResponseFinalized*(t: typedesc[RestApiResponse], data: auto, proc jsonResponseFinalized*(t: typedesc[RestApiResponse], data: auto,
exec: Opt[bool], exec: Opt[bool],
finalized: bool): RestApiResponse = finalized: bool): RestApiResponse =
let res = let res = RestApiResponse.prepareJsonResponseFinalized(data, exec, finalized)
block:
var default: seq[byte]
try:
var stream = memoryOutput()
var writer = JsonWriter[RestJson].init(stream)
writer.beginRecord()
if exec.isSome():
writer.writeField("execution_optimistic", exec.get())
writer.writeField("finalized", finalized)
writer.writeField("data", data)
writer.endRecord()
stream.getOutput(seq[byte])
except IOError:
default
RestApiResponse.response(res, Http200, "application/json") RestApiResponse.response(res, Http200, "application/json")
proc jsonResponseWVersion*(t: typedesc[RestApiResponse], data: auto, proc jsonResponseWVersion*(t: typedesc[RestApiResponse], data: auto,
@ -978,6 +981,29 @@ proc readValue*(reader: var JsonReader[RestJson], value: var uint64) {.
else: else:
reader.raiseUnexpectedValue($res.error() & ": " & svalue) reader.raiseUnexpectedValue($res.error() & ": " & svalue)
## RestReward
proc writeValue*(
w: var JsonWriter[RestJson], value: RestReward) {.raises: [IOError].} =
writeValue(w, $int64(value))
proc readValue*(reader: var JsonReader[RestJson], value: var RestReward) {.
raises: [IOError, SerializationError].} =
let svalue = reader.readValue(string)
if svalue.startsWith("-"):
let res =
Base10.decode(uint64, svalue.toOpenArray(1, len(svalue) - 1)).valueOr:
reader.raiseUnexpectedValue($error & ": " & svalue)
if res > uint64(high(int64)):
reader.raiseUnexpectedValue("Integer value overflow " & svalue)
value = RestReward(-int64(res))
else:
let res =
Base10.decode(uint64, svalue).valueOr:
reader.raiseUnexpectedValue($error & ": " & svalue)
if res > uint64(high(int64)):
reader.raiseUnexpectedValue("Integer value overflow " & svalue)
value = RestReward(int64(res))
## uint8 ## uint8
proc writeValue*( proc writeValue*(
w: var JsonWriter[RestJson], value: uint8) {.raises: [IOError].} = w: var JsonWriter[RestJson], value: uint8) {.raises: [IOError].} =
@ -1398,12 +1424,12 @@ proc readValue*(
raiseUnexpectedValue( raiseUnexpectedValue(
reader, "Expected a valid hex string with " & $value.len() & " bytes") reader, "Expected a valid hex string with " & $value.len() & " bytes")
template unrecognizedFieldWarning = template unrecognizedFieldWarning(fieldNameParam, typeNameParam: string) =
# TODO: There should be a different notification mechanism for informing the # TODO: There should be a different notification mechanism for informing the
# caller of a deserialization routine for unexpected fields. # caller of a deserialization routine for unexpected fields.
# The chonicles import in this module should be removed. # The chonicles import in this module should be removed.
trace "JSON field not recognized by the current version of Nimbus. Consider upgrading", trace "JSON field not recognized by the current version of Nimbus. Consider upgrading",
fieldName, typeName = typetraits.name(typeof value) fieldName = fieldNameParam, typeName = typeNameParam
template unrecognizedFieldIgnore = template unrecognizedFieldIgnore =
discard readValue(reader, JsonString) discard readValue(reader, JsonString)
@ -1434,7 +1460,7 @@ template prepareForkedBlockReading(blockType: typedesc,
"Multiple '" & fieldName & "' fields found", blockType.name) "Multiple '" & fieldName & "' fields found", blockType.name)
data = Opt.some(reader.readValue(JsonString)) data = Opt.some(reader.readValue(JsonString))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, blockType.name)
of "block_header", "block": of "block_header", "block":
when (blockType is Web3SignerForkedBeaconBlock): when (blockType is Web3SignerForkedBeaconBlock):
if data.isSome(): if data.isSome():
@ -1442,7 +1468,7 @@ template prepareForkedBlockReading(blockType: typedesc,
"Multiple '" & fieldName & "' fields found", blockType.name) "Multiple '" & fieldName & "' fields found", blockType.name)
data = Opt.some(reader.readValue(JsonString)) data = Opt.some(reader.readValue(JsonString))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, blockType.name)
of "execution_payload_blinded": of "execution_payload_blinded":
when (blockType is ProduceBlockResponseV3): when (blockType is ProduceBlockResponseV3):
if blinded.isSome(): if blinded.isSome():
@ -1450,7 +1476,7 @@ template prepareForkedBlockReading(blockType: typedesc,
"Multiple `execution_payload_blinded` fields found", blockType.name) "Multiple `execution_payload_blinded` fields found", blockType.name)
blinded = Opt.some(reader.readValue(bool)) blinded = Opt.some(reader.readValue(bool))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, blockType.name)
of "execution_payload_value": of "execution_payload_value":
when (blockType is ProduceBlockResponseV3): when (blockType is ProduceBlockResponseV3):
if payloadValue.isSome(): if payloadValue.isSome():
@ -1458,7 +1484,7 @@ template prepareForkedBlockReading(blockType: typedesc,
"Multiple `execution_payload_value` fields found", blockType.name) "Multiple `execution_payload_value` fields found", blockType.name)
payloadValue = Opt.some(reader.readValue(Uint256)) payloadValue = Opt.some(reader.readValue(Uint256))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, blockType.name)
of "consensus_block_value": of "consensus_block_value":
when (blockType is ProduceBlockResponseV3): when (blockType is ProduceBlockResponseV3):
if blockValue.isSome(): if blockValue.isSome():
@ -1466,9 +1492,9 @@ template prepareForkedBlockReading(blockType: typedesc,
"Multiple `consensus_block_value` fields found", blockType.name) "Multiple `consensus_block_value` fields found", blockType.name)
blockValue = Opt.some(reader.readValue(Uint256)) blockValue = Opt.some(reader.readValue(Uint256))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, blockType.name)
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, blockType.name)
if version.isNone(): if version.isNone():
reader.raiseUnexpectedValue("Field `version` is missing") reader.raiseUnexpectedValue("Field `version` is missing")
@ -1515,20 +1541,8 @@ proc readValue*[BlockType: ForkedBlindedBeaconBlock](
exc.formatMsg("BlindedBlock") & "]") exc.formatMsg("BlindedBlock") & "]")
value = ForkedBlindedBeaconBlock(kind: ConsensusFork.Altair, value = ForkedBlindedBeaconBlock(kind: ConsensusFork.Altair,
altairData: res) altairData: res)
of ConsensusFork.Bellatrix: of ConsensusFork.Bellatrix .. ConsensusFork.Capella:
reader.raiseUnexpectedValue("Bellatrix blinded block format unsupported") reader.raiseUnexpectedValue("pre-Deneb blinded block formats unsupported")
of ConsensusFork.Capella:
let res =
try:
RestJson.decode(string(data.get()),
capella_mev.BlindedBeaconBlock,
requireAllFields = true,
allowUnknownFields = true)
except SerializationError as exc:
reader.raiseUnexpectedValue("Incorrect capella block format, [" &
exc.formatMsg("BlindedBlock") & "]")
value = ForkedBlindedBeaconBlock(kind: ConsensusFork.Capella,
capellaData: res)
of ConsensusFork.Deneb: of ConsensusFork.Deneb:
let res = let res =
try: try:
@ -1591,34 +1605,6 @@ proc writeValue*[BlockType: Web3SignerForkedBeaconBlock](
writer.writeField("block_header", value.data) writer.writeField("block_header", value.data)
writer.endRecord() writer.endRecord()
proc writeValue*[BlockType: ForkedBeaconBlock](
writer: var JsonWriter[RestJson], value: BlockType) {.raises: [IOError].} =
template forkIdentifier(id: string): auto =
when BlockType is ForkedBeaconBlock:
id
else:
(static toUpperAscii id)
writer.beginRecord()
case value.kind
of ConsensusFork.Phase0:
writer.writeField("version", forkIdentifier "phase0")
writer.writeField("data", value.phase0Data)
of ConsensusFork.Altair:
writer.writeField("version", forkIdentifier "altair")
writer.writeField("data", value.altairData)
of ConsensusFork.Bellatrix:
writer.writeField("version", forkIdentifier "bellatrix")
writer.writeField("data", value.bellatrixData)
of ConsensusFork.Capella:
writer.writeField("version", forkIdentifier "capella")
writer.writeField("data", value.capellaData)
of ConsensusFork.Deneb:
writer.writeField("version", forkIdentifier "deneb")
writer.writeField("data", value.denebData)
writer.endRecord()
## RestPublishedBeaconBlockBody ## RestPublishedBeaconBlockBody
proc readValue*(reader: var JsonReader[RestJson], proc readValue*(reader: var JsonReader[RestJson],
value: var RestPublishedBeaconBlockBody) {. value: var RestPublishedBeaconBlockBody) {.
@ -1710,7 +1696,7 @@ proc readValue*(reader: var JsonReader[RestJson],
"RestPublishedBeaconBlockBody") "RestPublishedBeaconBlockBody")
blob_kzg_commitments = Opt.some(reader.readValue(KzgCommitments)) blob_kzg_commitments = Opt.some(reader.readValue(KzgCommitments))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if randao_reveal.isNone(): if randao_reveal.isNone():
reader.raiseUnexpectedValue("Field `randao_reveal` is missing") reader.raiseUnexpectedValue("Field `randao_reveal` is missing")
@ -1925,7 +1911,7 @@ proc readValue*(reader: var JsonReader[RestJson],
"RestPublishedBeaconBlock") "RestPublishedBeaconBlock")
blockBody = Opt.some(reader.readValue(RestPublishedBeaconBlockBody)) blockBody = Opt.some(reader.readValue(RestPublishedBeaconBlockBody))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if slot.isNone(): if slot.isNone():
reader.raiseUnexpectedValue("Field `slot` is missing") reader.raiseUnexpectedValue("Field `slot` is missing")
@ -2022,7 +2008,7 @@ proc readValue*(reader: var JsonReader[RestJson],
"RestPublishedSignedBeaconBlock") "RestPublishedSignedBeaconBlock")
signature = Opt.some(reader.readValue(ValidatorSig)) signature = Opt.some(reader.readValue(ValidatorSig))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if signature.isNone(): if signature.isNone():
reader.raiseUnexpectedValue("Field `signature` is missing") reader.raiseUnexpectedValue("Field `signature` is missing")
@ -2099,7 +2085,7 @@ proc readValue*(reader: var JsonReader[RestJson],
"RestPublishedSignedBlockContents") "RestPublishedSignedBlockContents")
blobs = Opt.some(reader.readValue(deneb.Blobs)) blobs = Opt.some(reader.readValue(deneb.Blobs))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if signed_message.isSome(): if signed_message.isSome():
if message.isSome(): if message.isSome():
@ -2160,6 +2146,7 @@ proc readValue*(reader: var JsonReader[RestJson],
reader.raiseUnexpectedField("Multiple version fields found", reader.raiseUnexpectedField("Multiple version fields found",
"ForkedSignedBeaconBlock") "ForkedSignedBeaconBlock")
let vres = reader.readValue(string) let vres = reader.readValue(string)
static: doAssert ConsensusFork.high == ConsensusFork.Electra
case vres case vres
of "phase0": of "phase0":
version = Opt.some(ConsensusFork.Phase0) version = Opt.some(ConsensusFork.Phase0)
@ -2171,6 +2158,8 @@ proc readValue*(reader: var JsonReader[RestJson],
version = Opt.some(ConsensusFork.Capella) version = Opt.some(ConsensusFork.Capella)
of "deneb": of "deneb":
version = Opt.some(ConsensusFork.Deneb) version = Opt.some(ConsensusFork.Deneb)
of "electra":
version = Opt.some(ConsensusFork.Electra)
else: else:
reader.raiseUnexpectedValue("Incorrect version field value") reader.raiseUnexpectedValue("Incorrect version field value")
of "data": of "data":
@ -2179,7 +2168,7 @@ proc readValue*(reader: var JsonReader[RestJson],
"ForkedSignedBeaconBlock") "ForkedSignedBeaconBlock")
data = Opt.some(reader.readValue(JsonString)) data = Opt.some(reader.readValue(JsonString))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if version.isNone(): if version.isNone():
reader.raiseUnexpectedValue("Field version is missing") reader.raiseUnexpectedValue("Field version is missing")
@ -2311,7 +2300,7 @@ proc readValue*(reader: var JsonReader[RestJson],
"ForkedBeaconState") "ForkedBeaconState")
data = Opt.some(reader.readValue(JsonString)) data = Opt.some(reader.readValue(JsonString))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if version.isNone(): if version.isNone():
reader.raiseUnexpectedValue("Field version is missing") reader.raiseUnexpectedValue("Field version is missing")
@ -2441,7 +2430,7 @@ proc readValue*[T: SomeForkedLightClientObject](
reader.raiseUnexpectedField("Multiple data fields found", T.name) reader.raiseUnexpectedField("Multiple data fields found", T.name)
data.ok reader.readValue(JsonString) data.ok reader.readValue(JsonString)
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if version.isNone: if version.isNone:
reader.raiseUnexpectedValue("Field version is missing") reader.raiseUnexpectedValue("Field version is missing")
@ -2631,7 +2620,7 @@ proc readValue*(reader: var JsonReader[RestJson],
data = Opt.some(reader.readValue(JsonString)) data = Opt.some(reader.readValue(JsonString))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if requestKind.isNone(): if requestKind.isNone():
reader.raiseUnexpectedValue("Field `type` is missing") reader.raiseUnexpectedValue("Field `type` is missing")
@ -2876,7 +2865,7 @@ proc readValue*(reader: var JsonReader[RestJson],
reader.raiseUnexpectedValue("Invalid `status` value") reader.raiseUnexpectedValue("Invalid `status` value")
) )
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if status.isNone(): if status.isNone():
reader.raiseUnexpectedValue("Field `status` is missing") reader.raiseUnexpectedValue("Field `status` is missing")
@ -2933,7 +2922,7 @@ proc readValue*(reader: var JsonReader[RestJson], value: var Pbkdf2Params) {.
"Pbkdf2Params") "Pbkdf2Params")
salt = Opt.some(reader.readValue(Pbkdf2Salt)) salt = Opt.some(reader.readValue(Pbkdf2Salt))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if dklen.isNone(): if dklen.isNone():
reader.raiseUnexpectedValue("Field `dklen` is missing") reader.raiseUnexpectedValue("Field `dklen` is missing")
@ -3007,7 +2996,7 @@ proc readValue*(reader: var JsonReader[RestJson], value: var ScryptParams) {.
"ScryptParams") "ScryptParams")
salt = Opt.some(reader.readValue(ScryptSalt)) salt = Opt.some(reader.readValue(ScryptSalt))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if dklen.isNone(): if dklen.isNone():
reader.raiseUnexpectedValue("Field `dklen` is missing") reader.raiseUnexpectedValue("Field `dklen` is missing")
@ -3076,7 +3065,7 @@ proc readValue*(reader: var JsonReader[RestJson],
"KeystoresAndSlashingProtection") "KeystoresAndSlashingProtection")
strSlashing = Opt.some(reader.readValue(string)) strSlashing = Opt.some(reader.readValue(string))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
if len(strKeystores) == 0: if len(strKeystores) == 0:
reader.raiseUnexpectedValue("Missing or empty `keystores` value") reader.raiseUnexpectedValue("Missing or empty `keystores` value")
@ -3907,10 +3896,10 @@ proc decodeBytes*[T: DecodeTypes](
else: else:
err("Content-Type not supported") err("Content-Type not supported")
proc encodeString*(value: string): RestResult[string] = func encodeString*(value: string): RestResult[string] =
ok(value) ok(value)
proc encodeString*( func encodeString*(
value: value:
uint64 | uint64 |
SyncCommitteePeriod | SyncCommitteePeriod |
@ -3920,26 +3909,26 @@ proc encodeString*(
SyncSubcommitteeIndex): RestResult[string] = SyncSubcommitteeIndex): RestResult[string] =
ok(Base10.toString(uint64(value))) ok(Base10.toString(uint64(value)))
proc encodeString*(value: ValidatorSig): RestResult[string] = func encodeString*(value: ValidatorSig): RestResult[string] =
ok(hexOriginal(toRaw(value))) ok(hexOriginal(toRaw(value)))
proc encodeString*(value: GraffitiBytes): RestResult[string] = func encodeString*(value: GraffitiBytes): RestResult[string] =
ok(hexOriginal(distinctBase(value))) ok(hexOriginal(distinctBase(value)))
proc encodeString*(value: Eth2Digest): RestResult[string] = func encodeString*(value: Eth2Digest): RestResult[string] =
ok(hexOriginal(value.data)) ok(hexOriginal(value.data))
proc encodeString*(value: ValidatorIdent): RestResult[string] = func encodeString*(value: ValidatorIdent): RestResult[string] =
case value.kind case value.kind
of ValidatorQueryKind.Index: of ValidatorQueryKind.Index:
ok(Base10.toString(uint64(value.index))) ok(Base10.toString(uint64(value.index)))
of ValidatorQueryKind.Key: of ValidatorQueryKind.Key:
ok(hexOriginal(toRaw(value.key))) ok(hexOriginal(toRaw(value.key)))
proc encodeString*(value: ValidatorPubKey): RestResult[string] = func encodeString*(value: ValidatorPubKey): RestResult[string] =
ok(hexOriginal(toRaw(value))) ok(hexOriginal(toRaw(value)))
proc encodeString*(value: StateIdent): RestResult[string] = func encodeString*(value: StateIdent): RestResult[string] =
case value.kind case value.kind
of StateQueryKind.Slot: of StateQueryKind.Slot:
ok(Base10.toString(uint64(value.slot))) ok(Base10.toString(uint64(value.slot)))
@ -3956,7 +3945,7 @@ proc encodeString*(value: StateIdent): RestResult[string] =
of StateIdentType.Justified: of StateIdentType.Justified:
ok("justified") ok("justified")
proc encodeString*(value: BroadcastValidationType): RestResult[string] = func encodeString*(value: BroadcastValidationType): RestResult[string] =
case value case value
of BroadcastValidationType.Gossip: of BroadcastValidationType.Gossip:
ok("gossip") ok("gossip")
@ -3965,7 +3954,7 @@ proc encodeString*(value: BroadcastValidationType): RestResult[string] =
of BroadcastValidationType.ConsensusAndEquivocation: of BroadcastValidationType.ConsensusAndEquivocation:
ok("consensus_and_equivocation") ok("consensus_and_equivocation")
proc encodeString*(value: BlockIdent): RestResult[string] = func encodeString*(value: BlockIdent): RestResult[string] =
case value.kind case value.kind
of BlockQueryKind.Slot: of BlockQueryKind.Slot:
ok(Base10.toString(uint64(value.slot))) ok(Base10.toString(uint64(value.slot)))
@ -3980,7 +3969,7 @@ proc encodeString*(value: BlockIdent): RestResult[string] =
of BlockIdentType.Finalized: of BlockIdentType.Finalized:
ok("finalized") ok("finalized")
proc decodeString*(t: typedesc[PeerStateKind], func decodeString*(t: typedesc[PeerStateKind],
value: string): Result[PeerStateKind, cstring] = value: string): Result[PeerStateKind, cstring] =
case value case value
of "disconnected": of "disconnected":
@ -3992,9 +3981,9 @@ proc decodeString*(t: typedesc[PeerStateKind],
of "disconnecting": of "disconnecting":
ok(PeerStateKind.Disconnecting) ok(PeerStateKind.Disconnecting)
else: else:
err("Incorrect peer's state value") err("Incorrect peer state value")
proc encodeString*(value: PeerStateKind): Result[string, cstring] = func encodeString*(value: PeerStateKind): Result[string, cstring] =
case value case value
of PeerStateKind.Disconnected: of PeerStateKind.Disconnected:
ok("disconnected") ok("disconnected")
@ -4005,7 +3994,7 @@ proc encodeString*(value: PeerStateKind): Result[string, cstring] =
of PeerStateKind.Disconnecting: of PeerStateKind.Disconnecting:
ok("disconnecting") ok("disconnecting")
proc decodeString*(t: typedesc[PeerDirectKind], func decodeString*(t: typedesc[PeerDirectKind],
value: string): Result[PeerDirectKind, cstring] = value: string): Result[PeerDirectKind, cstring] =
case value case value
of "inbound": of "inbound":
@ -4013,19 +4002,19 @@ proc decodeString*(t: typedesc[PeerDirectKind],
of "outbound": of "outbound":
ok(PeerDirectKind.Outbound) ok(PeerDirectKind.Outbound)
else: else:
err("Incorrect peer's direction value") err("Incorrect peer direction value")
proc encodeString*(value: PeerDirectKind): Result[string, cstring] = func encodeString*(value: PeerDirectKind): Result[string, cstring] =
case value case value
of PeerDirectKind.Inbound: of PeerDirectKind.Inbound:
ok("inbound") ok("inbound")
of PeerDirectKind.Outbound: of PeerDirectKind.Outbound:
ok("outbound") ok("outbound")
proc encodeString*(peerid: PeerId): Result[string, cstring] = func encodeString*(peerid: PeerId): Result[string, cstring] =
ok($peerid) ok($peerid)
proc decodeString*(t: typedesc[EventTopic], func decodeString*(t: typedesc[EventTopic],
value: string): Result[EventTopic, cstring] = value: string): Result[EventTopic, cstring] =
case value case value
of "head": of "head":
@ -4057,7 +4046,7 @@ proc decodeString*(t: typedesc[EventTopic],
else: else:
err("Incorrect event's topic value") err("Incorrect event's topic value")
proc encodeString*(value: set[EventTopic]): Result[string, cstring] = func encodeString*(value: set[EventTopic]): Result[string, cstring] =
var res: string var res: string
if EventTopic.Head in value: if EventTopic.Head in value:
res.add("head,") res.add("head,")
@ -4090,7 +4079,7 @@ proc encodeString*(value: set[EventTopic]): Result[string, cstring] =
res.setLen(len(res) - 1) res.setLen(len(res) - 1)
ok(res) ok(res)
proc toList*(value: set[ValidatorFilterKind]): seq[string] = func toList*(value: set[ValidatorFilterKind]): seq[string] =
const const
pendingSet = {ValidatorFilterKind.PendingInitialized, pendingSet = {ValidatorFilterKind.PendingInitialized,
ValidatorFilterKind.PendingQueued} ValidatorFilterKind.PendingQueued}
@ -4129,7 +4118,7 @@ proc toList*(value: set[ValidatorFilterKind]): seq[string] =
processSingle(ValidatorFilterKind.WithdrawalDone, "withdrawal_done") processSingle(ValidatorFilterKind.WithdrawalDone, "withdrawal_done")
res res
proc decodeString*(t: typedesc[ValidatorSig], func decodeString*(t: typedesc[ValidatorSig],
value: string): Result[ValidatorSig, cstring] = value: string): Result[ValidatorSig, cstring] =
if len(value) != ValidatorSigSize + 2: if len(value) != ValidatorSigSize + 2:
return err("Incorrect validator signature value length") return err("Incorrect validator signature value length")
@ -4137,7 +4126,7 @@ proc decodeString*(t: typedesc[ValidatorSig],
return err("Incorrect validator signature encoding") return err("Incorrect validator signature encoding")
ValidatorSig.fromHex(value) ValidatorSig.fromHex(value)
proc decodeString*(t: typedesc[ValidatorPubKey], func decodeString*(t: typedesc[ValidatorPubKey],
value: string): Result[ValidatorPubKey, cstring] = value: string): Result[ValidatorPubKey, cstring] =
if len(value) != ValidatorKeySize + 2: if len(value) != ValidatorKeySize + 2:
return err("Incorrect validator's key value length") return err("Incorrect validator's key value length")
@ -4146,35 +4135,35 @@ proc decodeString*(t: typedesc[ValidatorPubKey],
else: else:
ValidatorPubKey.fromHex(value) ValidatorPubKey.fromHex(value)
proc decodeString*(t: typedesc[GraffitiBytes], func decodeString*(t: typedesc[GraffitiBytes],
value: string): Result[GraffitiBytes, cstring] = value: string): Result[GraffitiBytes, cstring] =
try: try:
ok(GraffitiBytes.init(value)) ok(GraffitiBytes.init(value))
except ValueError: except ValueError:
err("Unable to decode graffiti value") err("Unable to decode graffiti value")
proc decodeString*(t: typedesc[string], func decodeString*(t: typedesc[string],
value: string): Result[string, cstring] = value: string): Result[string, cstring] =
ok(value) ok(value)
proc decodeString*(t: typedesc[Slot], value: string): Result[Slot, cstring] = func decodeString*(t: typedesc[Slot], value: string): Result[Slot, cstring] =
let res = ? Base10.decode(uint64, value) let res = ? Base10.decode(uint64, value)
ok(Slot(res)) ok(Slot(res))
proc decodeString*(t: typedesc[Epoch], value: string): Result[Epoch, cstring] = func decodeString*(t: typedesc[Epoch], value: string): Result[Epoch, cstring] =
let res = ? Base10.decode(uint64, value) let res = ? Base10.decode(uint64, value)
ok(Epoch(res)) ok(Epoch(res))
proc decodeString*(t: typedesc[SyncCommitteePeriod], func decodeString*(t: typedesc[SyncCommitteePeriod],
value: string): Result[SyncCommitteePeriod, cstring] = value: string): Result[SyncCommitteePeriod, cstring] =
let res = ? Base10.decode(uint64, value) let res = ? Base10.decode(uint64, value)
ok(SyncCommitteePeriod(res)) ok(SyncCommitteePeriod(res))
proc decodeString*(t: typedesc[uint64], func decodeString*(t: typedesc[uint64],
value: string): Result[uint64, cstring] = value: string): Result[uint64, cstring] =
Base10.decode(uint64, value) Base10.decode(uint64, value)
proc decodeString*(t: typedesc[StateIdent], func decodeString*(t: typedesc[StateIdent],
value: string): Result[StateIdent, cstring] = value: string): Result[StateIdent, cstring] =
if len(value) > 2: if len(value) > 2:
if (value[0] == '0') and (value[1] == 'x'): if (value[0] == '0') and (value[1] == 'x'):
@ -4206,7 +4195,7 @@ proc decodeString*(t: typedesc[StateIdent],
let res = ? Base10.decode(uint64, value) let res = ? Base10.decode(uint64, value)
ok(StateIdent(kind: StateQueryKind.Slot, slot: Slot(res))) ok(StateIdent(kind: StateQueryKind.Slot, slot: Slot(res)))
proc decodeString*(t: typedesc[BlockIdent], func decodeString*(t: typedesc[BlockIdent],
value: string): Result[BlockIdent, cstring] = value: string): Result[BlockIdent, cstring] =
if len(value) > 2: if len(value) > 2:
if (value[0] == '0') and (value[1] == 'x'): if (value[0] == '0') and (value[1] == 'x'):
@ -4235,7 +4224,7 @@ proc decodeString*(t: typedesc[BlockIdent],
let res = ? Base10.decode(uint64, value) let res = ? Base10.decode(uint64, value)
ok(BlockIdent(kind: BlockQueryKind.Slot, slot: Slot(res))) ok(BlockIdent(kind: BlockQueryKind.Slot, slot: Slot(res)))
proc decodeString*(t: typedesc[BroadcastValidationType], func decodeString*(t: typedesc[BroadcastValidationType],
value: string): Result[BroadcastValidationType, cstring] = value: string): Result[BroadcastValidationType, cstring] =
case value case value
of "gossip": of "gossip":
@ -4247,7 +4236,7 @@ proc decodeString*(t: typedesc[BroadcastValidationType],
else: else:
err("Incorrect broadcast validation type value") err("Incorrect broadcast validation type value")
proc decodeString*(t: typedesc[ValidatorIdent], func decodeString*(t: typedesc[ValidatorIdent],
value: string): Result[ValidatorIdent, cstring] = value: string): Result[ValidatorIdent, cstring] =
if len(value) > 2: if len(value) > 2:
if (value[0] == '0') and (value[1] == 'x'): if (value[0] == '0') and (value[1] == 'x'):
@ -4268,21 +4257,21 @@ proc decodeString*(t: typedesc[ValidatorIdent],
ok(ValidatorIdent(kind: ValidatorQueryKind.Index, ok(ValidatorIdent(kind: ValidatorQueryKind.Index,
index: RestValidatorIndex(res))) index: RestValidatorIndex(res)))
proc decodeString*(t: typedesc[PeerId], func decodeString*(t: typedesc[PeerId],
value: string): Result[PeerId, cstring] = value: string): Result[PeerId, cstring] =
PeerId.init(value) PeerId.init(value)
proc decodeString*(t: typedesc[CommitteeIndex], func decodeString*(t: typedesc[CommitteeIndex],
value: string): Result[CommitteeIndex, cstring] = value: string): Result[CommitteeIndex, cstring] =
let res = ? Base10.decode(uint64, value) let res = ? Base10.decode(uint64, value)
CommitteeIndex.init(res) CommitteeIndex.init(res)
proc decodeString*(t: typedesc[SyncSubcommitteeIndex], func decodeString*(t: typedesc[SyncSubcommitteeIndex],
value: string): Result[SyncSubcommitteeIndex, cstring] = value: string): Result[SyncSubcommitteeIndex, cstring] =
let res = ? Base10.decode(uint64, value) let res = ? Base10.decode(uint64, value)
SyncSubcommitteeIndex.init(res) SyncSubcommitteeIndex.init(res)
proc decodeString*(t: typedesc[Eth2Digest], func decodeString*(t: typedesc[Eth2Digest],
value: string): Result[Eth2Digest, cstring] = value: string): Result[Eth2Digest, cstring] =
if len(value) != RootHashSize + 2: if len(value) != RootHashSize + 2:
return err("Incorrect root value length") return err("Incorrect root value length")
@ -4290,7 +4279,7 @@ proc decodeString*(t: typedesc[Eth2Digest],
return err("Incorrect root value encoding") return err("Incorrect root value encoding")
parseRoot(value) parseRoot(value)
proc decodeString*(t: typedesc[ValidatorFilter], func decodeString*(t: typedesc[ValidatorFilter],
value: string): Result[ValidatorFilter, cstring] = value: string): Result[ValidatorFilter, cstring] =
case value case value
of "pending_initialized": of "pending_initialized":
@ -4335,14 +4324,16 @@ proc decodeString*(t: typedesc[ValidatorFilter],
else: else:
err("Incorrect validator state identifier value") err("Incorrect validator state identifier value")
proc decodeString*(t: typedesc[ConsensusFork], func decodeString*(t: typedesc[ConsensusFork],
value: string): Result[ConsensusFork, cstring] = value: string): Result[ConsensusFork, cstring] =
static: doAssert ConsensusFork.high == ConsensusFork.Electra
case toLowerAscii(value) case toLowerAscii(value)
of "phase0": ok(ConsensusFork.Phase0) of "phase0": ok(ConsensusFork.Phase0)
of "altair": ok(ConsensusFork.Altair) of "altair": ok(ConsensusFork.Altair)
of "bellatrix": ok(ConsensusFork.Bellatrix) of "bellatrix": ok(ConsensusFork.Bellatrix)
of "capella": ok(ConsensusFork.Capella) of "capella": ok(ConsensusFork.Capella)
of "deneb": ok(ConsensusFork.Deneb) of "deneb": ok(ConsensusFork.Deneb)
of "electra": ok(ConsensusFork.Electra)
else: err("Unsupported or invalid beacon block fork version") else: err("Unsupported or invalid beacon block fork version")
proc decodeString*(t: typedesc[EventBeaconBlockObject], proc decodeString*(t: typedesc[EventBeaconBlockObject],
@ -4386,7 +4377,7 @@ proc readValue*(reader: var JsonReader[RestJson],
"RestValidatorRequest") "RestValidatorRequest")
statuses = Opt.some(reader.readValue(seq[string])) statuses = Opt.some(reader.readValue(seq[string]))
else: else:
unrecognizedFieldWarning() unrecognizedFieldWarning(fieldName, typeof(value).name)
let let
validatorIds = validatorIds =
@ -4432,3 +4423,11 @@ proc writeValue*(writer: var JsonWriter[RestJson],
if len(res) > 0: if len(res) > 0:
writer.writeField("statuses", res) writer.writeField("statuses", res)
writer.endRecord() writer.endRecord()
## RestSyncCommitteeReward
proc writeValue*(writer: var JsonWriter[RestJson],
value: RestSyncCommitteeReward) {.raises: [IOError].} =
writer.beginRecord()
writer.writeField("validator_index", value.validator_index)
writer.writeField("reward", value.reward)
writer.endRecord()

View File

@ -527,9 +527,16 @@ type
subcommittee_index*: uint64 subcommittee_index*: uint64
selection_proof*: ValidatorSig selection_proof*: ValidatorSig
RestReward* = distinct int64
RestSyncCommitteeReward* = object
validator_index*: RestValidatorIndex
reward*: RestReward
# Types based on the OAPI yaml file - used in responses to requests # Types based on the OAPI yaml file - used in responses to requests
GetBeaconHeadResponse* = DataEnclosedObject[Slot] GetBeaconHeadResponse* = DataEnclosedObject[Slot]
GetAggregatedAttestationResponse* = DataEnclosedObject[phase0.Attestation] GetAggregatedAttestationResponse* = DataEnclosedObject[phase0.Attestation]
GetElectraAggregatedAttestationResponse* = DataEnclosedObject[electra.Attestation]
GetAttesterDutiesResponse* = DataRootEnclosedObject[seq[RestAttesterDuty]] GetAttesterDutiesResponse* = DataRootEnclosedObject[seq[RestAttesterDuty]]
GetBlockAttestationsResponse* = DataEnclosedObject[seq[phase0.Attestation]] GetBlockAttestationsResponse* = DataEnclosedObject[seq[phase0.Attestation]]
GetBlockHeaderResponse* = DataOptimisticAndFinalizedObject[RestBlockHeaderInfo] GetBlockHeaderResponse* = DataOptimisticAndFinalizedObject[RestBlockHeaderInfo]

View File

@ -71,6 +71,15 @@ proc getAggregatedAttestationPlain*(
meth: MethodGet.} meth: MethodGet.}
## https://ethereum.github.io/beacon-APIs/#/Validator/getAggregatedAttestation ## https://ethereum.github.io/beacon-APIs/#/Validator/getAggregatedAttestation
proc getAggregatedAttestationPlainV2*(
attestation_data_root: Eth2Digest,
slot: Slot,
committee_index: CommitteeIndex
): RestPlainResponse {.
rest, endpoint: "/eth/v2/validator/aggregate_attestation"
meth: MethodGet.}
## https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getPoolAttestationsV2
proc publishAggregateAndProofs*( proc publishAggregateAndProofs*(
body: seq[phase0.SignedAggregateAndProof] body: seq[phase0.SignedAggregateAndProof]
): RestPlainResponse {. ): RestPlainResponse {.
@ -78,6 +87,13 @@ proc publishAggregateAndProofs*(
meth: MethodPost.} meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/#/Validator/publishAggregateAndProofs ## https://ethereum.github.io/beacon-APIs/#/Validator/publishAggregateAndProofs
proc publishAggregateAndProofsV2*(
body: seq[phase0.SignedAggregateAndProof | electra.SignedAggregateAndProof]
): RestPlainResponse {.
rest, endpoint: "/eth/v2/validator/aggregate_and_proofs",
meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Validator/publishAggregateAndProofsV2
proc prepareBeaconCommitteeSubnet*( proc prepareBeaconCommitteeSubnet*(
body: seq[RestCommitteeSubscription] body: seq[RestCommitteeSubscription]
): RestPlainResponse {. ): RestPlainResponse {.

View File

@ -1231,11 +1231,7 @@ func toElectraLightClientHeader(
transactions_root: hash_tree_root(payload.transactions), transactions_root: hash_tree_root(payload.transactions),
withdrawals_root: hash_tree_root(payload.withdrawals), withdrawals_root: hash_tree_root(payload.withdrawals),
blob_gas_used: payload.blob_gas_used, blob_gas_used: payload.blob_gas_used,
excess_blob_gas: payload.excess_blob_gas, excess_blob_gas: payload.excess_blob_gas),
deposit_requests_root: hash_tree_root(payload.deposit_requests),
withdrawal_requests_root: hash_tree_root(payload.withdrawal_requests),
consolidation_requests_root:
hash_tree_root(payload.consolidation_requests)),
execution_branch: execution_branch:
blck.message.body.build_proof(EXECUTION_PAYLOAD_GINDEX_ELECTRA).get) blck.message.body.build_proof(EXECUTION_PAYLOAD_GINDEX_ELECTRA).get)

View File

@ -25,7 +25,7 @@ import
export export
eth2_merkleization, forks, rlp, ssz_codec eth2_merkleization, forks, rlp, ssz_codec
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/weak-subjectivity.md#constants # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/weak-subjectivity.md#constants
const ETH_TO_GWEI = 1_000_000_000.Gwei const ETH_TO_GWEI = 1_000_000_000.Gwei
func toEther*(gwei: Gwei): Ether = func toEther*(gwei: Gwei): Ether =
@ -162,7 +162,7 @@ func compute_domain*(
result[0..3] = domain_type.data result[0..3] = domain_type.data
result[4..31] = fork_data_root.data.toOpenArray(0, 27) result[4..31] = fork_data_root.data.toOpenArray(0, 27)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#get_domain # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_domain
func get_domain*( func get_domain*(
fork: Fork, fork: Fork,
domain_type: DomainType, domain_type: DomainType,
@ -192,7 +192,7 @@ func compute_signing_root*(ssz_object: auto, domain: Eth2Domain): Eth2Digest =
) )
hash_tree_root(domain_wrapped_object) hash_tree_root(domain_wrapped_object)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#get_seed # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_seed
func get_seed*( func get_seed*(
state: ForkyBeaconState, epoch: Epoch, domain_type: DomainType, state: ForkyBeaconState, epoch: Epoch, domain_type: DomainType,
mix: Eth2Digest): Eth2Digest = mix: Eth2Digest): Eth2Digest =
@ -211,7 +211,7 @@ func get_seed*(state: ForkyBeaconState, epoch: Epoch, domain_type: DomainType):
epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD - 1) epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD - 1)
state.get_seed(epoch, domain_type, mix) state.get_seed(epoch, domain_type, mix)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#add_flag # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#add_flag
func add_flag*(flags: ParticipationFlags, flag_index: TimelyFlag): ParticipationFlags = func add_flag*(flags: ParticipationFlags, flag_index: TimelyFlag): ParticipationFlags =
let flag = ParticipationFlags(1'u8 shl ord(flag_index)) let flag = ParticipationFlags(1'u8 shl ord(flag_index))
flags or flag flags or flag
@ -221,7 +221,7 @@ func has_flag*(flags: ParticipationFlags, flag_index: TimelyFlag): bool =
let flag = ParticipationFlags(1'u8 shl ord(flag_index)) let flag = ParticipationFlags(1'u8 shl ord(flag_index))
(flags and flag) == flag (flags and flag) == flag
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/deneb/p2p-interface.md#check_blob_sidecar_inclusion_proof # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/deneb/p2p-interface.md#verify_blob_sidecar_inclusion_proof
func verify_blob_sidecar_inclusion_proof*( func verify_blob_sidecar_inclusion_proof*(
blob_sidecar: ForkyBlobSidecar): Result[void, string] = blob_sidecar: ForkyBlobSidecar): Result[void, string] =
let gindex = withBlobFork(typeof(blob_sidecar).kind): let gindex = withBlobFork(typeof(blob_sidecar).kind):
@ -272,7 +272,7 @@ template is_sync_committee_update*(update: SomeForkyLightClientUpdate): bool =
else: else:
false false
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#is_finality_update # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/sync-protocol.md#is_finality_update
template is_finality_update*(update: SomeForkyLightClientUpdate): bool = template is_finality_update*(update: SomeForkyLightClientUpdate): bool =
when update is SomeForkyLightClientUpdateWithFinality: when update is SomeForkyLightClientUpdateWithFinality:
update.finality_branch != update.finality_branch !=
@ -393,7 +393,7 @@ func contextEpoch*(bootstrap: ForkyLightClientBootstrap): Epoch =
func contextEpoch*(update: SomeForkyLightClientUpdate): Epoch = func contextEpoch*(update: SomeForkyLightClientUpdate): Epoch =
update.attested_header.beacon.slot.epoch update.attested_header.beacon.slot.epoch
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#is_merge_transition_complete # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#is_merge_transition_complete
func is_merge_transition_complete*( func is_merge_transition_complete*(
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState |
electra.BeaconState): bool = electra.BeaconState): bool =
@ -401,7 +401,7 @@ func is_merge_transition_complete*(
default(typeof(state.latest_execution_payload_header)) default(typeof(state.latest_execution_payload_header))
state.latest_execution_payload_header != defaultExecutionPayloadHeader state.latest_execution_payload_header != defaultExecutionPayloadHeader
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/sync/optimistic.md#helpers # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/sync/optimistic.md#helpers
func is_execution_block*(blck: SomeForkyBeaconBlock): bool = func is_execution_block*(blck: SomeForkyBeaconBlock): bool =
when typeof(blck).kind >= ConsensusFork.Bellatrix: when typeof(blck).kind >= ConsensusFork.Bellatrix:
const defaultExecutionPayload = const defaultExecutionPayload =
@ -410,7 +410,7 @@ func is_execution_block*(blck: SomeForkyBeaconBlock): bool =
else: else:
false false
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#is_merge_transition_block # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#is_merge_transition_block
func is_merge_transition_block( func is_merge_transition_block(
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState |
electra.BeaconState, electra.BeaconState,
@ -426,7 +426,7 @@ func is_merge_transition_block(
not is_merge_transition_complete(state) and not is_merge_transition_complete(state) and
body.execution_payload != defaultExecutionPayload body.execution_payload != defaultExecutionPayload
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#is_execution_enabled # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#is_execution_enabled
func is_execution_enabled*( func is_execution_enabled*(
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState |
electra.BeaconState, electra.BeaconState,
@ -440,7 +440,7 @@ func is_execution_enabled*(
electra.SigVerifiedBeaconBlockBody): bool = electra.SigVerifiedBeaconBlockBody): bool =
is_merge_transition_block(state, body) or is_merge_transition_complete(state) is_merge_transition_block(state, body) or is_merge_transition_complete(state)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot
func compute_timestamp_at_slot*(state: ForkyBeaconState, slot: Slot): uint64 = func compute_timestamp_at_slot*(state: ForkyBeaconState, slot: Slot): uint64 =
# Note: This function is unsafe with respect to overflows and underflows. # Note: This function is unsafe with respect to overflows and underflows.
let slots_since_genesis = slot - GENESIS_SLOT let slots_since_genesis = slot - GENESIS_SLOT
@ -507,11 +507,11 @@ func toExecutionConsolidationRequest*(
targetPubkey: request.target_pubkey.blob) targetPubkey: request.target_pubkey.blob)
# https://eips.ethereum.org/EIPS/eip-7685 # https://eips.ethereum.org/EIPS/eip-7685
proc computeRequestsTrieRoot*( proc computeRequestsTrieRoot(
payload: electra.ExecutionPayload): ExecutionHash256 = requests: electra.ExecutionRequests): ExecutionHash256 =
if payload.deposit_requests.len == 0 and if requests.deposits.len == 0 and
payload.withdrawal_requests.len == 0 and requests.withdrawals.len == 0 and
payload.consolidation_requests.len == 0: requests.consolidations.len == 0:
return EMPTY_ROOT_HASH return EMPTY_ROOT_HASH
var var
@ -523,7 +523,7 @@ proc computeRequestsTrieRoot*(
doAssert WITHDRAWAL_REQUEST_TYPE < CONSOLIDATION_REQUEST_TYPE doAssert WITHDRAWAL_REQUEST_TYPE < CONSOLIDATION_REQUEST_TYPE
# EIP-6110 # EIP-6110
for request in payload.deposit_requests: for request in requests.deposits:
try: try:
tr.put(rlp.encode(i.uint), rlp.encode( tr.put(rlp.encode(i.uint), rlp.encode(
toExecutionDepositRequest(request))) toExecutionDepositRequest(request)))
@ -532,7 +532,7 @@ proc computeRequestsTrieRoot*(
inc i inc i
# EIP-7002 # EIP-7002
for request in payload.withdrawal_requests: for request in requests.withdrawals:
try: try:
tr.put(rlp.encode(i.uint), rlp.encode( tr.put(rlp.encode(i.uint), rlp.encode(
toExecutionWithdrawalRequest(request))) toExecutionWithdrawalRequest(request)))
@ -541,7 +541,7 @@ proc computeRequestsTrieRoot*(
inc i inc i
# EIP-7251 # EIP-7251
for request in payload.consolidation_requests: for request in requests.consolidations:
try: try:
tr.put(rlp.encode(i.uint), rlp.encode( tr.put(rlp.encode(i.uint), rlp.encode(
toExecutionConsolidationRequest(request))) toExecutionConsolidationRequest(request)))
@ -582,7 +582,7 @@ proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader =
Opt.none(ExecutionHash256) Opt.none(ExecutionHash256)
requestsRoot = requestsRoot =
when typeof(payload).kind >= ConsensusFork.Electra: when typeof(payload).kind >= ConsensusFork.Electra:
Opt.some payload.computeRequestsTrieRoot() Opt.some blck.body.execution_requests.computeRequestsTrieRoot()
else: else:
Opt.none(ExecutionHash256) Opt.none(ExecutionHash256)

View File

@ -14,13 +14,8 @@ import
func readExecutionTransaction( func readExecutionTransaction(
txBytes: bellatrix.Transaction): Result[ExecutionTransaction, string] = txBytes: bellatrix.Transaction): Result[ExecutionTransaction, string] =
# Nim 2.0.8: `rlp.decode(distinctBase(txBytes), ExecutionTransaction)`
# uses the generic `read` from `rlp.nim` instead of the specific `read`
# from `eth_types_rlp.nim`, leading to compilation error.
# Doing this in two steps works around this resolution order issue.
var rlp = rlpFromBytes(distinctBase(txBytes))
try: try:
ok rlp.read(ExecutionTransaction) ok rlp.decode(distinctBase(txBytes), ExecutionTransaction)
except RlpError as exc: except RlpError as exc:
err("Invalid transaction: " & exc.msg) err("Invalid transaction: " & exc.msg)

View File

@ -1380,13 +1380,13 @@ proc createWallet*(kdfKind: KdfKind,
crypto: crypto, crypto: crypto,
nextAccount: nextAccount.get(0)) nextAccount: nextAccount.get(0))
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/validator.md#bls_withdrawal_prefix # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#bls_withdrawal_prefix
func makeWithdrawalCredentials*(k: ValidatorPubKey): Eth2Digest = func makeWithdrawalCredentials*(k: ValidatorPubKey): Eth2Digest =
var bytes = eth2digest(k.toRaw()) var bytes = eth2digest(k.toRaw())
bytes.data[0] = BLS_WITHDRAWAL_PREFIX.uint8 bytes.data[0] = BLS_WITHDRAWAL_PREFIX.uint8
bytes bytes
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/deposit-contract.md#withdrawal-credentials # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/deposit-contract.md#withdrawal-credentials
func makeWithdrawalCredentials*(k: CookedPubKey): Eth2Digest = func makeWithdrawalCredentials*(k: CookedPubKey): Eth2Digest =
makeWithdrawalCredentials(k.toPubKey()) makeWithdrawalCredentials(k.toPubKey())

View File

@ -196,7 +196,7 @@ func apply_light_client_update(
didProgress = true didProgress = true
didProgress didProgress
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/sync-protocol.md#process_light_client_store_force_update # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/sync-protocol.md#process_light_client_store_force_update
type type
ForceUpdateResult* = enum ForceUpdateResult* = enum
NoUpdate, NoUpdate,

View File

@ -166,7 +166,9 @@ func toSignedBlindedBeaconBlock*(blck: deneb.SignedBeaconBlock):
transactions_root: transactions_root:
hash_tree_root(blck.message.body.execution_payload.transactions), hash_tree_root(blck.message.body.execution_payload.transactions),
withdrawals_root: withdrawals_root:
hash_tree_root(blck.message.body.execution_payload.withdrawals)), hash_tree_root(blck.message.body.execution_payload.withdrawals),
blob_gas_used: blck.message.body.execution_payload.blob_gas_used,
excess_blob_gas: blck.message.body.execution_payload.excess_blob_gas),
bls_to_execution_changes: blck.message.body.bls_to_execution_changes, bls_to_execution_changes: blck.message.body.bls_to_execution_changes,
blob_kzg_commitments: blck.message.body.blob_kzg_commitments)), blob_kzg_commitments: blck.message.body.blob_kzg_commitments)),
signature: blck.signature) signature: blck.signature)

View File

@ -46,6 +46,7 @@ type
List[SignedBLSToExecutionChange, List[SignedBLSToExecutionChange,
Limit MAX_BLS_TO_EXECUTION_CHANGES] Limit MAX_BLS_TO_EXECUTION_CHANGES]
blob_kzg_commitments*: KzgCommitments # [New in Deneb] blob_kzg_commitments*: KzgCommitments # [New in Deneb]
execution_requests*: ExecutionRequests # [New in Electra]
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#blindedbeaconblock # https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#blindedbeaconblock
BlindedBeaconBlock* = object BlindedBeaconBlock* = object
@ -143,12 +144,9 @@ func toSignedBlindedBeaconBlock*(blck: electra.SignedBeaconBlock):
hash_tree_root(blck.message.body.execution_payload.transactions), hash_tree_root(blck.message.body.execution_payload.transactions),
withdrawals_root: withdrawals_root:
hash_tree_root(blck.message.body.execution_payload.withdrawals), hash_tree_root(blck.message.body.execution_payload.withdrawals),
deposit_requests_root: hash_tree_root( blob_gas_used: blck.message.body.execution_payload.blob_gas_used,
blck.message.body.execution_payload.deposit_requests), excess_blob_gas: blck.message.body.execution_payload.excess_blob_gas),
withdrawal_requests_root: hash_tree_root(
blck.message.body.execution_payload.withdrawal_requests),
consolidation_requests_root: hash_tree_root(
blck.message.body.execution_payload.consolidation_requests)),
bls_to_execution_changes: blck.message.body.bls_to_execution_changes, bls_to_execution_changes: blck.message.body.bls_to_execution_changes,
blob_kzg_commitments: blck.message.body.blob_kzg_commitments)), blob_kzg_commitments: blck.message.body.blob_kzg_commitments,
execution_requests: blck.message.body.execution_requests)),
signature: blck.signature) signature: blck.signature)

View File

@ -35,3 +35,4 @@ type
execution_payload_header*: Opt[StableExecutionPayloadHeader] execution_payload_header*: Opt[StableExecutionPayloadHeader]
bls_to_execution_changes*: Opt[SignedBLSToExecutionChangeList] bls_to_execution_changes*: Opt[SignedBLSToExecutionChangeList]
blob_kzg_commitments*: Opt[KzgCommitments] blob_kzg_commitments*: Opt[KzgCommitments]
execution_requests*: Opt[StableExecutionRequests]

View File

@ -14,8 +14,8 @@ import
export base export base
const const
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/p2p-interface.md#topics-and-messages # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#topics-and-messages
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/p2p-interface.md#topics-and-messages # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/p2p-interface.md#topics-and-messages
topicBeaconBlocksSuffix* = "beacon_block/ssz_snappy" topicBeaconBlocksSuffix* = "beacon_block/ssz_snappy"
topicVoluntaryExitsSuffix* = "voluntary_exit/ssz_snappy" topicVoluntaryExitsSuffix* = "voluntary_exit/ssz_snappy"
topicProposerSlashingsSuffix* = "proposer_slashing/ssz_snappy" topicProposerSlashingsSuffix* = "proposer_slashing/ssz_snappy"
@ -27,7 +27,7 @@ const
# The spec now includes this as a bare uint64 as `RESP_TIMEOUT` # The spec now includes this as a bare uint64 as `RESP_TIMEOUT`
RESP_TIMEOUT_DUR* = RESP_TIMEOUT.int64.seconds RESP_TIMEOUT_DUR* = RESP_TIMEOUT.int64.seconds
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/p2p-interface.md#configuration # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/p2p-interface.md#configuration
MAX_REQUEST_LIGHT_CLIENT_UPDATES* = 128 MAX_REQUEST_LIGHT_CLIENT_UPDATES* = 128
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#configuration # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#configuration
@ -63,11 +63,11 @@ func getAttesterSlashingsTopic*(forkDigest: ForkDigest): string =
func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string = func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string =
eth2Prefix(forkDigest) & topicAggregateAndProofsSuffix eth2Prefix(forkDigest) & topicAggregateAndProofsSuffix
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/p2p-interface.md#topics-and-messages # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/p2p-interface.md#topics-and-messages
func getBlsToExecutionChangeTopic*(forkDigest: ForkDigest): string = func getBlsToExecutionChangeTopic*(forkDigest: ForkDigest): string =
eth2Prefix(forkDigest) & topicBlsToExecutionChangeSuffix eth2Prefix(forkDigest) & topicBlsToExecutionChangeSuffix
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/validator.md#broadcast-attestation # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#broadcast-attestation
func compute_subnet_for_attestation*( func compute_subnet_for_attestation*(
committees_per_slot: uint64, slot: Slot, committee_index: CommitteeIndex): committees_per_slot: uint64, slot: Slot, committee_index: CommitteeIndex):
SubnetId = SubnetId =
@ -89,7 +89,7 @@ func getAttestationTopic*(forkDigest: ForkDigest,
## For subscribing and unsubscribing to/from a subnet. ## For subscribing and unsubscribing to/from a subnet.
eth2Prefix(forkDigest) & "beacon_attestation_" & $(subnetId) & "/ssz_snappy" eth2Prefix(forkDigest) & "beacon_attestation_" & $(subnetId) & "/ssz_snappy"
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/p2p-interface.md#topics-and-messages # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/p2p-interface.md#topics-and-messages
func getSyncCommitteeTopic*(forkDigest: ForkDigest, func getSyncCommitteeTopic*(forkDigest: ForkDigest,
subcommitteeIdx: SyncSubcommitteeIndex): string = subcommitteeIdx: SyncSubcommitteeIndex): string =
## For subscribing and unsubscribing to/from a subnet. ## For subscribing and unsubscribing to/from a subnet.
@ -197,7 +197,7 @@ func getTargetGossipState*(
targetForks targetForks
func nearSyncCommitteePeriod*(epoch: Epoch): Opt[uint64] = func nearSyncCommitteePeriod*(epoch: Epoch): Opt[uint64] =
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#sync-committee-subnet-stability # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#sync-committee-subnet-stability
if epoch.is_sync_committee_period(): if epoch.is_sync_committee_period():
return Opt.some 0'u64 return Opt.some 0'u64
let epochsBefore = let epochsBefore =
@ -216,7 +216,7 @@ func getSyncSubnets*(
if not nodeHasPubkey(pubkey): if not nodeHasPubkey(pubkey):
continue continue
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#broadcast-sync-committee-message # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#broadcast-sync-committee-message
# The first quarter of the pubkeys map to subnet 0, the second quarter to # The first quarter of the pubkeys map to subnet 0, the second quarter to
# subnet 1, the third quarter to subnet 2 and the final quarter to subnet # subnet 1, the third quarter to subnet 2 and the final quarter to subnet
# 3. # 3.

View File

@ -787,7 +787,7 @@ proc readRuntimeConfig*(
"MAX_REQUEST_BLOB_SIDECARS" "MAX_REQUEST_BLOB_SIDECARS"
checkCompatibility BLOB_SIDECAR_SUBNET_COUNT checkCompatibility BLOB_SIDECAR_SUBNET_COUNT
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/fork-choice.md#configuration # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/fork-choice.md#configuration
# Isn't being used as a preset in the usual way: at any time, there's one correct value # Isn't being used as a preset in the usual way: at any time, there's one correct value
checkCompatibility PROPOSER_SCORE_BOOST checkCompatibility PROPOSER_SCORE_BOOST
checkCompatibility REORG_HEAD_WEIGHT_THRESHOLD checkCompatibility REORG_HEAD_WEIGHT_THRESHOLD

View File

@ -8,7 +8,7 @@
{.push raises: [].} {.push raises: [].}
# Gnosis preset - Electra (Gnosis version not avilable yet; EF mainnet for now) # Gnosis preset - Electra (Gnosis version not avilable yet; EF mainnet for now)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/mainnet/electra.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/mainnet/electra.yaml
const const
# Gwei values # Gwei values
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -8,7 +8,7 @@
{.push raises: [].} {.push raises: [].}
# Mainnet preset - Altair # Mainnet preset - Altair
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/mainnet/altair.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/mainnet/altair.yaml
const const
# Updated penalty values # Updated penalty values
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -8,7 +8,7 @@
{.push raises: [].} {.push raises: [].}
# Mainnet preset - Bellatrix # Mainnet preset - Bellatrix
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/mainnet/bellatrix.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/mainnet/bellatrix.yaml
const const
# Updated penalty values # Updated penalty values
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -8,7 +8,7 @@
{.push raises: [].} {.push raises: [].}
# Mainnet preset - Capella # Mainnet preset - Capella
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/mainnet/capella.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/mainnet/capella.yaml
const const
# Max operations per block # Max operations per block
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -8,7 +8,7 @@
{.push raises: [].} {.push raises: [].}
# Electra preset - Electra # Electra preset - Electra
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/mainnet/electra.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/mainnet/electra.yaml
const const
# Gwei values # Gwei values
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -8,7 +8,7 @@
{.push raises: [].} {.push raises: [].}
# Minimal preset - Altair # Minimal preset - Altair
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/minimal/altair.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/minimal/altair.yaml
const const
# Updated penalty values # Updated penalty values
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -8,7 +8,7 @@
{.push raises: [].} {.push raises: [].}
# Minimal preset - Bellatrix # Minimal preset - Bellatrix
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/minimal/bellatrix.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/minimal/bellatrix.yaml
const const
# Updated penalty values # Updated penalty values
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -8,7 +8,7 @@
{.push raises: [].} {.push raises: [].}
# Minimal preset - Capella # Minimal preset - Capella
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/presets/minimal/capella.yaml # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/presets/minimal/capella.yaml
const const
# Max operations per block # Max operations per block
# --------------------------------------------------------------- # ---------------------------------------------------------------

View File

@ -143,7 +143,7 @@ func compute_attestation_signing_root*(
fork, DOMAIN_BEACON_ATTESTER, epoch, genesis_validators_root) fork, DOMAIN_BEACON_ATTESTER, epoch, genesis_validators_root)
compute_signing_root(attestation_data, domain) compute_signing_root(attestation_data, domain)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/validator.md#aggregate-signature # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#aggregate-signature
func get_attestation_signature*( func get_attestation_signature*(
fork: Fork, genesis_validators_root: Eth2Digest, fork: Fork, genesis_validators_root: Eth2Digest,
attestation_data: AttestationData, attestation_data: AttestationData,
@ -269,7 +269,7 @@ proc verify_voluntary_exit_signature*(
blsVerify(pubkey, signing_root.data, signature) blsVerify(pubkey, signing_root.data, signature)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#prepare-sync-committee-message # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#prepare-sync-committee-message
func compute_sync_committee_message_signing_root*( func compute_sync_committee_message_signing_root*(
fork: Fork, genesis_validators_root: Eth2Digest, fork: Fork, genesis_validators_root: Eth2Digest,
slot: Slot, beacon_block_root: Eth2Digest): Eth2Digest = slot: Slot, beacon_block_root: Eth2Digest): Eth2Digest =
@ -304,7 +304,7 @@ proc verify_sync_committee_signature*(
blsFastAggregateVerify(pubkeys, signing_root.data, signature) blsFastAggregateVerify(pubkeys, signing_root.data, signature)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#aggregation-selection # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#aggregation-selection
func compute_sync_committee_selection_proof_signing_root*( func compute_sync_committee_selection_proof_signing_root*(
fork: Fork, genesis_validators_root: Eth2Digest, fork: Fork, genesis_validators_root: Eth2Digest,
slot: Slot, subcommittee_index: SyncSubcommitteeIndex): Eth2Digest = slot: Slot, subcommittee_index: SyncSubcommitteeIndex): Eth2Digest =
@ -335,7 +335,7 @@ proc verify_sync_committee_selection_proof*(
blsVerify(pubkey, signing_root.data, signature) blsVerify(pubkey, signing_root.data, signature)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#signature # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#signature
func compute_contribution_and_proof_signing_root*( func compute_contribution_and_proof_signing_root*(
fork: Fork, genesis_validators_root: Eth2Digest, fork: Fork, genesis_validators_root: Eth2Digest,
msg: ContributionAndProof): Eth2Digest = msg: ContributionAndProof): Eth2Digest =
@ -353,7 +353,7 @@ proc get_contribution_and_proof_signature*(
blsSign(privkey, signing_root.data) blsSign(privkey, signing_root.data)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#aggregation-selection # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#aggregation-selection
func is_sync_committee_aggregator*(signature: ValidatorSig): bool = func is_sync_committee_aggregator*(signature: ValidatorSig): bool =
let let
signatureDigest = eth2digest(signature.blob) signatureDigest = eth2digest(signature.blob)

View File

@ -83,7 +83,7 @@ func aggregateAttesters(
# Aggregation spec requires non-empty collection # Aggregation spec requires non-empty collection
# - https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04 # - https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04
# Consensus specs require at least one attesting index in attestation # Consensus specs require at least one attesting index in attestation
# - https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#is_valid_indexed_attestation # - https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#is_valid_indexed_attestation
return err("aggregateAttesters: no attesting indices") return err("aggregateAttesters: no attesting indices")
let let

View File

@ -365,7 +365,7 @@ func partialBeaconBlock*(
): auto = ): auto =
const consensusFork = typeof(state).kind const consensusFork = typeof(state).kind
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/validator.md#preparing-for-a-beaconblock # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#preparing-for-a-beaconblock
var res = consensusFork.BeaconBlock( var res = consensusFork.BeaconBlock(
slot: state.data.slot, slot: state.data.slot,
proposer_index: proposer_index.uint64, proposer_index: proposer_index.uint64,

View File

@ -10,10 +10,10 @@
# State transition - block processing, as described in # State transition - block processing, as described in
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#block-processing
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#block-processing
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#block-processing
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/capella/beacon-chain.md#block-processing
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#block-processing
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.1/specs/electra/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#block-processing
# #
# The entry point is `process_block` which is at the bottom of this file. # The entry point is `process_block` which is at the bottom of this file.
# #
@ -29,7 +29,7 @@ import
../extras, ../extras,
./datatypes/[phase0, altair, bellatrix, deneb], ./datatypes/[phase0, altair, bellatrix, deneb],
"."/[beaconstate, eth2_merkleization, helpers, validator, signatures], "."/[beaconstate, eth2_merkleization, helpers, validator, signatures],
kzg4844/kzg_abi, kzg4844/kzg_ex kzg4844/kzg_abi, kzg4844/kzg
from std/algorithm import fill, sorted from std/algorithm import fill, sorted
from std/sequtils import count, filterIt, mapIt from std/sequtils import count, filterIt, mapIt
@ -82,7 +82,7 @@ func `xor`[T: array](a, b: T): T =
for i in 0..<result.len: for i in 0..<result.len:
result[i] = a[i] xor b[i] result[i] = a[i] xor b[i]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#randao # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#randao
proc process_randao( proc process_randao(
state: var ForkyBeaconState, body: SomeForkyBeaconBlockBody, state: var ForkyBeaconState, body: SomeForkyBeaconBlockBody,
flags: UpdateFlags, cache: var StateCache): Result[void, cstring] = flags: UpdateFlags, cache: var StateCache): Result[void, cstring] =
@ -128,14 +128,14 @@ func process_eth1_data(
state.eth1_data = body.eth1_data state.eth1_data = body.eth1_data
ok() ok()
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#is_slashable_validator # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#is_slashable_validator
func is_slashable_validator(validator: Validator, epoch: Epoch): bool = func is_slashable_validator(validator: Validator, epoch: Epoch): bool =
# Check if ``validator`` is slashable. # Check if ``validator`` is slashable.
(not validator.slashed) and (not validator.slashed) and
(validator.activation_epoch <= epoch) and (validator.activation_epoch <= epoch) and
(epoch < validator.withdrawable_epoch) (epoch < validator.withdrawable_epoch)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#proposer-slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#proposer-slashings
proc check_proposer_slashing*( proc check_proposer_slashing*(
state: ForkyBeaconState, proposer_slashing: SomeProposerSlashing, state: ForkyBeaconState, proposer_slashing: SomeProposerSlashing,
flags: UpdateFlags): flags: UpdateFlags):
@ -249,7 +249,7 @@ proc check_attester_slashing*(
withState(state): withState(state):
check_attester_slashing(forkyState.data, attester_slashing, flags) check_attester_slashing(forkyState.data, attester_slashing, flags)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#attester-slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#attester-slashings
proc process_attester_slashing*( proc process_attester_slashing*(
cfg: RuntimeConfig, cfg: RuntimeConfig,
state: var ForkyBeaconState, state: var ForkyBeaconState,
@ -295,7 +295,6 @@ proc apply_deposit(
when typeof(state).kind < ConsensusFork.Electra: when typeof(state).kind < ConsensusFork.Electra:
increase_balance(state, index.get(), amount) increase_balance(state, index.get(), amount)
else: else:
debugComment "check hashlist add return"
discard state.pending_balance_deposits.add PendingBalanceDeposit( discard state.pending_balance_deposits.add PendingBalanceDeposit(
index: index.get.uint64, amount: amount) # [Modified in Electra:EIP-7251] index: index.get.uint64, amount: amount) # [Modified in Electra:EIP-7251]
@ -332,8 +331,6 @@ proc apply_deposit(
return err("apply_deposit: too many validators (inactivity_scores)") return err("apply_deposit: too many validators (inactivity_scores)")
let new_vidx = state.validators.lenu64 - 1 let new_vidx = state.validators.lenu64 - 1
when typeof(state).kind >= ConsensusFork.Electra: when typeof(state).kind >= ConsensusFork.Electra:
debugComment "check hashlist add return"
# [New in Electra:EIP7251] # [New in Electra:EIP7251]
discard state.pending_balance_deposits.add PendingBalanceDeposit( discard state.pending_balance_deposits.add PendingBalanceDeposit(
index: new_vidx, amount: amount) index: new_vidx, amount: amount)
@ -348,7 +345,7 @@ proc apply_deposit(
ok() ok()
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#deposits # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#deposits
proc process_deposit*( proc process_deposit*(
cfg: RuntimeConfig, state: var ForkyBeaconState, cfg: RuntimeConfig, state: var ForkyBeaconState,
bucketSortedValidators: var BucketSortedValidators, bucketSortedValidators: var BucketSortedValidators,
@ -389,7 +386,7 @@ func process_deposit_request*(
amount: deposit_request.amount, amount: deposit_request.amount,
signature: deposit_request.signature), flags) signature: deposit_request.signature), flags)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#voluntary-exits # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#voluntary-exits
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#modified-process_voluntary_exit # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#modified-process_voluntary_exit
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#updated-process_voluntary_exit # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#updated-process_voluntary_exit
proc check_voluntary_exit*( proc check_voluntary_exit*(
@ -636,7 +633,6 @@ proc process_consolidation_request*(
cfg, state, source_validator[].effective_balance, cache) cfg, state, source_validator[].effective_balance, cache)
source_validator[].withdrawable_epoch = source_validator[].withdrawable_epoch =
source_validator[].exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY source_validator[].exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
debugComment "check HashList add return value"
discard state.pending_consolidations.add(PendingConsolidation( discard state.pending_consolidations.add(PendingConsolidation(
source_index: source_index.uint64, target_index: target_index.uint64)) source_index: source_index.uint64, target_index: target_index.uint64))
@ -648,7 +644,7 @@ type
proposer_slashings*: Gwei proposer_slashings*: Gwei
attester_slashings*: Gwei attester_slashings*: Gwei
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#operations # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#operations
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#modified-process_operations # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#modified-process_operations
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#operations # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/electra/beacon-chain.md#operations
proc process_operations( proc process_operations(
@ -690,9 +686,9 @@ proc process_operations(
default(ExitQueueInfo) # not used default(ExitQueueInfo) # not used
bsv_use = bsv_use =
when typeof(body).kind >= ConsensusFork.Electra: when typeof(body).kind >= ConsensusFork.Electra:
body.deposits.len + body.execution_payload.deposit_requests.len + body.deposits.len + body.execution_requests.deposits.len +
body.execution_payload.withdrawal_requests.len + body.execution_requests.withdrawals.len +
body.execution_payload.consolidation_requests.len > 0 body.execution_requests.consolidations.len > 0
else: else:
body.deposits.len > 0 body.deposits.len > 0
bsv = bsv =
@ -724,12 +720,12 @@ proc process_operations(
? process_bls_to_execution_change(cfg, state, op) ? process_bls_to_execution_change(cfg, state, op)
when typeof(body).kind >= ConsensusFork.Electra: when typeof(body).kind >= ConsensusFork.Electra:
for op in body.execution_payload.deposit_requests: for op in body.execution_requests.deposits:
? process_deposit_request(cfg, state, bsv[], op, {}) ? process_deposit_request(cfg, state, bsv[], op, {})
for op in body.execution_payload.withdrawal_requests: for op in body.execution_requests.withdrawals:
# [New in Electra:EIP7002:7251] # [New in Electra:EIP7002:7251]
process_withdrawal_request(cfg, state, bsv[], op, cache) process_withdrawal_request(cfg, state, bsv[], op, cache)
for op in body.execution_payload.consolidation_requests: for op in body.execution_requests.consolidations:
# [New in Electra:EIP7251] # [New in Electra:EIP7251]
process_consolidation_request(cfg, state, bsv[], op, cache) process_consolidation_request(cfg, state, bsv[], op, cache)
@ -748,11 +744,11 @@ func get_participant_reward*(total_active_balance: Gwei): Gwei =
WEIGHT_DENOMINATOR div SLOTS_PER_EPOCH WEIGHT_DENOMINATOR div SLOTS_PER_EPOCH
max_participant_rewards div SYNC_COMMITTEE_SIZE max_participant_rewards div SYNC_COMMITTEE_SIZE
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#sync-aggregate-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#sync-aggregate-processing
func get_proposer_reward*(participant_reward: Gwei): Gwei = func get_proposer_reward*(participant_reward: Gwei): Gwei =
participant_reward * PROPOSER_WEIGHT div (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT) participant_reward * PROPOSER_WEIGHT div (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#sync-aggregate-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#sync-aggregate-processing
proc process_sync_aggregate*( proc process_sync_aggregate*(
state: var (altair.BeaconState | bellatrix.BeaconState | state: var (altair.BeaconState | bellatrix.BeaconState |
capella.BeaconState | deneb.BeaconState | electra.BeaconState), capella.BeaconState | deneb.BeaconState | electra.BeaconState),
@ -1005,13 +1001,7 @@ proc process_execution_payload*(
transactions_root: hash_tree_root(payload.transactions), transactions_root: hash_tree_root(payload.transactions),
withdrawals_root: hash_tree_root(payload.withdrawals), withdrawals_root: hash_tree_root(payload.withdrawals),
blob_gas_used: payload.blob_gas_used, blob_gas_used: payload.blob_gas_used,
excess_blob_gas: payload.excess_blob_gas, excess_blob_gas: payload.excess_blob_gas)
deposit_requests_root:
hash_tree_root(payload.deposit_requests), # [New in Electra:EIP6110]
withdrawal_requests_root:
hash_tree_root(payload.withdrawal_requests), # [New in Electra:EIP7002:EIP7251]
consolidation_requests_root:
hash_tree_root(payload.consolidation_requests)) # [New in Electra:EIP7251]
ok() ok()
@ -1083,7 +1073,7 @@ func kzg_commitment_to_versioned_hash*(
proc validate_blobs*( proc validate_blobs*(
expected_kzg_commitments: seq[KzgCommitment], blobs: seq[KzgBlob], expected_kzg_commitments: seq[KzgCommitment], blobs: seq[KzgBlob],
proofs: seq[KzgProof]): Result[void, string] = proofs: seq[KzgProof]): Result[void, string] =
let res = verifyProofs(blobs, expected_kzg_commitments, proofs).valueOr: let res = verifyBlobKzgProofBatch(blobs, expected_kzg_commitments, proofs).valueOr:
return err("validate_blobs proof verification error: " & error()) return err("validate_blobs proof verification error: " & error())
if not res: if not res:
@ -1109,7 +1099,7 @@ proc process_block*(
ok(? process_operations(cfg, state, blck.body, 0.Gwei, flags, cache)) ok(? process_operations(cfg, state, blck.body, 0.Gwei, flags, cache))
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#block-processing
# TODO workaround for https://github.com/nim-lang/Nim/issues/18095 # TODO workaround for https://github.com/nim-lang/Nim/issues/18095
# copy of datatypes/altair.nim # copy of datatypes/altair.nim
type SomeAltairBlock = type SomeAltairBlock =
@ -1138,7 +1128,7 @@ proc process_block*(
ok(operations_rewards) ok(operations_rewards)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#block-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#block-processing
# TODO workaround for https://github.com/nim-lang/Nim/issues/18095 # TODO workaround for https://github.com/nim-lang/Nim/issues/18095
type SomeBellatrixBlock = type SomeBellatrixBlock =
bellatrix.BeaconBlock | bellatrix.SigVerifiedBeaconBlock | bellatrix.TrustedBeaconBlock bellatrix.BeaconBlock | bellatrix.SigVerifiedBeaconBlock | bellatrix.TrustedBeaconBlock

View File

@ -8,9 +8,9 @@
{.push raises: [].} {.push raises: [].}
# State transition - epoch processing, as described in # State transition - epoch processing, as described in
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#epoch-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#epoch-processing
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#epoch-processing # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#epoch-processing
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#epoch-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#epoch-processing
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#epoch-processing # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#epoch-processing
# #
# The entry point is `process_epoch`, which is at the bottom of this file. # The entry point is `process_epoch`, which is at the bottom of this file.
@ -40,7 +40,7 @@ export extras, phase0, altair
logScope: topics = "consens" logScope: topics = "consens"
# Accessors that implement the max condition in `get_total_balance`: # Accessors that implement the max condition in `get_total_balance`:
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#get_total_balance # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_total_balance
template current_epoch*(v: TotalBalances): Gwei = template current_epoch*(v: TotalBalances): Gwei =
max(EFFECTIVE_BALANCE_INCREMENT.Gwei, v.current_epoch_raw) max(EFFECTIVE_BALANCE_INCREMENT.Gwei, v.current_epoch_raw)
template previous_epoch*(v: TotalBalances): Gwei = template previous_epoch*(v: TotalBalances): Gwei =
@ -535,7 +535,7 @@ func get_attestation_component_delta(
else: else:
RewardDelta(penalties: base_reward) RewardDelta(penalties: base_reward)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#components-of-attestation-deltas # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#components-of-attestation-deltas
func get_source_delta*( func get_source_delta*(
validator: RewardStatus, validator: RewardStatus,
base_reward: Gwei, base_reward: Gwei,
@ -661,7 +661,7 @@ func get_attestation_deltas(
info.validators[proposer_index].delta.add( info.validators[proposer_index].delta.add(
proposer_delta.get()[1]) proposer_delta.get()[1])
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_base_reward # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#get_base_reward
func get_base_reward_increment*( func get_base_reward_increment*(
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState | state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
deneb.BeaconState | electra.BeaconState, deneb.BeaconState | electra.BeaconState,
@ -694,14 +694,14 @@ func get_unslashed_participating_increment*(
flag_index: TimelyFlag): uint64 = flag_index: TimelyFlag): uint64 =
info.balances.previous_epoch[flag_index] div EFFECTIVE_BALANCE_INCREMENT.Gwei info.balances.previous_epoch[flag_index] div EFFECTIVE_BALANCE_INCREMENT.Gwei
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#get_flag_index_deltas # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#get_flag_index_deltas
func get_active_increments*( func get_active_increments*(
info: altair.EpochInfo | bellatrix.BeaconState): uint64 = info: altair.EpochInfo | bellatrix.BeaconState): uint64 =
info.balances.current_epoch div EFFECTIVE_BALANCE_INCREMENT.Gwei info.balances.current_epoch div EFFECTIVE_BALANCE_INCREMENT.Gwei
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_flag_index_deltas # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_flag_index_deltas
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#modified-get_inactivity_penalty_deltas # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#modified-get_inactivity_penalty_deltas
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#modified-get_inactivity_penalty_deltas # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#modified-get_inactivity_penalty_deltas
# Combines get_flag_index_deltas() and get_inactivity_penalty_deltas() # Combines get_flag_index_deltas() and get_inactivity_penalty_deltas()
template get_flag_and_inactivity_delta( template get_flag_and_inactivity_delta(
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState | state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
@ -843,7 +843,7 @@ func get_flag_and_inactivity_delta_for_validator(
active_increments, penalty_denominator, epoch_participation, active_increments, penalty_denominator, epoch_participation,
participating_increments, info, vidx, inactivity_score.uint64) participating_increments, info, vidx, inactivity_score.uint64)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#rewards-and-penalties-1 # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#rewards-and-penalties-1
func process_rewards_and_penalties*( func process_rewards_and_penalties*(
state: var phase0.BeaconState, info: var phase0.EpochInfo) = state: var phase0.BeaconState, info: var phase0.EpochInfo) =
# No rewards are applied at the end of `GENESIS_EPOCH` because rewards are # No rewards are applied at the end of `GENESIS_EPOCH` because rewards are
@ -866,7 +866,7 @@ func process_rewards_and_penalties*(
decrease_balance(balance, v.delta.penalties) decrease_balance(balance, v.delta.penalties)
state.balances.asSeq()[idx] = balance state.balances.asSeq()[idx] = balance
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#rewards-and-penalties # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#rewards-and-penalties
func process_rewards_and_penalties*( func process_rewards_and_penalties*(
cfg: RuntimeConfig, cfg: RuntimeConfig,
state: var (altair.BeaconState | bellatrix.BeaconState | state: var (altair.BeaconState | bellatrix.BeaconState |
@ -902,7 +902,7 @@ func process_rewards_and_penalties*(
from std/heapqueue import HeapQueue, `[]`, len, push, replace from std/heapqueue import HeapQueue, `[]`, len, push, replace
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#registry-updates # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#registry-updates
func process_registry_updates*( func process_registry_updates*(
cfg: RuntimeConfig, cfg: RuntimeConfig,
state: var (phase0.BeaconState | altair.BeaconState | state: var (phase0.BeaconState | altair.BeaconState |
@ -999,7 +999,7 @@ func process_registry_updates*(
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#slashings
func get_adjusted_total_slashing_balance*( func get_adjusted_total_slashing_balance*(
state: ForkyBeaconState, total_balance: Gwei): Gwei = state: ForkyBeaconState, total_balance: Gwei): Gwei =
const multiplier = const multiplier =
@ -1017,27 +1017,42 @@ func get_adjusted_total_slashing_balance*(
min(sum(state.slashings.data) * multiplier, total_balance) min(sum(state.slashings.data) * multiplier, total_balance)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#modified-process_slashings
func slashing_penalty_applies*(validator: Validator, epoch: Epoch): bool = func slashing_penalty_applies*(validator: Validator, epoch: Epoch): bool =
validator.slashed and validator.slashed and
epoch + EPOCHS_PER_SLASHINGS_VECTOR div 2 == validator.withdrawable_epoch epoch + EPOCHS_PER_SLASHINGS_VECTOR div 2 == validator.withdrawable_epoch
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#slashings
func get_slashing_penalty*(validator: Validator, # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#modified-process_slashings
adjusted_total_slashing_balance, func get_slashing_penalty*(
total_balance: Gwei): Gwei = consensusFork: static ConsensusFork, validator: Validator,
adjusted_total_slashing_balance, total_balance: Gwei): Gwei =
# Factored out from penalty numerator to avoid uint64 overflow # Factored out from penalty numerator to avoid uint64 overflow
const increment = EFFECTIVE_BALANCE_INCREMENT.Gwei const increment = EFFECTIVE_BALANCE_INCREMENT.Gwei
let penalty_numerator = validator.effective_balance div increment *
adjusted_total_slashing_balance when consensusFork <= ConsensusFork.Deneb:
penalty_numerator div total_balance * increment let penalty_numerator = validator.effective_balance div increment *
adjusted_total_slashing_balance
penalty_numerator div total_balance * increment
elif consensusFork == ConsensusFork.Electra:
let
effective_balance_increments = validator.effective_balance div increment
penalty_per_effective_balance_increment =
adjusted_total_slashing_balance div (total_balance div increment)
# [Modified in Electra:EIP7251]
penalty_per_effective_balance_increment * effective_balance_increments
else:
static: doAssert false
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/bellatrix/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/bellatrix/beacon-chain.md#slashings
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/electra/beacon-chain.md#modified-process_slashings
func get_slashing( func get_slashing(
state: ForkyBeaconState, total_balance: Gwei, vidx: ValidatorIndex): Gwei = state: ForkyBeaconState, total_balance: Gwei, vidx: ValidatorIndex): Gwei =
# For efficiency reasons, it doesn't make sense to have process_slashings use # For efficiency reasons, it doesn't make sense to have process_slashings use
@ -1050,7 +1065,8 @@ func get_slashing(
let validator = unsafeAddr state.validators.item(vidx) let validator = unsafeAddr state.validators.item(vidx)
if slashing_penalty_applies(validator[], epoch): if slashing_penalty_applies(validator[], epoch):
get_slashing_penalty( get_slashing_penalty(
validator[], adjusted_total_slashing_balance, total_balance) typeof(state).kind, validator[], adjusted_total_slashing_balance,
total_balance)
else: else:
0.Gwei 0.Gwei
@ -1064,10 +1080,11 @@ func process_slashings*(state: var ForkyBeaconState, total_balance: Gwei) =
let validator = unsafeAddr state.validators.item(vidx) let validator = unsafeAddr state.validators.item(vidx)
if slashing_penalty_applies(validator[], epoch): if slashing_penalty_applies(validator[], epoch):
let penalty = get_slashing_penalty( let penalty = get_slashing_penalty(
validator[], adjusted_total_slashing_balance, total_balance) typeof(state).kind, validator[], adjusted_total_slashing_balance,
total_balance)
decrease_balance(state, vidx, penalty) decrease_balance(state, vidx, penalty)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#eth1-data-votes-updates # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#eth1-data-votes-updates
func process_eth1_data_reset*(state: var ForkyBeaconState) = func process_eth1_data_reset*(state: var ForkyBeaconState) =
let next_epoch = get_current_epoch(state) + 1 let next_epoch = get_current_epoch(state) + 1
@ -1124,7 +1141,7 @@ func process_historical_roots_update*(state: var ForkyBeaconState) =
if next_epoch mod (SLOTS_PER_HISTORICAL_ROOT div SLOTS_PER_EPOCH) == 0: if next_epoch mod (SLOTS_PER_HISTORICAL_ROOT div SLOTS_PER_EPOCH) == 0:
# Equivalent to hash_tree_root(foo: HistoricalBatch), but without using # Equivalent to hash_tree_root(foo: HistoricalBatch), but without using
# significant additional stack or heap. # significant additional stack or heap.
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#historicalbatch # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#historicalbatch
# In response to https://github.com/status-im/nimbus-eth2/issues/921 # In response to https://github.com/status-im/nimbus-eth2/issues/921
if not state.historical_roots.add state.compute_historical_root(): if not state.historical_roots.add state.compute_historical_root():
raiseAssert "no more room for historical roots, so long and thanks for the fish!" raiseAssert "no more room for historical roots, so long and thanks for the fish!"
@ -1186,7 +1203,7 @@ template compute_inactivity_update(
min(cfg.INACTIVITY_SCORE_RECOVERY_RATE, inactivity_score) min(cfg.INACTIVITY_SCORE_RECOVERY_RATE, inactivity_score)
inactivity_score inactivity_score
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#inactivity-scores # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#inactivity-scores
func process_inactivity_updates*( func process_inactivity_updates*(
cfg: RuntimeConfig, cfg: RuntimeConfig,
state: var (altair.BeaconState | bellatrix.BeaconState | state: var (altair.BeaconState | bellatrix.BeaconState |
@ -1282,7 +1299,6 @@ func process_pending_balance_deposits*(
state.deposit_balance_to_consume = state.deposit_balance_to_consume =
available_for_processing - processed_amount available_for_processing - processed_amount
debugComment "yet another in-theory-might-overflow-maybe things, look at these more carefully"
if len(deposits_to_postpone) > 0: if len(deposits_to_postpone) > 0:
discard state.pending_balance_deposits.add deposits_to_postpone discard state.pending_balance_deposits.add deposits_to_postpone
@ -1384,7 +1400,7 @@ func init*(
deneb.BeaconState | electra.BeaconState): T = deneb.BeaconState | electra.BeaconState): T =
init(result, state) init(result, state)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#epoch-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#epoch-processing
proc process_epoch*( proc process_epoch*(
cfg: RuntimeConfig, cfg: RuntimeConfig,
state: var (altair.BeaconState | bellatrix.BeaconState), state: var (altair.BeaconState | bellatrix.BeaconState),
@ -1411,10 +1427,10 @@ proc process_epoch*(
process_inactivity_updates(cfg, state, info) # [New in Altair] process_inactivity_updates(cfg, state, info) # [New in Altair]
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#rewards-and-penalties # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#rewards-and-penalties
process_rewards_and_penalties(cfg, state, info) # [Modified in Altair] process_rewards_and_penalties(cfg, state, info) # [Modified in Altair]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#registry-updates # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#registry-updates
? process_registry_updates(cfg, state, cache) ? process_registry_updates(cfg, state, cache)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#slashings
@ -1430,7 +1446,7 @@ proc process_epoch*(
ok() ok()
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#epoch-processing # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/capella/beacon-chain.md#epoch-processing
proc process_epoch*( proc process_epoch*(
cfg: RuntimeConfig, cfg: RuntimeConfig,
state: var (capella.BeaconState | deneb.BeaconState), state: var (capella.BeaconState | deneb.BeaconState),
@ -1457,13 +1473,13 @@ proc process_epoch*(
process_inactivity_updates(cfg, state, info) process_inactivity_updates(cfg, state, info)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#rewards-and-penalties # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#rewards-and-penalties
process_rewards_and_penalties(cfg, state, info) process_rewards_and_penalties(cfg, state, info)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#registry-updates # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#registry-updates
? process_registry_updates(cfg, state, cache) ? process_registry_updates(cfg, state, cache)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#slashings # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#slashings
process_slashings(state, info.balances.current_epoch) process_slashings(state, info.balances.current_epoch)
process_eth1_data_reset(state) process_eth1_data_reset(state)
@ -1486,7 +1502,7 @@ proc process_epoch*(
info.init(state) info.init(state)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/beacon-chain.md#justification-and-finalization # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/beacon-chain.md#justification-and-finalization
process_justification_and_finalization(state, info.balances, flags) process_justification_and_finalization(state, info.balances, flags)
# state.slot hasn't been incremented yet. # state.slot hasn't been incremented yet.

View File

@ -21,7 +21,7 @@ const
TOTAL_SIZE = PIVOT_VIEW_SIZE + POSITION_WINDOW_SIZE TOTAL_SIZE = PIVOT_VIEW_SIZE + POSITION_WINDOW_SIZE
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#compute_shuffled_index # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#compute_shuffled_index
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#compute_committee # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#compute_committee
# Port of https://github.com/protolambda/zrnt/blob/v0.14.0/eth2/beacon/shuffle.go # Port of https://github.com/protolambda/zrnt/blob/v0.14.0/eth2/beacon/shuffle.go
func shuffle_list*(input: var seq[ValidatorIndex], seed: Eth2Digest) = func shuffle_list*(input: var seq[ValidatorIndex], seed: Eth2Digest) =
let list_size = input.lenu64 let list_size = input.lenu64
@ -158,7 +158,7 @@ func get_shuffled_active_validator_indices*(
withState(state): withState(state):
cache.get_shuffled_active_validator_indices(forkyState.data, epoch) cache.get_shuffled_active_validator_indices(forkyState.data, epoch)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#get_active_validator_indices # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_active_validator_indices
func count_active_validators*(state: ForkyBeaconState, func count_active_validators*(state: ForkyBeaconState,
epoch: Epoch, epoch: Epoch,
cache: var StateCache): uint64 = cache: var StateCache): uint64 =
@ -394,7 +394,7 @@ func compute_proposer_index(state: ForkyBeaconState,
## Return from ``indices`` a random index sampled by effective balance. ## Return from ``indices`` a random index sampled by effective balance.
compute_proposer_index(state, indices, seed, shuffled_index) compute_proposer_index(state, indices, seed, shuffled_index)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#get_beacon_proposer_index # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#get_beacon_proposer_index
func get_beacon_proposer_index*( func get_beacon_proposer_index*(
state: ForkyBeaconState, cache: var StateCache, slot: Slot): state: ForkyBeaconState, cache: var StateCache, slot: Slot):
Opt[ValidatorIndex] = Opt[ValidatorIndex] =

View File

@ -10,10 +10,10 @@
import import
./datatypes/base, ./beaconstate, ./forks, ./helpers ./datatypes/base, ./beaconstate, ./forks, ./helpers
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/weak-subjectivity.md#configuration # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/weak-subjectivity.md#configuration
const SAFETY_DECAY* = 10'u64 const SAFETY_DECAY* = 10'u64
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/weak-subjectivity.md#compute_weak_subjectivity_period # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/weak-subjectivity.md#compute_weak_subjectivity_period
func compute_weak_subjectivity_period( func compute_weak_subjectivity_period(
cfg: RuntimeConfig, state: ForkyBeaconState): uint64 = cfg: RuntimeConfig, state: ForkyBeaconState): uint64 =
## Returns the weak subjectivity period for the current ``state``. ## Returns the weak subjectivity period for the current ``state``.
@ -49,7 +49,7 @@ func compute_weak_subjectivity_period(
ws_period ws_period
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/weak-subjectivity.md#is_within_weak_subjectivity_period # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/weak-subjectivity.md#is_within_weak_subjectivity_period
func is_within_weak_subjectivity_period*(cfg: RuntimeConfig, current_slot: Slot, func is_within_weak_subjectivity_period*(cfg: RuntimeConfig, current_slot: Slot,
ws_state: ForkedHashedBeaconState, ws_state: ForkedHashedBeaconState,
ws_checkpoint: Checkpoint): bool = ws_checkpoint: Checkpoint): bool =

View File

@ -330,7 +330,7 @@ template query[E](
): Future[bool].Raising([CancelledError]) = ): Future[bool].Raising([CancelledError]) =
self.query(e, Nothing()) self.query(e, Nothing())
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/light-client.md#light-client-sync-process # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/light-client.md#light-client-sync-process
proc loop(self: LightClientManager) {.async: (raises: [CancelledError]).} = proc loop(self: LightClientManager) {.async: (raises: [CancelledError]).} =
var nextSyncTaskTime = self.getBeaconTime() var nextSyncTaskTime = self.getBeaconTime()
while true: while true:

View File

@ -90,7 +90,7 @@ p2pProtocol LightClientSync(version = 1,
debug "LC bootstrap request done", peer, blockRoot debug "LC bootstrap request done", peer, blockRoot
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/p2p-interface.md#lightclientupdatesbyrange # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/p2p-interface.md#lightclientupdatesbyrange
proc lightClientUpdatesByRange( proc lightClientUpdatesByRange(
peer: Peer, peer: Peer,
startPeriod: SyncCommitteePeriod, startPeriod: SyncCommitteePeriod,
@ -134,7 +134,7 @@ p2pProtocol LightClientSync(version = 1,
debug "LC updates by range request done", peer, startPeriod, count, found debug "LC updates by range request done", peer, startPeriod, count, found
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/p2p-interface.md#getlightclientfinalityupdate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/p2p-interface.md#getlightclientfinalityupdate
proc lightClientFinalityUpdate( proc lightClientFinalityUpdate(
peer: Peer, peer: Peer,
response: SingleChunkResponse[ForkedLightClientFinalityUpdate]) response: SingleChunkResponse[ForkedLightClientFinalityUpdate])
@ -160,7 +160,7 @@ p2pProtocol LightClientSync(version = 1,
debug "LC finality update request done", peer debug "LC finality update request done", peer
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/p2p-interface.md#getlightclientoptimisticupdate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/p2p-interface.md#getlightclientoptimisticupdate
proc lightClientOptimisticUpdate( proc lightClientOptimisticUpdate(
peer: Peer, peer: Peer,
response: SingleChunkResponse[ForkedLightClientOptimisticUpdate]) response: SingleChunkResponse[ForkedLightClientOptimisticUpdate])

View File

@ -171,7 +171,7 @@ proc doTrustedNodeSync*(
let stateId = let stateId =
case syncTarget.kind case syncTarget.kind
of TrustedNodeSyncKind.TrustedBlockRoot: of TrustedNodeSyncKind.TrustedBlockRoot:
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/light-client.md#light-client-sync-process # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/light-client/light-client.md#light-client-sync-process
const lcDataFork = LightClientDataFork.high const lcDataFork = LightClientDataFork.high
var bestViableCheckpoint: Opt[tuple[slot: Slot, state_root: Eth2Digest]] var bestViableCheckpoint: Opt[tuple[slot: Slot, state_root: Eth2Digest]]
func trackBestViableCheckpoint(store: lcDataFork.LightClientStore) = func trackBestViableCheckpoint(store: lcDataFork.LightClientStore) =

View File

@ -122,7 +122,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
let let
maybeBlock = maybeBlock =
try: try:
await vc.produceBlockV3(slot, randao_reveal, graffiti, await vc.produceBlockV3(slot, randaoReveal, graffiti,
vc.config.builderBoostFactor, vc.config.builderBoostFactor,
ApiStrategyKind.Best) ApiStrategyKind.Best)
except ValidatorApiError as exc: except ValidatorApiError as exc:

View File

@ -150,7 +150,6 @@ proc serveContributionAndProof*(service: SyncCommitteeServiceRef,
vc = service.client vc = service.client
startTime = Moment.now() startTime = Moment.now()
slot = proof.contribution.slot slot = proof.contribution.slot
validatorIdx = validator.index.get()
genesisRoot = vc.beaconGenesis.genesis_validators_root genesisRoot = vc.beaconGenesis.genesis_validators_root
fork = vc.forkAtEpoch(slot.epoch) fork = vc.forkAtEpoch(slot.epoch)

View File

@ -696,8 +696,6 @@ proc constructSignableBlindedBlock[T: electra_mev.SignedBlindedBeaconBlock](
blindedBlock.message.body.blob_kzg_commitments, blindedBlock.message.body.blob_kzg_commitments,
blindedBundle.blob_kzg_commitments) blindedBundle.blob_kzg_commitments)
debugComment "check for any additional electra mev requirements"
blindedBlock blindedBlock
func constructPlainBlindedBlock[T: deneb_mev.BlindedBeaconBlock]( func constructPlainBlindedBlock[T: deneb_mev.BlindedBeaconBlock](
@ -746,8 +744,6 @@ func constructPlainBlindedBlock[T: electra_mev.BlindedBeaconBlock](
blindedBlock.body.blob_kzg_commitments, blindedBlock.body.blob_kzg_commitments,
blindedBundle.blob_kzg_commitments) blindedBundle.blob_kzg_commitments)
debugComment "check for any additional electra mev requirements"
blindedBlock blindedBlock
proc blindedBlockCheckSlashingAndSign[ proc blindedBlockCheckSlashingAndSign[
@ -1600,7 +1596,7 @@ proc signAndSendAggregate(
shufflingRef, slot, committee_index, selectionProof): shufflingRef, slot, committee_index, selectionProof):
return return
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#construct-aggregate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#construct-aggregate
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#aggregateandproof # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#aggregateandproof
var var
msg = phase0.SignedAggregateAndProof( msg = phase0.SignedAggregateAndProof(
@ -1950,8 +1946,8 @@ proc handleValidatorDuties*(node: BeaconNode, lastSlot, slot: Slot) {.async: (ra
updateValidatorMetrics(node) # the important stuff is done, update the vanity numbers updateValidatorMetrics(node) # the important stuff is done, update the vanity numbers
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/validator.md#broadcast-aggregate # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#broadcast-aggregate
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#broadcast-sync-committee-contribution # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#broadcast-sync-committee-contribution
# Wait 2 / 3 of the slot time to allow messages to propagate, then collect # Wait 2 / 3 of the slot time to allow messages to propagate, then collect
# the result in aggregates # the result in aggregates
static: static:

View File

@ -659,7 +659,8 @@ proc queryValidatorsSource*(web3signerUrl: Web3SignerUrl):
let let
httpFlags: HttpClientFlags = {} httpFlags: HttpClientFlags = {}
prestoFlags = {RestClientFlag.CommaSeparatedArray} prestoFlags = {RestClientFlag.CommaSeparatedArray,
RestClientFlag.ResolveAlways}
socketFlags = {SocketFlags.TcpNoDelay} socketFlags = {SocketFlags.TcpNoDelay}
client = client =
block: block:

View File

@ -269,7 +269,8 @@ proc routeAttestation*(
attestation, subnet_id, checkSignature = true, checkValidator = true) attestation, subnet_id, checkSignature = true, checkValidator = true)
proc routeSignedAggregateAndProof*( proc routeSignedAggregateAndProof*(
router: ref MessageRouter, proof: phase0.SignedAggregateAndProof, router: ref MessageRouter,
proof: phase0.SignedAggregateAndProof | electra.SignedAggregateAndProof,
checkSignature = true): checkSignature = true):
Future[SendResult] {.async: (raises: [CancelledError]).} = Future[SendResult] {.async: (raises: [CancelledError]).} =
## Validate and broadcast aggregate ## Validate and broadcast aggregate

View File

@ -128,7 +128,7 @@ proc unblindAndRouteBlockMEV*(
if blindedBlock.message.body.blob_kzg_commitments != if blindedBlock.message.body.blob_kzg_commitments !=
bundle.data.blobs_bundle.commitments: bundle.data.blobs_bundle.commitments:
return err("unblinded blobs bundle has unexpected commitments") return err("unblinded blobs bundle has unexpected commitments")
let ok = verifyProofs( let ok = verifyBlobKzgProofBatch(
blobs_bundle.blobs.mapIt(KzgBlob(bytes: it)), blobs_bundle.blobs.mapIt(KzgBlob(bytes: it)),
asSeq blobs_bundle.commitments, asSeq blobs_bundle.commitments,
asSeq blobs_bundle.proofs).valueOr: asSeq blobs_bundle.proofs).valueOr:

View File

@ -36,7 +36,7 @@ export results
# - https://notes.ethereum.org/@djrtwo/Bkn3zpwxB#Validator-responsibilities # - https://notes.ethereum.org/@djrtwo/Bkn3zpwxB#Validator-responsibilities
# #
# Phase 0 spec - Honest Validator - how to avoid slashing # Phase 0 spec - Honest Validator - how to avoid slashing
# - https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/validator.md#how-to-avoid-slashing # - https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#how-to-avoid-slashing
# #
# In-depth reading on slashing conditions # In-depth reading on slashing conditions
# #

View File

@ -522,7 +522,7 @@ proc signData(v: AttachedValidator,
else: else:
v.signWithDistributedKey(request) v.signWithDistributedKey(request)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#signature # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#signature
proc getBlockSignature*(v: AttachedValidator, fork: Fork, proc getBlockSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, slot: Slot, genesis_validators_root: Eth2Digest, slot: Slot,
block_root: Eth2Digest, block_root: Eth2Digest,
@ -776,7 +776,7 @@ proc getAggregateAndProofSignature*(v: AttachedValidator,
fork, genesis_validators_root, aggregate_and_proof) fork, genesis_validators_root, aggregate_and_proof)
await v.signData(request) await v.signData(request)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#prepare-sync-committee-message # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#prepare-sync-committee-message
proc getSyncCommitteeMessage*(v: AttachedValidator, proc getSyncCommitteeMessage*(v: AttachedValidator,
fork: Fork, fork: Fork,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
@ -807,7 +807,7 @@ proc getSyncCommitteeMessage*(v: AttachedValidator,
) )
) )
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#aggregation-selection # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#aggregation-selection
proc getSyncCommitteeSelectionProof*(v: AttachedValidator, fork: Fork, proc getSyncCommitteeSelectionProof*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
slot: Slot, slot: Slot,
@ -827,7 +827,7 @@ proc getSyncCommitteeSelectionProof*(v: AttachedValidator, fork: Fork,
) )
await v.signData(request) await v.signData(request)
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#broadcast-sync-committee-contribution # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/altair/validator.md#broadcast-sync-committee-contribution
proc getContributionAndProofSignature*(v: AttachedValidator, fork: Fork, proc getContributionAndProofSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
contribution_and_proof: ContributionAndProof contribution_and_proof: ContributionAndProof
@ -843,7 +843,7 @@ proc getContributionAndProofSignature*(v: AttachedValidator, fork: Fork,
fork, genesis_validators_root, contribution_and_proof) fork, genesis_validators_root, contribution_and_proof)
await v.signData(request) await v.signData(request)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#randao-reveal # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/validator.md#randao-reveal
proc getEpochSignature*(v: AttachedValidator, fork: Fork, proc getEpochSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, epoch: Epoch genesis_validators_root: Eth2Digest, epoch: Epoch
): Future[SignatureResult] ): Future[SignatureResult]

18
ci/Jenkinsfile vendored
View File

@ -143,13 +143,17 @@ pipeline {
} } } }
} }
} }
post { always { timeout(5) { post {
archiveArtifacts( always { timeout(10) {
artifacts: '*.tar.gz', /* DEBUG: Show file sizes to catch too big ones. */
excludes: '**/geth-*.tar.gz', /* `scripts/geth_binaries.sh` */ sh 'ls -hl *.tar.gz'
allowEmptyArchive: true archiveArtifacts(
) artifacts: '*.tar.gz',
} } } excludes: '**/geth-*.tar.gz', /* `scripts/geth_binaries.sh` */
allowEmptyArchive: true
)
} }
}
} }
} }

View File

@ -100,14 +100,11 @@ if defined(windows):
if defined(disableMarchNative): if defined(disableMarchNative):
if defined(i386) or defined(amd64): if defined(i386) or defined(amd64):
if defined(macosx): if defined(macosx):
# macOS Big Sur is EOL as of 2023-11 # https://support.apple.com/en-us/102861
# https://support.apple.com/en-us/HT212551 # "macOS Ventura is compatible with these computers" lists current oldest
# "macOS Monterey is compatible with these computers" of which the # supported x86 models, all of which have Kaby Lake or newer CPUs.
# oldest is "Mac Pro (Late 2013)". All have Haswell or newer CPUs. switch("passC", "-march=skylake -mtune=generic")
# switch("passL", "-march=skylake -mtune=generic")
# This ensures AVX2, AES-NI, PCLMUL, BMI1, and BMI2 instruction set support.
switch("passC", "-march=haswell -mtune=generic")
switch("passL", "-march=haswell -mtune=generic")
else: else:
if defined(marchOptimized): if defined(marchOptimized):
# https://github.com/status-im/nimbus-eth2/blob/stable/docs/cpu_features.md#bmi2--adx # https://github.com/status-im/nimbus-eth2/blob/stable/docs/cpu_features.md#bmi2--adx

View File

@ -6,7 +6,7 @@ This is a WIP document to explain the attestation flows.
It is important to distinguish attestation `validation` from attestation `verification`. It is important to distinguish attestation `validation` from attestation `verification`.
- Attestation `validation` is defined in the P2P specs. Validated attestations can be forwarded on GossipSub. - Attestation `validation` is defined in the P2P specs. Validated attestations can be forwarded on GossipSub.
- Aggregated: https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof - Aggregated: https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof
- Unaggregated: https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id - Unaggregated: https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
- Attestation `verification` is defined in the consensus specs. Verified attestations can affect fork choice and may be included in a block. - Attestation `verification` is defined in the consensus specs. Verified attestations can affect fork choice and may be included in a block.
- https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#attestations - https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#attestations

View File

@ -9,7 +9,7 @@ Important distinction:
https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#beacon_block. https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/p2p-interface.md#beacon_block.
A validated block can be forwarded on gossipsub. A validated block can be forwarded on gossipsub.
- and we distinguish `verification` which is defined in consensus specs: - and we distinguish `verification` which is defined in consensus specs:
https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/beacon-chain.md#block-processing https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#block-processing
A block needs to be verified to enter fork choice, the DAG and the BeaconChainDB A block needs to be verified to enter fork choice, the DAG and the BeaconChainDB
In particular in terms of costly checks validating a block only requires checking: In particular in terms of costly checks validating a block only requires checking:

View File

@ -104,7 +104,7 @@ The following sections explain how to do this for certain EL clients.
## Running the light client ## Running the light client
The light client starts syncing from a trusted block. The light client starts syncing from a trusted block.
This trusted block should be somewhat recent ([~1-2 weeks](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/weak-subjectivity.md)) and needs to be configured each time when starting the light client. This trusted block should be somewhat recent ([~1-2 weeks](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/weak-subjectivity.md)) and needs to be configured each time when starting the light client.
### 1. Obtaining a trusted block root ### 1. Obtaining a trusted block root

View File

@ -32,7 +32,7 @@ When building from source, you will need additional build dependencies to be ins
dnf install @development-tools cmake dnf install @development-tools cmake
# Arch Linux, using an AUR manager # Arch Linux, using an AUR manager
yourAURmanager -S base-devel cmake yourAURmanager -S base-devel git-lfs cmake
``` ```
=== "macOS" === "macOS"

View File

@ -155,6 +155,6 @@ Since the generalized index of a particular field may change in a hard-fork, in
``` ```
Nimbus automatically computes the generalized index depending on the currently active fork. Nimbus automatically computes the generalized index depending on the currently active fork.
The remote signer is expected to verify the incoming Merkle proof through the standardized [is_valid_merkle_branch](https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#is_valid_merkle_branch) function by utilizing a similar automatic mapping mechanism for the generalized index. The remote signer is expected to verify the incoming Merkle proof through the standardized [is_valid_merkle_branch](https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.6/specs/phase0/beacon-chain.md#is_valid_merkle_branch) function by utilizing a similar automatic mapping mechanism for the generalized index.
You can instruct Nimbus to use the verifying Web3Signer protocol by either supplying the `--verifying-web3-signer` command-line option or by creating a remote keystore file in the format described above. You can use the command-line option `--proven-block-property` once or multiple times to enumerate the properties of the block for which Merkle proofs will be supplied. You can instruct Nimbus to use the verifying Web3Signer protocol by either supplying the `--verifying-web3-signer` command-line option or by creating a remote keystore file in the format described above. You can use the command-line option `--proven-block-property` once or multiple times to enumerate the properties of the block for which Merkle proofs will be supplied.

View File

@ -201,8 +201,9 @@ func collectSlashings(
let validator = unsafeAddr state.validators[index] let validator = unsafeAddr state.validators[index]
if slashing_penalty_applies(validator[], epoch): if slashing_penalty_applies(validator[], epoch):
rewardsAndPenalties[index].slashing_outcome += rewardsAndPenalties[index].slashing_outcome +=
validator[].get_slashing_penalty( get_slashing_penalty(
adjusted_total_slashing_balance, total_balance).int64 typeof(state).kind, validator[], adjusted_total_slashing_balance,
total_balance).int64
proc collectEpochRewardsAndPenalties*( proc collectEpochRewardsAndPenalties*(
rewardsAndPenalties: var seq[RewardsAndPenalties], rewardsAndPenalties: var seq[RewardsAndPenalties],

View File

@ -22,17 +22,11 @@ import
./logtrace ./logtrace
from std/os import changeFileExt, fileExists from std/os import changeFileExt, fileExists
from std/sequtils import mapIt, toSeq
from std/times import toUnix from std/times import toUnix
from ../beacon_chain/el/engine_api_conversions import asEth2Digest from ../beacon_chain/el/engine_api_conversions import asEth2Digest
from ../beacon_chain/spec/beaconstate import initialize_beacon_state_from_eth1 from ../beacon_chain/spec/beaconstate import initialize_beacon_state_from_eth1
from ../tests/mocking/mock_genesis import mockEth1BlockHash from ../tests/mocking/mock_genesis import mockEth1BlockHash
# Compiled version of /scripts/depositContract.v.py in this repo
# The contract was compiled in Remix (https://remix.ethereum.org/) with vyper (remote) compiler.
const depositContractCode =
hexToSeqByte staticRead "../beacon_chain/el/deposit_contract_code.txt"
# For nim-confutils, which uses this kind of init(Type, value) pattern # For nim-confutils, which uses this kind of init(Type, value) pattern
func init(T: type IpAddress, ip: IpAddress): T = ip func init(T: type IpAddress, ip: IpAddress): T = ip
@ -389,19 +383,6 @@ proc createEnr(rng: var HmacDrbgContext,
]) ])
bootstrapEnr.tryGet() bootstrapEnr.tryGet()
proc doCreateTestnetEnr(config: CliConfig,
rng: var HmacDrbgContext)
{.raises: [CatchableError].} =
let
cfg = getRuntimeConfig(config.eth2Network)
bootstrapEnr = parseBootstrapAddress(toSeq(lines(string config.inputBootstrapEnr))[0]).get()
forkIdField = bootstrapEnr.tryGet(enrForkIdField, seq[byte]).get()
enr =
createEnr(rng, string config.enrDataDir, string config.enrNetKeyFile,
config.enrNetKeyInsecurePassword, cfg, forkIdField,
config.enrAddress, config.enrPort)
stderr.writeLine(enr.toURI)
proc doCreateTestnet*(config: CliConfig, proc doCreateTestnet*(config: CliConfig,
rng: var HmacDrbgContext) rng: var HmacDrbgContext)
{.raises: [CatchableError].} = {.raises: [CatchableError].} =
@ -504,29 +485,6 @@ proc doCreateTestnet*(config: CliConfig,
writeFile(bootstrapFile, enr.toURI) writeFile(bootstrapFile, enr.toURI)
echo "Wrote ", bootstrapFile echo "Wrote ", bootstrapFile
proc deployContract(web3: Web3, code: seq[byte]): Future[ReceiptObject] {.async.} =
let tr = TransactionArgs(
`from`: Opt.some web3.defaultAccount,
data: Opt.some code,
gas: Opt.some Quantity(3000000),
gasPrice: Opt.some Quantity(1))
let r = await web3.send(tr)
result = await web3.getMinedTransactionReceipt(r)
proc sendEth(web3: Web3, to: Eth1Address, valueEth: int): Future[TxHash] =
let tr = TransactionArgs(
`from`: Opt.some web3.defaultAccount,
# TODO: Force json-rpc to generate 'data' field
# should not be needed anymore, new execution-api schema
# is using `input` field
data: Opt.some(newSeq[byte]()),
gas: Opt.some Quantity(3000000),
gasPrice: Opt.some Quantity(1),
value: Opt.some(valueEth.u256 * 1000000000000000000.u256),
to: Opt.some(to))
web3.send(tr)
type type
DelayGenerator = proc(): chronos.Duration {.gcsafe, raises: [].} DelayGenerator = proc(): chronos.Duration {.gcsafe, raises: [].}
@ -542,43 +500,6 @@ proc initWeb3(web3Url, privateKey: string): Future[Web3] {.async.} =
doAssert(accounts.len > 0) doAssert(accounts.len > 0)
result.defaultAccount = accounts[0] result.defaultAccount = accounts[0]
# TODO: async functions should note take `seq` inputs because
# this leads to full copies.
proc sendDeposits(deposits: seq[LaunchPadDeposit],
web3Url, privateKey: string,
depositContractAddress: Eth1Address,
delayGenerator: DelayGenerator = nil) {.async.} =
notice "Sending deposits",
web3 = web3Url,
depositContract = depositContractAddress
var web3 = await initWeb3(web3Url, privateKey)
let gasPrice = int(await web3.provider.eth_gasPrice()) * 2
let depositContract = web3.contractSender(
DepositContract, depositContractAddress)
for i in 4200 ..< deposits.len:
let dp = deposits[i] as DepositData
while true:
try:
let tx = depositContract.deposit(
PubKeyBytes(@(dp.pubkey.toRaw())),
WithdrawalCredentialsBytes(@(dp.withdrawal_credentials.data)),
SignatureBytes(@(dp.signature.toRaw())),
FixedBytes[32](hash_tree_root(dp).data))
let status = await tx.send(value = 32.u256.ethToWei, gasPrice = gasPrice)
info "Deposit sent", tx = $status
if delayGenerator != nil:
await sleepAsync(delayGenerator())
break
except CatchableError:
await sleepAsync(chronos.seconds 60)
web3 = await initWeb3(web3Url, privateKey)
{.pop.} # TODO confutils.nim(775, 17) Error: can raise an unlisted exception: ref IOError {.pop.} # TODO confutils.nim(775, 17) Error: can raise an unlisted exception: ref IOError
when isMainModule: when isMainModule:
@ -586,8 +507,88 @@ when isMainModule:
web3/confutils_defs, web3/confutils_defs,
../beacon_chain/filepath ../beacon_chain/filepath
from std/sequtils import mapIt, toSeq
from std/terminal import readPasswordFromStdin from std/terminal import readPasswordFromStdin
# Compiled version of /scripts/depositContract.v.py in this repo
# The contract was compiled in Remix (https://remix.ethereum.org/) with vyper (remote) compiler.
const depositContractCode =
hexToSeqByte staticRead "../beacon_chain/el/deposit_contract_code.txt"
proc doCreateTestnetEnr(config: CliConfig,
rng: var HmacDrbgContext)
{.raises: [CatchableError].} =
let
cfg = getRuntimeConfig(config.eth2Network)
bootstrapEnr = parseBootstrapAddress(toSeq(lines(string config.inputBootstrapEnr))[0]).get()
forkIdField = bootstrapEnr.tryGet(enrForkIdField, seq[byte]).get()
enr =
createEnr(rng, string config.enrDataDir, string config.enrNetKeyFile,
config.enrNetKeyInsecurePassword, cfg, forkIdField,
config.enrAddress, config.enrPort)
stderr.writeLine(enr.toURI)
proc deployContract(web3: Web3, code: seq[byte]): Future[ReceiptObject] {.async.} =
let tr = TransactionArgs(
`from`: Opt.some web3.defaultAccount,
data: Opt.some code,
gas: Opt.some Quantity(3000000),
gasPrice: Opt.some Quantity(1))
let r = await web3.send(tr)
result = await web3.getMinedTransactionReceipt(r)
proc sendEth(web3: Web3, to: Eth1Address, valueEth: int): Future[TxHash] =
let tr = TransactionArgs(
`from`: Opt.some web3.defaultAccount,
# TODO: Force json-rpc to generate 'data' field
# should not be needed anymore, new execution-api schema
# is using `input` field
data: Opt.some(newSeq[byte]()),
gas: Opt.some Quantity(3000000),
gasPrice: Opt.some Quantity(1),
value: Opt.some(valueEth.u256 * 1000000000000000000.u256),
to: Opt.some(to))
web3.send(tr)
# TODO: async functions should note take `seq` inputs because
# this leads to full copies.
proc sendDeposits(deposits: seq[LaunchPadDeposit],
web3Url, privateKey: string,
depositContractAddress: Eth1Address,
delayGenerator: DelayGenerator = nil) {.async.} =
notice "Sending deposits",
web3 = web3Url,
depositContract = depositContractAddress
var web3 = await initWeb3(web3Url, privateKey)
let gasPrice = int(await web3.provider.eth_gasPrice()) * 2
let depositContract = web3.contractSender(
DepositContract, depositContractAddress)
for i in 4200 ..< deposits.len:
let dp = deposits[i] as DepositData
while true:
try:
let tx = depositContract.deposit(
PubKeyBytes(@(dp.pubkey.toRaw())),
WithdrawalCredentialsBytes(@(dp.withdrawal_credentials.data)),
SignatureBytes(@(dp.signature.toRaw())),
FixedBytes[32](hash_tree_root(dp).data))
let status = await tx.send(
value = 32.u256.ethToWei, gasPrice = gasPrice)
info "Deposit sent", tx = $status
if delayGenerator != nil:
await sleepAsync(delayGenerator())
break
except CatchableError:
await sleepAsync(chronos.seconds 60)
web3 = await initWeb3(web3Url, privateKey)
proc main() {.async.} = proc main() {.async.} =
var conf = try: CliConfig.load() var conf = try: CliConfig.load()
except CatchableError as exc: except CatchableError as exc:

View File

@ -4523,6 +4523,74 @@
"status": {"operator": "oneof", "value": ["400", "200"]} "status": {"operator": "oneof", "value": ["400", "200"]}
} }
}, },
{
"topics": ["validator", "aggregate_attestation"],
"request": {
"url": "/eth/v2/validator/aggregate_attestation",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "400"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 400, "message": ""}}]
}
},
{
"topics": ["validator", "aggregate_attestation"],
"request": {
"url": "/eth/v2/validator/aggregate_attestation?slot=0",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "400"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 400, "message": ""}}]
}
},
{
"topics": ["validator", "aggregate_attestation"],
"request": {
"url": "/eth/v2/validator/aggregate_attestation?slot=&attestation_data_root=",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "400"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 400, "message": ""}}]
}
},
{
"topics": ["validator", "aggregate_attestation"],
"request": {
"url": "/eth/v2/validator/aggregate_attestation?slot=&attestation_data_root=&committee_index=",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "400"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 400, "message": ""}}]
}
},
{
"topics": ["validator", "aggregate_attestation"],
"request": {
"url": "/eth/v2/validator/aggregate_attestation?slot=0&attestation_data_root=0x0000000000000000000000000000000000000000000000000000000000000000",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "oneof", "value": ["400", "200"]}
}
},
{
"topics": ["validator", "aggregate_attestation"],
"request": {
"url": "/eth/v2/validator/aggregate_attestation?slot=0&attestation_data_root=0x0000000000000000000000000000000000000000000000000000000000000000&committee_index=0",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "oneof", "value": ["400", "200"]}
}
},
{ {
"topics": ["validator", "attester_duties"], "topics": ["validator", "attester_duties"],
"request": { "request": {
@ -4900,5 +4968,376 @@
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpnsav", "value": {"code": 500, "message": "Only `gossip` broadcast_validation option supported"}}] "body": [{"operator": "jstructcmpnsav", "value": {"code": 500, "message": "Only `gossip` broadcast_validation option supported"}}]
} }
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/head",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmps", "start": ["data"], "value": {"proposer_index": "", "total": "", "attestations": "", "sync_aggregate": "", "proposer_slashings": "", "attester_slashings": ""}}]
}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/genesis",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmps", "start": ["data"], "value": {"proposer_index": "", "total": "", "attestations": "", "sync_aggregate": "", "proposer_slashings": "", "attester_slashings": ""}}]
}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/finalized",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmps", "start": ["data"], "value": {"proposer_index": "", "total": "", "attestations": "", "sync_aggregate": "", "proposer_slashings": "", "attester_slashings": ""}}]
}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/heat",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/geneziz",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/finalised",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/0",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmps", "start": ["data"], "value": {"proposer_index": "", "total": "", "attestations": "", "sync_aggregate": "", "proposer_slashings": "", "attester_slashings": ""}}]
}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/0x0000000000000000000000000000000000000000000000000000000000000000",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "404"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 404, "message": ""}}]
}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/18446744073709551615",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "404"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 404, "message": ""}}]
}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/18446744073709551616",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "400"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 400, "message": ""}}]
}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/0x",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/0x0",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/0x00",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/0xII",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "block_rewards_blockid"],
"request": {
"url": "/eth/v1/beacon/rewards/blocks/foobar",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/head",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmps", "start": ["data"], "value": [{"validator_index": "", "reward": ""}]}]
}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/genesis",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmps", "start": ["data"], "value": [{"validator_index": "", "reward": ""}]}]
}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/finalized",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmps", "start": ["data"], "value": [{"validator_index": "", "reward": ""}]}]
}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/heat",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/geneziz",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/finalised",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/0",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmps", "start": ["data"], "value": [{"validator_index": "", "reward": ""}]}]
}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/0x0000000000000000000000000000000000000000000000000000000000000000",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "404"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 404, "message": ""}}]
}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/18446744073709551615",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "404"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 404, "message": ""}}]
}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/18446744073709551616",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "400"},
"headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}],
"body": [{"operator": "jstructcmpns", "value": {"code": 400, "message": ""}}]
}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/0x",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/0x0",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/0x00",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/0xII",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "rewards", "sync_committee_rewards_blockid"],
"request": {
"method": "POST",
"body": {
"content-type": "application/json",
"data": "[]"
},
"url": "/eth/v1/beacon/rewards/sync_committee/foobar",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
} }
] ]

View File

@ -286,9 +286,7 @@ cli do(validatorsDir: string, secretsDir: string,
forkyState.data.eth1_data, forkyState.data.eth1_data,
graffitiValue, graffitiValue,
when typeof(payload).kind == ConsensusFork.Electra: when typeof(payload).kind == ConsensusFork.Electra:
block: default(seq[electra.Attestation])
debugComment "wss_sim electra aggregates"
default(seq[electra.Attestation])
else: else:
blockAggregates, blockAggregates,
@[], @[],

View File

@ -27,6 +27,7 @@ import # Unit test
./test_discovery, ./test_discovery,
./test_engine_api_conversions, ./test_engine_api_conversions,
./test_engine_authentication, ./test_engine_authentication,
./test_eip7594_helpers,
./test_el_manager, ./test_el_manager,
./test_el_conf, ./test_el_conf,
./test_eth2_ssz_serialization, ./test_eth2_ssz_serialization,

Some files were not shown because too many files have changed in this diff Show More