From d1347bfc5b39c2faabc2e8abb5201903309ee66f Mon Sep 17 00:00:00 2001 From: Paul Harris Date: Wed, 3 Apr 2024 13:30:22 +1000 Subject: [PATCH] added beaconState and dependent structures Signed-off-by: Paul Harris --- .../beacon/schema/BeaconStateElectra.json | 50 ++++++++- .../beacon/schema/PendingBalanceDeposit.json | 19 ++++ .../beacon/schema/PendingConsolidation.json | 19 ++++ .../schema/PendingPartialWithdrawal.json | 25 +++++ .../schema/electra/BeaconStateElectra.java | 101 +++++++++++++++++- .../schema/electra/PendingBalanceDeposit.java | 57 ++++++++++ .../schema/electra/PendingConsolidation.java | 59 ++++++++++ .../electra/PendingPartialWithdrawal.java | 66 ++++++++++++ .../spec/config/DelegatingSpecConfig.java | 15 +++ .../pegasys/teku/spec/config/SpecConfig.java | 6 ++ .../teku/spec/config/SpecConfigPhase0.java | 34 +++++- .../config/builder/SpecConfigBuilder.java | 29 ++++- .../beaconstate/common/BeaconStateFields.java | 11 +- .../versions/electra/BeaconStateElectra.java | 52 +++++++++ .../electra/BeaconStateSchemaElectra.java | 92 +++++++++++++++- .../electra/MutableBeaconStateElectra.java | 47 ++++++++ .../electra/PendingBalanceDeposit.java | 69 ++++++++++++ .../electra/PendingConsolidation.java | 65 +++++++++++ .../electra/PendingPartialWithdrawal.java | 78 ++++++++++++++ .../schemas/SchemaDefinitionsElectra.java | 26 +++++ .../spec/config/presets/minimal/phase0.yaml | 7 ++ .../spec/util/BeaconStateBuilderElectra.java | 40 +++++++ 22 files changed, 960 insertions(+), 7 deletions(-) create mode 100644 data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingBalanceDeposit.json create mode 100644 data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingConsolidation.json create mode 100644 data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingPartialWithdrawal.json create mode 100644 data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingBalanceDeposit.java create mode 100644 data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingConsolidation.java create mode 100644 data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingPartialWithdrawal.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingBalanceDeposit.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingConsolidation.java create mode 100644 ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingPartialWithdrawal.java diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/BeaconStateElectra.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/BeaconStateElectra.json index dafbfaab9a7..eb3779670fa 100644 --- a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/BeaconStateElectra.json +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/BeaconStateElectra.json @@ -1,7 +1,7 @@ { "title" : "BeaconStateElectra", "type" : "object", - "required" : [ "genesis_time", "genesis_validators_root", "slot", "fork", "latest_block_header", "block_roots", "state_roots", "historical_roots", "eth1_data", "eth1_data_votes", "eth1_deposit_index", "validators", "balances", "randao_mixes", "slashings", "previous_epoch_participation", "current_epoch_participation", "justification_bits", "previous_justified_checkpoint", "current_justified_checkpoint", "finalized_checkpoint", "inactivity_scores", "current_sync_committee", "next_sync_committee", "latest_execution_payload_header", "next_withdrawal_index", "next_withdrawal_validator_index", "historical_summaries", "deposit_receipts_start_index" ], + "required" : [ "genesis_time", "genesis_validators_root", "slot", "fork", "latest_block_header", "block_roots", "state_roots", "historical_roots", "eth1_data", "eth1_data_votes", "eth1_deposit_index", "validators", "balances", "randao_mixes", "slashings", "previous_epoch_participation", "current_epoch_participation", "justification_bits", "previous_justified_checkpoint", "current_justified_checkpoint", "finalized_checkpoint", "inactivity_scores", "current_sync_committee", "next_sync_committee", "latest_execution_payload_header", "next_withdrawal_index", "next_withdrawal_validator_index", "historical_summaries", "deposit_receipts_start_index", "deposit_balance_to_consume", "exit_balance_to_consume", "earliest_exit_epoch", "consolidation_balance_to_consume", "earliest_consolidation_epoch", "pending_balance_deposits", "pending_partial_withdrawals", "pending_consolidations" ], "properties" : { "genesis_time" : { "type" : "string", @@ -176,6 +176,54 @@ "description" : "unsigned 64 bit integer", "example" : "1", "format" : "uint64" + }, + "deposit_balance_to_consume" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "exit_balance_to_consume" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "earliest_exit_epoch" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "consolidation_balance_to_consume" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "earliest_consolidation_epoch" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "pending_balance_deposits" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/PendingBalanceDeposit" + } + }, + "pending_partial_withdrawals" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/PendingPartialWithdrawal" + } + }, + "pending_consolidations" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/PendingConsolidation" + } } } } \ No newline at end of file diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingBalanceDeposit.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingBalanceDeposit.json new file mode 100644 index 00000000000..9f93161f54c --- /dev/null +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingBalanceDeposit.json @@ -0,0 +1,19 @@ +{ + "title" : "PendingBalanceDeposit", + "type" : "object", + "required" : [ "index", "amount" ], + "properties" : { + "index" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "amount" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + } + } +} \ No newline at end of file diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingConsolidation.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingConsolidation.json new file mode 100644 index 00000000000..aa9b77f2895 --- /dev/null +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingConsolidation.json @@ -0,0 +1,19 @@ +{ + "title" : "PendingConsolidation", + "type" : "object", + "required" : [ "source_index", "target_index" ], + "properties" : { + "source_index" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "target_index" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + } + } +} \ No newline at end of file diff --git a/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingPartialWithdrawal.json b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingPartialWithdrawal.json new file mode 100644 index 00000000000..34496555bed --- /dev/null +++ b/data/beaconrestapi/src/integration-test/resources/tech/pegasys/teku/beaconrestapi/beacon/schema/PendingPartialWithdrawal.json @@ -0,0 +1,25 @@ +{ + "title" : "PendingPartialWithdrawal", + "type" : "object", + "required" : [ "index", "amount", "epoch" ], + "properties" : { + "index" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "amount" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + }, + "epoch" : { + "type" : "string", + "description" : "unsigned 64 bit integer", + "example" : "1", + "format" : "uint64" + } + } +} \ No newline at end of file diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BeaconStateElectra.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BeaconStateElectra.java index d7d8e33a3e0..9e36efb5542 100644 --- a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BeaconStateElectra.java +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/BeaconStateElectra.java @@ -57,6 +57,30 @@ public class BeaconStateElectra extends BeaconStateAltair { @JsonProperty("deposit_receipts_start_index") public final UInt64 depositReceiptsStartIndex; + @JsonProperty("deposit_balance_to_consume") + public final UInt64 depositBalanceToConsume; + + @JsonProperty("exit_balance_to_consume") + public final UInt64 exitBalanceToConsume; + + @JsonProperty("earliest_exit_epoch") + public final UInt64 earliestExitEpoch; + + @JsonProperty("consolidation_balance_to_consume") + public final UInt64 consolidationBalanceToConsume; + + @JsonProperty("earliest_consolidation_epoch") + public final UInt64 earliestConsolidationEpoch; + + @JsonProperty("pending_balance_deposits") + public final List pendingBalanceDeposits; + + @JsonProperty("pending_partial_withdrawals") + public final List pendingPartialWithdrawals; + + @JsonProperty("pending_consolidations") + public final List pendingConsolidations; + public BeaconStateElectra( @JsonProperty("genesis_time") final UInt64 genesisTime, @JsonProperty("genesis_validators_root") final Bytes32 genesisValidatorsRoot, @@ -87,7 +111,18 @@ public BeaconStateElectra( @JsonProperty("next_withdrawal_index") final UInt64 nextWithdrawalIndex, @JsonProperty("next_withdrawal_validator_index") final UInt64 nextWithdrawalValidatorIndex, @JsonProperty("historical_summaries") final List historicalSummaries, - @JsonProperty("deposit_receipts_start_index") final UInt64 depositReceiptsStartIndex) { + @JsonProperty("deposit_receipts_start_index") final UInt64 depositReceiptsStartIndex, + @JsonProperty("deposit_balance_to_consume") final UInt64 depositBalanceToConsume, + @JsonProperty("exit_balance_to_consume") final UInt64 exitBalanceToConsume, + @JsonProperty("earliest_exit_epoch") final UInt64 earliestExitEpoch, + @JsonProperty("consolidation_balance_to_consume") final UInt64 consolidationBalanceToConsume, + @JsonProperty("earliest_consolidation_epoch") final UInt64 earliestConsolidationEpoch, + @JsonProperty("pending_balance_deposits") + final List pendingBalanceDeposits, + @JsonProperty("pending_partial_withdrawals") + final List pendingPartialWithdrawals, + @JsonProperty("pending_consolidations") + final List pendingConsolidations) { super( genesisTime, genesisValidatorsRoot, @@ -118,6 +153,14 @@ public BeaconStateElectra( this.nextWithdrawalValidatorIndex = nextWithdrawalValidatorIndex; this.historicalSummaries = historicalSummaries; this.depositReceiptsStartIndex = depositReceiptsStartIndex; + this.depositBalanceToConsume = depositBalanceToConsume; + this.exitBalanceToConsume = exitBalanceToConsume; + this.earliestExitEpoch = earliestExitEpoch; + this.consolidationBalanceToConsume = consolidationBalanceToConsume; + this.earliestConsolidationEpoch = earliestConsolidationEpoch; + this.pendingBalanceDeposits = pendingBalanceDeposits; + this.pendingPartialWithdrawals = pendingPartialWithdrawals; + this.pendingConsolidations = pendingConsolidations; } public BeaconStateElectra(final BeaconState beaconState) { @@ -132,6 +175,17 @@ public BeaconStateElectra(final BeaconState beaconState) { this.historicalSummaries = electra.getHistoricalSummaries().stream().map(HistoricalSummary::new).toList(); this.depositReceiptsStartIndex = electra.getDepositReceiptsStartIndex(); + this.depositBalanceToConsume = electra.getDepositBalanceToConsume(); + this.exitBalanceToConsume = electra.getExitBalanceToConsume(); + this.earliestExitEpoch = electra.getEarliestExitEpoch(); + this.consolidationBalanceToConsume = electra.getConsolidationBalanceToConsume(); + this.earliestConsolidationEpoch = electra.getEarliestConsolidationEpoch(); + this.pendingBalanceDeposits = + electra.getPendingBalanceDeposits().stream().map(PendingBalanceDeposit::new).toList(); + this.pendingPartialWithdrawals = + electra.getPendingPartialWithdrawals().stream().map(PendingPartialWithdrawal::new).toList(); + this.pendingConsolidations = + electra.getPendingConsolidations().stream().map(PendingConsolidation::new).toList(); } @Override @@ -153,6 +207,15 @@ protected void applyAdditionalFields( BeaconStateSchemaElectra.required( mutableBeaconStateElectra.getBeaconStateSchema()) .getHistoricalSummariesSchema(), + BeaconStateSchemaElectra.required( + mutableBeaconStateElectra.getBeaconStateSchema()) + .getPendingBalanceDepositsSchema(), + BeaconStateSchemaElectra.required( + mutableBeaconStateElectra.getBeaconStateSchema()) + .getPendingPartialWithdrawalsSchema(), + BeaconStateSchemaElectra.required( + mutableBeaconStateElectra.getBeaconStateSchema()) + .getPendingConsolidationsSchema(), this)); } @@ -164,6 +227,16 @@ protected static void applyElectraFields( final SszListSchema< tech.pegasys.teku.spec.datastructures.state.versions.capella.HistoricalSummary, ?> historicalSummariesSchema, + final SszListSchema< + tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit, ?> + pendingBalanceDepositsSchema, + final SszListSchema< + tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal, + ?> + pendingPartialWithdrawalsSchema, + final SszListSchema< + tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation, ?> + pendingConsolidationsSchema, final BeaconStateElectra instance) { BeaconStateAltair.applyAltairFields(state, syncCommitteeSchema, instance); @@ -181,5 +254,31 @@ protected static void applyElectraFields( historicalSummary -> historicalSummary.asInternalHistoricalSummary(specVersion)) .toList())); state.setDepositReceiptsStartIndex(instance.depositReceiptsStartIndex); + state.setDepositBalanceToConsume(instance.depositBalanceToConsume); + state.setExitBalanceToConsume(instance.exitBalanceToConsume); + state.setEarliestExitEpoch(instance.earliestExitEpoch); + state.setConsolidationBalanceToConsume(instance.consolidationBalanceToConsume); + state.setEarliestConsolidationEpoch(instance.earliestConsolidationEpoch); + state.setPendingBalanceDeposits( + pendingBalanceDepositsSchema.createFromElements( + instance.pendingBalanceDeposits.stream() + .map( + pendingBalanceDeposit -> + pendingBalanceDeposit.asInternalPendingBalanceDeposit(specVersion)) + .toList())); + state.setPendingPartialWithdrawals( + pendingPartialWithdrawalsSchema.createFromElements( + instance.pendingPartialWithdrawals.stream() + .map( + pendingPartialWithdrawal -> + pendingPartialWithdrawal.asInternalPendingPartialWithdrawal(specVersion)) + .toList())); + state.setPendingConsolidations( + pendingConsolidationsSchema.createFromElements( + instance.pendingConsolidations.stream() + .map( + pendingConsolidation -> + pendingConsolidation.asInternalPendingConsolidation(specVersion)) + .toList())); } } diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingBalanceDeposit.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingBalanceDeposit.java new file mode 100644 index 00000000000..b3105b77fe3 --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingBalanceDeposit.java @@ -0,0 +1,57 @@ +/* + * Copyright Consensys Software Inc., 2024 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.api.schema.electra; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Optional; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; + +public class PendingBalanceDeposit { + + @JsonProperty("index") + public final int index; + + @JsonProperty("amount") + public final UInt64 amount; + + public PendingBalanceDeposit( + @JsonProperty("index") int index, @JsonProperty("amount") UInt64 amount) { + this.index = index; + this.amount = amount; + } + + public PendingBalanceDeposit( + final tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit + internalPendingBalanceDeposit) { + this.index = internalPendingBalanceDeposit.getIndex(); + this.amount = internalPendingBalanceDeposit.getAmount(); + } + + public tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit + asInternalPendingBalanceDeposit(final SpecVersion spec) { + final Optional schemaDefinitionsElectra = + spec.getSchemaDefinitions().toVersionElectra(); + if (schemaDefinitionsElectra.isEmpty()) { + throw new IllegalArgumentException( + "Could not create PendingBalanceDeposit for pre-electra spec"); + } + return schemaDefinitionsElectra + .get() + .getPendingBalanceDepositSchema() + .create(SszUInt64.of(UInt64.valueOf(this.index)), SszUInt64.of(this.amount)); + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingConsolidation.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingConsolidation.java new file mode 100644 index 00000000000..cdf90d4400c --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingConsolidation.java @@ -0,0 +1,59 @@ +/* + * Copyright Consensys Software Inc., 2024 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.api.schema.electra; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Optional; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; + +public class PendingConsolidation { + @JsonProperty("source_index") + public final int sourceIndex; + + @JsonProperty("target_index") + public final int targetIndex; + + PendingConsolidation( + @JsonProperty("source_index") int sourceIndex, + @JsonProperty("target_index") int targetIndex) { + this.sourceIndex = sourceIndex; + this.targetIndex = targetIndex; + } + + public PendingConsolidation( + final tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation + internalPendingConsolidation) { + this.sourceIndex = internalPendingConsolidation.getSourceIndex(); + this.targetIndex = internalPendingConsolidation.getTargetIndex(); + } + + public tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation + asInternalPendingConsolidation(final SpecVersion spec) { + final Optional schemaDefinitionsElectra = + spec.getSchemaDefinitions().toVersionElectra(); + if (schemaDefinitionsElectra.isEmpty()) { + throw new IllegalArgumentException( + "Could not create PendingBalanceDeposit for pre-electra spec"); + } + return schemaDefinitionsElectra + .get() + .getPendingConsolidationSchema() + .create( + SszUInt64.of(UInt64.valueOf(this.sourceIndex)), + SszUInt64.of(UInt64.valueOf(this.targetIndex))); + } +} diff --git a/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingPartialWithdrawal.java b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingPartialWithdrawal.java new file mode 100644 index 00000000000..62f14b5a775 --- /dev/null +++ b/data/serializer/src/main/java/tech/pegasys/teku/api/schema/electra/PendingPartialWithdrawal.java @@ -0,0 +1,66 @@ +/* + * Copyright Consensys Software Inc., 2024 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.api.schema.electra; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Optional; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.spec.SpecVersion; +import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; + +public class PendingPartialWithdrawal { + @JsonProperty("index") + public final int index; + + @JsonProperty("amount") + public final UInt64 amount; + + @JsonProperty("withdrawable_epoch") + public final UInt64 epoch; + + public PendingPartialWithdrawal( + @JsonProperty("index") int index, + @JsonProperty("amount") UInt64 amount, + @JsonProperty("withdrawable_epoch") UInt64 epoch) { + this.index = index; + this.amount = amount; + this.epoch = epoch; + } + + public PendingPartialWithdrawal( + final tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal + pendingPartialWithdrawal) { + this.index = pendingPartialWithdrawal.getIndex(); + this.amount = pendingPartialWithdrawal.getAmount(); + this.epoch = pendingPartialWithdrawal.getEpoch(); + } + + public tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal + asInternalPendingPartialWithdrawal(final SpecVersion spec) { + final Optional schemaDefinitionsElectra = + spec.getSchemaDefinitions().toVersionElectra(); + if (schemaDefinitionsElectra.isEmpty()) { + throw new IllegalArgumentException( + "Could not create PendingBalanceDeposit for pre-electra spec"); + } + return schemaDefinitionsElectra + .get() + .getPendingPartialWithdrawalSchema() + .create( + SszUInt64.of(UInt64.valueOf(this.index)), + SszUInt64.of(this.amount), + SszUInt64.of(this.epoch)); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/DelegatingSpecConfig.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/DelegatingSpecConfig.java index 19d4970cc86..470745ea538 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/DelegatingSpecConfig.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/DelegatingSpecConfig.java @@ -296,6 +296,21 @@ public int getReorgParentWeightThreshold() { return specConfig.getReorgParentWeightThreshold(); } + @Override + public int getPendingBalanceDepositsLimit() { + return specConfig.getPendingBalanceDepositsLimit(); + } + + @Override + public int getPendingConsolidationsLimit() { + return specConfig.getPendingConsolidationsLimit(); + } + + @Override + public int getPendingPartialWithdrawalsLimit() { + return specConfig.getPendingPartialWithdrawalsLimit(); + } + @Override public long getDepositChainId() { return specConfig.getDepositChainId(); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfig.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfig.java index dcc2ce1b8af..b4f09c1e995 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfig.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfig.java @@ -186,4 +186,10 @@ default Optional toVersionDeneb() { default Optional toVersionElectra() { return Optional.empty(); } + + int getPendingBalanceDepositsLimit(); + + int getPendingConsolidationsLimit(); + + int getPendingPartialWithdrawalsLimit(); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigPhase0.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigPhase0.java index 87c070098d0..26d57791164 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigPhase0.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/SpecConfigPhase0.java @@ -119,6 +119,9 @@ public class SpecConfigPhase0 implements SpecConfig { private final int reorgMaxEpochsSinceFinalization; private final int reorgHeadWeightThreshold; private final int reorgParentWeightThreshold; + private final int pendingBalanceDepositsLimit; + private final int pendingPartialWithdrawalsLimit; + private final int pendingConsolidationsLimit; public SpecConfigPhase0( final Map rawConfig, @@ -188,7 +191,10 @@ public SpecConfigPhase0( final int attestationSubnetPrefixBits, final int reorgMaxEpochsSinceFinalization, final int reorgHeadWeightThreshold, - final int reorgParentWeightThreshold) { + final int reorgParentWeightThreshold, + final int pendingBalanceDepositsLimit, + final int pendingPartialWithdrawalsLimit, + final int pendingConsolidationsLimit) { this.rawConfig = rawConfig; this.eth1FollowDistance = eth1FollowDistance; this.maxCommitteesPerSlot = maxCommitteesPerSlot; @@ -258,6 +264,9 @@ public SpecConfigPhase0( this.reorgMaxEpochsSinceFinalization = reorgMaxEpochsSinceFinalization; this.reorgHeadWeightThreshold = reorgHeadWeightThreshold; this.reorgParentWeightThreshold = reorgParentWeightThreshold; + this.pendingBalanceDepositsLimit = pendingBalanceDepositsLimit; + this.pendingPartialWithdrawalsLimit = pendingPartialWithdrawalsLimit; + this.pendingConsolidationsLimit = pendingConsolidationsLimit; } @Override @@ -530,6 +539,21 @@ public int getReorgParentWeightThreshold() { return reorgParentWeightThreshold; } + @Override + public int getPendingBalanceDepositsLimit() { + return pendingBalanceDepositsLimit; + } + + @Override + public int getPendingConsolidationsLimit() { + return pendingConsolidationsLimit; + } + + @Override + public int getPendingPartialWithdrawalsLimit() { + return pendingPartialWithdrawalsLimit; + } + @Override public int getProposerScoreBoost() { return proposerScoreBoost; @@ -680,6 +704,9 @@ public boolean equals(final Object o) { && respTimeout == that.respTimeout && attestationPropagationSlotRange == that.attestationPropagationSlotRange && maximumGossipClockDisparity == that.maximumGossipClockDisparity + && pendingBalanceDepositsLimit == that.pendingBalanceDepositsLimit + && pendingPartialWithdrawalsLimit == that.pendingPartialWithdrawalsLimit + && pendingConsolidationsLimit == that.pendingConsolidationsLimit && Objects.equals(eth1FollowDistance, that.eth1FollowDistance) && Objects.equals(minGenesisTime, that.minGenesisTime) && Objects.equals(hysteresisQuotient, that.hysteresisQuotient) @@ -766,6 +793,9 @@ public int hashCode() { subnetsPerNode, attestationSubnetCount, attestationSubnetExtraBits, - attestationSubnetPrefixBits); + attestationSubnetPrefixBits, + pendingBalanceDepositsLimit, + pendingPartialWithdrawalsLimit, + pendingConsolidationsLimit); } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/builder/SpecConfigBuilder.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/builder/SpecConfigBuilder.java index 72abe2516d5..9eaeef15aa8 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/builder/SpecConfigBuilder.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/config/builder/SpecConfigBuilder.java @@ -130,6 +130,10 @@ public class SpecConfigBuilder { private Integer reorgParentWeightThreshold = 160; + private Integer pendingBalanceDepositsLimit = 134217728; + private Integer pendingPartialWithdrawalsLimit = 134217728; + private Integer pendingConsolidationsLimit = 262144; + private final BuilderChain builderChain = BuilderChain.create(new AltairBuilder()) .appendBuilder(new BellatrixBuilder()) @@ -214,7 +218,10 @@ public SpecConfig build() { attestationSubnetPrefixBits, reorgMaxEpochsSinceFinalization, reorgHeadWeightThreshold, - reorgParentWeightThreshold); + reorgParentWeightThreshold, + pendingBalanceDepositsLimit, + pendingPartialWithdrawalsLimit, + pendingConsolidationsLimit); return builderChain.build(config); } @@ -288,6 +295,10 @@ private Map getValidationMap() { constants.put("reorgMaxEpochsSinceFinalization", reorgMaxEpochsSinceFinalization); constants.put("reorgHeadWeightThreshold", reorgHeadWeightThreshold); constants.put("reorgParentWeightThreshold", reorgParentWeightThreshold); + + constants.put("pendingBalanceDepositsLimit", pendingBalanceDepositsLimit); + constants.put("pendingPartialWithdrawalsLimit", pendingPartialWithdrawalsLimit); + constants.put("pendingConsolidationsLimit", pendingConsolidationsLimit); return constants; } @@ -513,6 +524,22 @@ public SpecConfigBuilder historicalRootsLimit(final Integer historicalRootsLimit return this; } + public SpecConfigBuilder pendingBalanceDepositsLimit(final Integer pendingBalanceDepositsLimit) { + this.pendingBalanceDepositsLimit = pendingBalanceDepositsLimit; + return this; + } + + public SpecConfigBuilder pendingPartialWithdrawalsLimit( + final Integer pendingPartialWithdrawalsLimit) { + this.pendingPartialWithdrawalsLimit = pendingPartialWithdrawalsLimit; + return this; + } + + public SpecConfigBuilder pendingConsolidationsLimit(final Integer pendingConsolidationsLimit) { + this.pendingConsolidationsLimit = pendingConsolidationsLimit; + return this; + } + public SpecConfigBuilder validatorRegistryLimit(final Long validatorRegistryLimit) { checkNotNull(validatorRegistryLimit); this.validatorRegistryLimit = validatorRegistryLimit; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/common/BeaconStateFields.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/common/BeaconStateFields.java index d63e6444dd7..aeed13192f9 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/common/BeaconStateFields.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/common/BeaconStateFields.java @@ -70,7 +70,16 @@ public enum BeaconStateFields implements SszFieldName { NEXT_WITHDRAWAL_VALIDATOR_INDEX, HISTORICAL_SUMMARIES, // Electra fields - DEPOSIT_RECEIPTS_START_INDEX; + DEPOSIT_RECEIPTS_START_INDEX, + + DEPOSIT_BALANCE_TO_CONSUME, + EXIT_BALANCE_TO_CONSUME, + EARLIEST_EXIT_EPOCH, + CONSOLIDATION_BALANCE_TO_CONSUME, + EARLIEST_CONSOLIDATION_EPOCH, + PENDING_BALANCE_DEPOSITS, + PENDING_PARTIAL_WITHDRAWALS, + PENDING_CONSOLIDATIONS; private final String sszFieldName; diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateElectra.java index b5121a1b17d..77f19625d08 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateElectra.java @@ -13,14 +13,26 @@ package tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra; +import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.CONSOLIDATION_BALANCE_TO_CONSUME; +import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.DEPOSIT_BALANCE_TO_CONSUME; import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.DEPOSIT_RECEIPTS_START_INDEX; +import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.EARLIEST_CONSOLIDATION_EPOCH; +import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.EARLIEST_EXIT_EPOCH; +import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.EXIT_BALANCE_TO_CONSUME; +import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.PENDING_BALANCE_DEPOSITS; +import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.PENDING_CONSOLIDATIONS; +import static tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields.PENDING_PARTIAL_WITHDRAWALS; import com.google.common.base.MoreObjects; import java.util.Optional; +import tech.pegasys.teku.infrastructure.ssz.SszList; import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.BeaconStateDeneb; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; public interface BeaconStateElectra extends BeaconStateDeneb { static BeaconStateElectra required(final BeaconState state) { @@ -58,4 +70,44 @@ default UInt64 getDepositReceiptsStartIndex() { final int index = getSchema().getFieldIndex(DEPOSIT_RECEIPTS_START_INDEX); return ((SszUInt64) get(index)).get(); } + + default UInt64 getDepositBalanceToConsume() { + final int index = getSchema().getFieldIndex(DEPOSIT_BALANCE_TO_CONSUME); + return ((SszUInt64) get(index)).get(); + } + + default UInt64 getExitBalanceToConsume() { + final int index = getSchema().getFieldIndex(EXIT_BALANCE_TO_CONSUME); + return ((SszUInt64) get(index)).get(); + } + + default UInt64 getEarliestExitEpoch() { + final int index = getSchema().getFieldIndex(EARLIEST_EXIT_EPOCH); + return ((SszUInt64) get(index)).get(); + } + + default UInt64 getConsolidationBalanceToConsume() { + final int index = getSchema().getFieldIndex(CONSOLIDATION_BALANCE_TO_CONSUME); + return ((SszUInt64) get(index)).get(); + } + + default UInt64 getEarliestConsolidationEpoch() { + final int index = getSchema().getFieldIndex(EARLIEST_CONSOLIDATION_EPOCH); + return ((SszUInt64) get(index)).get(); + } + + default SszList getPendingBalanceDeposits() { + final int index = getSchema().getFieldIndex(PENDING_BALANCE_DEPOSITS); + return getAny(index); + } + + default SszList getPendingPartialWithdrawals() { + final int index = getSchema().getFieldIndex(PENDING_PARTIAL_WITHDRAWALS); + return getAny(index); + } + + default SszList getPendingConsolidations() { + final int index = getSchema().getFieldIndex(PENDING_CONSOLIDATIONS); + return getAny(index); + } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateSchemaElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateSchemaElectra.java index b0215c5259b..60e74c18542 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateSchemaElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/BeaconStateSchemaElectra.java @@ -38,10 +38,21 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateSchemaAltair; import tech.pegasys.teku.spec.datastructures.state.versions.capella.HistoricalSummary; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; public class BeaconStateSchemaElectra extends AbstractBeaconStateSchema { public static final int DEPOSIT_RECEIPTS_START_INDEX = 28; + public static final int DEPOSIT_BALANCE_TO_CONSUME_INDEX = 29; + public static final int EXIT_BALANCE_TO_CONSUME_INDEX = 30; + public static final int EARLIEST_EXIT_EPOCH_INDEX = 31; + public static final int CONSOLIDATION_BALANCE_TO_CONSUME_INDEX = 32; + public static final int EARLIEST_CONSOLIDATION_EPOCH_INDEX = 33; + public static final int PENDING_BALANCE_DEPOSITS_INDEX = 34; + public static final int PENDING_PARTIAL_WITHDRAWALS_INDEX = 35; + public static final int PENDING_CONSOLIDATIONS_INDEX = 36; @VisibleForTesting BeaconStateSchemaElectra(final SpecConfig specConfig) { @@ -51,6 +62,12 @@ public class BeaconStateSchemaElectra private static List getUniqueFields(final SpecConfig specConfig) { final HistoricalSummary.HistoricalSummarySchema historicalSummarySchema = new HistoricalSummary.HistoricalSummarySchema(); + final PendingBalanceDeposit.PendingBalanceDepositSchema pendingBalanceDepositSchema = + new PendingBalanceDeposit.PendingBalanceDepositSchema(); + final PendingPartialWithdrawal.PendingPartialWithdrawalSchema pendingPartialWithdrawalSchema = + new PendingPartialWithdrawal.PendingPartialWithdrawalSchema(); + final PendingConsolidation.PendingConsolidationSchema pendingConsolidationSchema = + new PendingConsolidation.PendingConsolidationSchema(); final SszField latestExecutionPayloadHeaderField = new SszField( LATEST_EXECUTION_PAYLOAD_HEADER_FIELD_INDEX, @@ -79,6 +96,53 @@ private static List getUniqueFields(final SpecConfig specConfig) { DEPOSIT_RECEIPTS_START_INDEX, BeaconStateFields.DEPOSIT_RECEIPTS_START_INDEX, () -> SszPrimitiveSchemas.UINT64_SCHEMA); + final SszField depositBalanceToConsumeField = + new SszField( + DEPOSIT_BALANCE_TO_CONSUME_INDEX, + BeaconStateFields.DEPOSIT_BALANCE_TO_CONSUME, + () -> SszPrimitiveSchemas.UINT64_SCHEMA); + final SszField exitBalanceToConsumeField = + new SszField( + EXIT_BALANCE_TO_CONSUME_INDEX, + BeaconStateFields.EXIT_BALANCE_TO_CONSUME, + () -> SszPrimitiveSchemas.UINT64_SCHEMA); + final SszField earliestExitEpochField = + new SszField( + EARLIEST_EXIT_EPOCH_INDEX, + BeaconStateFields.EARLIEST_EXIT_EPOCH, + () -> SszPrimitiveSchemas.UINT64_SCHEMA); + final SszField consolidationBalanceToConsumeField = + new SszField( + CONSOLIDATION_BALANCE_TO_CONSUME_INDEX, + BeaconStateFields.CONSOLIDATION_BALANCE_TO_CONSUME, + () -> SszPrimitiveSchemas.UINT64_SCHEMA); + final SszField earliestConsolidationEpochField = + new SszField( + EARLIEST_CONSOLIDATION_EPOCH_INDEX, + BeaconStateFields.EARLIEST_CONSOLIDATION_EPOCH, + () -> SszPrimitiveSchemas.UINT64_SCHEMA); + final SszField pendingBalanceDepositsField = + new SszField( + PENDING_BALANCE_DEPOSITS_INDEX, + BeaconStateFields.PENDING_BALANCE_DEPOSITS, + () -> + SszListSchema.create( + pendingBalanceDepositSchema, specConfig.getPendingBalanceDepositsLimit())); + final SszField pendingPartialWithdrawalsField = + new SszField( + PENDING_PARTIAL_WITHDRAWALS_INDEX, + BeaconStateFields.PENDING_PARTIAL_WITHDRAWALS, + () -> + SszListSchema.create( + pendingPartialWithdrawalSchema, + specConfig.getPendingPartialWithdrawalsLimit())); + final SszField pendingConsolidationsField = + new SszField( + PENDING_CONSOLIDATIONS_INDEX, + BeaconStateFields.PENDING_CONSOLIDATIONS, + () -> + SszListSchema.create( + pendingConsolidationSchema, specConfig.getPendingConsolidationsLimit())); return Stream.concat( BeaconStateSchemaAltair.getUniqueFields(specConfig).stream(), Stream.of( @@ -86,7 +150,15 @@ private static List getUniqueFields(final SpecConfig specConfig) { nextWithdrawalIndexField, nextWithdrawalValidatorIndexField, historicalSummariesField, - depositReceiptsStartIndexField)) + depositReceiptsStartIndexField, + depositBalanceToConsumeField, + exitBalanceToConsumeField, + earliestExitEpochField, + consolidationBalanceToConsumeField, + earliestConsolidationEpochField, + pendingBalanceDepositsField, + pendingPartialWithdrawalsField, + pendingConsolidationsField)) .toList(); } @@ -153,4 +225,22 @@ private BeaconStateElectraImpl createEmptyBeaconStateImpl() { public BeaconStateElectraImpl createFromBackingNode(TreeNode node) { return new BeaconStateElectraImpl(this, node); } + + @SuppressWarnings("unchecked") + public SszListSchema getPendingBalanceDepositsSchema() { + return (SszListSchema) + getChildSchema(getFieldIndex(BeaconStateFields.PENDING_BALANCE_DEPOSITS)); + } + + @SuppressWarnings("unchecked") + public SszListSchema getPendingPartialWithdrawalsSchema() { + return (SszListSchema) + getChildSchema(getFieldIndex(BeaconStateFields.PENDING_PARTIAL_WITHDRAWALS)); + } + + @SuppressWarnings("unchecked") + public SszListSchema getPendingConsolidationsSchema() { + return (SszListSchema) + getChildSchema(getFieldIndex(BeaconStateFields.PENDING_CONSOLIDATIONS)); + } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/MutableBeaconStateElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/MutableBeaconStateElectra.java index 7e03486adad..7db3042e85e 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/MutableBeaconStateElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/beaconstate/versions/electra/MutableBeaconStateElectra.java @@ -14,11 +14,15 @@ package tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra; import java.util.Optional; +import tech.pegasys.teku.infrastructure.ssz.SszList; import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.common.BeaconStateFields; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.deneb.MutableBeaconStateDeneb; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; public interface MutableBeaconStateElectra extends MutableBeaconStateDeneb, BeaconStateElectra { static MutableBeaconStateElectra required(final MutableBeaconState state) { @@ -43,4 +47,47 @@ default void setDepositReceiptsStartIndex(final UInt64 depositReceiptsStartIndex default Optional toMutableVersionElectra() { return Optional.of(this); } + + default void setDepositBalanceToConsume(final UInt64 depositBalanceToConsume) { + final int fieldIndex = getSchema().getFieldIndex(BeaconStateFields.DEPOSIT_BALANCE_TO_CONSUME); + set(fieldIndex, SszUInt64.of(depositBalanceToConsume)); + } + + default void setExitBalanceToConsume(final UInt64 exitBalanceToConsume) { + final int fieldIndex = getSchema().getFieldIndex(BeaconStateFields.EXIT_BALANCE_TO_CONSUME); + set(fieldIndex, SszUInt64.of(exitBalanceToConsume)); + } + + default void setEarliestExitEpoch(final UInt64 earliestExitEpoch) { + final int fieldIndex = getSchema().getFieldIndex(BeaconStateFields.EARLIEST_EXIT_EPOCH); + set(fieldIndex, SszUInt64.of(earliestExitEpoch)); + } + + default void setConsolidationBalanceToConsume(final UInt64 consolidationBalanceToConsume) { + final int fieldIndex = + getSchema().getFieldIndex(BeaconStateFields.CONSOLIDATION_BALANCE_TO_CONSUME); + set(fieldIndex, SszUInt64.of(consolidationBalanceToConsume)); + } + + default void setEarliestConsolidationEpoch(final UInt64 earliestConsolidationEpoch) { + final int fieldIndex = + getSchema().getFieldIndex(BeaconStateFields.EARLIEST_CONSOLIDATION_EPOCH); + set(fieldIndex, SszUInt64.of(earliestConsolidationEpoch)); + } + + default void setPendingBalanceDeposits(SszList pendingBalanceDeposits) { + final int fieldIndex = getSchema().getFieldIndex(BeaconStateFields.PENDING_BALANCE_DEPOSITS); + set(fieldIndex, pendingBalanceDeposits); + } + + default void setPendingPartialWithdrawals( + SszList pendingPartialWithdrawals) { + final int fieldIndex = getSchema().getFieldIndex(BeaconStateFields.PENDING_PARTIAL_WITHDRAWALS); + set(fieldIndex, pendingPartialWithdrawals); + } + + default void setPendingConsolidations(SszList pendingConsolidations) { + final int fieldIndex = getSchema().getFieldIndex(BeaconStateFields.PENDING_CONSOLIDATIONS); + set(fieldIndex, pendingConsolidations); + } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingBalanceDeposit.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingBalanceDeposit.java new file mode 100644 index 00000000000..6973406b8d8 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingBalanceDeposit.java @@ -0,0 +1,69 @@ +/* + * Copyright Consensys Software Inc., 2024 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.state.versions.electra; + +import tech.pegasys.teku.infrastructure.ssz.containers.Container2; +import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema2; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; + +public class PendingBalanceDeposit extends Container2 { + public static class PendingBalanceDepositSchema + extends ContainerSchema2 { + + public PendingBalanceDepositSchema() { + super( + "PendingBalanceDeposit", + namedSchema("index", SszPrimitiveSchemas.UINT64_SCHEMA), + namedSchema("amount", SszPrimitiveSchemas.UINT64_SCHEMA)); + } + + @Override + public PendingBalanceDeposit createFromBackingNode(final TreeNode node) { + return new PendingBalanceDeposit(this, node); + } + + public PendingBalanceDeposit create(final SszUInt64 index, final SszUInt64 amount) { + return new PendingBalanceDeposit(this, index, amount); + } + + public SszUInt64 getIndexSchema() { + return (SszUInt64) getFieldSchema0(); + } + + public SszUInt64 getAmountSchema() { + return (SszUInt64) getFieldSchema1(); + } + } + + private PendingBalanceDeposit( + final PendingBalanceDepositSchema type, final TreeNode backingNode) { + super(type, backingNode); + } + + private PendingBalanceDeposit( + PendingBalanceDepositSchema type, final SszUInt64 index, final SszUInt64 amount) { + super(type, index, amount); + } + + public int getIndex() { + return ((SszUInt64) get(0)).get().intValue(); + } + + public UInt64 getAmount() { + return ((SszUInt64) get(1)).get(); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingConsolidation.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingConsolidation.java new file mode 100644 index 00000000000..f67b4a2329e --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingConsolidation.java @@ -0,0 +1,65 @@ +/* + * Copyright Consensys Software Inc., 2024 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.state.versions.electra; + +import tech.pegasys.teku.infrastructure.ssz.containers.Container2; +import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema2; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; + +public class PendingConsolidation extends Container2 { + protected PendingConsolidation( + ContainerSchema2 schema) { + super(schema); + } + + public PendingConsolidation( + final PendingConsolidationSchema pendingConsolidationSchema, + final SszUInt64 sourceIndex, + final SszUInt64 targetIndex) { + super(pendingConsolidationSchema, sourceIndex, targetIndex); + } + + public static class PendingConsolidationSchema + extends ContainerSchema2 { + public PendingConsolidationSchema() { + super( + "PendingConsolidation", + namedSchema("source_index", SszPrimitiveSchemas.UINT64_SCHEMA), + namedSchema("target_index", SszPrimitiveSchemas.UINT64_SCHEMA)); + } + + @Override + public PendingConsolidation createFromBackingNode(TreeNode node) { + return new PendingConsolidation(this, node); + } + + public PendingConsolidation create(final SszUInt64 sourceIndex, final SszUInt64 targetIndex) { + return new PendingConsolidation(this, sourceIndex, targetIndex); + } + } + + private PendingConsolidation(final PendingConsolidationSchema type, final TreeNode backingNode) { + super(type, backingNode); + } + + public int getSourceIndex() { + return ((SszUInt64) get(0)).get().intValue(); + } + + public int getTargetIndex() { + return ((SszUInt64) get(1)).get().intValue(); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingPartialWithdrawal.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingPartialWithdrawal.java new file mode 100644 index 00000000000..a3c95ee00a1 --- /dev/null +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/state/versions/electra/PendingPartialWithdrawal.java @@ -0,0 +1,78 @@ +/* + * Copyright Consensys Software Inc., 2024 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package tech.pegasys.teku.spec.datastructures.state.versions.electra; + +import tech.pegasys.teku.infrastructure.ssz.containers.Container3; +import tech.pegasys.teku.infrastructure.ssz.containers.ContainerSchema3; +import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; +import tech.pegasys.teku.infrastructure.ssz.schema.SszPrimitiveSchemas; +import tech.pegasys.teku.infrastructure.ssz.tree.TreeNode; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; + +public class PendingPartialWithdrawal + extends Container3 { + + public static class PendingPartialWithdrawalSchema + extends ContainerSchema3 { + public PendingPartialWithdrawalSchema() { + super( + "PendingPartialWithdrawal", + namedSchema("index", SszPrimitiveSchemas.UINT64_SCHEMA), + namedSchema("amount", SszPrimitiveSchemas.UINT64_SCHEMA), + namedSchema("epoch", SszPrimitiveSchemas.UINT64_SCHEMA)); + } + + public PendingPartialWithdrawal create( + final SszUInt64 index, final SszUInt64 amount, final SszUInt64 epoch) { + return new PendingPartialWithdrawal(this, index, amount, epoch); + } + + public SszUInt64 getIndexSchema() { + return (SszUInt64) getFieldSchema0(); + } + + public SszUInt64 getAmountSchema() { + return (SszUInt64) getFieldSchema1(); + } + + public SszUInt64 getEpochSchema() { + return (SszUInt64) getFieldSchema2(); + } + + @Override + public PendingPartialWithdrawal createFromBackingNode(TreeNode node) { + return null; + } + } + + private PendingPartialWithdrawal( + PendingPartialWithdrawal.PendingPartialWithdrawalSchema type, + final SszUInt64 index, + final SszUInt64 amount, + final SszUInt64 epoch) { + super(type, index, amount, epoch); + } + + public int getIndex() { + return ((SszUInt64) get(0)).get().intValue(); + } + + public UInt64 getAmount() { + return ((SszUInt64) get(1)).get(); + } + + public UInt64 getEpoch() { + return ((SszUInt64) get(2)).get(); + } +} diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java index 5bc528b2576..811c82bf3ac 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/schemas/SchemaDefinitionsElectra.java @@ -48,6 +48,9 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateSchemaElectra; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; public class SchemaDefinitionsElectra extends SchemaDefinitionsDeneb { @@ -76,6 +79,12 @@ public class SchemaDefinitionsElectra extends SchemaDefinitionsDeneb { private final ExecutionLayerExitSchema executionLayerExitSchema; + private final PendingBalanceDeposit.PendingBalanceDepositSchema pendingBalanceDepositSchema; + + private final PendingPartialWithdrawal.PendingPartialWithdrawalSchema + pendingPartialWithdrawalSchema; + private final PendingConsolidation.PendingConsolidationSchema pendingConsolidationSchema; + public SchemaDefinitionsElectra(final SpecConfigElectra specConfig) { super(specConfig); this.executionPayloadSchemaElectra = new ExecutionPayloadSchemaElectra(specConfig); @@ -126,6 +135,10 @@ public SchemaDefinitionsElectra(final SpecConfigElectra specConfig) { this.depositReceiptSchema = DepositReceipt.SSZ_SCHEMA; this.executionLayerExitSchema = ExecutionLayerExit.SSZ_SCHEMA; + this.pendingBalanceDepositSchema = new PendingBalanceDeposit.PendingBalanceDepositSchema(); + this.pendingPartialWithdrawalSchema = + new PendingPartialWithdrawal.PendingPartialWithdrawalSchema(); + this.pendingConsolidationSchema = new PendingConsolidation.PendingConsolidationSchema(); } public static SchemaDefinitionsElectra required(final SchemaDefinitions schemaDefinitions) { @@ -251,8 +264,21 @@ public ExecutionLayerExitSchema getExecutionLayerExitSchema() { return executionLayerExitSchema; } + public PendingBalanceDeposit.PendingBalanceDepositSchema getPendingBalanceDepositSchema() { + return pendingBalanceDepositSchema; + } + + public PendingPartialWithdrawal.PendingPartialWithdrawalSchema + getPendingPartialWithdrawalSchema() { + return pendingPartialWithdrawalSchema; + } + @Override public Optional toVersionElectra() { return Optional.of(this); } + + public PendingConsolidation.PendingConsolidationSchema getPendingConsolidationSchema() { + return pendingConsolidationSchema; + } } diff --git a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/phase0.yaml b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/phase0.yaml index 2c6fbb36915..02bfdacb355 100644 --- a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/phase0.yaml +++ b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/phase0.yaml @@ -63,6 +63,13 @@ HISTORICAL_ROOTS_LIMIT: 16777216 # 2**40 (= 1,099,511,627,776) validator spots VALIDATOR_REGISTRY_LIMIT: 1099511627776 +# 2**27 (= 134,217,728) pending balance deposits +PENDING_BALANCE_DEPOSITS_LIMIT: 134217728 +# 2**27 (= 134,217,728) pending partial withdrawals +PENDING_PARTIAL_WITHDRAWALS_LIMIT: 134217728 +# 2**18 (= 262,144) pending consolidations +PENDING_CONSOLIDATIONS_LIMIT: 262144 + # Reward and penalty quotients # --------------------------------------------------------------- diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/BeaconStateBuilderElectra.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/BeaconStateBuilderElectra.java index 3352d73aa28..381910f75d3 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/BeaconStateBuilderElectra.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/util/BeaconStateBuilderElectra.java @@ -15,6 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import java.util.List; import tech.pegasys.teku.infrastructure.ssz.SszList; import tech.pegasys.teku.infrastructure.ssz.collections.SszUInt64List; import tech.pegasys.teku.infrastructure.ssz.primitive.SszByte; @@ -28,6 +29,9 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateSchemaElectra; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingBalanceDeposit; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingConsolidation; +import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal; public class BeaconStateBuilderElectra extends AbstractBeaconStateBuilder< @@ -43,6 +47,17 @@ public class BeaconStateBuilderElectra private ExecutionPayloadHeader latestExecutionPayloadHeader; private UInt64 depositReceiptsStartIndex; + private UInt64 depositBalanceToConsume; + private UInt64 exitBalanceToConsume; + private UInt64 earliestExitEpoch; + + private UInt64 consolidationBalanceToConsume; + + private UInt64 earliestConsolidationEpoch; + + private SszList pendingBalanceDeposits; + private SszList pendingPartialWithdrawals; + private SszList pendingConsolidations; protected BeaconStateBuilderElectra( final SpecVersion spec, @@ -68,6 +83,14 @@ protected void setUniqueFields(final MutableBeaconStateElectra state) { state.setNextWithdrawalIndex(nextWithdrawalIndex); state.setNextWithdrawalValidatorIndex(nextWithdrawalValidatorIndex); state.setDepositReceiptsStartIndex(depositReceiptsStartIndex); + state.setDepositBalanceToConsume(depositBalanceToConsume); + state.setExitBalanceToConsume(exitBalanceToConsume); + state.setEarliestExitEpoch(earliestExitEpoch); + state.setConsolidationBalanceToConsume(consolidationBalanceToConsume); + state.setEarliestConsolidationEpoch(earliestConsolidationEpoch); + state.setPendingBalanceDeposits(pendingBalanceDeposits); + state.setPendingPartialWithdrawals(pendingPartialWithdrawals); + state.setPendingConsolidations(pendingConsolidations); } public static BeaconStateBuilderElectra create( @@ -102,6 +125,12 @@ public BeaconStateBuilderElectra depositReceiptsStartIndex( return this; } + public BeaconStateBuilderElectra depositBalanceToConsume(final UInt64 depositBalanceToConsume) { + checkNotNull(depositBalanceToConsume); + this.depositBalanceToConsume = depositBalanceToConsume; + return this; + } + private BeaconStateSchemaElectra getBeaconStateSchema() { return (BeaconStateSchemaElectra) spec.getSchemaDefinitions().getBeaconStateSchema(); } @@ -138,5 +167,16 @@ protected void initDefaults() { : UInt64.ZERO; this.depositReceiptsStartIndex = SpecConfigElectra.UNSET_DEPOSIT_RECEIPTS_START_INDEX; + this.depositBalanceToConsume = UInt64.ZERO; + this.exitBalanceToConsume = UInt64.ZERO; + this.earliestExitEpoch = UInt64.ZERO; + this.consolidationBalanceToConsume = UInt64.ZERO; + this.earliestConsolidationEpoch = UInt64.ZERO; + this.pendingBalanceDeposits = + schema.getPendingBalanceDepositsSchema().createFromElements(List.of()); + this.pendingPartialWithdrawals = + schema.getPendingPartialWithdrawalsSchema().createFromElements(List.of()); + this.pendingConsolidations = + schema.getPendingConsolidationsSchema().createFromElements(List.of()); } }