From 81e421bd3a9c39e5804f9a5a14506e6bb5e0a976 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 27 Feb 2019 20:07:26 +0600 Subject: [PATCH 01/21] Update get_shuffle in SpecHelpers --- .../beacon/consensus/SpecHelpers.java | 108 +++++++++++++----- .../beacon/core/spec/MiscParameters.java | 4 + .../pegasys/artemis/util/uint/UInt64.java | 14 ++- 3 files changed, 98 insertions(+), 28 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 923153cc1..3593eaac6 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -34,9 +34,9 @@ import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.bytes.Bytes3; import tech.pegasys.artemis.util.bytes.Bytes32; -import tech.pegasys.artemis.util.bytes.Bytes32s; import tech.pegasys.artemis.util.bytes.Bytes8; import tech.pegasys.artemis.util.bytes.BytesValue; +import tech.pegasys.artemis.util.bytes.BytesValues; import tech.pegasys.artemis.util.collections.ReadList; import tech.pegasys.artemis.util.uint.UInt64; import tech.pegasys.artemis.util.uint.UInt64s; @@ -126,6 +126,8 @@ int get_epoch_committee_count(int active_validator_count) { )).times(spec.getEpochLength()).intValue(); } + + /* def get_previous_epoch_committee_count(state: BeaconState) -> int: """ @@ -447,6 +449,60 @@ public List shuffle(List values, Hash32 seed) { return output; } + /* + def get_permuted_index(index: int, list_size: int, seed: Bytes32) -> int: + """ + Return `p(index)` in a pseudorandom permutation `p` of `0...list_size-1` with ``seed`` as entropy. + + Utilizes 'swap or not' shuffling found in + https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf + See the 'generalized domain' algorithm on page 3. + """ + assert index < list_size + assert list_size <= 2**40 + + for round in range(SHUFFLE_ROUND_COUNT): + pivot = bytes_to_int(hash(seed + int_to_bytes1(round))[0:8]) % list_size + flip = (pivot - index) % list_size + position = max(index, flip) + source = hash(seed + int_to_bytes1(round) + int_to_bytes4(position // 256)) + byte = source[(position % 256) // 8] + bit = (byte >> (position % 8)) % 2 + index = flip if bit else index + + return index + */ + public UInt64 get_permuted_index(UInt64 index, UInt64 listSize, Bytes32 seed) { + assertTrue(index.compareTo(listSize) < 0); + assertTrue(listSize.compareTo(UInt64.valueOf(1L << 40)) <= 0); + + for (int round = 0; round < spec.getShuffleRoundCount(); round++) { + Bytes8 pivotBytes = Bytes8.wrap(hash(seed.concat(int_to_bytes1(round))), 0); + UInt64 pivot = bytes_to_int(pivotBytes).modulo(listSize); + UInt64 flip = pivot.minus(index).modulo(listSize); + UInt64 position = UInt64s.max(index, flip); + BytesValue positionBytes = int_to_bytes4(position.dividedBy(UInt64.valueOf(256)).getValue()); + Bytes32 source = hash(seed.concat(int_to_bytes1(round)).concat(positionBytes)); + byte byt = source.get(position.modulo(256).getIntValue() / 8); + byte bit = (byte) ((byt >> (position.modulo(8).getIntValue())) % 2); + index = bit > 0 ? flip : index; + } + + return index; + } + + public UInt64 bytes_to_int(Bytes8 bytes) { + return UInt64.fromBytesLittleEndian(bytes); + } + + public BytesValue int_to_bytes1(int value) { + return BytesValues.ofUnsignedByte(value); + } + + public BytesValue int_to_bytes4(long value) { + return BytesValues.ofUnsignedInt(value); + } + /* def split(values: List[Any], split_count: int) -> List[Any]: """ @@ -468,33 +524,33 @@ public List> split(List values, int split_count) { return ret; } - // def get_shuffling(randao_mix: Hash32, - // validators: List[ValidatorRecord], - // slot: int) -> List[List[int]] - // """ - // Shuffles ``validators`` into shard committees seeded by ``seed`` and ``slot``. - // Returns a list of ``EPOCH_LENGTH * committees_per_slot`` committees where each - // committee is itself a list of validator indices. - // """ - public List> get_shuffling(Hash32 _seed, + /* + def get_shuffling(seed: Bytes32, + validators: List[Validator], + epoch: Epoch) -> List[List[ValidatorIndex]] + """ + Shuffle active validators and split into crosslink committees. + Return a list of committees (each a list of validator indices). + """ + # Shuffle active validator indices + active_validator_indices = get_active_validator_indices(validators, epoch) + length = len(active_validator_indices) + shuffled_indices = [active_validator_indices[get_permuted_index(i, length, seed)] for i in range(length)] + + # Split the shuffled active validator indices + return split(shuffled_indices, get_epoch_committee_count(length)) + */ + public List> get_shuffling(Hash32 seed, ReadList validators, EpochNumber epoch) { - - - // active_validator_indices = get_active_validator_indices(validators, slot) - List active_validator_indices = get_active_validator_indices(validators, epoch); - // committees_per_epoch = get_epoch_committee_count(len(active_validator_indices)) - int committees_per_epoch = get_epoch_committee_count(active_validator_indices.size()); - - // # Shuffle - // seed = xor(seed, int_to_bytes32(epoch)) - Hash32 seed = Hash32.wrap(Bytes32s.xor(_seed, Bytes32.leftPad(epoch.toBytesBigEndian()))); - - // shuffled_active_validator_indices = shuffle(active_validator_indices, seed) - List shuffled_active_validator_indices = shuffle(active_validator_indices, seed); - // # Split the shuffled list into committees_per_epoch pieces - // return split(shuffled_active_validator_indices, committees_per_epoch) - return split(shuffled_active_validator_indices, committees_per_epoch); + List active_validator_indices = get_active_validator_indices(validators, epoch); + int length = active_validator_indices.size(); + List shuffled_indices = + IntStream.range(0, length) + .mapToObj(i -> get_permuted_index(UInt64.valueOf(i), UInt64.valueOf(length), seed)) + .map(permutedIndex -> active_validator_indices.get(permutedIndex.getIntValue())) + .collect(toList()); + return split(shuffled_indices, get_epoch_committee_count(length)); } /* diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java b/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java index 9bab48ebd..6681aabad 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java @@ -21,6 +21,7 @@ public interface MiscParameters { ShardNumber BEACON_CHAIN_SHARD_NUMBER = ShardNumber.of(UInt64.MAX_VALUE); // (1 << 64) - 1 UInt64 MAX_INDICES_PER_SLASHABLE_VOTE = UInt64.valueOf(1 << 12); UInt64 MAX_WITHDRAWALS_PER_EPOCH = UInt64.valueOf(1 << 2); // 4 + int SHUFFLE_ROUND_COUNT = 90; /* Values defined in the spec. */ @@ -52,4 +53,7 @@ default UInt64 getMaxWithdrawalsPerEpoch() { return MAX_WITHDRAWALS_PER_EPOCH; } + default int getShuffleRoundCount() { + return SHUFFLE_ROUND_COUNT; + } } diff --git a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java index dcf23ceb4..8be16751b 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java +++ b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java @@ -77,8 +77,18 @@ public static UInt64 valueOf(String unsignedStringValue) throws NumberFormatExce } public static UInt64 fromBytesBigEndian(Bytes8 bytes) { - ByteBuffer byteBuffer = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.BIG_ENDIAN) - .put(bytes.getArrayUnsafe()); + return fromBytes(bytes, true); + } + + public static UInt64 fromBytesLittleEndian(Bytes8 bytes) { + return fromBytes(bytes, false); + } + + private static UInt64 fromBytes(Bytes8 bytes, boolean bigEndian) { + ByteBuffer byteBuffer = + ByteBuffer.allocate(Long.BYTES) + .order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN) + .put(bytes.getArrayUnsafe()); byteBuffer.rewind(); return valueOf(byteBuffer.getLong()); } From 831969fcedf9ff1a423112142d845f11e9fa8e2d Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 27 Feb 2019 20:07:26 +0600 Subject: [PATCH 02/21] Update get_shuffle in SpecHelpers --- .../beacon/consensus/SpecHelpers.java | 108 +++++++++++++----- .../beacon/core/spec/MiscParameters.java | 4 + .../pegasys/artemis/util/uint/UInt64.java | 14 ++- 3 files changed, 98 insertions(+), 28 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 923153cc1..3593eaac6 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -34,9 +34,9 @@ import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.bytes.Bytes3; import tech.pegasys.artemis.util.bytes.Bytes32; -import tech.pegasys.artemis.util.bytes.Bytes32s; import tech.pegasys.artemis.util.bytes.Bytes8; import tech.pegasys.artemis.util.bytes.BytesValue; +import tech.pegasys.artemis.util.bytes.BytesValues; import tech.pegasys.artemis.util.collections.ReadList; import tech.pegasys.artemis.util.uint.UInt64; import tech.pegasys.artemis.util.uint.UInt64s; @@ -126,6 +126,8 @@ int get_epoch_committee_count(int active_validator_count) { )).times(spec.getEpochLength()).intValue(); } + + /* def get_previous_epoch_committee_count(state: BeaconState) -> int: """ @@ -447,6 +449,60 @@ public List shuffle(List values, Hash32 seed) { return output; } + /* + def get_permuted_index(index: int, list_size: int, seed: Bytes32) -> int: + """ + Return `p(index)` in a pseudorandom permutation `p` of `0...list_size-1` with ``seed`` as entropy. + + Utilizes 'swap or not' shuffling found in + https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf + See the 'generalized domain' algorithm on page 3. + """ + assert index < list_size + assert list_size <= 2**40 + + for round in range(SHUFFLE_ROUND_COUNT): + pivot = bytes_to_int(hash(seed + int_to_bytes1(round))[0:8]) % list_size + flip = (pivot - index) % list_size + position = max(index, flip) + source = hash(seed + int_to_bytes1(round) + int_to_bytes4(position // 256)) + byte = source[(position % 256) // 8] + bit = (byte >> (position % 8)) % 2 + index = flip if bit else index + + return index + */ + public UInt64 get_permuted_index(UInt64 index, UInt64 listSize, Bytes32 seed) { + assertTrue(index.compareTo(listSize) < 0); + assertTrue(listSize.compareTo(UInt64.valueOf(1L << 40)) <= 0); + + for (int round = 0; round < spec.getShuffleRoundCount(); round++) { + Bytes8 pivotBytes = Bytes8.wrap(hash(seed.concat(int_to_bytes1(round))), 0); + UInt64 pivot = bytes_to_int(pivotBytes).modulo(listSize); + UInt64 flip = pivot.minus(index).modulo(listSize); + UInt64 position = UInt64s.max(index, flip); + BytesValue positionBytes = int_to_bytes4(position.dividedBy(UInt64.valueOf(256)).getValue()); + Bytes32 source = hash(seed.concat(int_to_bytes1(round)).concat(positionBytes)); + byte byt = source.get(position.modulo(256).getIntValue() / 8); + byte bit = (byte) ((byt >> (position.modulo(8).getIntValue())) % 2); + index = bit > 0 ? flip : index; + } + + return index; + } + + public UInt64 bytes_to_int(Bytes8 bytes) { + return UInt64.fromBytesLittleEndian(bytes); + } + + public BytesValue int_to_bytes1(int value) { + return BytesValues.ofUnsignedByte(value); + } + + public BytesValue int_to_bytes4(long value) { + return BytesValues.ofUnsignedInt(value); + } + /* def split(values: List[Any], split_count: int) -> List[Any]: """ @@ -468,33 +524,33 @@ public List> split(List values, int split_count) { return ret; } - // def get_shuffling(randao_mix: Hash32, - // validators: List[ValidatorRecord], - // slot: int) -> List[List[int]] - // """ - // Shuffles ``validators`` into shard committees seeded by ``seed`` and ``slot``. - // Returns a list of ``EPOCH_LENGTH * committees_per_slot`` committees where each - // committee is itself a list of validator indices. - // """ - public List> get_shuffling(Hash32 _seed, + /* + def get_shuffling(seed: Bytes32, + validators: List[Validator], + epoch: Epoch) -> List[List[ValidatorIndex]] + """ + Shuffle active validators and split into crosslink committees. + Return a list of committees (each a list of validator indices). + """ + # Shuffle active validator indices + active_validator_indices = get_active_validator_indices(validators, epoch) + length = len(active_validator_indices) + shuffled_indices = [active_validator_indices[get_permuted_index(i, length, seed)] for i in range(length)] + + # Split the shuffled active validator indices + return split(shuffled_indices, get_epoch_committee_count(length)) + */ + public List> get_shuffling(Hash32 seed, ReadList validators, EpochNumber epoch) { - - - // active_validator_indices = get_active_validator_indices(validators, slot) - List active_validator_indices = get_active_validator_indices(validators, epoch); - // committees_per_epoch = get_epoch_committee_count(len(active_validator_indices)) - int committees_per_epoch = get_epoch_committee_count(active_validator_indices.size()); - - // # Shuffle - // seed = xor(seed, int_to_bytes32(epoch)) - Hash32 seed = Hash32.wrap(Bytes32s.xor(_seed, Bytes32.leftPad(epoch.toBytesBigEndian()))); - - // shuffled_active_validator_indices = shuffle(active_validator_indices, seed) - List shuffled_active_validator_indices = shuffle(active_validator_indices, seed); - // # Split the shuffled list into committees_per_epoch pieces - // return split(shuffled_active_validator_indices, committees_per_epoch) - return split(shuffled_active_validator_indices, committees_per_epoch); + List active_validator_indices = get_active_validator_indices(validators, epoch); + int length = active_validator_indices.size(); + List shuffled_indices = + IntStream.range(0, length) + .mapToObj(i -> get_permuted_index(UInt64.valueOf(i), UInt64.valueOf(length), seed)) + .map(permutedIndex -> active_validator_indices.get(permutedIndex.getIntValue())) + .collect(toList()); + return split(shuffled_indices, get_epoch_committee_count(length)); } /* diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java b/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java index 9bab48ebd..6681aabad 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java @@ -21,6 +21,7 @@ public interface MiscParameters { ShardNumber BEACON_CHAIN_SHARD_NUMBER = ShardNumber.of(UInt64.MAX_VALUE); // (1 << 64) - 1 UInt64 MAX_INDICES_PER_SLASHABLE_VOTE = UInt64.valueOf(1 << 12); UInt64 MAX_WITHDRAWALS_PER_EPOCH = UInt64.valueOf(1 << 2); // 4 + int SHUFFLE_ROUND_COUNT = 90; /* Values defined in the spec. */ @@ -52,4 +53,7 @@ default UInt64 getMaxWithdrawalsPerEpoch() { return MAX_WITHDRAWALS_PER_EPOCH; } + default int getShuffleRoundCount() { + return SHUFFLE_ROUND_COUNT; + } } diff --git a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java index dcf23ceb4..8be16751b 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java +++ b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java @@ -77,8 +77,18 @@ public static UInt64 valueOf(String unsignedStringValue) throws NumberFormatExce } public static UInt64 fromBytesBigEndian(Bytes8 bytes) { - ByteBuffer byteBuffer = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.BIG_ENDIAN) - .put(bytes.getArrayUnsafe()); + return fromBytes(bytes, true); + } + + public static UInt64 fromBytesLittleEndian(Bytes8 bytes) { + return fromBytes(bytes, false); + } + + private static UInt64 fromBytes(Bytes8 bytes, boolean bigEndian) { + ByteBuffer byteBuffer = + ByteBuffer.allocate(Long.BYTES) + .order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN) + .put(bytes.getArrayUnsafe()); byteBuffer.rewind(); return valueOf(byteBuffer.getLong()); } From eb75719236453ae8031a9be447b0a48f89594f09 Mon Sep 17 00:00:00 2001 From: Anton Nashatyrev Date: Thu, 28 Feb 2019 16:45:49 +0300 Subject: [PATCH 03/21] Fix 'any active validator' notion according to spec --- .../transition/PerEpochTransition.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java index 56ed9cbe8..0ec541e7d 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java @@ -504,6 +504,9 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Note: When applying penalties in the following balance recalculations // implementers should make sure the uint64 does not underflow. + // Note: Rewards and penalties are for participation in the previous epoch, + // so the "active validator" set is drawn from + // get_active_validator_indices(state.validator_registry, previous_epoch). // Let epochs_since_finality = next_epoch - state.finalized_epoch. EpochNumber epochs_since_finality = next_epoch.minus(state.getFinalizedEpoch()); @@ -531,7 +534,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // base_reward(state, index). // FIXME 'active validator' - not exact meaning List previous_epoch_justified_attester_loosers = new ArrayList<>(); - for (ValidatorIndex index : current_active_validator_indices) { + for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_justified_attester_indices.contains(index)) { state.getValidatorBalances().update(index, balance -> balance.minus(base_reward.apply(index))); @@ -563,7 +566,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // base_reward(state, index). // FIXME 'active validator' - not exact meaning List previous_epoch_boundary_attester_loosers = new ArrayList<>(); - for (ValidatorIndex index : current_active_validator_indices) { + for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_boundary_attester_indices.contains(index)) { state.getValidatorBalances().update(index, balance -> balance.minus(base_reward.apply(index))); @@ -593,7 +596,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Any active validator index not in previous_epoch_head_attester_indices loses // base_reward(state, index). List previous_epoch_head_attester_loosers = new ArrayList<>(); - for (ValidatorIndex index : current_active_validator_indices) { + for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_head_attester_indices.contains(index)) { state.getValidatorBalances().update(index, balance -> balance.minus(base_reward.apply(index))); @@ -626,7 +629,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Any active validator index not in previous_epoch_justified_attester_indices, loses // inactivity_penalty(state, index, epochs_since_finality). List previous_epoch_justified_attester_loosers = new ArrayList<>(); - for (ValidatorIndex index : current_active_validator_indices) { + for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_justified_attester_indices.contains(index)) { state.getValidatorBalances().update(index, balance -> balance.minus(inactivity_penalty.apply(index, epochs_since_finality))); @@ -641,7 +644,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Any active validator index not in previous_epoch_boundary_attester_indices, loses // inactivity_penalty(state, index, epochs_since_finality). List previous_epoch_boundary_attester_loosers = new ArrayList<>(); - for (ValidatorIndex index : current_active_validator_indices) { + for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_boundary_attester_indices.contains(index)) { state.getValidatorBalances().update(index, balance -> balance.minus(inactivity_penalty.apply(index, epochs_since_finality))); @@ -656,7 +659,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Any active validator index not in previous_epoch_head_attester_indices, loses // base_reward(state, index). List previous_epoch_head_attester_loosers = new ArrayList<>(); - for (ValidatorIndex index : current_active_validator_indices) { + for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_head_attester_indices.contains(index)) { state.getValidatorBalances().update(index, balance -> balance.minus(base_reward.apply(index))); @@ -670,7 +673,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Any active_validator index with validator.penalized_epoch <= current_epoch, loses // 2 * inactivity_penalty(state, index, epochs_since_finality) + base_reward(state, index). List inactive_attester_loosers = new ArrayList<>(); - for (ValidatorIndex index : current_active_validator_indices) { + for (ValidatorIndex index : previous_active_validator_indices) { ValidatorRecord validator = state.getValidatorRegistry().get(index); if (validator.getPenalizedEpoch().lessEqual(current_epoch)) { state.getValidatorBalances().update(index, balance -> From 372970ee1c0a8153bf7fda1382ff9ad04b94928f Mon Sep 17 00:00:00 2001 From: Anton Nashatyrev Date: Thu, 28 Feb 2019 16:41:20 +0300 Subject: [PATCH 04/21] Add EpochTransitionSummary --- .../transition/EpochTransitionSummary.java | 141 ++++++++++++++ .../transition/PerEpochTransition.java | 181 +++++++++++++----- 2 files changed, 276 insertions(+), 46 deletions(-) create mode 100644 consensus/src/main/java/org/ethereum/beacon/consensus/transition/EpochTransitionSummary.java diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/EpochTransitionSummary.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/EpochTransitionSummary.java new file mode 100644 index 000000000..e3e888220 --- /dev/null +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/EpochTransitionSummary.java @@ -0,0 +1,141 @@ +package org.ethereum.beacon.consensus.transition; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.ethereum.beacon.consensus.BeaconStateEx; +import org.ethereum.beacon.core.types.Gwei; +import org.ethereum.beacon.core.types.ValidatorIndex; + +public class EpochTransitionSummary { + + public class EpochSummary { + Gwei validatorBalance; + Gwei boundaryAttestingBalance; + + List activeAttesters = new ArrayList<>(); + List boundaryAttesters = new ArrayList<>(); + + public Gwei getValidatorBalance() { + return validatorBalance; + } + + public Gwei getBoundaryAttestingBalance() { + return boundaryAttestingBalance; + } + + public List getActiveAttesters() { + return activeAttesters; + } + + public List getBoundaryAttesters() { + return boundaryAttesters; + } + } + + BeaconStateEx preState; + BeaconStateEx postState; + + EpochSummary previousEpochSummary = new EpochSummary(); + EpochSummary currentEpochSummary = new EpochSummary(); + + Gwei headAttestingBalance; + Gwei justifiedAttestingBalance; + List headAttesters = new ArrayList<>(); + List justifiedAttesters = new ArrayList<>(); + + boolean noFinality; + Map attestationRewards = new HashMap<>(); + Map attestationPenalties = new HashMap<>(); + Map boundaryAttestationRewards = new HashMap<>(); + Map boundaryAttestationPenalties = new HashMap<>(); + Map beaconHeadAttestationRewards = new HashMap<>(); + Map beaconHeadAttestationPenalties = new HashMap<>(); + Map inclusionDistanceRewards = new HashMap<>(); + Map penalizedEpochPenalties = new HashMap<>(); + Map noFinalityPenalties = new HashMap<>(); + Map attestationInclusionRewards = new HashMap<>(); + + List ejectedValidators = new ArrayList<>(); + + public BeaconStateEx getPreState() { + return preState; + } + + public BeaconStateEx getPostState() { + return postState; + } + + public EpochSummary getPreviousEpochSummary() { + return previousEpochSummary; + } + + public EpochSummary getCurrentEpochSummary() { + return currentEpochSummary; + } + + public Gwei getHeadAttestingBalance() { + return headAttestingBalance; + } + + public Gwei getJustifiedAttestingBalance() { + return justifiedAttestingBalance; + } + + public List getHeadAttesters() { + return headAttesters; + } + + public List getJustifiedAttesters() { + return justifiedAttesters; + } + + public boolean isNoFinality() { + return noFinality; + } + + public Map getAttestationRewards() { + return attestationRewards; + } + + public Map getAttestationPenalties() { + return attestationPenalties; + } + + public Map getBoundaryAttestationRewards() { + return boundaryAttestationRewards; + } + + public Map getBoundaryAttestationPenalties() { + return boundaryAttestationPenalties; + } + + public Map getBeaconHeadAttestationRewards() { + return beaconHeadAttestationRewards; + } + + public Map getBeaconHeadAttestationPenalties() { + return beaconHeadAttestationPenalties; + } + + public Map getInclusionDistanceRewards() { + return inclusionDistanceRewards; + } + + public Map getPenalizedEpochPenalties() { + return penalizedEpochPenalties; + } + + public Map getNoFinalityPenalties() { + return noFinalityPenalties; + } + + public Map getAttestationInclusionRewards() { + return attestationInclusionRewards; + } + + public List getEjectedValidators() { + return ejectedValidators; + } +} diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java index 0ec541e7d..ff2d16d86 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java @@ -17,7 +17,6 @@ import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.consensus.StateTransition; import org.ethereum.beacon.consensus.TransitionType; -import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.state.CrosslinkRecord; @@ -54,12 +53,24 @@ public PerEpochTransition(SpecHelpers specHelpers) { @Override public BeaconStateEx apply(BeaconStateEx stateEx) { + return apply(stateEx, null); + } + + public EpochTransitionSummary applyWithSummary(BeaconStateEx stateEx) { + EpochTransitionSummary summary = new EpochTransitionSummary(); + apply(stateEx, summary); + return summary; + } + + private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summary) { logger.debug(() -> "Applying epoch transition to state: (" + - spec.hash_tree_root(stateEx).toStringShort() + ") " + stateEx.toString(specConst)); + spec.hash_tree_root(origState).toStringShort() + ") " + origState.toString(specConst)); - TransitionType.EPOCH.checkCanBeAppliedAfter(stateEx.getTransition()); + TransitionType.EPOCH.checkCanBeAppliedAfter(origState.getTransition()); - BeaconState origState = stateEx; // var for debugging + if (summary != null) { + summary.preState = origState; + } MutableBeaconState state = origState.createMutableCopy(); // The steps below happen when (state.slot + 1) % EPOCH_LENGTH == 0. @@ -124,6 +135,7 @@ public BeaconStateEx apply(BeaconStateEx stateEx) { .stream()) .collect(Collectors.toSet()); + // Let current_epoch_boundary_attesting_balance = // sum([get_effective_balance(state, i) for i in current_epoch_boundary_attester_indices]). Gwei current_epoch_boundary_attesting_balance = current_epoch_boundary_attester_indices @@ -132,15 +144,22 @@ public BeaconStateEx apply(BeaconStateEx stateEx) { .reduce(Gwei::plus) .orElse(Gwei.ZERO); + if (summary != null) { + summary.currentEpochSummary.activeAttesters = current_active_validator_indices; + summary.currentEpochSummary.validatorBalance = current_total_balance; + summary.currentEpochSummary.boundaryAttesters.addAll(current_epoch_boundary_attester_indices); + summary.currentEpochSummary.boundaryAttestingBalance = current_epoch_boundary_attesting_balance; + } /* Helpers: Validators attesting during the previous epoch: */ + List previous_active_validator_indices = spec + .get_active_validator_indices(state.getValidatorRegistry(), previous_epoch); + //Let previous_total_balance = sum([get_effective_balance(state, i) // for i in get_active_validator_indices(state.validator_registry, previous_epoch)]). - Gwei previous_total_balance = spec - .get_active_validator_indices(state.getValidatorRegistry(), previous_epoch) - .stream() + Gwei previous_total_balance = previous_active_validator_indices.stream() .map(i -> spec.get_effective_balance(state, i)) .reduce(Gwei::plus) .orElse(Gwei.ZERO); @@ -243,6 +262,18 @@ public BeaconStateEx apply(BeaconStateEx stateEx) { .reduce(Gwei::plus) .orElse(Gwei.ZERO); + if (summary != null) { + summary.previousEpochSummary.activeAttesters = current_active_validator_indices; + summary.previousEpochSummary.validatorBalance = current_total_balance; + summary.previousEpochSummary.boundaryAttesters.addAll(previous_epoch_boundary_attester_indices); + summary.previousEpochSummary.boundaryAttestingBalance = previous_epoch_boundary_attesting_balance; + summary.headAttesters.addAll(previous_epoch_head_attester_indices); + summary.headAttestingBalance = previous_epoch_head_attesting_balance; + summary.justifiedAttesters.addAll(previous_epoch_justified_attester_indices); + summary.justifiedAttestingBalance = previous_epoch_justified_attesting_balance; + } + + Map, Hash32>, Set> attesting_validator_indices = new HashMap<>(); Map, Pair> winning_root_tmp = new HashMap<>(); @@ -514,16 +545,24 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: if (epochs_since_finality.lessEqual(EpochNumber.of(4))) { // Case 1: epochs_since_finality <= 4: logger.debug("Case 1: epochs_since_finality <= 4"); + if (summary != null) { + summary.noFinality = false; + } // Expected FFG source: // Any validator index in previous_epoch_justified_attester_indices gains // base_reward(state, index) * previous_epoch_justified_attesting_balance // previous_total_balance. for (ValidatorIndex index : previous_epoch_justified_attester_indices) { + Gwei reward = base_reward.apply(index) + .times(previous_epoch_justified_attesting_balance) + .dividedBy(previous_total_balance); state.getValidatorBalances().update(index, balance -> - balance.plus(base_reward.apply(index) - .times(previous_epoch_justified_attesting_balance) - .dividedBy(previous_total_balance))); + balance.plus(reward)); + + if (summary != null) { + summary.attestationRewards.put(index, reward); + } } if (logger.isTraceEnabled() && !previous_epoch_justified_attester_indices.isEmpty()) { logger.trace("Rewarded: Previous epoch justified attesters: " @@ -536,9 +575,13 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: List previous_epoch_justified_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_justified_attester_indices.contains(index)) { - state.getValidatorBalances().update(index, balance -> - balance.minus(base_reward.apply(index))); + Gwei penalty = base_reward.apply(index); + state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); + previous_epoch_justified_attester_loosers.add(index); + if (summary != null) { + summary.attestationPenalties.put(index, penalty); + } } } if (logger.isDebugEnabled() && !previous_epoch_justified_attester_loosers.isEmpty()) { @@ -551,11 +594,14 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Any validator index in previous_epoch_boundary_attester_indices gains // base_reward(state, index) * previous_epoch_boundary_attesting_balance // previous_total_balance. for (ValidatorIndex index : previous_epoch_boundary_attester_indices) { - state.getValidatorBalances().update(index, balance -> - balance - .plus(base_reward.apply(index) - .times(previous_epoch_boundary_attesting_balance) - .dividedBy(previous_total_balance))); + Gwei reward = base_reward.apply(index) + .times(previous_epoch_boundary_attesting_balance) + .dividedBy(previous_total_balance); + state.getValidatorBalances().update(index, balance -> balance.plus(reward)); + + if (summary != null) { + summary.boundaryAttestationRewards.put(index, reward); + } } if (logger.isTraceEnabled() && !previous_epoch_boundary_attester_indices.isEmpty()) { logger.trace("Rewarded: Previous epoch boundary attesters: " @@ -568,9 +614,13 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: List previous_epoch_boundary_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_boundary_attester_indices.contains(index)) { + Gwei penalty = base_reward.apply(index); state.getValidatorBalances().update(index, balance -> - balance.minus(base_reward.apply(index))); + balance.minus(penalty)); previous_epoch_boundary_attester_loosers.add(index); + if (summary != null) { + summary.boundaryAttestationPenalties.put(index, penalty); + } } } if (logger.isDebugEnabled() && !previous_epoch_boundary_attester_loosers.isEmpty()) { @@ -583,10 +633,14 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Any validator index in previous_epoch_head_attester_indices gains // base_reward(state, index) * previous_epoch_head_attesting_balance // previous_total_balance). for (ValidatorIndex index : previous_epoch_head_attester_indices) { - state.getValidatorBalances().update(index, balance -> - balance.plus(base_reward.apply(index) - .times(previous_epoch_head_attesting_balance) - .dividedBy(previous_total_balance))); + Gwei reward = base_reward.apply(index) + .times(previous_epoch_head_attesting_balance) + .dividedBy(previous_total_balance); + state.getValidatorBalances().update(index, balance -> balance.plus(reward)); + if (summary != null) { + summary.beaconHeadAttestationRewards.put(index, reward); + } + } if (logger.isTraceEnabled() && !previous_epoch_head_attester_indices.isEmpty()) { logger.trace("Rewarded: Previous epoch head attesters: " @@ -598,9 +652,13 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: List previous_epoch_head_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_head_attester_indices.contains(index)) { + Gwei penalty = base_reward.apply(index); state.getValidatorBalances().update(index, balance -> - balance.minus(base_reward.apply(index))); + balance.minus(penalty)); previous_epoch_head_attester_loosers.add(index); + if (summary != null) { + summary.beaconHeadAttestationPenalties.put(index, penalty); + } } } if (logger.isDebugEnabled() && !previous_epoch_head_attester_loosers.isEmpty()) { @@ -614,10 +672,13 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // base_reward(state, index) * MIN_ATTESTATION_INCLUSION_DELAY // // inclusion_distance(state, index) for (ValidatorIndex index : previous_epoch_attester_indices) { - state.getValidatorBalances().update(index, balance -> - balance.plus(base_reward.apply(index) - .times(specConst.getMinAttestationInclusionDelay()) - .dividedBy(inclusion_distance.get(index)))); + Gwei reward = base_reward.apply(index) + .times(specConst.getMinAttestationInclusionDelay()) + .dividedBy(inclusion_distance.get(index)); + state.getValidatorBalances().update(index, balance -> balance.plus(reward)); + if (summary != null) { + summary.inclusionDistanceRewards.put(index, reward); + } } if (logger.isTraceEnabled() && !previous_epoch_attester_indices.isEmpty()) { logger.trace("Rewarded: Previous epoch attesters: " + previous_epoch_attester_indices); @@ -625,15 +686,21 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: } else { // Case 2: epochs_since_finality > 4: logger.debug("Case 2: epochs_since_finality > 4"); + if (summary != null) { + summary.noFinality = true; + } // Any active validator index not in previous_epoch_justified_attester_indices, loses // inactivity_penalty(state, index, epochs_since_finality). List previous_epoch_justified_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_justified_attester_indices.contains(index)) { - state.getValidatorBalances().update(index, balance -> - balance.minus(inactivity_penalty.apply(index, epochs_since_finality))); + Gwei penalty = inactivity_penalty.apply(index, epochs_since_finality); + state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); previous_epoch_justified_attester_loosers.add(index); + if (summary != null) { + summary.attestationPenalties.put(index, penalty); + } } } if (logger.isDebugEnabled() && !previous_epoch_justified_attester_loosers.isEmpty()) { @@ -646,9 +713,13 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: List previous_epoch_boundary_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_boundary_attester_indices.contains(index)) { + Gwei penalty = inactivity_penalty.apply(index, epochs_since_finality); state.getValidatorBalances().update(index, balance -> - balance.minus(inactivity_penalty.apply(index, epochs_since_finality))); + balance.minus(penalty)); previous_epoch_boundary_attester_loosers.add(index); + if (summary != null) { + summary.boundaryAttestationPenalties.put(index, penalty); + } } } if (logger.isDebugEnabled() && !previous_epoch_boundary_attester_loosers.isEmpty()) { @@ -661,9 +732,13 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: List previous_epoch_head_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { if (!previous_epoch_head_attester_indices.contains(index)) { + Gwei penalty = base_reward.apply(index); state.getValidatorBalances().update(index, balance -> - balance.minus(base_reward.apply(index))); + balance.minus(penalty)); previous_epoch_head_attester_loosers.add(index); + if (summary != null) { + summary.beaconHeadAttestationPenalties.put(index, penalty); + } } } if (logger.isDebugEnabled() && !previous_epoch_head_attester_loosers.isEmpty()) { @@ -675,14 +750,14 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: List inactive_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { ValidatorRecord validator = state.getValidatorRegistry().get(index); + Gwei penalty = inactivity_penalty.apply(index, epochs_since_finality) + .times(2).plus(base_reward.apply(index)); if (validator.getPenalizedEpoch().lessEqual(current_epoch)) { - state.getValidatorBalances().update(index, balance -> - balance.minus( - inactivity_penalty.apply(index, epochs_since_finality)) - .times(2) - .plus(base_reward.apply(index)) - ); + state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); inactive_attester_loosers.add(index); + if (summary != null) { + summary.penalizedEpochPenalties.put(index, penalty); + } } } if (logger.isDebugEnabled() && !inactive_attester_loosers.isEmpty()) { @@ -693,13 +768,15 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // base_reward(state, index) - base_reward(state, index) * // MIN_ATTESTATION_INCLUSION_DELAY // inclusion_distance(state, index) for (ValidatorIndex index : previous_epoch_attester_indices) { - state.getValidatorBalances().update(index, balance -> balance.minus( - base_reward.apply(index).minus( + Gwei penalty = base_reward.apply(index) + .minus( base_reward.apply(index) - .times(specConst.getMinAttestationInclusionDelay()) - .dividedBy(inclusion_distance.get(index)) - ) - )); + .times(specConst.getMinAttestationInclusionDelay()) + .dividedBy(inclusion_distance.get(index))); + state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); + if (summary != null) { + summary.noFinalityPenalties.put(index, penalty); + } } if (logger.isDebugEnabled() && !previous_epoch_attester_indices.isEmpty()) { logger.debug("Penalized: No finality attesters: " + previous_epoch_attester_indices); @@ -718,10 +795,15 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: for (ValidatorIndex index : previous_epoch_attester_indices) { ValidatorIndex proposer_index = spec .get_beacon_proposer_index(state, inclusion_slot.get(index)); + Gwei reward = base_reward.apply(index).dividedBy(specConst.getIncluderRewardQuotient()); state.getValidatorBalances().update(proposer_index, balance -> - balance.plus(base_reward.apply(index) - .dividedBy(specConst.getIncluderRewardQuotient()))); + balance.plus(reward)); attestation_inclusion_gainers.add(proposer_index); + if (summary != null) { + summary.attestationInclusionRewards.put(proposer_index, reward); + } + + } if (logger.isTraceEnabled() && !attestation_inclusion_gainers.isEmpty()) { logger.trace("Rewarded: Attestation include proposers: " + attestation_inclusion_gainers); @@ -787,6 +869,9 @@ def process_ejections(state: BeaconState) -> None: if (state.getValidatorBalances().get(index).less(specConst.getEjectionBalance())) { spec.exit_validator(state, index); exit_validators.add(index); + if (summary != null) { + summary.ejectedValidators.add(index); + } } } if (logger.isInfoEnabled() && !exit_validators.isEmpty()) { @@ -886,7 +971,11 @@ def process_ejections(state: BeaconState) -> None: a -> spec.slot_to_epoch(a.getData().getSlot()).less(current_epoch)); BeaconStateEx ret = new BeaconStateExImpl(state.createImmutable(), - stateEx.getHeadBlockHash(), TransitionType.EPOCH); + origState.getHeadBlockHash(), TransitionType.EPOCH); + + if (summary != null) { + summary.postState = ret; + } logger.debug(() -> "Epoch transition result state: (" + spec.hash_tree_root(ret).toStringShort() + ") " + ret.toString(specConst)); From bf17c5e727b42e5006100f92f940f7bf0ce2e6ca Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 1 Mar 2019 13:18:53 +0600 Subject: [PATCH 05/21] Pull first part of renamings from spec 0.4.0 --- .../chain/observer/PendingOperations.java | 7 +- .../observer/PendingOperationsState.java | 10 +- .../chain/util/PendingOperationsTestUtil.java | 6 +- .../beacon/consensus/SpecHelpers.java | 142 +++++++++--------- .../transition/DelegateBeaconState.java | 36 ++--- .../transition/EpochTransitionSummary.java | 6 +- .../transition/InitialStateTransition.java | 28 ++-- .../transition/PerBlockTransition.java | 11 +- .../transition/PerEpochTransition.java | 84 +++++------ .../verifier/block/ExitListVerifier.java | 14 +- .../operation/AttestationVerifier.java | 22 +-- .../operation/AttesterSlashingVerifier.java | 4 +- .../verifier/operation/ExitVerifier.java | 24 ++- .../operation/ProposerSlashingVerifier.java | 12 +- .../org/ethereum/beacon/core/BeaconBlock.java | 11 +- .../ethereum/beacon/core/BeaconBlockBody.java | 23 ++- .../org/ethereum/beacon/core/BeaconState.java | 23 +-- .../beacon/core/MutableBeaconState.java | 21 ++- .../core/operations/ProposerSlashing.java | 23 +-- .../beacon/core/operations/Transfer.java | 79 ++++++++++ .../beacon/core/operations/VoluntaryExit.java | 82 ++++++++++ .../attestation/AttestationData.java | 41 +++-- .../operations/attestation/Crosslink.java | 70 +++++++++ .../core/spec/MaxOperationsPerBlock.java | 11 +- .../beacon/core/spec/StateListLengths.java | 6 +- .../beacon/core/spec/TimeParameters.java | 6 +- .../core/spec/ValidatorStatusFlags.java | 17 --- .../beacon/core/state/BeaconStateImpl.java | 123 +++++++-------- .../beacon/core/state/CrosslinkRecord.java | 50 ------ .../beacon/core/state/ValidatorRecord.java | 81 +++++----- .../beacon/core/ModelsSerializeTest.java | 48 +++--- .../core/SSZSerializableAnnotationTest.java | 8 +- .../beacon/core/util/AttestationTestUtil.java | 4 +- .../beacon/core/util/ExitTestUtil.java | 9 +- .../core/util/ProposerSlashingTestUtil.java | 10 +- .../resources/config/default-chainSpec.yml | 6 +- .../config/chainspec/ChainSpecData.java | 12 +- .../chainspec/MaxOperationsPerBlockData.java | 16 +- .../chainspec/StateListLengthsData.java | 16 +- .../config/chainspec/TimeParametersData.java | 16 +- start/config/src/test/resources/chainSpec.yml | 6 +- .../attester/BeaconChainAttesterImpl.java | 17 ++- .../proposer/BeaconChainProposerImpl.java | 9 +- .../attester/BeaconChainAttesterTest.java | 6 +- .../proposer/BeaconChainProposerTest.java | 12 +- 45 files changed, 715 insertions(+), 553 deletions(-) create mode 100644 core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java create mode 100644 core/src/main/java/org/ethereum/beacon/core/operations/VoluntaryExit.java create mode 100644 core/src/main/java/org/ethereum/beacon/core/operations/attestation/Crosslink.java delete mode 100644 core/src/main/java/org/ethereum/beacon/core/spec/ValidatorStatusFlags.java delete mode 100644 core/src/main/java/org/ethereum/beacon/core/state/CrosslinkRecord.java diff --git a/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperations.java b/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperations.java index 7c20c5bd8..816d1233b 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperations.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperations.java @@ -3,7 +3,8 @@ import java.util.List; import java.util.Optional; import org.ethereum.beacon.core.operations.Attestation; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.spec.ChainSpec; @@ -23,7 +24,9 @@ public interface PendingOperations { List peekAggregatedAttestations(int maxCount, SlotNumber minSlot, SlotNumber maxSlot); - List peekExits(int maxCount); + List peekExits(int maxCount); + + List peekTransfers(int maxCount); default String toStringShort() { return "PendingOperations[" diff --git a/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperationsState.java b/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperationsState.java index 15bc24619..c50cf1820 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperationsState.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperationsState.java @@ -10,7 +10,8 @@ import java.util.Optional; import java.util.stream.Collectors; import org.ethereum.beacon.core.operations.Attestation; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; @@ -92,7 +93,12 @@ private Attestation aggregateAttestations(List attestations) { } @Override - public List peekExits(int maxCount) { + public List peekExits(int maxCount) { + return Collections.emptyList(); + } + + @Override + public List peekTransfers(int maxCount) { return Collections.emptyList(); } } diff --git a/chain/src/test/java/org/ethereum/beacon/chain/util/PendingOperationsTestUtil.java b/chain/src/test/java/org/ethereum/beacon/chain/util/PendingOperationsTestUtil.java index 5dd4f6b57..8cf564e24 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/util/PendingOperationsTestUtil.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/util/PendingOperationsTestUtil.java @@ -8,7 +8,7 @@ import java.util.List; import org.ethereum.beacon.chain.observer.PendingOperations; import org.ethereum.beacon.core.operations.Attestation; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.mockito.Mockito; @@ -29,14 +29,14 @@ public static PendingOperations mockPendingOperations( List aggregateAttestations, List proposerSlashings, List attesterSlashings, - List exits) { + List voluntaryExits) { PendingOperations pendingOperations = Mockito.mock(PendingOperations.class); when(pendingOperations.getAttestations()).thenReturn(attestations); when(pendingOperations.peekProposerSlashings(anyInt())).thenReturn(proposerSlashings); when(pendingOperations.peekAttesterSlashings(anyInt())).thenReturn(attesterSlashings); when(pendingOperations.peekAggregatedAttestations(anyInt(), any(), any())) .thenReturn(aggregateAttestations); - when(pendingOperations.peekExits(anyInt())).thenReturn(exits); + when(pendingOperations.peekExits(anyInt())).thenReturn(voluntaryExits); return pendingOperations; } } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 3593eaac6..9b07af299 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -12,7 +12,6 @@ import org.ethereum.beacon.core.operations.slashing.SlashableAttestation; import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.spec.SignatureDomains; -import org.ethereum.beacon.core.spec.ValidatorStatusFlags; import org.ethereum.beacon.core.state.ForkData; import org.ethereum.beacon.core.state.ShardCommittee; import org.ethereum.beacon.core.state.ValidatorRecord; @@ -135,14 +134,14 @@ def get_previous_epoch_committee_count(state: BeaconState) -> int: """ previous_active_validators = get_active_validator_indices( state.validator_registry, - state.previous_calculation_epoch, + state.previous_shuffling_epoch, ) return get_epoch_committee_count(len(previous_active_validators)) */ public int get_previous_epoch_committee_count(BeaconState state) { List previous_active_validators = get_active_validator_indices( state.getValidatorRegistry(), - state.getPreviousCalculationEpoch()); + state.getPreviousShufflingEpoch()); return get_epoch_committee_count(previous_active_validators.size()); } @@ -153,14 +152,14 @@ def get_current_epoch_committee_count(state: BeaconState) -> int: """ current_active_validators = get_active_validator_indices( state.validator_registry, - state.current_calculation_epoch, + state.current_shuffling_epoch, ) return get_epoch_committee_count(len(current_active_validators)) */ public int get_current_epoch_committee_count(BeaconState state) { List current_active_validators = get_active_validator_indices( state.getValidatorRegistry(), - state.getCurrentCalculationEpoch()); + state.getCurrentShufflingEpoch()); return get_epoch_committee_count(current_active_validators.size()); } @@ -209,9 +208,9 @@ public List get_crosslink_committees_at_slot( /* if epoch == previous_epoch: committees_per_epoch = get_previous_epoch_committee_count(state) - seed = state.previous_epoch_seed - shuffling_epoch = state.previous_calculation_epoch - shuffling_start_shard = state.previous_epoch_start_shard + seed = state.previous_shuffling_seed + shuffling_epoch = state.previous_shuffling_epoch + shuffling_start_shard = state.previous_shuffling_start_shard */ int committees_per_epoch; Hash32 seed; @@ -219,21 +218,21 @@ public List get_crosslink_committees_at_slot( ShardNumber shuffling_start_shard; if (epoch.equals(previous_epoch)) { committees_per_epoch = get_previous_epoch_committee_count(state); - seed = state.getPreviousEpochSeed(); - shuffling_epoch = state.getPreviousCalculationEpoch(); - shuffling_start_shard = state.getPreviousEpochStartShard(); + seed = state.getPreviousShufflingSeed(); + shuffling_epoch = state.getPreviousShufflingEpoch(); + shuffling_start_shard = state.getPreviousShufflingStartShard(); } else if (epoch.equals(current_epoch)) { /* elif epoch == current_epoch: committees_per_epoch = get_current_epoch_committee_count(state) - seed = state.current_epoch_seed - shuffling_epoch = state.current_calculation_epoch + seed = state.current_shuffling_seed + shuffling_epoch = state.current_shuffling_epoch */ committees_per_epoch = get_current_epoch_committee_count(state); - seed = state.getCurrentEpochSeed(); - shuffling_epoch = state.getCurrentCalculationEpoch(); - shuffling_start_shard = state.getCurrentEpochStartShard(); + seed = state.getCurrentShufflingSeed(); + shuffling_epoch = state.getCurrentShufflingEpoch(); + shuffling_start_shard = state.getCurrentShufflingStartShard(); } else { assertTrue(epoch.equals(next_epoch)); /* @@ -252,29 +251,29 @@ public List get_crosslink_committees_at_slot( /* if registry_change: seed = generate_seed(state, next_epoch) - shuffling_start_shard = (state.current_epoch_start_shard + current_committees_per_epoch) % SHARD_COUNT + shuffling_start_shard = (state.current_shuffling_start_shard + current_committees_per_epoch) % SHARD_COUNT */ if (registry_change) { seed = generate_seed(state, next_epoch); - shuffling_start_shard = state.getCurrentEpochStartShard() + shuffling_start_shard = state.getCurrentShufflingStartShard() .plusModulo(current_committees_per_epoch, spec.getShardCount()); } else if (epochs_since_last_registry_update.greater(EpochNumber.of(1)) && is_power_of_two(epochs_since_last_registry_update)) { /* elif epochs_since_last_registry_update > 1 and is_power_of_two(epochs_since_last_registry_update): seed = generate_seed(state, next_epoch) - shuffling_start_shard = state.current_epoch_start_shard + shuffling_start_shard = state.current_shuffling_start_shard */ seed = generate_seed(state, next_epoch); - shuffling_start_shard = state.getCurrentEpochStartShard(); + shuffling_start_shard = state.getCurrentShufflingStartShard(); } else { /* else: - seed = state.current_epoch_seed - shuffling_start_shard = state.current_epoch_start_shard + seed = state.current_shuffling_seed + shuffling_start_shard = state.current_shuffling_start_shard */ - seed = state.getCurrentEpochSeed(); - shuffling_start_shard = state.getCurrentEpochStartShard(); + seed = state.getCurrentShufflingSeed(); + shuffling_start_shard = state.getCurrentShufflingStartShard(); } } List> shuffling = get_shuffling(seed, state.getValidatorRegistry(), @@ -707,28 +706,26 @@ public ValidatorIndex process_deposit( // if pubkey not in validator_pubkeys: if (index == null) { // # Add new validator - // validator = Validator( - // pubkey=pubkey, - // withdrawal_credentials=withdrawal_credentials, - // proposer_slots=0, - // activation_slot=FAR_FUTURE_SLOT, - // exit_slot=FAR_FUTURE_SLOT, - // withdrawal_slot=FAR_FUTURE_SLOT, - // penalized_slot=FAR_FUTURE_SLOT, - // exit_count=0, - // status_flags=0, - // custody_commitment=custody_commitment, - // latest_custody_reseed_slot=GENESIS_SLOT, - // penultimate_custody_reseed_slot=GENESIS_SLOT, - // ) + /* + validator = Validator( + pubkey=pubkey, + withdrawal_credentials=withdrawal_credentials, + activation_epoch=FAR_FUTURE_EPOCH, + exit_epoch=FAR_FUTURE_EPOCH, + withdrawable_epoch=FAR_FUTURE_EPOCH, + initiated_exit=False, + slashed=False, + ) + */ + ValidatorRecord validator = new ValidatorRecord( pubkey, withdrawal_credentials, spec.getFarFutureEpoch(), spec.getFarFutureEpoch(), spec.getFarFutureEpoch(), - spec.getFarFutureEpoch(), - UInt64.ZERO); + Boolean.FALSE, + Boolean.FALSE); // # Note: In phase 2 registry indices that has been withdrawn for a long time will be recycled. // index = len(state.validator_registry) @@ -792,18 +789,18 @@ public void activate_validator(MutableBeaconState state, ValidatorIndex index, b def penalize_validator(state: BeaconState, index: int) -> None: exit_validator(state, index) validator = state.validator_registry[index] - state.latest_penalized_balances[get_current_epoch(state) % LATEST_PENALIZED_EXIT_LENGTH] + state.latest_slashed_balances[get_current_epoch(state) % LATEST_PENALIZED_EXIT_LENGTH] += get_effective_balance(state, index) whistleblower_index = get_beacon_proposer_index(state, state.slot) whistleblower_reward = get_effective_balance(state, index) // WHISTLEBLOWER_REWARD_QUOTIENT state.validator_balances[whistleblower_index] += whistleblower_reward state.validator_balances[index] -= whistleblower_reward - validator.penalized_epoch = get_current_epoch(state) + validator.initiated_exit = get_current_epoch(state) */ public void penalize_validator(MutableBeaconState state, ValidatorIndex index) { exit_validator(state, index); - state.getLatestPenalizedBalances().update( + state.getLatestSlashedBalances().update( get_current_epoch(state).modulo(spec.getLatestPenalizedExitLength()), balance -> balance.plus(get_effective_balance(state, index))); @@ -815,13 +812,15 @@ public void penalize_validator(MutableBeaconState state, ValidatorIndex index) { state.getValidatorBalances().update(index, oldVal -> oldVal.minus(whistleblower_reward)); state.getValidatorRegistry().update(index, - v -> v.builder().withPenalizedEpoch(get_current_epoch(state)).build()); + v -> v.builder().withSlashed(Boolean.TRUE) + .withWithdrawableEpoch(get_current_epoch(state).plus(spec.getLatestPenalizedExitLength())) + .build()); } /* def initiate_validator_exit(state: BeaconState, index: int) -> None: validator = state.validator_registry[index] - validator.status_flags |= INITIATED_EXIT + validator.slashed = True */ public void initiate_validator_exit(MutableBeaconState state, ValidatorIndex index) { state @@ -830,7 +829,7 @@ public void initiate_validator_exit(MutableBeaconState state, ValidatorIndex ind index, v -> v.builder() - .withStatusFlags(flags -> flags.or(ValidatorStatusFlags.INITIATED_EXIT)) + .withInitiatedExit(Boolean.TRUE) .build()); } @@ -925,9 +924,9 @@ public void update_validator_registry(MutableBeaconState state) { for (ValidatorIndex index : state.getValidatorRegistry().size().iterateFromZero()) { ValidatorRecord validator = state.getValidatorRegistry().get(index); // if validator.exit_epoch > get_entry_exit_effect_epoch(current_epoch) - // and validator.status_flags & INITIATED_EXIT: - if (validator.getExitEpoch().greater(get_entry_exit_effect_epoch(current_epoch)) - && !validator.getStatusFlags().and(ValidatorStatusFlags.INITIATED_EXIT).equals(UInt64.ZERO)) { + // and validator.slashed: + if (validator.getActivationEpoch().equals(spec.getFarFutureEpoch()) + && validator.getInitiatedExit()) { // # Check the balance churn would be within the allowance // balance_churn += get_effective_balance(state, index) balance_churn = balance_churn.plus(get_effective_balance(state, index)); @@ -950,7 +949,7 @@ public void update_validator_registry(MutableBeaconState state) { /* def prepare_validator_for_withdrawal(state: BeaconState, index: int) -> None: validator = state.validator_registry[index] - validator.status_flags |= WITHDRAWABLE + validator.slashed = False */ public void prepare_validator_for_withdrawal(MutableBeaconState state, ValidatorIndex index) { state @@ -959,7 +958,8 @@ public void prepare_validator_for_withdrawal(MutableBeaconState state, Validator index, v -> v.builder() - .withStatusFlags(flags -> flags.or(ValidatorStatusFlags.WITHDRAWABLE)) + .withWithdrawableEpoch( + get_current_epoch(state).plus(spec.getMinValidatorWithdrawabilityDelay())) .build()); } @@ -985,17 +985,18 @@ public void process_penalties_and_exits(MutableBeaconState state) { // for index, validator in enumerate(state.validator_registry): for (ValidatorIndex index : state.getValidatorRegistry().size()) { ValidatorRecord validator = state.getValidatorRegistry().get(index); - // if current_epoch == validator.penalized_epoch + LATEST_PENALIZED_EXIT_LENGTH // 2: - if (current_epoch.equals( - validator.getPenalizedEpoch().plus(spec.getLatestPenalizedExitLength().half()))) { + // if validator.slashed and current_epoch == + // validator.withdrawable_epoch - LATEST_SLASHED_EXIT_LENGTH // 2: + if (validator.getSlashed() && current_epoch.equals( + validator.getWithdrawableEpoch().minus(spec.getLatestPenalizedExitLength().half()))) { // epoch_index = current_epoch % LATEST_PENALIZED_EXIT_LENGTH EpochNumber epoch_index = current_epoch.modulo(spec.getLatestPenalizedExitLength()); - // total_at_start = state.latest_penalized_balances[(epoch_index + 1) % LATEST_PENALIZED_EXIT_LENGTH] - Gwei total_at_start = state.getLatestPenalizedBalances().get( + // total_at_start = state.latest_slashed_balances[(epoch_index + 1) % LATEST_PENALIZED_EXIT_LENGTH] + Gwei total_at_start = state.getLatestSlashedBalances().get( epoch_index.increment().modulo(spec.getLatestPenalizedExitLength())); - // total_at_end = state.latest_penalized_balances[epoch_index] - Gwei total_at_end = state.getLatestPenalizedBalances().get(epoch_index); + // total_at_end = state.latest_slashed_balances[epoch_index] + Gwei total_at_end = state.getLatestSlashedBalances().get(epoch_index); // total_penalties = total_at_end - total_at_start Gwei total_penalties = total_at_end.minus(total_at_start); // penalty = get_effective_balance(state, index) * @@ -1011,11 +1012,11 @@ public void process_penalties_and_exits(MutableBeaconState state) { /* def eligible(index): validator = state.validator_registry[index] - if validator.penalized_epoch <= current_epoch: + if validator.initiated_exit <= current_epoch: penalized_withdrawal_epochs = LATEST_PENALIZED_EXIT_LENGTH // 2 - return current_epoch >= validator.penalized_epoch + penalized_withdrawal_epochs + return current_epoch >= validator.initiated_exit + penalized_withdrawal_epochs else: - return current_epoch >= validator.exit_epoch + MIN_VALIDATOR_WITHDRAWAL_EPOCHS + return current_epoch >= validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY all_indices = list(range(len(state.validator_registry))) eligible_indices = filter(eligible, all_indices) @@ -1023,14 +1024,11 @@ def eligible(index): List eligible_indices = new ArrayList<>(); for (ValidatorIndex index : state.getValidatorRegistry().size().iterateFromZero()) { ValidatorRecord validator = state.getValidatorRegistry().get(index); - if (validator.getPenalizedEpoch().lessEqual(current_epoch)) { - if (current_epoch.greaterEqual( - validator.getPenalizedEpoch().plus(spec.getLatestPenalizedExitLength().half()))) { - eligible_indices.add(index); - } + if (validator.getWithdrawableEpoch().equals(spec.getFarFutureEpoch())) { + eligible_indices.add(index); } else { - if (current_epoch.greaterEqual( - validator.getExitEpoch().plus(spec.getMinValidatorWithdrawalEpochs()))) { + if (get_current_epoch(state).greaterEqual( + validator.getExitEpoch().plus(spec.getMinValidatorWithdrawabilityDelay()))) { eligible_indices.add(index); } } @@ -1078,15 +1076,15 @@ def get_active_index_root(state: BeaconState, """ Return the index root at a recent ``epoch``. """ - assert get_current_epoch(state) - LATEST_INDEX_ROOTS_LENGTH + ENTRY_EXIT_DELAY < epoch + assert get_current_epoch(state) - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ENTRY_EXIT_DELAY < epoch <= get_current_epoch(state) + ENTRY_EXIT_DELAY - return state.latest_index_roots[epoch % LATEST_INDEX_ROOTS_LENGTH] + return state.latest_active_index_roots[epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] */ Hash32 get_active_index_root(BeaconState state, EpochNumber epoch) { - assertTrue(get_current_epoch(state).minus(spec.getLatestIndexRootsLength()).plus(spec.getEntryExitDelay()) + assertTrue(get_current_epoch(state).minus(spec.getLatestActiveIndexRootsLength()).plus(spec.getEntryExitDelay()) .less(epoch)); assertTrue(epoch.lessEqual(get_current_epoch(state).plus(spec.getEntryExitDelay()))); - return state.getLatestIndexRoots().get(epoch.modulo(spec.getLatestIndexRootsLength())); + return state.getLatestActiveIndexRoots().get(epoch.modulo(spec.getLatestActiveIndexRootsLength())); } /* diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java index d8027c51a..770298675 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java @@ -4,7 +4,7 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.spec.ChainSpec; -import org.ethereum.beacon.core.state.CrosslinkRecord; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.ForkData; @@ -71,33 +71,33 @@ public ReadList getLatestRandaoMixes() { } @Override - public ShardNumber getPreviousEpochStartShard() { - return delegate.getPreviousEpochStartShard(); + public ShardNumber getPreviousShufflingStartShard() { + return delegate.getPreviousShufflingStartShard(); } @Override - public ShardNumber getCurrentEpochStartShard() { - return delegate.getCurrentEpochStartShard(); + public ShardNumber getCurrentShufflingStartShard() { + return delegate.getCurrentShufflingStartShard(); } @Override - public EpochNumber getPreviousCalculationEpoch() { - return delegate.getPreviousCalculationEpoch(); + public EpochNumber getPreviousShufflingEpoch() { + return delegate.getPreviousShufflingEpoch(); } @Override - public EpochNumber getCurrentCalculationEpoch() { - return delegate.getCurrentCalculationEpoch(); + public EpochNumber getCurrentShufflingEpoch() { + return delegate.getCurrentShufflingEpoch(); } @Override - public Hash32 getPreviousEpochSeed() { - return delegate.getPreviousEpochSeed(); + public Hash32 getPreviousShufflingSeed() { + return delegate.getPreviousShufflingSeed(); } @Override - public Hash32 getCurrentEpochSeed() { - return delegate.getCurrentEpochSeed(); + public Hash32 getCurrentShufflingSeed() { + return delegate.getCurrentShufflingSeed(); } @Override @@ -121,7 +121,7 @@ public EpochNumber getFinalizedEpoch() { } @Override - public ReadList getLatestCrosslinks() { + public ReadList getLatestCrosslinks() { return delegate.getLatestCrosslinks(); } @@ -131,13 +131,13 @@ public ReadList getLatestBlockRoots() { } @Override - public ReadList getLatestIndexRoots() { - return delegate.getLatestIndexRoots(); + public ReadList getLatestActiveIndexRoots() { + return delegate.getLatestActiveIndexRoots(); } @Override - public ReadList getLatestPenalizedBalances() { - return delegate.getLatestPenalizedBalances(); + public ReadList getLatestSlashedBalances() { + return delegate.getLatestSlashedBalances(); } @Override diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/EpochTransitionSummary.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/EpochTransitionSummary.java index e3e888220..37b8983f7 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/EpochTransitionSummary.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/EpochTransitionSummary.java @@ -53,7 +53,7 @@ public List getBoundaryAttesters() { Map beaconHeadAttestationRewards = new HashMap<>(); Map beaconHeadAttestationPenalties = new HashMap<>(); Map inclusionDistanceRewards = new HashMap<>(); - Map penalizedEpochPenalties = new HashMap<>(); + Map initiatedExitPenalties = new HashMap<>(); Map noFinalityPenalties = new HashMap<>(); Map attestationInclusionRewards = new HashMap<>(); @@ -123,8 +123,8 @@ public Map getInclusionDistanceRewards() { return inclusionDistanceRewards; } - public Map getPenalizedEpochPenalties() { - return penalizedEpochPenalties; + public Map getInitiatedExitPenalties() { + return initiatedExitPenalties; } public Map getNoFinalityPenalties() { diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java index 509d1abcc..99fa899e3 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java @@ -16,7 +16,7 @@ import org.ethereum.beacon.core.operations.deposit.DepositData; import org.ethereum.beacon.core.operations.deposit.DepositInput; import org.ethereum.beacon.core.spec.ChainSpec; -import org.ethereum.beacon.core.state.CrosslinkRecord; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.ForkData; import org.ethereum.beacon.core.types.Bitfield64; import org.ethereum.beacon.core.types.EpochNumber; @@ -79,12 +79,12 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { // Randomness and committees initialState.getLatestRandaoMixes().addAll( nCopies(chainSpec.getLatestRandaoMixesLength().getIntValue(), Hash32.ZERO)); - initialState.setPreviousEpochStartShard(chainSpec.getGenesisStartShard()); - initialState.setCurrentEpochStartShard(chainSpec.getGenesisStartShard()); - initialState.setPreviousCalculationEpoch(chainSpec.getGenesisEpoch()); - initialState.setCurrentCalculationEpoch(chainSpec.getGenesisEpoch()); - initialState.setPreviousEpochSeed(Hash32.ZERO); - initialState.setCurrentEpochSeed(Hash32.ZERO); + initialState.setPreviousShufflingStartShard(chainSpec.getGenesisStartShard()); + initialState.setCurrentShufflingStartShard(chainSpec.getGenesisStartShard()); + initialState.setPreviousShufflingEpoch(chainSpec.getGenesisEpoch()); + initialState.setCurrentShufflingEpoch(chainSpec.getGenesisEpoch()); + initialState.setPreviousShufflingSeed(Hash32.ZERO); + initialState.setCurrentShufflingSeed(Hash32.ZERO); // Finality initialState.setPreviousJustifiedEpoch(chainSpec.getGenesisEpoch()); @@ -94,12 +94,12 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { // Recent state initialState.getLatestCrosslinks().addAll( - nCopies(chainSpec.getShardCount().getIntValue(), CrosslinkRecord.EMPTY)); + nCopies(chainSpec.getShardCount().getIntValue(), Crosslink.EMPTY)); initialState.getLatestBlockRoots().addAll( nCopies(chainSpec.getLatestBlockRootsLength().getIntValue(), Hash32.ZERO)); - initialState.getLatestIndexRoots().addAll( - nCopies(chainSpec.getLatestIndexRootsLength().getIntValue(), Hash32.ZERO)); - initialState.getLatestPenalizedBalances().addAll( + initialState.getLatestActiveIndexRoots().addAll( + nCopies(chainSpec.getLatestActiveIndexRootsLength().getIntValue(), Hash32.ZERO)); + initialState.getLatestSlashedBalances().addAll( nCopies(chainSpec.getLatestPenalizedExitLength().getIntValue(), Gwei.ZERO)); initialState.getLatestAttestations().clear(); initialState.getBatchedBlockRoots().clear(); @@ -137,11 +137,11 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { specHelpers.get_active_validator_indices( initialState.getValidatorRegistry(), chainSpec.getGenesisEpoch())); - for (EpochNumber index : chainSpec.getLatestIndexRootsLength().iterateFromZero()) { - initialState.getLatestIndexRoots().set(index, genesis_active_index_root); + for (EpochNumber index : chainSpec.getLatestActiveIndexRootsLength().iterateFromZero()) { + initialState.getLatestActiveIndexRoots().set(index, genesis_active_index_root); } - initialState.setCurrentEpochSeed( + initialState.setCurrentShufflingSeed( specHelpers.generate_seed(initialState, chainSpec.getGenesisEpoch())); BeaconState validatorsState = initialState.createImmutable(); diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java index 702aaa350..fea4f1eb1 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java @@ -10,7 +10,7 @@ import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.deposit.DepositData; import org.ethereum.beacon.core.operations.deposit.DepositInput; @@ -100,7 +100,7 @@ Run penalize_validator(state, proposer_slashing.proposer_index). Let slashable_attestation_2 = attester_slashing.slashable_attestation_2. Let slashable_indices = [index for index in slashable_attestation_1.validator_indices if index in slashable_attestation_2.validator_indices - and state.validator_registry[index].penalized_epoch > get_current_epoch(state)]. + and state.validator_registry[index].initiated_exit > get_current_epoch(state)]. Run penalize_validator(state, index) for each index in slashable_indices. */ for (AttesterSlashing attester_slashing : block.getBody().getAttesterSlashings()) { @@ -108,8 +108,7 @@ Run penalize_validator(state, index) for each index in slashable_indices. attester_slashing.getSlashableAttestation1().getValidatorIndices().intersection( attester_slashing.getSlashableAttestation2().getValidatorIndices()); for (ValidatorIndex index : intersection) { - if (state.getValidatorRegistry().get(index).getPenalizedEpoch().greater( - specHelpers.get_current_epoch(state))) { + if (!state.getValidatorRegistry().get(index).getSlashed()) { specHelpers.penalize_validator(state, index); } } @@ -167,8 +166,8 @@ Append PendingAttestationRecord( For each exit in block.body.exits: Run initiate_validator_exit(state, exit.validator_index). */ - for (Exit exit : block.getBody().getExits()) { - specHelpers.initiate_validator_exit(state, exit.getValidatorIndex()); + for (VoluntaryExit voluntaryExit : block.getBody().getExits()) { + specHelpers.initiate_validator_exit(state, voluntaryExit.getValidatorIndex()); } BeaconStateEx ret = new BeaconStateExImpl(state.createImmutable(), diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java index ff2d16d86..999e1793d 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java @@ -19,7 +19,7 @@ import org.ethereum.beacon.consensus.TransitionType; import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.spec.ChainSpec; -import org.ethereum.beacon.core.state.CrosslinkRecord; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.PendingAttestationRecord; import org.ethereum.beacon.core.state.ShardCommittee; @@ -287,29 +287,29 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ List crosslink_committee = s.getCommittee(); ShardNumber shard = s.getShard(); - // Let shard_block_root be state.latest_crosslinks[shard].shard_block_root - Hash32 shard_block_root = state.getLatestCrosslinks().get(shard).getShardBlockRoot(); - // Let attesting_validator_indices(crosslink_committee, shard_block_root) + // Let crosslink_data_root be state.latest_crosslinks[shard].crosslink_data_root + Hash32 crosslink_data_root = state.getLatestCrosslinks().get(shard).getCrosslinkDataRoot(); + // Let attesting_validator_indices(crosslink_committee, crosslink_data_root) // be the union of the validator index sets given by // [get_attestation_participants(state, a.data, a.aggregation_bitfield) // for a in current_epoch_attestations + previous_epoch_attestations - // if a.data.shard == shard and a.data.shard_block_root == shard_block_root]. + // if a.data.shard == shard and a.data.crosslink_data_root == crosslink_data_root]. Set attesting_validator_indices_tmp = Stream .concat(current_epoch_attestations.stream(), previous_epoch_attestations.stream()) .filter(a -> a.getData().getShard().equals(shard) - && a.getData().getShardBlockRoot().equals(shard_block_root)) + && a.getData().getCrosslinkDataRoot().equals(crosslink_data_root)) .flatMap(a -> spec.get_attestation_participants( state, a.getData(), a.getAggregationBitfield()).stream()) .collect(Collectors.toSet()); attesting_validator_indices.put( - Pair.with(crosslink_committee, shard_block_root), + Pair.with(crosslink_committee, crosslink_data_root), attesting_validator_indices_tmp); - // Let winning_root(crosslink_committee) be equal to the value of shard_block_root + // Let winning_root(crosslink_committee) be equal to the value of crosslink_data_root // such that sum([get_effective_balance(state, i) - // for i in attesting_validator_indices(crosslink_committee, shard_block_root)]) - // is maximized (ties broken by favoring lower shard_block_root values). + // for i in attesting_validator_indices(crosslink_committee, crosslink_data_root)]) + // is maximized (ties broken by favoring lower crosslink_data_root values). // TODO not sure this is correct implementation Gwei sum = attesting_validator_indices_tmp.stream() .map(i -> spec.get_effective_balance(state, i)) @@ -317,7 +317,7 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ .orElse(Gwei.ZERO); winning_root_tmp.compute(crosslink_committee, (k, v) -> v == null || sum.compareTo(v.getValue0()) > 0 ? - Pair.with(sum, shard_block_root) : v + Pair.with(sum, crosslink_data_root) : v ); } } @@ -479,7 +479,7 @@ For every slot in range(get_epoch_start_slot(previous_epoch), get_epoch_start_sl For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: Set state.latest_crosslinks[shard] = Crosslink( epoch=current_epoch, - shard_block_root=winning_root(crosslink_committee)) + crosslink_data_root=winning_root(crosslink_committee)) if 3 * total_attesting_balance(crosslink_committee) >= 2 * total_balance(crosslink_committee). */ for (SlotNumber slot : spec.get_epoch_start_slot(previous_epoch) @@ -492,7 +492,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: if (total_attesting_balance.apply(crosslink_committee).times(3).greaterEqual( total_balance.apply(crosslink_committee).times(2))) { state.getLatestCrosslinks().set(shard, - new CrosslinkRecord(current_epoch, winning_root.get(crosslink_committee))); + new Crosslink(current_epoch, winning_root.get(crosslink_committee))); } } } @@ -745,18 +745,18 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: logger.debug("Penalized: Previous epoch head attesters: " + previous_epoch_head_attester_loosers); } - // Any active_validator index with validator.penalized_epoch <= current_epoch, loses + // Any active_validator index with validator.initiated_exit <= current_epoch, loses // 2 * inactivity_penalty(state, index, epochs_since_finality) + base_reward(state, index). List inactive_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { ValidatorRecord validator = state.getValidatorRegistry().get(index); Gwei penalty = inactivity_penalty.apply(index, epochs_since_finality) .times(2).plus(base_reward.apply(index)); - if (validator.getPenalizedEpoch().lessEqual(current_epoch)) { + if (validator.getSlashed()) { state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); inactive_attester_loosers.add(index); if (summary != null) { - summary.penalizedEpochPenalties.put(index, penalty); + summary.initiatedExitPenalties.put(index, penalty); } } } @@ -884,19 +884,19 @@ def process_ejections(state: BeaconState) -> None: // First, update the following: - // Set state.previous_calculation_epoch = state.current_calculation_epoch. - state.setPreviousCalculationEpoch(state.getCurrentCalculationEpoch()); - // Set state.previous_epoch_start_shard = state.current_epoch_start_shard. - state.setPreviousEpochStartShard(state.getCurrentEpochStartShard()); - // Set state.previous_epoch_seed = state.current_epoch_seed. - state.setPreviousEpochSeed(state.getCurrentEpochSeed()); + // Set state.previous_shuffling_epoch = state.current_shuffling_epoch. + state.setPreviousShufflingEpoch(state.getCurrentShufflingEpoch()); + // Set state.previous_shuffling_start_shard = state.current_shuffling_start_shard. + state.setPreviousShufflingStartShard(state.getCurrentShufflingStartShard()); + // Set state.previous_shuffling_seed = state.current_shuffling_seed. + state.setPreviousShufflingSeed(state.getCurrentShufflingSeed()); /* If the following are satisfied: state.finalized_epoch > state.validator_registry_update_epoch state.latest_crosslinks[shard].epoch > state.validator_registry_update_epoch for every shard number shard in - [(state.current_epoch_start_shard + i) % SHARD_COUNT + [(state.current_shuffling_start_shard + i) % SHARD_COUNT for i in range(get_current_epoch_committee_count(state))] (that is, for every shard in the current committees) @@ -905,7 +905,7 @@ def process_ejections(state: BeaconState) -> None: state.getFinalizedEpoch().greater(state.getValidatorRegistryUpdateEpoch()); for (int i = 0; i < spec.get_current_epoch_committee_count(state); i++) { - ShardNumber shard = state.getCurrentEpochStartShard().plusModulo(i, specConst.getShardCount()); + ShardNumber shard = state.getCurrentShufflingStartShard().plusModulo(i, specConst.getShardCount()); if (!state.getLatestCrosslinks().get(shard).getEpoch().greater( state.getValidatorRegistryUpdateEpoch())) { updateRegistry = false; @@ -916,14 +916,14 @@ def process_ejections(state: BeaconState) -> None: if (updateRegistry) { // update the validator registry and associated fields by running spec.update_validator_registry(state); - // Set state.current_calculation_epoch = next_epoch - state.setCurrentCalculationEpoch(next_epoch); - // Set state.current_epoch_start_shard = (state.current_epoch_start_shard + + // Set state.current_shuffling_epoch = next_epoch + state.setCurrentShufflingEpoch(next_epoch); + // Set state.current_shuffling_start_shard = (state.current_shuffling_start_shard + // get_current_epoch_committee_count(state)) % SHARD_COUNT - state.setCurrentEpochStartShard(state.getCurrentEpochStartShard().plusModulo( + state.setCurrentShufflingStartShard(state.getCurrentShufflingStartShard().plusModulo( spec.get_current_epoch_committee_count(state), specConst.getShardCount())); - // Set state.current_epoch_seed = generate_seed(state, state.current_calculation_epoch) - state.setCurrentEpochSeed(spec.generate_seed(state, state.getCurrentCalculationEpoch())); + // Set state.current_shuffling_seed = generate_seed(state, state.current_shuffling_epoch) + state.setCurrentShufflingSeed(spec.generate_seed(state, state.getCurrentShufflingEpoch())); } else { // If a validator registry update does not happen do the following: @@ -935,11 +935,11 @@ def process_ejections(state: BeaconState) -> None: // If epochs_since_last_registry_update > 1 and is_power_of_two(epochs_since_last_registry_update): if (epochs_since_last_registry_update.greater(EpochNumber.of(1)) && epochs_since_last_registry_update.isPowerOf2()) { - // Set state.current_calculation_epoch = next_epoch. - state.setCurrentCalculationEpoch(next_epoch); - // Set state.current_epoch_seed = generate_seed(state, state.current_calculation_epoch) - state.setCurrentEpochSeed(spec.generate_seed(state, state.getCurrentCalculationEpoch())); - // Note that state.current_epoch_start_shard is left unchanged. + // Set state.current_shuffling_epoch = next_epoch. + state.setCurrentShufflingEpoch(next_epoch); + // Set state.current_shuffling_seed = generate_seed(state, state.current_shuffling_epoch) + state.setCurrentShufflingSeed(spec.generate_seed(state, state.getCurrentShufflingEpoch())); + // Note that state.current_shuffling_start_shard is left unchanged. } } @@ -950,16 +950,16 @@ def process_ejections(state: BeaconState) -> None: Final updates */ - // Set state.latest_index_roots[(next_epoch + ENTRY_EXIT_DELAY) % LATEST_INDEX_ROOTS_LENGTH] = + // Set state.latest_active_index_roots[(next_epoch + ENTRY_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] = // hash_tree_root(get_active_validator_indices(state, next_epoch + ENTRY_EXIT_DELAY)). - state.getLatestIndexRoots().set( - next_epoch.plus(specConst.getEntryExitDelay()).modulo(specConst.getLatestIndexRootsLength()), + state.getLatestActiveIndexRoots().set( + next_epoch.plus(specConst.getEntryExitDelay()).modulo(specConst.getLatestActiveIndexRootsLength()), spec.hash_tree_root(spec.get_active_validator_indices(state.getValidatorRegistry(), next_epoch.plus(specConst.getEntryExitDelay())))); - // Set state.latest_penalized_balances[(next_epoch) % LATEST_PENALIZED_EXIT_LENGTH] = - // state.latest_penalized_balances[current_epoch % LATEST_PENALIZED_EXIT_LENGTH]. - state.getLatestPenalizedBalances().set(next_epoch.modulo(specConst.getLatestPenalizedExitLength()), - state.getLatestPenalizedBalances().get( + // Set state.latest_slashed_balances[(next_epoch) % LATEST_PENALIZED_EXIT_LENGTH] = + // state.latest_slashed_balances[current_epoch % LATEST_PENALIZED_EXIT_LENGTH]. + state.getLatestSlashedBalances().set(next_epoch.modulo(specConst.getLatestPenalizedExitLength()), + state.getLatestSlashedBalances().get( current_epoch.modulo(specConst.getLatestPenalizedExitLength()))); // Set state.latest_randao_mixes[next_epoch % LATEST_RANDAO_MIXES_LENGTH] = // get_randao_mix(state, current_epoch). diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java index f46542678..afcf35406 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java @@ -1,22 +1,22 @@ package org.ethereum.beacon.consensus.verifier.block; import org.ethereum.beacon.consensus.verifier.OperationVerifier; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.spec.ChainSpec; /** * Verifies exit operation list. * - * @see Exit + * @see VoluntaryExit */ -public class ExitListVerifier extends OperationListVerifier { +public class ExitListVerifier extends OperationListVerifier { - public ExitListVerifier(OperationVerifier operationVerifier, ChainSpec chainSpec) { - super(operationVerifier, block -> block.getBody().getExits(), chainSpec.getMaxExits()); + public ExitListVerifier(OperationVerifier operationVerifier, ChainSpec chainSpec) { + super(operationVerifier, block -> block.getBody().getExits(), chainSpec.getMaxVoluntaryExits()); } @Override - protected Class getType() { - return Exit.class; + protected Class getType() { + return VoluntaryExit.class; } } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java index 243ad166e..d192aeea5 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java @@ -83,16 +83,16 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { } // Verify that either attestation.data.latest_crosslink_root or - // attestation.data.shard_block_root equals state.latest_crosslinks[shard].shard_block_root - Hash32 shardBlockRoot = - state.getLatestCrosslinks().get(data.getShard()).getShardBlockRoot(); - if (!data.getLatestCrosslinkRoot().equals(shardBlockRoot) - && !data.getShardBlockRoot().equals(shardBlockRoot)) { + // attestation.data.crosslink_data_root equals state.latest_crosslinks[shard].crosslink_data_root + Hash32 crosslinkDataRoot = + state.getLatestCrosslinks().get(data.getShard()).getCrosslinkDataRoot(); + if (!data.getLatestCrosslink().getCrosslinkDataRoot().equals(crosslinkDataRoot) + && !data.getCrosslinkDataRoot().equals(crosslinkDataRoot)) { return failedResult( - "either attestation_data.justified_block_root or attestation_data.shard_block_root must be " - + "equal to latest_crosslink.shard_block_root, justified_block_root=%s, " - + "attestation_data.shard_block_root=%s, latest_crosslink.shard_block_root=%s", - data.getJustifiedBlockRoot(), data.getShardBlockRoot(), shardBlockRoot); + "either attestation_data.justified_block_root or attestation_data.crosslink_data_root must be " + + "equal to latest_crosslink.crosslink_data_root, justified_block_root=%s, " + + "attestation_data.crosslink_data_root=%s, latest_crosslink.crosslink_data_root=%s", + data.getJustifiedBlockRoot(), data.getCrosslinkDataRoot(), crosslinkDataRoot); } // Verify bitfields and aggregate signature: @@ -167,9 +167,9 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { return failedResult("failed to verify aggregated signature"); } - if (!Hash32.ZERO.equals(data.getShardBlockRoot())) { + if (!Hash32.ZERO.equals(data.getCrosslinkDataRoot())) { return failedResult( - "attestation_data.shard_block_root must be equal to zero hash, phase 0 check"); + "attestation_data.crosslink_data_root must be equal to zero hash, phase 0 check"); } return PASSED; diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttesterSlashingVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttesterSlashingVerifier.java index 1ec511dd2..ef3885025 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttesterSlashingVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttesterSlashingVerifier.java @@ -60,9 +60,7 @@ public VerificationResult verify(AttesterSlashing attesterSlashing, BeaconState slashableAttestation1.getValidatorIndices().intersection( slashableAttestation1.getValidatorIndices()); if (intersection.stream() - .noneMatch(i -> - state.getValidatorRegistry().get(i).getPenalizedEpoch() - .greater(specHelpers.get_current_epoch(state)))) { + .noneMatch(i -> state.getValidatorRegistry().get(i).getSlashed())) { return failedResult("spec assertion failed"); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java index 6f6201e19..77cb0a035 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java @@ -8,21 +8,19 @@ import org.ethereum.beacon.consensus.verifier.OperationVerifier; import org.ethereum.beacon.consensus.verifier.VerificationResult; import org.ethereum.beacon.core.BeaconState; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.state.ValidatorRecord; -import org.ethereum.beacon.core.types.BLSSignature; -import tech.pegasys.artemis.ethereum.core.Hash32; /** - * Verifies {@link Exit} beacon chain operation. + * Verifies {@link VoluntaryExit} beacon chain operation. * - * @see Exit + * @see VoluntaryExit * @see Exits * in the spec. */ -public class ExitVerifier implements OperationVerifier { +public class ExitVerifier implements OperationVerifier { private ChainSpec chainSpec; private SpecHelpers specHelpers; @@ -33,10 +31,10 @@ public ExitVerifier(SpecHelpers specHelpers) { } @Override - public VerificationResult verify(Exit exit, BeaconState state) { - specHelpers.checkIndexRange(state, exit.getValidatorIndex()); + public VerificationResult verify(VoluntaryExit voluntaryExit, BeaconState state) { + specHelpers.checkIndexRange(state, voluntaryExit.getValidatorIndex()); - ValidatorRecord validator = state.getValidatorRegistry().get(exit.getValidatorIndex()); + ValidatorRecord validator = state.getValidatorRegistry().get(voluntaryExit.getValidatorIndex()); // Verify that validator.exit_epoch > get_entry_exit_effect_epoch(get_current_epoch(state)) if (!validator.getExitEpoch().greater( @@ -47,7 +45,7 @@ public VerificationResult verify(Exit exit, BeaconState state) { } // Verify that get_current_epoch(state) >= exit.epoch - if (!specHelpers.get_current_epoch(state).greaterEqual(exit.getEpoch())) { + if (!specHelpers.get_current_epoch(state).greaterEqual(voluntaryExit.getEpoch())) { return failedResult( "exit.epoch must be greater or equal to current_epoch"); } @@ -64,9 +62,9 @@ public VerificationResult verify(Exit exit, BeaconState state) { // domain=get_domain(state.fork, exit.epoch, DOMAIN_EXIT)). if (!specHelpers.bls_verify( validator.getPubKey(), - specHelpers.signed_root(exit, "signature"), - exit.getSignature(), - specHelpers.get_domain(state.getForkData(), exit.getEpoch(), EXIT))) { + specHelpers.signed_root(voluntaryExit, "signature"), + voluntaryExit.getSignature(), + specHelpers.get_domain(state.getForkData(), voluntaryExit.getEpoch(), EXIT))) { return failedResult("failed to verify signature"); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ProposerSlashingVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ProposerSlashingVerifier.java index 0aee117f4..be229a42f 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ProposerSlashingVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ProposerSlashingVerifier.java @@ -57,31 +57,31 @@ public VerificationResult verify(ProposerSlashing proposerSlashing, BeaconState ValidatorRecord proposer = state.getValidatorRegistry().get(proposerSlashing.getProposerIndex()); - if (!proposer.getPenalizedEpoch().greater(specHelpers.get_current_epoch(state))) { + if (proposer.getSlashed()) { return failedResult( - "proposer penalized_epoch should be less than get_current_epoch(state)"); + "proposer was already slashed"); } if (!specHelpers.bls_verify( proposer.getPubKey(), specHelpers.signed_root(proposerSlashing.getProposal1(), "signature"), - proposerSlashing.getProposalSignature1(), + proposerSlashing.getProposal1().getSignature(), specHelpers.get_domain( state.getForkData(), specHelpers.slot_to_epoch(proposerSlashing.getProposal1().getSlot()), PROPOSAL))) { - return failedResult("proposal_signature_1 is invalid"); + return failedResult("proposal_1.signature is invalid"); } if (!specHelpers.bls_verify( proposer.getPubKey(), specHelpers.signed_root(proposerSlashing.getProposal2(), "signature"), - proposerSlashing.getProposalSignature2(), + proposerSlashing.getProposal2().getSignature(), specHelpers.get_domain( state.getForkData(), specHelpers.slot_to_epoch(proposerSlashing.getProposal2().getSlot()), PROPOSAL))) { - return failedResult("proposal_signature_2 is invalid"); + return failedResult("proposal_2.signature is invalid"); } return PASSED; diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java b/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java index 9c334364f..869bf6b58 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java @@ -6,7 +6,7 @@ import javax.annotation.Nullable; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.spec.ChainSpec; @@ -41,11 +41,10 @@ public class BeaconBlock { @SSZ private final BLSSignature randaoReveal; /** Eth1 data that is observed by proposer. */ @SSZ private final Eth1Data eth1Data; - /** Proposer's signature. */ - @SSZ private final BLSSignature signature; - /** Block body. */ @SSZ private final BeaconBlockBody body; + /** Proposer's signature. */ + @SSZ private final BLSSignature signature; public BeaconBlock( SlotNumber slot, @@ -135,8 +134,8 @@ public String toStringFull(@Nullable ChainSpec spec,@Nullable Time beaconStart, for (Deposit deposit : body.getDeposits()) { ret.append(" " + deposit.toString() + "\n"); } - for (Exit exit : body.getExits()) { - ret.append(" " + exit.toString(spec) + "\n"); + for (VoluntaryExit voluntaryExit : body.getExits()) { + ret.append(" " + voluntaryExit.toString(spec) + "\n"); } for (ProposerSlashing proposerSlashing : body.getProposerSlashings()) { ret.append(" " + proposerSlashing.toString(spec, beaconStart) + "\n"); diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconBlockBody.java b/core/src/main/java/org/ethereum/beacon/core/BeaconBlockBody.java index dac5f7619..d25a3d393 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconBlockBody.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconBlockBody.java @@ -7,7 +7,8 @@ import java.util.List; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.ssz.annotation.SSZ; @@ -35,6 +36,7 @@ public class BeaconBlockBody { emptyList(), emptyList(), emptyList(), + emptyList(), emptyList()); /** A list of proposer slashing challenges. */ @@ -46,18 +48,23 @@ public class BeaconBlockBody { /** A list of validator deposit proofs. */ @SSZ private final List depositsList; /** A list of validator exits. */ - @SSZ private final List exitsList; + @SSZ private final List exitsList; + /** A list of transfers. */ + @SSZ private final List transferList; public BeaconBlockBody( List proposerSlashings, List attesterSlashings, List attestations, - List deposits, List exits) { + List deposits, + List voluntaryExits, + List transfers) { this.proposerSlashingsList = new ArrayList<>(proposerSlashings); this.attesterSlashingsList = new ArrayList<>(attesterSlashings); this.attestationsList = new ArrayList<>(attestations); this.depositsList = new ArrayList<>(deposits); - this.exitsList = new ArrayList<>(exits); + this.exitsList = new ArrayList<>(voluntaryExits); + this.transferList = new ArrayList<>(transfers); } public ReadList getProposerSlashings() { @@ -76,10 +83,14 @@ public ReadList getDeposits() { return WriteList.wrap(depositsList, Integer::intValue); } - public ReadList getExits() { + public ReadList getExits() { return WriteList.wrap(exitsList, Integer::intValue); } + public ReadList getTransfers() { + return WriteList.wrap(transferList, Integer::intValue); + } + /** * @deprecated for serialization only */ @@ -111,7 +122,7 @@ public List getDepositsList() { /** * @deprecated for serialization only */ - public List getExitsList() { + public List getExitsList() { return exitsList; } diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconState.java b/core/src/main/java/org/ethereum/beacon/core/BeaconState.java index 10dcad998..5542b2b2a 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconState.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconState.java @@ -4,7 +4,7 @@ import javax.annotation.Nullable; import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.state.BeaconStateImpl; -import org.ethereum.beacon.core.state.CrosslinkRecord; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.ForkData; @@ -19,6 +19,7 @@ import org.ethereum.beacon.core.types.ValidatorIndex; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.collections.ReadList; +import tech.pegasys.artemis.util.uint.UInt64; /** * Beacon chain state. @@ -61,17 +62,17 @@ static BeaconState getEmpty() { /** The most recent randao mixes. */ ReadList getLatestRandaoMixes(); - ShardNumber getPreviousEpochStartShard(); + ShardNumber getPreviousShufflingStartShard(); - ShardNumber getCurrentEpochStartShard(); + ShardNumber getCurrentShufflingStartShard(); - EpochNumber getPreviousCalculationEpoch(); + EpochNumber getPreviousShufflingEpoch(); - EpochNumber getCurrentCalculationEpoch(); + EpochNumber getCurrentShufflingEpoch(); - Hash32 getPreviousEpochSeed(); + Hash32 getPreviousShufflingSeed(); - Hash32 getCurrentEpochSeed(); + Hash32 getCurrentShufflingSeed(); /********* Finality **********/ @@ -90,16 +91,16 @@ static BeaconState getEmpty() { /** ******* Recent state ********* */ /** Latest crosslink record for each shard. */ - ReadList getLatestCrosslinks(); + ReadList getLatestCrosslinks(); /** Latest block hashes for each shard. */ ReadList getLatestBlockRoots(); /** Latest block hashes for each shard. */ - ReadList getLatestIndexRoots(); + ReadList getLatestActiveIndexRoots(); - /** Balances penalized at every withdrawal period */ - ReadList getLatestPenalizedBalances(); + /** Balances slashed at every withdrawal period */ + ReadList getLatestSlashedBalances(); /** Attestations that has not been processed yet. */ ReadList getLatestAttestations(); diff --git a/core/src/main/java/org/ethereum/beacon/core/MutableBeaconState.java b/core/src/main/java/org/ethereum/beacon/core/MutableBeaconState.java index c2483928a..d56677868 100644 --- a/core/src/main/java/org/ethereum/beacon/core/MutableBeaconState.java +++ b/core/src/main/java/org/ethereum/beacon/core/MutableBeaconState.java @@ -1,6 +1,6 @@ package org.ethereum.beacon.core; -import org.ethereum.beacon.core.state.CrosslinkRecord; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.ForkData; @@ -15,7 +15,6 @@ import org.ethereum.beacon.core.types.ValidatorIndex; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.collections.WriteList; -import tech.pegasys.artemis.util.uint.UInt64; public interface MutableBeaconState extends BeaconState { @@ -36,17 +35,17 @@ public interface MutableBeaconState extends BeaconState { @Override WriteList getLatestRandaoMixes(); - void setPreviousEpochStartShard(ShardNumber previousEpochStartShard); + void setPreviousShufflingStartShard(ShardNumber previousShufflingStartShard); - void setCurrentEpochStartShard(ShardNumber currentEpochStartShard); + void setCurrentShufflingStartShard(ShardNumber currentShufflingStartShard); - void setPreviousCalculationEpoch(EpochNumber previousCalculationEpoch); + void setPreviousShufflingEpoch(EpochNumber previousShufflingEpoch); - void setCurrentCalculationEpoch(EpochNumber currentCalculationEpoch); + void setCurrentShufflingEpoch(EpochNumber currentShufflingEpoch); - void setPreviousEpochSeed(Hash32 previousEpochRandaoMix); + void setPreviousShufflingSeed(Hash32 previousEpochRandaoMix); - void setCurrentEpochSeed(Hash32 currentEpochRandaoMix); + void setCurrentShufflingSeed(Hash32 currentEpochRandaoMix); void setPreviousJustifiedEpoch(EpochNumber previousJustifiedEpoch); @@ -57,16 +56,16 @@ public interface MutableBeaconState extends BeaconState { void setFinalizedEpoch(EpochNumber finalizedEpoch); @Override - WriteList getLatestCrosslinks(); + WriteList getLatestCrosslinks(); @Override WriteList getLatestBlockRoots(); @Override - WriteList getLatestIndexRoots(); + WriteList getLatestActiveIndexRoots(); @Override - WriteList getLatestPenalizedBalances(); + WriteList getLatestSlashedBalances(); @Override WriteList getLatestAttestations(); diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/ProposerSlashing.java b/core/src/main/java/org/ethereum/beacon/core/operations/ProposerSlashing.java index 27751b56a..20c6a6b48 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/ProposerSlashing.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/ProposerSlashing.java @@ -5,7 +5,6 @@ import org.ethereum.beacon.core.operations.slashing.Proposal; import org.ethereum.beacon.core.spec.ChainSpec; -import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.core.types.ValidatorIndex; import org.ethereum.beacon.ssz.annotation.SSZ; @@ -15,21 +14,15 @@ public class ProposerSlashing { @SSZ private final ValidatorIndex proposerIndex; @SSZ private final Proposal proposal1; - @SSZ private final BLSSignature proposalSignature1; @SSZ private final Proposal proposal2; - @SSZ private final BLSSignature proposalSignature2; public ProposerSlashing( ValidatorIndex proposerIndex, Proposal proposal1, - BLSSignature proposalSignature1, - Proposal proposal2, - BLSSignature proposalSignature2) { + Proposal proposal2) { this.proposerIndex = proposerIndex; this.proposal1 = proposal1; - this.proposalSignature1 = proposalSignature1; this.proposal2 = proposal2; - this.proposalSignature2 = proposalSignature2; } public ValidatorIndex getProposerIndex() { @@ -40,18 +33,10 @@ public Proposal getProposal1() { return proposal1; } - public BLSSignature getProposalSignature1() { - return proposalSignature1; - } - public Proposal getProposal2() { return proposal2; } - public BLSSignature getProposalSignature2() { - return proposalSignature2; - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -59,9 +44,7 @@ public boolean equals(Object o) { ProposerSlashing that = (ProposerSlashing) o; return Objects.equal(proposerIndex, that.proposerIndex) && Objects.equal(proposal1, that.proposal1) - && Objects.equal(proposalSignature1, that.proposalSignature1) - && Objects.equal(proposal2, that.proposal2) - && Objects.equal(proposalSignature2, that.proposalSignature2); + && Objects.equal(proposal2, that.proposal2); } @Override @@ -74,8 +57,6 @@ public String toString(@Nullable ChainSpec spec, @Nullable Time beaconStart) { + "proposer: " + proposerIndex + ", data1: " + proposal1.toString(spec, beaconStart) + ", data2: " + proposal2.toString(spec, beaconStart) - + ", sig1: " + proposalSignature1 - + ", sig2: " + proposalSignature2 + "]"; } } diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java b/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java new file mode 100644 index 000000000..722b84136 --- /dev/null +++ b/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java @@ -0,0 +1,79 @@ +package org.ethereum.beacon.core.operations; + +import org.ethereum.beacon.core.types.BLSPubkey; +import org.ethereum.beacon.core.types.BLSSignature; +import org.ethereum.beacon.core.types.Gwei; +import org.ethereum.beacon.core.types.SlotNumber; +import org.ethereum.beacon.core.types.ValidatorIndex; +import org.ethereum.beacon.ssz.annotation.SSZ; +import org.ethereum.beacon.ssz.annotation.SSZSerializable; + +/** + * A value transfer between validator. + * + * @see Transfers + * in the spec. + */ +@SSZSerializable +public class Transfer { + /** Sender index. */ + @SSZ private final ValidatorIndex from; + /** Recipient index. */ + @SSZ private final ValidatorIndex to; + /** Amount in Gwei. */ + @SSZ private final Gwei amount; + /** Fee in Gwei for block proposer. */ + @SSZ private final Gwei fee; + /** Inclusion slot. */ + @SSZ private final SlotNumber slot; + /** Sender withdrawal pubkey. */ + @SSZ private final BLSPubkey pubkey; + /** Sender signature. */ + @SSZ private final BLSSignature signature; + + public Transfer( + ValidatorIndex from, + ValidatorIndex to, + Gwei amount, + Gwei fee, + SlotNumber slot, + BLSPubkey pubkey, + BLSSignature signature) { + this.from = from; + this.to = to; + this.amount = amount; + this.fee = fee; + this.slot = slot; + this.pubkey = pubkey; + this.signature = signature; + } + + public ValidatorIndex getFrom() { + return from; + } + + public ValidatorIndex getTo() { + return to; + } + + public Gwei getAmount() { + return amount; + } + + public Gwei getFee() { + return fee; + } + + public SlotNumber getSlot() { + return slot; + } + + public BLSPubkey getPubkey() { + return pubkey; + } + + public BLSSignature getSignature() { + return signature; + } +} diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/VoluntaryExit.java b/core/src/main/java/org/ethereum/beacon/core/operations/VoluntaryExit.java new file mode 100644 index 000000000..ae8ca715d --- /dev/null +++ b/core/src/main/java/org/ethereum/beacon/core/operations/VoluntaryExit.java @@ -0,0 +1,82 @@ +package org.ethereum.beacon.core.operations; + +import com.google.common.base.Objects; +import javax.annotation.Nullable; +import org.ethereum.beacon.core.BeaconBlockBody; +import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.types.BLSSignature; +import org.ethereum.beacon.core.types.EpochNumber; +import org.ethereum.beacon.core.types.ValidatorIndex; +import org.ethereum.beacon.ssz.annotation.SSZ; +import org.ethereum.beacon.ssz.annotation.SSZSerializable; + +/** + * Requests a quit from validator registry. + * + * @see BeaconBlockBody + * @see VoluntaryExit + * in the spec + */ +@SSZSerializable +public class VoluntaryExit { + + /** + * Minimum slot for processing exit. + */ + @SSZ + private final EpochNumber epoch; + /** + * Index of the exiting validator. + */ + @SSZ + private final ValidatorIndex validatorIndex; + /** + * Validator signature. + */ + @SSZ + private final BLSSignature signature; + + public VoluntaryExit(EpochNumber epoch, ValidatorIndex validatorIndex, BLSSignature signature) { + this.epoch = epoch; + this.validatorIndex = validatorIndex; + this.signature = signature; + } + + public EpochNumber getEpoch() { + return epoch; + } + + public ValidatorIndex getValidatorIndex() { + return validatorIndex; + } + + public BLSSignature getSignature() { + return signature; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + VoluntaryExit voluntaryExit = (VoluntaryExit) o; + return Objects.equal(epoch, voluntaryExit.epoch) + && Objects.equal(validatorIndex, voluntaryExit.validatorIndex) + && Objects.equal(signature, voluntaryExit.signature); + } + + @Override + public String toString() { + return toString(null); + } + + public String toString(@Nullable ChainSpec spec) { + return "VoluntaryExit[" + + "epoch=" + epoch.toString(spec) + + ", validator=" + validatorIndex + + ", sig=" + signature + +"]"; + } +} \ No newline at end of file diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/attestation/AttestationData.java b/core/src/main/java/org/ethereum/beacon/core/operations/attestation/AttestationData.java index d930cb49d..da5725279 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/attestation/AttestationData.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/attestation/AttestationData.java @@ -11,7 +11,6 @@ import org.ethereum.beacon.ssz.annotation.SSZ; import org.ethereum.beacon.ssz.annotation.SSZSerializable; import tech.pegasys.artemis.ethereum.core.Hash32; -import tech.pegasys.artemis.util.uint.UInt64; /** * Attestation data that validators are signing off on. @@ -28,14 +27,14 @@ public class AttestationData { @SSZ private final SlotNumber slot; /** Shard number. */ @SSZ private final ShardNumber shard; - /** Hash of signed beacon block. */ + /** Root of the signed beacon block. */ @SSZ private final Hash32 beaconBlockRoot; - /** Hash of beacon block's ancestor at the epoch boundary. */ + /** Root of the ancestor at the epoch boundary. */ @SSZ private final Hash32 epochBoundaryRoot; - /** Hash of shard's block. */ - @SSZ private final Hash32 shardBlockRoot; - /** Hash of last crosslink block. */ - @SSZ private final Hash32 latestCrosslinkRoot; + /** Data from the shard since the last attestation. */ + @SSZ private final Hash32 crosslinkDataRoot; + /** Last crosslink. */ + @SSZ private final Crosslink latestCrosslink; /** Slot of the last justified beacon block. */ @SSZ private final EpochNumber justifiedEpoch; /** Hash of the last justified beacon block. */ @@ -46,16 +45,16 @@ public AttestationData( ShardNumber shard, Hash32 beaconBlockRoot, Hash32 epochBoundaryRoot, - Hash32 shardBlockRoot, - Hash32 latestCrosslinkRoot, + Hash32 crosslinkDataRoot, + Crosslink latestCrosslink, EpochNumber justifiedEpoch, Hash32 justifiedBlockRoot) { this.slot = slot; this.shard = shard; this.beaconBlockRoot = beaconBlockRoot; this.epochBoundaryRoot = epochBoundaryRoot; - this.shardBlockRoot = shardBlockRoot; - this.latestCrosslinkRoot = latestCrosslinkRoot; + this.crosslinkDataRoot = crosslinkDataRoot; + this.latestCrosslink = latestCrosslink; this.justifiedEpoch = justifiedEpoch; this.justifiedBlockRoot = justifiedBlockRoot; } @@ -76,12 +75,12 @@ public Hash32 getEpochBoundaryRoot() { return epochBoundaryRoot; } - public Hash32 getShardBlockRoot() { - return shardBlockRoot; + public Hash32 getCrosslinkDataRoot() { + return crosslinkDataRoot; } - public Hash32 getLatestCrosslinkRoot() { - return latestCrosslinkRoot; + public Crosslink getLatestCrosslink() { + return latestCrosslink; } public EpochNumber getJustifiedEpoch() { @@ -101,8 +100,8 @@ public boolean equals(Object o) { && Objects.equal(shard, that.shard) && Objects.equal(beaconBlockRoot, that.beaconBlockRoot) && Objects.equal(epochBoundaryRoot, that.epochBoundaryRoot) - && Objects.equal(shardBlockRoot, that.shardBlockRoot) - && Objects.equal(latestCrosslinkRoot, that.latestCrosslinkRoot) + && Objects.equal(crosslinkDataRoot, that.crosslinkDataRoot) + && Objects.equal(latestCrosslink, that.latestCrosslink) && Objects.equal(justifiedEpoch, that.justifiedEpoch) && Objects.equal(justifiedBlockRoot, that.justifiedBlockRoot); } @@ -113,8 +112,8 @@ public int hashCode() { result = 31 * result + (shard != null ? shard.hashCode() : 0); result = 31 * result + (beaconBlockRoot != null ? beaconBlockRoot.hashCode() : 0); result = 31 * result + (epochBoundaryRoot != null ? epochBoundaryRoot.hashCode() : 0); - result = 31 * result + (shardBlockRoot != null ? shardBlockRoot.hashCode() : 0); - result = 31 * result + (latestCrosslinkRoot != null ? latestCrosslinkRoot.hashCode() : 0); + result = 31 * result + (crosslinkDataRoot != null ? crosslinkDataRoot.hashCode() : 0); + result = 31 * result + (latestCrosslink != null ? latestCrosslink.hashCode() : 0); result = 31 * result + (justifiedEpoch != null ? justifiedEpoch.hashCode() : 0); result = 31 * result + (justifiedBlockRoot != null ? justifiedBlockRoot.hashCode() : 0); return result; @@ -131,8 +130,8 @@ public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart) { + ", shard=" + shard.toString(spec) + ", beaconBlock=" + beaconBlockRoot.toStringShort() + ", epochBoundary=" + epochBoundaryRoot.toStringShort() - + ", shardBlock=" + shardBlockRoot.toStringShort() - + ", latestCrosslink=" + latestCrosslinkRoot.toStringShort() + + ", shardBlock=" + crosslinkDataRoot.toStringShort() + + ", latestCrosslink=" + latestCrosslink.toString(spec) + ", justifiedEpoch=" + justifiedEpoch.toString(spec) + ", justifiedBlock=" + justifiedBlockRoot.toStringShort() +"]"; diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/attestation/Crosslink.java b/core/src/main/java/org/ethereum/beacon/core/operations/attestation/Crosslink.java new file mode 100644 index 000000000..dd331b546 --- /dev/null +++ b/core/src/main/java/org/ethereum/beacon/core/operations/attestation/Crosslink.java @@ -0,0 +1,70 @@ +package org.ethereum.beacon.core.operations.attestation; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; +import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.types.EpochNumber; +import org.ethereum.beacon.ssz.annotation.SSZ; +import org.ethereum.beacon.ssz.annotation.SSZSerializable; +import tech.pegasys.artemis.ethereum.core.Hash32; + +/** + * A Crosslink record. + * + * @see Crosslink + * in the spec. + */ +@SSZSerializable +public class Crosslink { + + public static final Crosslink EMPTY = new Crosslink(EpochNumber.ZERO, Hash32.ZERO); + + /** Epoch number. */ + @SSZ private final EpochNumber epoch; + /** Shard data since the previous crosslink. */ + @SSZ private final Hash32 crosslinkDataRoot; + + public Crosslink(EpochNumber epoch, Hash32 crosslinkDataRoot) { + this.epoch = epoch; + this.crosslinkDataRoot = crosslinkDataRoot; + } + + public EpochNumber getEpoch() { + return epoch; + } + + public Hash32 getCrosslinkDataRoot() { + return crosslinkDataRoot; + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + Crosslink crosslink = (Crosslink) object; + return Objects.equal(epoch, crosslink.epoch) + && Objects.equal(crosslinkDataRoot, crosslink.crosslinkDataRoot); + } + + @Override + public int hashCode() { + return Objects.hashCode(epoch, crosslinkDataRoot); + } + + @Override + public String toString() { + return toString(null); + } + + public String toString(ChainSpec spec) { + return MoreObjects.toStringHelper(this) + .add("epoch", epoch.toString(spec)) + .add("crosslinkDataRoot", crosslinkDataRoot.toStringShort()) + .toString(); + } +} diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/MaxOperationsPerBlock.java b/core/src/main/java/org/ethereum/beacon/core/spec/MaxOperationsPerBlock.java index 8df348a72..8153daf6b 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/MaxOperationsPerBlock.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/MaxOperationsPerBlock.java @@ -13,7 +13,8 @@ public interface MaxOperationsPerBlock { int MAX_ATTESTER_SLASHINGS = 1; int MAX_ATTESTATIONS = 1 << 7; // 128 int MAX_DEPOSITS = 1 << 4; // 16 - int MAX_EXITS = 1 << 4; // 16 + int MAX_VOLUNTARY_EXITS = 1 << 4; // 16 + int MAX_TRANSFERS = 1 << 4; // 16 /* Values defined in the spec. */ @@ -34,7 +35,11 @@ default int getMaxDeposits() { return MAX_DEPOSITS; } - default int getMaxExits() { - return MAX_EXITS; + default int getMaxVoluntaryExits() { + return MAX_VOLUNTARY_EXITS; + } + + default int getMaxTransfers() { + return MAX_TRANSFERS; } } diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java b/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java index 2d715d237..914ae9313 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java @@ -14,7 +14,7 @@ public interface StateListLengths { SlotNumber LATEST_BLOCK_ROOTS_LENGTH = SlotNumber.of(1 << 13); // 8192 block roots EpochNumber LATEST_RANDAO_MIXES_LENGTH = EpochNumber.of(1 << 13); // 8192 randao mixes - EpochNumber LATEST_INDEX_ROOTS_LENGTH = EpochNumber.of(1 << 13); + EpochNumber LATEST_ACTIVE_INDEX_ROOTS_LENGTH = EpochNumber.of(1 << 13); EpochNumber LATEST_PENALIZED_EXIT_LENGTH = EpochNumber.of(1 << 13); // 8192 epochs default SlotNumber getLatestBlockRootsLength() { @@ -25,8 +25,8 @@ default EpochNumber getLatestRandaoMixesLength() { return LATEST_RANDAO_MIXES_LENGTH; } - default EpochNumber getLatestIndexRootsLength() { - return LATEST_INDEX_ROOTS_LENGTH; + default EpochNumber getLatestActiveIndexRootsLength() { + return LATEST_ACTIVE_INDEX_ROOTS_LENGTH; } default EpochNumber getLatestPenalizedExitLength() { diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/TimeParameters.java b/core/src/main/java/org/ethereum/beacon/core/spec/TimeParameters.java index 4eb749247..610ec5975 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/TimeParameters.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/TimeParameters.java @@ -21,7 +21,7 @@ public interface TimeParameters { EpochNumber SEED_LOOKAHEAD = EpochNumber.of(1); EpochNumber ENTRY_EXIT_DELAY = EpochNumber.of(1 << 2); EpochNumber ETH1_DATA_VOTING_PERIOD = EpochNumber.of(1 << 4); - EpochNumber MIN_VALIDATOR_WITHDRAWAL_EPOCHS = EpochNumber.of(1 << 8); + EpochNumber MIN_VALIDATOR_WITHDRAWABILITY_DELAY = EpochNumber.of(1 << 8); /* Values defined in the spec. */ @@ -49,7 +49,7 @@ default EpochNumber getEth1DataVotingPeriod() { return ETH1_DATA_VOTING_PERIOD; } - default EpochNumber getMinValidatorWithdrawalEpochs() { - return MIN_VALIDATOR_WITHDRAWAL_EPOCHS; + default EpochNumber getMinValidatorWithdrawabilityDelay() { + return MIN_VALIDATOR_WITHDRAWABILITY_DELAY; } } diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/ValidatorStatusFlags.java b/core/src/main/java/org/ethereum/beacon/core/spec/ValidatorStatusFlags.java deleted file mode 100644 index 6f0ca5af5..000000000 --- a/core/src/main/java/org/ethereum/beacon/core/spec/ValidatorStatusFlags.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.ethereum.beacon.core.spec; - -import tech.pegasys.artemis.util.uint.UInt64; - -/** - * Validator status flags. - * - * @see Status - * flags in the spec. - */ -public interface ValidatorStatusFlags { - - UInt64 INITIATED_EXIT = UInt64.valueOf(1); - - UInt64 WITHDRAWABLE = UInt64.valueOf(2); -} diff --git a/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java b/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java index 7a3921961..96d30af3a 100644 --- a/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java +++ b/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java @@ -4,6 +4,7 @@ import java.util.List; import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.types.Bitfield64; import org.ethereum.beacon.core.types.EpochNumber; import org.ethereum.beacon.core.types.Gwei; @@ -35,12 +36,12 @@ public class BeaconStateImpl implements MutableBeaconState { /* Randomness and committees */ @SSZ private List latestRandaoMixesList = new ArrayList<>(); - @SSZ private ShardNumber previousEpochStartShard = ShardNumber.ZERO; - @SSZ private ShardNumber currentEpochStartShard = ShardNumber.ZERO; - @SSZ private EpochNumber previousCalculationEpoch = EpochNumber.ZERO; - @SSZ private EpochNumber currentCalculationEpoch = EpochNumber.ZERO; - @SSZ private Hash32 previousEpochSeed = Hash32.ZERO; - @SSZ private Hash32 currentEpochSeed = Hash32.ZERO; + @SSZ private ShardNumber previousShufflingStartShard = ShardNumber.ZERO; + @SSZ private ShardNumber currentShufflingStartShard = ShardNumber.ZERO; + @SSZ private EpochNumber previousShufflingEpoch = EpochNumber.ZERO; + @SSZ private EpochNumber currentShufflingEpoch = EpochNumber.ZERO; + @SSZ private Hash32 previousShufflingSeed = Hash32.ZERO; + @SSZ private Hash32 currentShufflingSeed = Hash32.ZERO; /* Finality */ @@ -51,10 +52,10 @@ public class BeaconStateImpl implements MutableBeaconState { /* Recent state */ - @SSZ private List latestCrosslinksList = new ArrayList<>(); + @SSZ private List latestCrosslinksList = new ArrayList<>(); @SSZ private List latestBlockRootsList = new ArrayList<>(); - @SSZ private List latestIndexRootsList = new ArrayList<>(); - @SSZ private List latestPenalizedBalancesList = new ArrayList<>(); + @SSZ private List latestActiveIndexRootsList = new ArrayList<>(); + @SSZ private List latestSlashedBalancesList = new ArrayList<>(); @SSZ private List latestAttestationsList = new ArrayList<>(); @SSZ private List batchedBlockRootsList = new ArrayList<>(); @@ -75,12 +76,12 @@ private BeaconStateImpl(BeaconState state) { validatorRegistryUpdateEpoch = state.getValidatorRegistryUpdateEpoch(); latestRandaoMixesList = state.getLatestRandaoMixes().listCopy(); - previousEpochStartShard = state.getPreviousEpochStartShard(); - currentEpochStartShard = state.getCurrentEpochStartShard(); - previousCalculationEpoch = state.getPreviousCalculationEpoch(); - currentCalculationEpoch = state.getCurrentCalculationEpoch(); - previousEpochSeed = state.getPreviousEpochSeed(); - currentEpochSeed = state.getCurrentEpochSeed(); + previousShufflingStartShard = state.getPreviousShufflingStartShard(); + currentShufflingStartShard = state.getCurrentShufflingStartShard(); + previousShufflingEpoch = state.getPreviousShufflingEpoch(); + currentShufflingEpoch = state.getCurrentShufflingEpoch(); + previousShufflingSeed = state.getPreviousShufflingSeed(); + currentShufflingSeed = state.getCurrentShufflingSeed(); previousJustifiedEpoch = state.getPreviousJustifiedEpoch(); justifiedEpoch = state.getJustifiedEpoch(); @@ -89,8 +90,8 @@ private BeaconStateImpl(BeaconState state) { latestCrosslinksList = state.getLatestCrosslinks().listCopy(); latestBlockRootsList = state.getLatestBlockRoots().listCopy(); - latestIndexRootsList = state.getLatestIndexRoots().listCopy(); - latestPenalizedBalancesList = state.getLatestPenalizedBalances().listCopy(); + latestActiveIndexRootsList = state.getLatestActiveIndexRoots().listCopy(); + latestSlashedBalancesList = state.getLatestSlashedBalances().listCopy(); latestAttestationsList = state.getLatestAttestations().listCopy(); batchedBlockRootsList = state.getBatchedBlockRoots().listCopy(); @@ -173,66 +174,66 @@ public void setLatestRandaoMixesList( } @Override - public ShardNumber getPreviousEpochStartShard() { - return previousEpochStartShard; + public ShardNumber getPreviousShufflingStartShard() { + return previousShufflingStartShard; } @Override - public void setPreviousEpochStartShard( - ShardNumber previousEpochStartShard) { - this.previousEpochStartShard = previousEpochStartShard; + public void setPreviousShufflingStartShard( + ShardNumber previousShufflingStartShard) { + this.previousShufflingStartShard = previousShufflingStartShard; } @Override - public ShardNumber getCurrentEpochStartShard() { - return currentEpochStartShard; + public ShardNumber getCurrentShufflingStartShard() { + return currentShufflingStartShard; } @Override - public void setCurrentEpochStartShard(ShardNumber currentEpochStartShard) { - this.currentEpochStartShard = currentEpochStartShard; + public void setCurrentShufflingStartShard(ShardNumber currentShufflingStartShard) { + this.currentShufflingStartShard = currentShufflingStartShard; } @Override - public EpochNumber getPreviousCalculationEpoch() { - return previousCalculationEpoch; + public EpochNumber getPreviousShufflingEpoch() { + return previousShufflingEpoch; } @Override - public void setPreviousCalculationEpoch( - EpochNumber previousCalculationEpoch) { - this.previousCalculationEpoch = previousCalculationEpoch; + public void setPreviousShufflingEpoch( + EpochNumber previousShufflingEpoch) { + this.previousShufflingEpoch = previousShufflingEpoch; } @Override - public EpochNumber getCurrentCalculationEpoch() { - return currentCalculationEpoch; + public EpochNumber getCurrentShufflingEpoch() { + return currentShufflingEpoch; } @Override - public void setCurrentCalculationEpoch( - EpochNumber currentCalculationEpoch) { - this.currentCalculationEpoch = currentCalculationEpoch; + public void setCurrentShufflingEpoch( + EpochNumber currentShufflingEpoch) { + this.currentShufflingEpoch = currentShufflingEpoch; } @Override - public Hash32 getPreviousEpochSeed() { - return previousEpochSeed; + public Hash32 getPreviousShufflingSeed() { + return previousShufflingSeed; } @Override - public void setPreviousEpochSeed(Hash32 previousEpochSeed) { - this.previousEpochSeed = previousEpochSeed; + public void setPreviousShufflingSeed(Hash32 previousShufflingSeed) { + this.previousShufflingSeed = previousShufflingSeed; } @Override - public Hash32 getCurrentEpochSeed() { - return currentEpochSeed; + public Hash32 getCurrentShufflingSeed() { + return currentShufflingSeed; } @Override - public void setCurrentEpochSeed(Hash32 currentEpochSeed) { - this.currentEpochSeed = currentEpochSeed; + public void setCurrentShufflingSeed(Hash32 currentShufflingSeed) { + this.currentShufflingSeed = currentShufflingSeed; } @Override @@ -274,12 +275,12 @@ public void setFinalizedEpoch(EpochNumber finalizedEpoch) { this.finalizedEpoch = finalizedEpoch; } - public List getLatestCrosslinksList() { + public List getLatestCrosslinksList() { return latestCrosslinksList; } public void setLatestCrosslinksList( - List latestCrosslinksList) { + List latestCrosslinksList) { this.latestCrosslinksList = latestCrosslinksList; } @@ -292,22 +293,22 @@ public void setLatestBlockRootsList( this.latestBlockRootsList = latestBlockRootsList; } - public List getLatestIndexRootsList() { - return latestIndexRootsList; + public List getLatestActiveIndexRootsList() { + return latestActiveIndexRootsList; } - public void setLatestIndexRootsList( - List latestIndexRootsList) { - this.latestIndexRootsList = latestIndexRootsList; + public void setLatestActiveIndexRootsList( + List latestActiveIndexRootsList) { + this.latestActiveIndexRootsList = latestActiveIndexRootsList; } - public List getLatestPenalizedBalancesList() { - return latestPenalizedBalancesList; + public List getLatestSlashedBalancesList() { + return latestSlashedBalancesList; } - public void setLatestPenalizedBalancesList( - List latestPenalizedBalancesList) { - this.latestPenalizedBalancesList = latestPenalizedBalancesList; + public void setLatestSlashedBalancesList( + List latestSlashedBalancesList) { + this.latestSlashedBalancesList = latestSlashedBalancesList; } public List getLatestAttestationsList() { @@ -363,7 +364,7 @@ public WriteList getLatestRandaoMixes() { } @Override - public WriteList getLatestCrosslinks() { + public WriteList getLatestCrosslinks() { return WriteList.wrap(getLatestCrosslinksList(), ShardNumber::of); } @@ -373,13 +374,13 @@ public WriteList getLatestBlockRoots() { } @Override - public WriteList getLatestIndexRoots() { - return WriteList.wrap(getLatestIndexRootsList(), EpochNumber::of); + public WriteList getLatestActiveIndexRoots() { + return WriteList.wrap(getLatestActiveIndexRootsList(), EpochNumber::of); } @Override - public WriteList getLatestPenalizedBalances() { - return WriteList.wrap(getLatestPenalizedBalancesList(), EpochNumber::of); + public WriteList getLatestSlashedBalances() { + return WriteList.wrap(getLatestSlashedBalancesList(), EpochNumber::of); } @Override diff --git a/core/src/main/java/org/ethereum/beacon/core/state/CrosslinkRecord.java b/core/src/main/java/org/ethereum/beacon/core/state/CrosslinkRecord.java deleted file mode 100644 index 4c890993e..000000000 --- a/core/src/main/java/org/ethereum/beacon/core/state/CrosslinkRecord.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.ethereum.beacon.core.state; - -import com.google.common.base.Objects; -import org.ethereum.beacon.core.BeaconState; -import org.ethereum.beacon.core.types.EpochNumber; -import org.ethereum.beacon.core.types.SlotNumber; -import org.ethereum.beacon.ssz.annotation.SSZ; -import org.ethereum.beacon.ssz.annotation.SSZSerializable; -import tech.pegasys.artemis.ethereum.core.Hash32; -import tech.pegasys.artemis.util.uint.UInt64; - -/** - * Crosslink to a shard block. - * - * @see BeaconState - * @see CrosslinkRecord - * in the spec - */ -@SSZSerializable -public class CrosslinkRecord { - - public static final CrosslinkRecord EMPTY = new CrosslinkRecord(EpochNumber.of(0), Hash32.ZERO); - - /** Slot number. */ - @SSZ private final EpochNumber epoch; - /** Shard block hash. */ - @SSZ private final Hash32 shardBlockRoot; - - public CrosslinkRecord(EpochNumber epoch, Hash32 shardBlockRoot) { - this.epoch = epoch; - this.shardBlockRoot = shardBlockRoot; - } - - public EpochNumber getEpoch() { - return epoch; - } - - public Hash32 getShardBlockRoot() { - return shardBlockRoot; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - CrosslinkRecord that = (CrosslinkRecord) o; - return Objects.equal(epoch, that.epoch) && Objects.equal(shardBlockRoot, that.shardBlockRoot); - } -} diff --git a/core/src/main/java/org/ethereum/beacon/core/state/ValidatorRecord.java b/core/src/main/java/org/ethereum/beacon/core/state/ValidatorRecord.java index 7240a757c..417856ced 100644 --- a/core/src/main/java/org/ethereum/beacon/core/state/ValidatorRecord.java +++ b/core/src/main/java/org/ethereum/beacon/core/state/ValidatorRecord.java @@ -5,11 +5,9 @@ import org.ethereum.beacon.core.operations.deposit.DepositInput; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.EpochNumber; -import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.ssz.annotation.SSZ; import org.ethereum.beacon.ssz.annotation.SSZSerializable; import tech.pegasys.artemis.ethereum.core.Hash32; -import tech.pegasys.artemis.util.bytes.Bytes48; import tech.pegasys.artemis.util.uint.UInt64; import java.util.function.Function; @@ -32,24 +30,24 @@ public class ValidatorRecord { @SSZ private final EpochNumber activationEpoch; /** Slot when validator exited */ @SSZ private final EpochNumber exitEpoch; - /** Slot when validator withdrew */ - @SSZ private final EpochNumber withdrawalEpoch; - /** Slot when validator was penalized */ - @SSZ private final EpochNumber penalizedEpoch; + /** Epoch when validator is eligible to withdraw */ + @SSZ private final EpochNumber WithdrawableEpoch; + /** Did the validator initiate an exit */ + @SSZ private final Boolean initiatedExit; /** Status flags. */ - @SSZ private final UInt64 statusFlags; + @SSZ private final Boolean slashed; public ValidatorRecord(BLSPubkey pubKey, Hash32 withdrawalCredentials, EpochNumber activationEpoch, - EpochNumber exitEpoch, EpochNumber withdrawalEpoch, - EpochNumber penalizedEpoch, UInt64 statusFlags) { + EpochNumber exitEpoch, EpochNumber WithdrawableEpoch, + Boolean initiatedExit, Boolean slashed) { this.pubKey = pubKey; this.withdrawalCredentials = withdrawalCredentials; this.activationEpoch = activationEpoch; this.exitEpoch = exitEpoch; - this.withdrawalEpoch = withdrawalEpoch; - this.penalizedEpoch = penalizedEpoch; - this.statusFlags = statusFlags; + this.WithdrawableEpoch = WithdrawableEpoch; + this.initiatedExit = initiatedExit; + this.slashed = slashed; } public BLSPubkey getPubKey() { @@ -68,16 +66,16 @@ public EpochNumber getExitEpoch() { return exitEpoch; } - public EpochNumber getWithdrawalEpoch() { - return withdrawalEpoch; + public EpochNumber getWithdrawableEpoch() { + return WithdrawableEpoch; } - public EpochNumber getPenalizedEpoch() { - return penalizedEpoch; + public Boolean getInitiatedExit() { + return initiatedExit; } - public UInt64 getStatusFlags() { - return statusFlags; + public Boolean getSlashed() { + return slashed; } @Override @@ -89,9 +87,9 @@ public boolean equals(Object o) { && Objects.equal(withdrawalCredentials, that.withdrawalCredentials) && Objects.equal(activationEpoch, that.activationEpoch) && Objects.equal(exitEpoch, that.exitEpoch) - && Objects.equal(withdrawalEpoch, that.withdrawalEpoch) - && Objects.equal(penalizedEpoch, that.penalizedEpoch) - && Objects.equal(statusFlags, that.statusFlags); + && Objects.equal(WithdrawableEpoch, that.WithdrawableEpoch) + && Objects.equal(initiatedExit, that.initiatedExit) + && Objects.equal(slashed, that.slashed); } public Builder builder() { @@ -104,9 +102,9 @@ public static class Builder { private Hash32 withdrawalCredentials; private EpochNumber activationEpoch; private EpochNumber exitEpoch; - private EpochNumber withdrawalEpoch; - private EpochNumber penalizedEpoch; - private UInt64 statusFlags; + private EpochNumber withdrawableEpoch; + private Boolean initiatedExit; + private Boolean slashed; private Builder() {} @@ -130,9 +128,9 @@ public static Builder fromRecord(ValidatorRecord record) { builder.withdrawalCredentials = record.withdrawalCredentials; builder.activationEpoch = record.activationEpoch; builder.exitEpoch = record.exitEpoch; - builder.withdrawalEpoch = record.withdrawalEpoch; - builder.penalizedEpoch = record.penalizedEpoch; - builder.statusFlags = record.statusFlags; + builder.withdrawableEpoch = record.WithdrawableEpoch; + builder.initiatedExit = record.initiatedExit; + builder.slashed = record.slashed; return builder; } @@ -142,18 +140,18 @@ public ValidatorRecord build() { assert withdrawalCredentials != null; assert activationEpoch != null; assert exitEpoch != null; - assert withdrawalEpoch != null; - assert penalizedEpoch != null; - assert statusFlags != null; + assert withdrawableEpoch != null; + assert initiatedExit != null; + assert slashed != null; return new ValidatorRecord( pubKey, withdrawalCredentials, activationEpoch, exitEpoch, - withdrawalEpoch, - penalizedEpoch, - statusFlags); + withdrawableEpoch, + initiatedExit, + slashed); } public Builder withPubKey(BLSPubkey pubKey) { @@ -176,23 +174,18 @@ public Builder withExitEpoch(EpochNumber exitEpoch) { return this; } - public Builder withWithdrawalEpoch(EpochNumber withdrawalEpoch) { - this.withdrawalEpoch = withdrawalEpoch; + public Builder withWithdrawableEpoch(EpochNumber withdrawableEpoch) { + this.withdrawableEpoch = withdrawableEpoch; return this; } - public Builder withPenalizedEpoch(EpochNumber penalizedEpoch) { - this.penalizedEpoch = penalizedEpoch; + public Builder withInitiatedExit(Boolean initiatedExit) { + this.initiatedExit = initiatedExit; return this; } - public Builder withStatusFlags(UInt64 statusFlags) { - this.statusFlags = statusFlags; - return this; - } - - public Builder withStatusFlags(Function statusFlagsUpdater) { - this.statusFlags = statusFlagsUpdater.apply(statusFlags); + public Builder withSlashed(Boolean slashed) { + this.slashed = slashed; return this; } } diff --git a/core/src/test/java/org/ethereum/beacon/core/ModelsSerializeTest.java b/core/src/test/java/org/ethereum/beacon/core/ModelsSerializeTest.java index 54a0f7392..2de052824 100644 --- a/core/src/test/java/org/ethereum/beacon/core/ModelsSerializeTest.java +++ b/core/src/test/java/org/ethereum/beacon/core/ModelsSerializeTest.java @@ -4,7 +4,8 @@ import org.ethereum.beacon.consensus.transition.BeaconStateExImpl; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.deposit.DepositData; @@ -13,7 +14,7 @@ import org.ethereum.beacon.core.operations.slashing.Proposal; import org.ethereum.beacon.core.operations.slashing.SlashableAttestation; import org.ethereum.beacon.core.state.BeaconStateImpl; -import org.ethereum.beacon.core.state.CrosslinkRecord; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.ForkData; @@ -61,7 +62,7 @@ private AttestationData createAttestationData() { Hashes.keccak256(BytesValue.fromHexString("aa")), Hashes.keccak256(BytesValue.fromHexString("bb")), Hashes.keccak256(BytesValue.fromHexString("cc")), - Hashes.keccak256(BytesValue.fromHexString("dd")), + new Crosslink(EpochNumber.ZERO, Hashes.keccak256(BytesValue.fromHexString("dd"))), EpochNumber.ZERO, Hash32.ZERO); @@ -156,17 +157,17 @@ public void depositTest() { assertEquals(expected2, reconstructed2); } - private Exit createExit() { - Exit exit = new Exit(EpochNumber.of(123), ValidatorIndex.MAX, BLSSignature.wrap(Bytes96.fromHexString("aa"))); + private VoluntaryExit createExit() { + VoluntaryExit voluntaryExit = new VoluntaryExit(EpochNumber.of(123), ValidatorIndex.MAX, BLSSignature.wrap(Bytes96.fromHexString("aa"))); - return exit; + return voluntaryExit; } @Test public void exitTest() { - Exit expected = createExit(); + VoluntaryExit expected = createExit(); BytesValue encoded = sszSerializer.encode2(expected); - Exit reconstructed = sszSerializer.decode(encoded, Exit.class); + VoluntaryExit reconstructed = sszSerializer.decode(encoded, VoluntaryExit.class); assertEquals(expected, reconstructed); } @@ -193,9 +194,7 @@ private ProposerSlashing createProposerSlashing() { new ProposerSlashing( ValidatorIndex.MAX, createProposalSignedData(), - BLSSignature.wrap(Bytes96.fromHexString("aa")), - createProposalSignedData(), - BLSSignature.wrap(Bytes96.fromHexString("bb"))); + createProposalSignedData()); return proposerSlashing; } @@ -219,15 +218,18 @@ private BeaconBlockBody createBeaconBlockBody() { List deposits = new ArrayList<>(); deposits.add(createDeposit1()); deposits.add(createDeposit2()); - List exits = new ArrayList<>(); - exits.add(createExit()); + List voluntaryExits = new ArrayList<>(); + voluntaryExits.add(createExit()); + List transfers = new ArrayList<>(); BeaconBlockBody beaconBlockBody = new BeaconBlockBody( proposerSlashings, attesterSlashings, attestations, deposits, - exits); + voluntaryExits, + transfers + ); return beaconBlockBody; } @@ -317,17 +319,17 @@ public void beaconStateExTest() { assertEquals(expected, reconstructed); } - private CrosslinkRecord createCrosslinkRecord() { - CrosslinkRecord crosslinkRecord = CrosslinkRecord.EMPTY; + private Crosslink createCrosslink() { + Crosslink crosslink = Crosslink.EMPTY; - return crosslinkRecord; + return crosslink; } @Test - public void crosslinkRecordTest() { - CrosslinkRecord expected = createCrosslinkRecord(); + public void crosslinkTest() { + Crosslink expected = createCrosslink(); BytesValue encoded = sszSerializer.encode2(expected); - CrosslinkRecord reconstructed = sszSerializer.decode(encoded, CrosslinkRecord.class); + Crosslink reconstructed = sszSerializer.decode(encoded, Crosslink.class); assertEquals(expected, reconstructed); } @@ -386,10 +388,10 @@ private ValidatorRecord createValidatorRecord() { .withWithdrawalCredentials(Hash32.ZERO) .withActivationEpoch(EpochNumber.ZERO) .withExitEpoch(EpochNumber.ZERO) - .withWithdrawalEpoch(EpochNumber.ZERO) - .withPenalizedEpoch(EpochNumber.ZERO) + .withWithdrawableEpoch(EpochNumber.ZERO) + .withInitiatedExit(Boolean.FALSE) .withExitEpoch(EpochNumber.ZERO) - .withStatusFlags(UInt64.ZERO) + .withSlashed(Boolean.FALSE) .build(); return validatorRecord; diff --git a/core/src/test/java/org/ethereum/beacon/core/SSZSerializableAnnotationTest.java b/core/src/test/java/org/ethereum/beacon/core/SSZSerializableAnnotationTest.java index b4cb3868d..5271fe960 100644 --- a/core/src/test/java/org/ethereum/beacon/core/SSZSerializableAnnotationTest.java +++ b/core/src/test/java/org/ethereum/beacon/core/SSZSerializableAnnotationTest.java @@ -11,7 +11,7 @@ import java.util.Set; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; @@ -21,7 +21,7 @@ import org.ethereum.beacon.core.operations.slashing.Proposal; import org.ethereum.beacon.core.operations.slashing.SlashableAttestation; import org.ethereum.beacon.core.state.BeaconStateImpl; -import org.ethereum.beacon.core.state.CrosslinkRecord; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.ForkData; @@ -124,10 +124,10 @@ public void testAnnotatedClassesHaveTests() throws Exception { Deposit.class, DepositData.class, DepositInput.class, - Exit.class, + VoluntaryExit.class, Proposal.class, ProposerSlashing.class, - CrosslinkRecord.class, + Crosslink.class, Eth1DataVote.class, ForkData.class, PendingAttestationRecord.class, diff --git a/core/src/test/java/org/ethereum/beacon/core/util/AttestationTestUtil.java b/core/src/test/java/org/ethereum/beacon/core/util/AttestationTestUtil.java index 3c9309666..2f8a0fbee 100644 --- a/core/src/test/java/org/ethereum/beacon/core/util/AttestationTestUtil.java +++ b/core/src/test/java/org/ethereum/beacon/core/util/AttestationTestUtil.java @@ -7,8 +7,10 @@ import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Bitfield; +import org.ethereum.beacon.core.types.EpochNumber; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.bytes.Bytes96; import tech.pegasys.artemis.util.bytes.BytesValue; @@ -37,7 +39,7 @@ public static AttestationData createRandomAttestationData(Random random) { Hash32.random(random), Hash32.random(random), Hash32.random(random), - Hash32.random(random), + new Crosslink(EpochNumber.ZERO, Hash32.random(random)), ChainSpec.DEFAULT.getGenesisEpoch(), Hash32.random(random)); } diff --git a/core/src/test/java/org/ethereum/beacon/core/util/ExitTestUtil.java b/core/src/test/java/org/ethereum/beacon/core/util/ExitTestUtil.java index f8167ad9a..7ebe0680c 100644 --- a/core/src/test/java/org/ethereum/beacon/core/util/ExitTestUtil.java +++ b/core/src/test/java/org/ethereum/beacon/core/util/ExitTestUtil.java @@ -4,24 +4,23 @@ import java.util.Random; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.EpochNumber; -import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.core.types.ValidatorIndex; import tech.pegasys.artemis.util.bytes.Bytes96; public abstract class ExitTestUtil { private ExitTestUtil() {} - public static List createRandomList(Random random, int maxCount) { + public static List createRandomList(Random random, int maxCount) { return Stream.generate(() -> createRandom(random)) .limit(Math.abs(random.nextInt()) % maxCount + 1) .collect(Collectors.toList()); } - public static Exit createRandom(Random random) { - return new Exit( + public static VoluntaryExit createRandom(Random random) { + return new VoluntaryExit( EpochNumber.ZERO, ValidatorIndex.ZERO, BLSSignature.wrap(Bytes96.random(random))); } } diff --git a/core/src/test/java/org/ethereum/beacon/core/util/ProposerSlashingTestUtil.java b/core/src/test/java/org/ethereum/beacon/core/util/ProposerSlashingTestUtil.java index dc37f0fca..d0c9a0ac1 100644 --- a/core/src/test/java/org/ethereum/beacon/core/util/ProposerSlashingTestUtil.java +++ b/core/src/test/java/org/ethereum/beacon/core/util/ProposerSlashingTestUtil.java @@ -24,15 +24,15 @@ public static List createRandomList(Random random, int maxCoun public static ProposerSlashing createRandom(Random random) { Proposal signedData1 = new Proposal( - ChainSpec.GENESIS_SLOT, ChainSpec.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), BLSSignature.ZERO); + ChainSpec.GENESIS_SLOT, ChainSpec.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), + BLSSignature.wrap(Bytes96.random(random))); Proposal signedData2 = new Proposal( - ChainSpec.GENESIS_SLOT, ChainSpec.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), BLSSignature.ZERO); + ChainSpec.GENESIS_SLOT, ChainSpec.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), + BLSSignature.wrap(Bytes96.random(random))); return new ProposerSlashing( ValidatorIndex.ZERO, signedData1, - BLSSignature.wrap(Bytes96.random(random)), - signedData2, - BLSSignature.wrap(Bytes96.random(random))); + signedData2); } } diff --git a/start/cli/src/main/resources/config/default-chainSpec.yml b/start/cli/src/main/resources/config/default-chainSpec.yml index 48feef5ae..6bb40d834 100644 --- a/start/cli/src/main/resources/config/default-chainSpec.yml +++ b/start/cli/src/main/resources/config/default-chainSpec.yml @@ -18,7 +18,7 @@ maxOperationsPerBlock: MAX_ATTESTER_SLASHINGS: 1 MAX_ATTESTATIONS: 128 MAX_DEPOSITS: 16 - MAX_EXITS: 16 + MAX_VOLUNTARY_EXITS: 16 miscParameters: SHARD_COUNT: 1024 TARGET_COMMITTEE_SIZE: 128 @@ -35,7 +35,7 @@ rewardAndPenaltyQuotients: stateListLengths: LATEST_BLOCK_ROOTS_LENGTH: 8192 LATEST_RANDAO_MIXES_LENGTH: 8192 - LATEST_INDEX_ROOTS_LENGTH: 8192 + LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 8192 LATEST_PENALIZED_EXIT_LENGTH: 8192 timeParameters: SLOT_DURATION: 6 @@ -44,4 +44,4 @@ timeParameters: SEED_LOOKAHEAD: 1 ENTRY_EXIT_DELAY: 4 ETH1_DATA_VOTING_PERIOD: 16 - MIN_VALIDATOR_WITHDRAWAL_EPOCHS: 256 + MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256 diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java index 74dd31ea5..f527865ce 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java @@ -110,8 +110,8 @@ public int getMaxDeposits() { } @Override - public int getMaxExits() { - return maxOperationsPerBlock.getMaxExits(); + public int getMaxVoluntaryExits() { + return maxOperationsPerBlock.getMaxVoluntaryExits(); } @Override @@ -180,8 +180,8 @@ public EpochNumber getLatestRandaoMixesLength() { } @Override - public EpochNumber getLatestIndexRootsLength() { - return stateListLengths.getLatestIndexRootsLength(); + public EpochNumber getLatestActiveIndexRootsLength() { + return stateListLengths.getLatestActiveIndexRootsLength(); } @Override @@ -220,8 +220,8 @@ public EpochNumber getEth1DataVotingPeriod() { } @Override - public EpochNumber getMinValidatorWithdrawalEpochs() { - return timeParameters.getMinValidatorWithdrawalEpochs(); + public EpochNumber getMinValidatorWithdrawabilityDelay() { + return timeParameters.getMinValidatorWithdrawabilityDelay(); } }; } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MaxOperationsPerBlockData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MaxOperationsPerBlockData.java index 426c3a0f1..a14861c54 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MaxOperationsPerBlockData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MaxOperationsPerBlockData.java @@ -14,8 +14,8 @@ public class MaxOperationsPerBlockData implements MaxOperationsPerBlock { private Integer MAX_ATTESTATIONS; @JsonProperty("MAX_DEPOSITS") private Integer MAX_DEPOSITS; - @JsonProperty("MAX_EXITS") - private Integer MAX_EXITS; + @JsonProperty("MAX_VOLUNTARY_EXITS") + private Integer MAX_VOLUNTARY_EXITS; @Override @JsonIgnore @@ -43,8 +43,8 @@ public int getMaxDeposits() { @Override @JsonIgnore - public int getMaxExits() { - return getMAX_EXITS(); + public int getMaxVoluntaryExits() { + return getMAX_VOLUNTARY_EXITS(); } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @@ -84,11 +84,11 @@ public void setMAX_DEPOSITS(Integer MAX_DEPOSITS) { } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public Integer getMAX_EXITS() { - return MAX_EXITS; + public Integer getMAX_VOLUNTARY_EXITS() { + return MAX_VOLUNTARY_EXITS; } - public void setMAX_EXITS(Integer MAX_EXITS) { - this.MAX_EXITS = MAX_EXITS; + public void setMAX_VOLUNTARY_EXITS(Integer MAX_VOLUNTARY_EXITS) { + this.MAX_VOLUNTARY_EXITS = MAX_VOLUNTARY_EXITS; } } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java index 7957a2c35..136127b90 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java @@ -13,8 +13,8 @@ public class StateListLengthsData implements StateListLengths { private String LATEST_BLOCK_ROOTS_LENGTH; @JsonProperty("LATEST_RANDAO_MIXES_LENGTH") private String LATEST_RANDAO_MIXES_LENGTH; - @JsonProperty("LATEST_INDEX_ROOTS_LENGTH") - private String LATEST_INDEX_ROOTS_LENGTH; + @JsonProperty("LATEST_ACTIVE_INDEX_ROOTS_LENGTH") + private String LATEST_ACTIVE_INDEX_ROOTS_LENGTH; @JsonProperty("LATEST_PENALIZED_EXIT_LENGTH") private String LATEST_PENALIZED_EXIT_LENGTH; @@ -32,8 +32,8 @@ public EpochNumber getLatestRandaoMixesLength() { @Override @JsonIgnore - public EpochNumber getLatestIndexRootsLength() { - return new EpochNumber(UInt64.valueOf(getLATEST_INDEX_ROOTS_LENGTH())); + public EpochNumber getLatestActiveIndexRootsLength() { + return new EpochNumber(UInt64.valueOf(getLATEST_ACTIVE_INDEX_ROOTS_LENGTH())); } @Override @@ -61,12 +61,12 @@ public void setLATEST_RANDAO_MIXES_LENGTH(String LATEST_RANDAO_MIXES_LENGTH) { } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getLATEST_INDEX_ROOTS_LENGTH() { - return LATEST_INDEX_ROOTS_LENGTH; + public String getLATEST_ACTIVE_INDEX_ROOTS_LENGTH() { + return LATEST_ACTIVE_INDEX_ROOTS_LENGTH; } - public void setLATEST_INDEX_ROOTS_LENGTH(String LATEST_INDEX_ROOTS_LENGTH) { - this.LATEST_INDEX_ROOTS_LENGTH = LATEST_INDEX_ROOTS_LENGTH; + public void setLATEST_ACTIVE_INDEX_ROOTS_LENGTH(String LATEST_ACTIVE_INDEX_ROOTS_LENGTH) { + this.LATEST_ACTIVE_INDEX_ROOTS_LENGTH = LATEST_ACTIVE_INDEX_ROOTS_LENGTH; } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/TimeParametersData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/TimeParametersData.java index 0dc7265a5..ede82aa84 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/TimeParametersData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/TimeParametersData.java @@ -23,8 +23,8 @@ public class TimeParametersData implements TimeParameters { private String ENTRY_EXIT_DELAY; @JsonProperty("ETH1_DATA_VOTING_PERIOD") private String ETH1_DATA_VOTING_PERIOD; - @JsonProperty("MIN_VALIDATOR_WITHDRAWAL_EPOCHS") - private String MIN_VALIDATOR_WITHDRAWAL_EPOCHS; + @JsonProperty("MIN_VALIDATOR_WITHDRAWABILITY_DELAY") + private String MIN_VALIDATOR_WITHDRAWABILITY_DELAY; @Override @JsonIgnore @@ -64,8 +64,8 @@ public EpochNumber getEth1DataVotingPeriod() { @Override @JsonIgnore - public EpochNumber getMinValidatorWithdrawalEpochs() { - return new EpochNumber(UInt64.valueOf(getMIN_VALIDATOR_WITHDRAWAL_EPOCHS())); + public EpochNumber getMinValidatorWithdrawabilityDelay() { + return new EpochNumber(UInt64.valueOf(getMIN_VALIDATOR_WITHDRAWABILITY_DELAY())); } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @@ -123,11 +123,11 @@ public void setETH1_DATA_VOTING_PERIOD(String ETH1_DATA_VOTING_PERIOD) { } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getMIN_VALIDATOR_WITHDRAWAL_EPOCHS() { - return MIN_VALIDATOR_WITHDRAWAL_EPOCHS; + public String getMIN_VALIDATOR_WITHDRAWABILITY_DELAY() { + return MIN_VALIDATOR_WITHDRAWABILITY_DELAY; } - public void setMIN_VALIDATOR_WITHDRAWAL_EPOCHS(String MIN_VALIDATOR_WITHDRAWAL_EPOCHS) { - this.MIN_VALIDATOR_WITHDRAWAL_EPOCHS = MIN_VALIDATOR_WITHDRAWAL_EPOCHS; + public void setMIN_VALIDATOR_WITHDRAWABILITY_DELAY(String MIN_VALIDATOR_WITHDRAWABILITY_DELAY) { + this.MIN_VALIDATOR_WITHDRAWABILITY_DELAY = MIN_VALIDATOR_WITHDRAWABILITY_DELAY; } } diff --git a/start/config/src/test/resources/chainSpec.yml b/start/config/src/test/resources/chainSpec.yml index e5810fa53..6f8aa2845 100644 --- a/start/config/src/test/resources/chainSpec.yml +++ b/start/config/src/test/resources/chainSpec.yml @@ -18,7 +18,7 @@ maxOperationsPerBlock: MAX_ATTESTER_SLASHINGS: 1 MAX_ATTESTATIONS: 128 MAX_DEPOSITS: 16 - MAX_EXITS: 16 + MAX_VOLUNTARY_EXITS: 16 miscParameters: SHARD_COUNT: 1024 TARGET_COMMITTEE_SIZE: 128 @@ -35,7 +35,7 @@ rewardAndPenaltyQuotients: stateListLengths: LATEST_BLOCK_ROOTS_LENGTH: 8192 LATEST_RANDAO_MIXES_LENGTH: 8192 - LATEST_INDEX_ROOTS_LENGTH: 8192 + LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 8192 LATEST_PENALIZED_EXIT_LENGTH: 8192 timeParameters: SLOT_DURATION: 6 @@ -44,4 +44,4 @@ timeParameters: SEED_LOOKAHEAD: 1 ENTRY_EXIT_DELAY: 4 ETH1_DATA_VOTING_PERIOD: 16 - MIN_VALIDATOR_WITHDRAWAL_EPOCHS: 256 + MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256 diff --git a/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java b/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java index f8bb8b982..ed92acdff 100644 --- a/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java +++ b/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java @@ -13,6 +13,7 @@ import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Bitfield; import org.ethereum.beacon.core.types.EpochNumber; @@ -56,8 +57,8 @@ public Attestation attest( SlotNumber slot = state.getSlot(); Hash32 beaconBlockRoot = specHelpers.hash_tree_root(observableState.getHead()); Hash32 epochBoundaryRoot = getEpochBoundaryRoot(state, observableState.getHead()); - Hash32 shardBlockRoot = Hash32.ZERO; // Note: This is a stub for phase 0. - Hash32 latestCrosslinkRoot = getLatestCrosslinkRoot(state, shard); + Hash32 crosslinkDataRoot = Hash32.ZERO; // Note: This is a stub for phase 0. + Crosslink latestCrosslink = getLatestCrosslink(state, shard); EpochNumber justifiedEpoch = state.getJustifiedEpoch(); Hash32 justifiedBlockRoot = getJustifiedBlockRoot(state); AttestationData data = @@ -66,8 +67,8 @@ public Attestation attest( shard, beaconBlockRoot, epochBoundaryRoot, - shardBlockRoot, - latestCrosslinkRoot, + crosslinkDataRoot, + latestCrosslink, justifiedEpoch, justifiedBlockRoot); @@ -114,15 +115,15 @@ Hash32 getEpochBoundaryRoot(BeaconState state, BeaconBlock head) { } /* - Set attestation_data.latest_crosslink_root = state.latest_crosslinks[shard].shard_block_root + Set attestation_data.latest_crosslink_root = state.latest_crosslinks[shard].crosslink_data_root where state is the beacon state at head and shard is the validator's assigned shard. */ @VisibleForTesting - Hash32 getLatestCrosslinkRoot(BeaconState state, ShardNumber shard) { + Crosslink getLatestCrosslink(BeaconState state, ShardNumber shard) { if (shard.equals(chainSpec.getBeaconChainShardNumber())) { - return Hash32.ZERO; + return Crosslink.EMPTY; } else { - return state.getLatestCrosslinks().get(shard).getShardBlockRoot(); + return state.getLatestCrosslinks().get(shard); } } diff --git a/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java b/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java index 6fedbb1fc..a353a0c54 100644 --- a/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java +++ b/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java @@ -18,7 +18,8 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.operations.slashing.Proposal; @@ -210,7 +211,8 @@ private BeaconBlockBody getBlockBody(BeaconState state, PendingOperations operat chainSpec.getMaxAttestations(), state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay()).minus(chainSpec.getEpochLength()), state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay())); - List exits = operations.peekExits(chainSpec.getMaxExits()); + List voluntaryExits = operations.peekExits(chainSpec.getMaxVoluntaryExits()); + List transfers = operations.peekTransfers(chainSpec.getMaxTransfers()); Eth1Data latestProcessedDeposit = null; // TODO wait for spec update to include this to state List deposits = @@ -226,6 +228,7 @@ private BeaconBlockBody getBlockBody(BeaconState state, PendingOperations operat attesterSlashings, attestations, deposits, - exits); + voluntaryExits, + transfers); } } diff --git a/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java b/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java index d85d1dc23..4954b87ba 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java @@ -49,7 +49,7 @@ public void attestASlot() { Mockito.doReturn(committee).when(attester).getCommittee(any(), any()); Mockito.doReturn(epochBoundaryRoot).when(attester).getEpochBoundaryRoot(any(), any()); - Mockito.doReturn(latestCrosslinkRoot).when(attester).getLatestCrosslinkRoot(any(), any()); + Mockito.doReturn(latestCrosslinkRoot).when(attester).getLatestCrosslink(any(), any()); Mockito.doReturn(justifiedBlockRoot).when(attester).getJustifiedBlockRoot(any()); Attestation attestation = @@ -63,8 +63,8 @@ public void attestASlot() { Assert.assertEquals( specHelpers.hash_tree_root(initiallyObservedState.getHead()), data.getBeaconBlockRoot()); Assert.assertEquals(epochBoundaryRoot, data.getEpochBoundaryRoot()); - Assert.assertEquals(Hash32.ZERO, data.getShardBlockRoot()); - Assert.assertEquals(latestCrosslinkRoot, data.getLatestCrosslinkRoot()); + Assert.assertEquals(Hash32.ZERO, data.getCrosslinkDataRoot()); + Assert.assertEquals(latestCrosslinkRoot, data.getLatestCrosslink().getCrosslinkDataRoot()); Assert.assertEquals(state.getJustifiedEpoch(), data.getJustifiedEpoch()); Assert.assertEquals(justifiedBlockRoot, data.getJustifiedBlockRoot()); diff --git a/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java b/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java index 7362cef2d..915594a5d 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java @@ -22,7 +22,7 @@ import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.Exit; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.operations.slashing.Proposal; @@ -102,12 +102,12 @@ public void proposeABlockWithOperations() { List casperSlashings = AttesterSlashingTestUtil.createRandomList( random, specHelpers.getChainSpec().getMaxAttesterSlashings()); - List exits = - ExitTestUtil.createRandomList(random, specHelpers.getChainSpec().getMaxExits()); + List voluntaryExits = + ExitTestUtil.createRandomList(random, specHelpers.getChainSpec().getMaxVoluntaryExits()); PendingOperations pendingOperations = PendingOperationsTestUtil.mockPendingOperations( - attestations, attestations, proposerSlashings, casperSlashings, exits); + attestations, attestations, proposerSlashings, casperSlashings, voluntaryExits); ObservableBeaconState initialObservedState = ObservableBeaconStateTestUtil.createInitialState(random, specHelpers, pendingOperations); BeaconState initialState = initialObservedState.getLatestSlotState(); @@ -128,7 +128,7 @@ public void proposeABlockWithOperations() { .peekProposerSlashings(specHelpers.getChainSpec().getMaxProposerSlashings()); Mockito.verify(pendingOperations) .peekAttesterSlashings(specHelpers.getChainSpec().getMaxAttesterSlashings()); - Mockito.verify(pendingOperations).peekExits(specHelpers.getChainSpec().getMaxExits()); + Mockito.verify(pendingOperations).peekExits(specHelpers.getChainSpec().getMaxVoluntaryExits()); BeaconStateEx stateAfterBlock = perBlockTransition.apply(new BeaconStateExImpl(initialState, Hash32.ZERO), block); @@ -140,7 +140,7 @@ public void proposeABlockWithOperations() { Assert.assertEquals(attestations, block.getBody().getAttestations().listCopy()); Assert.assertEquals(proposerSlashings, block.getBody().getProposerSlashings().listCopy()); Assert.assertEquals(casperSlashings, block.getBody().getAttesterSlashings().listCopy()); - Assert.assertEquals(exits, block.getBody().getExits().listCopy()); + Assert.assertEquals(voluntaryExits, block.getBody().getExits().listCopy()); } @Test From 13a1c96fbb52ab2328a8010a1b4cb93160b66fde Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 1 Mar 2019 15:41:41 +0600 Subject: [PATCH 06/21] Adjust chain cosntants with spec:0.4.0 --- .../org/ethereum/beacon/chain/SlotTicker.java | 2 +- .../ObservableStateProcessorImpl.java | 9 +- .../beacon/chain/SlotTickerTests.java | 2 +- .../chain/util/SampleObservableState.java | 4 +- .../beacon/consensus/SpecHelpers.java | 94 +++++++++---------- .../transition/InitialStateTransition.java | 2 +- .../transition/PerEpochTransition.java | 30 +++--- .../operation/AttestationVerifier.java | 4 +- .../verifier/operation/ExitVerifier.java | 4 +- .../beacon/consensus/SpecHelpersTest.java | 2 +- .../transition/PerEpochTransitionTest.java | 2 +- .../transition/PerSlotTransitionTest.java | 2 +- .../ethereum/beacon/core/spec/ChainSpec.java | 7 +- .../core/spec/DepositContractParameters.java | 10 -- .../ethereum/beacon/core/spec/GweiValues.java | 34 +++++++ .../beacon/core/spec/InitialValues.java | 2 +- .../beacon/core/spec/MiscParameters.java | 11 +-- .../core/spec/RewardAndPenaltyQuotients.java | 11 ++- .../beacon/core/spec/SignatureDomains.java | 2 + .../beacon/core/spec/StateListLengths.java | 6 +- .../beacon/core/spec/TimeParameters.java | 28 +++--- .../beacon/core/types/SlotNumber.java | 10 +- .../resources/config/default-chainSpec.yml | 26 ++--- .../test/resources/config/fast-chainSpec.yml | 4 +- .../beacon/LocalMultiValidatorTest.java | 4 +- .../org/ethereum/beacon/LocalNetTest.java | 4 +- .../config/chainspec/ChainSpecData.java | 53 +++++++---- .../DepositContractParametersData.java | 34 ------- .../config/chainspec/GweiValuesData.java | 79 ++++++++++++++++ .../chainspec/MaxOperationsPerBlockData.java | 17 ++++ .../config/chainspec/MiscParametersData.java | 33 ++----- .../RewardAndPenaltyQuotientsData.java | 33 +++++-- .../chainspec/StateListLengthsData.java | 16 ++-- .../config/chainspec/TimeParametersData.java | 78 +++++++-------- .../emulator/config/ConfigBuilderTest.java | 10 +- start/config/src/test/resources/chainSpec.yml | 26 ++--- .../attester/BeaconChainAttesterImpl.java | 4 +- .../proposer/BeaconChainProposerImpl.java | 2 +- .../proposer/BeaconChainProposerTest.java | 4 +- 39 files changed, 410 insertions(+), 295 deletions(-) create mode 100644 core/src/main/java/org/ethereum/beacon/core/spec/GweiValues.java create mode 100644 start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/GweiValuesData.java diff --git a/chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java b/chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java index a7997fd05..d93fdae3e 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java @@ -46,7 +46,7 @@ public void start() { this.scheduler = schedulers.newSingleThreadDaemon("slot-ticker"); SlotNumber nextSlot = specHelpers.get_current_slot(state).increment(); - Time period = specHelpers.getChainSpec().getSlotDuration(); + Time period = specHelpers.getChainSpec().getSecondsPerSlot(); startImpl(nextSlot, period, scheduler); } diff --git a/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableStateProcessorImpl.java b/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableStateProcessorImpl.java index b54f27585..d684b81cc 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableStateProcessorImpl.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableStateProcessorImpl.java @@ -31,7 +31,6 @@ import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; import reactor.core.publisher.ReplayProcessor; -import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.collections.ReadList; public class ObservableStateProcessorImpl implements ObservableStateProcessor { @@ -122,12 +121,12 @@ private void runTaskInSeparateThread(Runnable task) { private void onNewSlot(SlotNumber newSlot) { // From spec: Verify that attestation.data.slot <= state.slot - MIN_ATTESTATION_INCLUSION_DELAY - // < attestation.data.slot + EPOCH_LENGTH - // state.slot - MIN_ATTESTATION_INCLUSION_DELAY < attestation.data.slot + EPOCH_LENGTH - // state.slot - MIN_ATTESTATION_INCLUSION_DELAY - EPOCH_LENGTH < attestation.data.slot + // < attestation.data.slot + SLOTS_PER_EPOCH + // state.slot - MIN_ATTESTATION_INCLUSION_DELAY < attestation.data.slot + SLOTS_PER_EPOCH + // state.slot - MIN_ATTESTATION_INCLUSION_DELAY - SLOTS_PER_EPOCH < attestation.data.slot SlotNumber slotMinimum = newSlot - .minus(chainSpec.getEpochLength()) + .minus(chainSpec.getSlotsPerEpoch()) .minus(chainSpec.getMinAttestationInclusionDelay()); runTaskInSeparateThread( () -> { diff --git a/chain/src/test/java/org/ethereum/beacon/chain/SlotTickerTests.java b/chain/src/test/java/org/ethereum/beacon/chain/SlotTickerTests.java index f3862baa0..522d1f4e8 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/SlotTickerTests.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/SlotTickerTests.java @@ -40,7 +40,7 @@ public SlotNumber getGenesisSlot() { } @Override - public Time getSlotDuration() { + public Time getSecondsPerSlot() { return Time.of(1); } }; diff --git a/chain/src/test/java/org/ethereum/beacon/chain/util/SampleObservableState.java b/chain/src/test/java/org/ethereum/beacon/chain/util/SampleObservableState.java index 10014f436..93b6db13b 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/util/SampleObservableState.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/util/SampleObservableState.java @@ -60,12 +60,12 @@ public SampleObservableState( ChainSpec chainSpec = new ChainSpec() { @Override - public SlotNumber.EpochLength getEpochLength() { + public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(validatorCount)); } @Override - public Time getSlotDuration() { + public Time getSecondsPerSlot() { return Time.of(slotDuration.getSeconds()); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 9b07af299..87cc83108 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -110,19 +110,19 @@ def get_epoch_committee_count(active_validator_count: int) -> int: return max( 1, min( - SHARD_COUNT // EPOCH_LENGTH, - active_validator_count // EPOCH_LENGTH // TARGET_COMMITTEE_SIZE, + SHARD_COUNT // SLOTS_PER_EPOCH, + active_validator_count // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE, ) - ) * EPOCH_LENGTH + ) * SLOTS_PER_EPOCH */ int get_epoch_committee_count(int active_validator_count) { return UInt64s.max(UInt64.valueOf(1), UInt64s.min( - spec.getShardCount().dividedBy(spec.getEpochLength()), + spec.getShardCount().dividedBy(spec.getSlotsPerEpoch()), UInt64.valueOf(active_validator_count) - .dividedBy(spec.getEpochLength()) + .dividedBy(spec.getSlotsPerEpoch()) .dividedBy(spec.getTargetCommitteeSize()) - )).times(spec.getEpochLength()).intValue(); + )).times(spec.getSlotsPerEpoch()).intValue(); } @@ -189,9 +189,9 @@ public List get_crosslink_committees_at_slot( public List get_crosslink_committees_at_slot( BeaconState state, SlotNumber slot, boolean registry_change) { - SlotNumber state_epoch_slot = state.getSlot().minus(state.getSlot().modulo(spec.getEpochLength())); - assertTrue(state_epoch_slot.lessEqual(slot.plus(spec.getEpochLength()))); - assertTrue(slot.less(state_epoch_slot.plus(spec.getEpochLength()))); + SlotNumber state_epoch_slot = state.getSlot().minus(state.getSlot().modulo(spec.getSlotsPerEpoch())); + assertTrue(state_epoch_slot.lessEqual(slot.plus(spec.getSlotsPerEpoch()))); + assertTrue(slot.less(state_epoch_slot.plus(spec.getSlotsPerEpoch()))); // epoch = slot_to_epoch(slot) // current_epoch = get_current_epoch(state) @@ -279,10 +279,10 @@ public List get_crosslink_committees_at_slot( List> shuffling = get_shuffling(seed, state.getValidatorRegistry(), shuffling_epoch); - // offset = slot % EPOCH_LENGTH - SlotNumber offset = slot.modulo(spec.getEpochLength()); - // committees_per_slot = committees_per_epoch // EPOCH_LENGTH - UInt64 committees_per_slot = UInt64.valueOf(committees_per_epoch).dividedBy(spec.getEpochLength()); + // offset = slot % SLOTS_PER_EPOCH + SlotNumber offset = slot.modulo(spec.getSlotsPerEpoch()); + // committees_per_slot = committees_per_epoch // SLOTS_PER_EPOCH + UInt64 committees_per_slot = UInt64.valueOf(committees_per_epoch).dividedBy(spec.getSlotsPerEpoch()); // slot_start_shard = (shuffling_start_shard + committees_per_slot * offset) % SHARD_COUNT ShardNumber slot_start_shard = shuffling_start_shard .plusModulo(committees_per_slot.times(offset), spec.getShardCount()); @@ -756,17 +756,17 @@ def get_entry_exit_effect_epoch(epoch: EpochNumber) -> EpochNumber: An entry or exit triggered in the ``epoch`` given by the input takes effect at the epoch given by the output. """ - return epoch + 1 + ENTRY_EXIT_DELAY + return epoch + 1 + ACTIVATION_EXIT_DELAY */ public EpochNumber get_entry_exit_effect_epoch(EpochNumber epoch) { - return epoch.plus(1).plus(spec.getEntryExitDelay()); + return epoch.plus(1).plus(spec.getActivationExitDelay()); } /* def activate_validator(state: BeaconState, index: int, genesis: bool) -> None: validator = state.validator_registry[index] - validator.activation_slot = GENESIS_SLOT if genesis else (state.slot + ENTRY_EXIT_DELAY) + validator.activation_slot = GENESIS_SLOT if genesis else (state.slot + ACTIVATION_EXIT_DELAY) state.validator_registry_delta_chain_tip = hash_tree_root( ValidatorRegistryDeltaBlock( latest_registry_delta_root=state.validator_registry_delta_chain_tip, @@ -789,7 +789,7 @@ public void activate_validator(MutableBeaconState state, ValidatorIndex index, b def penalize_validator(state: BeaconState, index: int) -> None: exit_validator(state, index) validator = state.validator_registry[index] - state.latest_slashed_balances[get_current_epoch(state) % LATEST_PENALIZED_EXIT_LENGTH] + state.latest_slashed_balances[get_current_epoch(state) % LATEST_SLASHED_EXIT_LENGTH] += get_effective_balance(state, index) whistleblower_index = get_beacon_proposer_index(state, state.slot) @@ -801,7 +801,7 @@ def penalize_validator(state: BeaconState, index: int) -> None: public void penalize_validator(MutableBeaconState state, ValidatorIndex index) { exit_validator(state, index); state.getLatestSlashedBalances().update( - get_current_epoch(state).modulo(spec.getLatestPenalizedExitLength()), + get_current_epoch(state).modulo(spec.getSlashedExitLength()), balance -> balance.plus(get_effective_balance(state, index))); ValidatorIndex whistleblower_index = get_beacon_proposer_index(state, state.getSlot()); @@ -813,7 +813,7 @@ public void penalize_validator(MutableBeaconState state, ValidatorIndex index) { oldVal -> oldVal.minus(whistleblower_reward)); state.getValidatorRegistry().update(index, v -> v.builder().withSlashed(Boolean.TRUE) - .withWithdrawableEpoch(get_current_epoch(state).plus(spec.getLatestPenalizedExitLength())) + .withWithdrawableEpoch(get_current_epoch(state).plus(spec.getSlashedExitLength())) .build()); } @@ -988,13 +988,13 @@ public void process_penalties_and_exits(MutableBeaconState state) { // if validator.slashed and current_epoch == // validator.withdrawable_epoch - LATEST_SLASHED_EXIT_LENGTH // 2: if (validator.getSlashed() && current_epoch.equals( - validator.getWithdrawableEpoch().minus(spec.getLatestPenalizedExitLength().half()))) { + validator.getWithdrawableEpoch().minus(spec.getSlashedExitLength().half()))) { - // epoch_index = current_epoch % LATEST_PENALIZED_EXIT_LENGTH - EpochNumber epoch_index = current_epoch.modulo(spec.getLatestPenalizedExitLength()); - // total_at_start = state.latest_slashed_balances[(epoch_index + 1) % LATEST_PENALIZED_EXIT_LENGTH] + // epoch_index = current_epoch % LATEST_SLASHED_EXIT_LENGTH + EpochNumber epoch_index = current_epoch.modulo(spec.getSlashedExitLength()); + // total_at_start = state.latest_slashed_balances[(epoch_index + 1) % LATEST_SLASHED_EXIT_LENGTH] Gwei total_at_start = state.getLatestSlashedBalances().get( - epoch_index.increment().modulo(spec.getLatestPenalizedExitLength())); + epoch_index.increment().modulo(spec.getSlashedExitLength())); // total_at_end = state.latest_slashed_balances[epoch_index] Gwei total_at_end = state.getLatestSlashedBalances().get(epoch_index); // total_penalties = total_at_end - total_at_start @@ -1013,7 +1013,7 @@ public void process_penalties_and_exits(MutableBeaconState state) { def eligible(index): validator = state.validator_registry[index] if validator.initiated_exit <= current_epoch: - penalized_withdrawal_epochs = LATEST_PENALIZED_EXIT_LENGTH // 2 + penalized_withdrawal_epochs = LATEST_SLASHED_EXIT_LENGTH // 2 return current_epoch >= validator.initiated_exit + penalized_withdrawal_epochs else: return current_epoch >= validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY @@ -1052,9 +1052,9 @@ def eligible(index): prepare_validator_for_withdrawal(state, index); // withdrawn_so_far += 1 withdrawn_so_far++; - // if withdrawn_so_far >= MAX_WITHDRAWALS_PER_EPOCH: + // if withdrawn_so_far >= MAX_EXIT_DEQUEUES_PER_EPOCH: // break - if (withdrawn_so_far >= spec.getMaxWithdrawalsPerEpoch().getIntValue()) { + if (withdrawn_so_far >= spec.getMaxExitDequesPerEpoch().getIntValue()) { break; } } @@ -1076,14 +1076,14 @@ def get_active_index_root(state: BeaconState, """ Return the index root at a recent ``epoch``. """ - assert get_current_epoch(state) - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ENTRY_EXIT_DELAY < epoch - <= get_current_epoch(state) + ENTRY_EXIT_DELAY + assert get_current_epoch(state) - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY < epoch + <= get_current_epoch(state) + ACTIVATION_EXIT_DELAY return state.latest_active_index_roots[epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] */ Hash32 get_active_index_root(BeaconState state, EpochNumber epoch) { - assertTrue(get_current_epoch(state).minus(spec.getLatestActiveIndexRootsLength()).plus(spec.getEntryExitDelay()) + assertTrue(get_current_epoch(state).minus(spec.getLatestActiveIndexRootsLength()).plus(spec.getActivationExitDelay()) .less(epoch)); - assertTrue(epoch.lessEqual(get_current_epoch(state).plus(spec.getEntryExitDelay()))); + assertTrue(epoch.lessEqual(get_current_epoch(state).plus(spec.getActivationExitDelay()))); return state.getLatestActiveIndexRoots().get(epoch.modulo(spec.getLatestActiveIndexRootsLength())); } @@ -1095,13 +1095,13 @@ def generate_seed(state: BeaconState, """ return hash( - get_randao_mix(state, epoch - SEED_LOOKAHEAD) + + get_randao_mix(state, epoch - MIN_SEED_LOOKAHEAD) + get_active_index_root(state, epoch) ) */ public Hash32 generate_seed(BeaconState state, EpochNumber epoch) { return hash( - get_randao_mix(state, epoch.minus(spec.getSeedLookahead())) + get_randao_mix(state, epoch.minus(spec.getMinSeedLookahead())) .concat(get_active_index_root(state, epoch))); } @@ -1173,8 +1173,8 @@ def is_double_vote(attestation_data_1: AttestationData, Returns True if the provided ``AttestationData`` are slashable due to a 'double vote'. """ - target_epoch_1 = attestation_data_1.slot // EPOCH_LENGTH - target_epoch_2 = attestation_data_2.slot // EPOCH_LENGTH + target_epoch_1 = attestation_data_1.slot // SLOTS_PER_EPOCH + target_epoch_2 = attestation_data_2.slot // SLOTS_PER_EPOCH return target_epoch_1 == target_epoch_2 */ public boolean is_double_vote( @@ -1194,10 +1194,10 @@ def is_surround_vote(attestation_data_1: AttestationData, Note: parameter order matters as this function only checks that ``attestation_data_1`` surrounds ``attestation_data_2``. """ - source_epoch_1 = attestation_data_1.justified_slot // EPOCH_LENGTH - source_epoch_2 = attestation_data_2.justified_slot // EPOCH_LENGTH - target_epoch_1 = attestation_data_1.slot // EPOCH_LENGTH - target_epoch_2 = attestation_data_2.slot // EPOCH_LENGTH + source_epoch_1 = attestation_data_1.justified_slot // SLOTS_PER_EPOCH + source_epoch_2 = attestation_data_2.justified_slot // SLOTS_PER_EPOCH + target_epoch_1 = attestation_data_1.slot // SLOTS_PER_EPOCH + target_epoch_2 = attestation_data_2.slot // SLOTS_PER_EPOCH return ( (source_epoch_1 < source_epoch_2) and (source_epoch_2 + 1 == target_epoch_2) and @@ -1444,7 +1444,7 @@ public SlotNumber get_current_slot(BeaconState state) { Millis currentTime = Millis.of(systemTimeSupplier.get()); assertTrue(state.getGenesisTime().lessEqual(currentTime.getSeconds())); Time sinceGenesis = currentTime.getSeconds().minus(state.getGenesisTime()); - return SlotNumber.castFrom(sinceGenesis.dividedBy(spec.getSlotDuration())) + return SlotNumber.castFrom(sinceGenesis.dividedBy(spec.getSecondsPerSlot())) .plus(getChainSpec().getGenesisSlot()); } @@ -1455,19 +1455,19 @@ public boolean is_current_slot(BeaconState state) { public Time get_slot_start_time(BeaconState state, SlotNumber slot) { return state .getGenesisTime() - .plus(spec.getSlotDuration().times(slot.minus(getChainSpec().getGenesisSlot()))); + .plus(spec.getSecondsPerSlot().times(slot.minus(getChainSpec().getGenesisSlot()))); } public Time get_slot_middle_time(BeaconState state, SlotNumber slot) { - return get_slot_start_time(state, slot).plus(spec.getSlotDuration().dividedBy(2)); + return get_slot_start_time(state, slot).plus(spec.getSecondsPerSlot().dividedBy(2)); } /* def slot_to_epoch(slot: SlotNumber) -> EpochNumber: - return slot // EPOCH_LENGTH + return slot // SLOTS_PER_EPOCH */ public EpochNumber slot_to_epoch(SlotNumber slot) { - return slot.dividedBy(spec.getEpochLength()); + return slot.dividedBy(spec.getSlotsPerEpoch()); } /* def get_current_epoch(state: BeaconState) -> EpochNumber: @@ -1478,10 +1478,10 @@ public EpochNumber get_current_epoch(BeaconState state) { } /* def get_epoch_start_slot(epoch: EpochNumber) -> SlotNumber: - return epoch * EPOCH_LENGTH + return epoch * SLOTS_PER_EPOCH */ public SlotNumber get_epoch_start_slot(EpochNumber epoch) { - return epoch.mul(spec.getEpochLength()); + return epoch.mul(spec.getSlotsPerEpoch()); } public EpochNumber get_genesis_epoch() { @@ -1634,7 +1634,7 @@ private Optional get_ancestor( } public boolean is_epoch_end(SlotNumber slot) { - return slot.increment().modulo(spec.getEpochLength()).equals(SlotNumber.ZERO); + return slot.increment().modulo(spec.getSlotsPerEpoch()).equals(SlotNumber.ZERO); } private static void assertTrue(boolean assertion) { diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java index 99fa899e3..6db6fbe3d 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java @@ -100,7 +100,7 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { initialState.getLatestActiveIndexRoots().addAll( nCopies(chainSpec.getLatestActiveIndexRootsLength().getIntValue(), Hash32.ZERO)); initialState.getLatestSlashedBalances().addAll( - nCopies(chainSpec.getLatestPenalizedExitLength().getIntValue(), Gwei.ZERO)); + nCopies(chainSpec.getSlashedExitLength().getIntValue(), Gwei.ZERO)); initialState.getLatestAttestations().clear(); initialState.getBatchedBlockRoots().clear(); diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java index 999e1793d..87a3d44d5 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java @@ -73,7 +73,7 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ } MutableBeaconState state = origState.createMutableCopy(); - // The steps below happen when (state.slot + 1) % EPOCH_LENGTH == 0. + // The steps below happen when (state.slot + 1) % SLOTS_PER_EPOCH == 0. /* Let current_epoch = get_current_epoch(state). @@ -374,10 +374,10 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ /* Eth1 data - If next_epoch % ETH1_DATA_VOTING_PERIOD == 0: + If next_epoch % EPOCHS_PER_ETH1_VOTING_PERIOD == 0: If eth1_data_vote.vote_count * 2 > - ETH1_DATA_VOTING_PERIOD * EPOCH_LENGTH for some eth1_data_vote in state.eth1_data_votes + EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH for some eth1_data_vote in state.eth1_data_votes (ie. more than half the votes in this voting period were for that value), set state.latest_eth1_data = eth1_data_vote.eth1_data. Set state.eth1_data_votes = []. @@ -385,7 +385,7 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ if (next_epoch.modulo(specConst.getEth1DataVotingPeriod()).equals(EpochNumber.ZERO)) { for (Eth1DataVote eth1_data_vote : state.getEth1DataVotes()) { if (SlotNumber.castFrom(eth1_data_vote.getVoteCount().times(2)) - .greater(specConst.getEth1DataVotingPeriod().mul(specConst.getEpochLength()))) { + .greater(specConst.getEth1DataVotingPeriod().mul(specConst.getSlotsPerEpoch()))) { state.setLatestEth1Data(eth1_data_vote.getEth1Data()); logger.debug(() -> "Latest Eth1Data changed to " + state.getLatestEth1Data()); break; @@ -418,7 +418,7 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ // if 3 * current_epoch_boundary_attesting_balance >= 2 * current_total_balance. // Set state.justification_bitfield |= 1 and - // state.justified_slot = state.slot - 1 * EPOCH_LENGTH + // state.justified_slot = state.slot - 1 * SLOTS_PER_EPOCH // if 3 * current_epoch_boundary_attesting_balance >= 2 * total_balance. if (current_epoch_boundary_attesting_balance.times(3).greaterEqual( current_total_balance.times(2))) { @@ -790,12 +790,12 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // For each index in previous_epoch_attester_indices, we determine the proposer // proposer_index = get_beacon_proposer_index(state, inclusion_slot(state, index)) // and set state.validator_balances[proposer_index] += - // base_reward(state, index) // INCLUDER_REWARD_QUOTIENT. + // base_reward(state, index) // ATTESTATION_INCLUSION_REWARD_QUOTIENT. Set attestation_inclusion_gainers = new HashSet<>(); for (ValidatorIndex index : previous_epoch_attester_indices) { ValidatorIndex proposer_index = spec .get_beacon_proposer_index(state, inclusion_slot.get(index)); - Gwei reward = base_reward.apply(index).dividedBy(specConst.getIncluderRewardQuotient()); + Gwei reward = base_reward.apply(index).dividedBy(specConst.getAttestationInclusionRewardQuotient()); state.getValidatorBalances().update(proposer_index, balance -> balance.plus(reward)); attestation_inclusion_gainers.add(proposer_index); @@ -950,17 +950,17 @@ def process_ejections(state: BeaconState) -> None: Final updates */ - // Set state.latest_active_index_roots[(next_epoch + ENTRY_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] = - // hash_tree_root(get_active_validator_indices(state, next_epoch + ENTRY_EXIT_DELAY)). + // Set state.latest_active_index_roots[(next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] = + // hash_tree_root(get_active_validator_indices(state, next_epoch + ACTIVATION_EXIT_DELAY)). state.getLatestActiveIndexRoots().set( - next_epoch.plus(specConst.getEntryExitDelay()).modulo(specConst.getLatestActiveIndexRootsLength()), + next_epoch.plus(specConst.getActivationExitDelay()).modulo(specConst.getLatestActiveIndexRootsLength()), spec.hash_tree_root(spec.get_active_validator_indices(state.getValidatorRegistry(), - next_epoch.plus(specConst.getEntryExitDelay())))); - // Set state.latest_slashed_balances[(next_epoch) % LATEST_PENALIZED_EXIT_LENGTH] = - // state.latest_slashed_balances[current_epoch % LATEST_PENALIZED_EXIT_LENGTH]. - state.getLatestSlashedBalances().set(next_epoch.modulo(specConst.getLatestPenalizedExitLength()), + next_epoch.plus(specConst.getActivationExitDelay())))); + // Set state.latest_slashed_balances[(next_epoch) % LATEST_SLASHED_EXIT_LENGTH] = + // state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH]. + state.getLatestSlashedBalances().set(next_epoch.modulo(specConst.getSlashedExitLength()), state.getLatestSlashedBalances().get( - current_epoch.modulo(specConst.getLatestPenalizedExitLength()))); + current_epoch.modulo(specConst.getSlashedExitLength()))); // Set state.latest_randao_mixes[next_epoch % LATEST_RANDAO_MIXES_LENGTH] = // get_randao_mix(state, current_epoch). state.getLatestRandaoMixes().set(next_epoch.modulo(specConst.getLatestRandaoMixesLength()), diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java index d192aeea5..7c3bd813e 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java @@ -47,13 +47,13 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { specHelpers.checkShardRange(data.getShard()); // Verify that attestation.data.slot <= state.slot - MIN_ATTESTATION_INCLUSION_DELAY - // < attestation.data.slot + EPOCH_LENGTH + // < attestation.data.slot + SLOTS_PER_EPOCH if (!(data.getSlot() .lessEqual(state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay())) && state .getSlot() .minus(chainSpec.getMinAttestationInclusionDelay()) - .less(data.getSlot().plus(chainSpec.getEpochLength())))) { + .less(data.getSlot().plus(chainSpec.getSlotsPerEpoch())))) { return failedResult( "MIN_ATTESTATION_INCLUSION_DELAY violated, inclusion slot starts from %s but got %s", diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java index 77cb0a035..b89b2b3e4 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java @@ -40,8 +40,8 @@ public VerificationResult verify(VoluntaryExit voluntaryExit, BeaconState state) if (!validator.getExitEpoch().greater( specHelpers.get_entry_exit_effect_epoch(specHelpers.get_current_epoch(state)))) { return failedResult( - "ENTRY_EXIT_DELAY exceeded, min exit epoch %s, got %s", - state.getSlot().plus(chainSpec.getEntryExitDelay()), validator.getExitEpoch()); + "ACTIVATION_EXIT_DELAY exceeded, min exit epoch %s, got %s", + state.getSlot().plus(chainSpec.getActivationExitDelay()), validator.getExitEpoch()); } // Verify that get_current_epoch(state) >= exit.epoch diff --git a/consensus/src/test/java/org/ethereum/beacon/consensus/SpecHelpersTest.java b/consensus/src/test/java/org/ethereum/beacon/consensus/SpecHelpersTest.java index 2e160e025..94477465c 100644 --- a/consensus/src/test/java/org/ethereum/beacon/consensus/SpecHelpersTest.java +++ b/consensus/src/test/java/org/ethereum/beacon/consensus/SpecHelpersTest.java @@ -129,7 +129,7 @@ public void committeeTest1() { ChainSpec chainSpec = new ChainSpec() { @Override - public SlotNumber.EpochLength getEpochLength() { + public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(epochLength)); } diff --git a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerEpochTransitionTest.java b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerEpochTransitionTest.java index da01b4f81..a763adf47 100644 --- a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerEpochTransitionTest.java +++ b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerEpochTransitionTest.java @@ -29,7 +29,7 @@ public void test1() { ChainSpec chainSpec = new ChainSpec() { @Override - public SlotNumber.EpochLength getEpochLength() { + public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(8)); } }; diff --git a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerSlotTransitionTest.java b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerSlotTransitionTest.java index 985563cd7..3f7b6014c 100644 --- a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerSlotTransitionTest.java +++ b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerSlotTransitionTest.java @@ -27,7 +27,7 @@ public void test1() { ChainSpec chainSpec = new ChainSpec() { @Override - public SlotNumber.EpochLength getEpochLength() { + public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(8)); } }; diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/ChainSpec.java b/core/src/main/java/org/ethereum/beacon/core/spec/ChainSpec.java index 64e544d72..b1882b8ec 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/ChainSpec.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/ChainSpec.java @@ -10,12 +10,13 @@ public interface ChainSpec TimeParameters, RewardAndPenaltyQuotients, MaxOperationsPerBlock, - HonestValidatorParameters { + HonestValidatorParameters, + GweiValues { - ChainSpec DEFAULT = new ChainSpec(){}; + ChainSpec DEFAULT = new ChainSpec() {}; @Override default EpochNumber getGenesisEpoch() { - return getGenesisSlot().dividedBy(getEpochLength()); + return getGenesisSlot().dividedBy(getSlotsPerEpoch()); } } diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/DepositContractParameters.java b/core/src/main/java/org/ethereum/beacon/core/spec/DepositContractParameters.java index 5fbb2a86e..1f52c9e90 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/DepositContractParameters.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/DepositContractParameters.java @@ -16,8 +16,6 @@ public interface DepositContractParameters { Address DEPOSIT_CONTRACT_ADDRESS = Address.fromHexString("0x0000000000000000000000000000000000000000"); // TBD UInt64 DEPOSIT_CONTRACT_TREE_DEPTH = UInt64.valueOf(1 << 5); // 32 - Gwei MIN_DEPOSIT_AMOUNT = Gwei.ofEthers(1); // 1 ETH - Gwei MAX_DEPOSIT_AMOUNT = Gwei.ofEthers(1 << 5); // 32 ETH /* Values defined in the spec. */ @@ -28,12 +26,4 @@ default Address getDepositContractAddress() { default UInt64 getDepositContractTreeDepth() { return DEPOSIT_CONTRACT_TREE_DEPTH; } - - default Gwei getMinDepositAmount() { - return MIN_DEPOSIT_AMOUNT; - } - - default Gwei getMaxDepositAmount() { - return MAX_DEPOSIT_AMOUNT; - } } diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/GweiValues.java b/core/src/main/java/org/ethereum/beacon/core/spec/GweiValues.java new file mode 100644 index 000000000..b3275efb4 --- /dev/null +++ b/core/src/main/java/org/ethereum/beacon/core/spec/GweiValues.java @@ -0,0 +1,34 @@ +package org.ethereum.beacon.core.spec; + +import org.ethereum.beacon.core.types.Gwei; + +/** + * Gwei values. + * + * @see Gwei + * values in the spec. + */ +public interface GweiValues { + + Gwei MIN_DEPOSIT_AMOUNT = Gwei.ofEthers(1); // 1 ETH + Gwei MAX_DEPOSIT_AMOUNT = Gwei.ofEthers(1 << 5); // 32 ETH + Gwei FORK_CHOICE_BALANCE_INCREMENT = Gwei.ofEthers(1); // 1 ETH + Gwei EJECTION_BALANCE = Gwei.ofEthers(1 << 4); // 16 ETH + + default Gwei getMinDepositAmount() { + return MIN_DEPOSIT_AMOUNT; + } + + default Gwei getMaxDepositAmount() { + return MAX_DEPOSIT_AMOUNT; + } + + default Gwei getForkChoiceBalanceIncrement() { + return FORK_CHOICE_BALANCE_INCREMENT; + } + + default Gwei getEjectionBalance() { + return EJECTION_BALANCE; + } +} diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/InitialValues.java b/core/src/main/java/org/ethereum/beacon/core/spec/InitialValues.java index 47d61e715..a3d13af72 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/InitialValues.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/InitialValues.java @@ -19,7 +19,7 @@ public interface InitialValues { UInt64 GENESIS_FORK_VERSION = UInt64.ZERO; - SlotNumber GENESIS_SLOT = SlotNumber.of(1 << 19); // 2**19 + SlotNumber GENESIS_SLOT = SlotNumber.of(1L << 32); // 2**32 ShardNumber GENESIS_START_SHARD = ShardNumber.of(0); EpochNumber FAR_FUTURE_EPOCH = EpochNumber.castFrom(UInt64.MAX_VALUE); // (1 << 64) - 1 Hash32 ZERO_HASH = Hash32.ZERO; diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java b/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java index 6681aabad..d96ec1194 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/MiscParameters.java @@ -16,11 +16,10 @@ public interface MiscParameters { ShardNumber SHARD_COUNT = ShardNumber.of(1 << 10); // 1024 shards ValidatorIndex TARGET_COMMITTEE_SIZE = ValidatorIndex.of(1 << 7); // 128 validators - Gwei EJECTION_BALANCE = Gwei.ofEthers(1 << 4); // 16 ETH UInt64 MAX_BALANCE_CHURN_QUOTIENT = UInt64.valueOf(1 << 5); // 32 ShardNumber BEACON_CHAIN_SHARD_NUMBER = ShardNumber.of(UInt64.MAX_VALUE); // (1 << 64) - 1 UInt64 MAX_INDICES_PER_SLASHABLE_VOTE = UInt64.valueOf(1 << 12); - UInt64 MAX_WITHDRAWALS_PER_EPOCH = UInt64.valueOf(1 << 2); // 4 + UInt64 MAX_EXIT_DEQUEUES_PER_EPOCH = UInt64.valueOf(1 << 2); // 4 int SHUFFLE_ROUND_COUNT = 90; /* Values defined in the spec. */ @@ -33,10 +32,6 @@ default ValidatorIndex getTargetCommitteeSize() { return TARGET_COMMITTEE_SIZE; } - default Gwei getEjectionBalance() { - return EJECTION_BALANCE; - } - default UInt64 getMaxBalanceChurnQuotient() { return MAX_BALANCE_CHURN_QUOTIENT; } @@ -49,8 +44,8 @@ default UInt64 getMaxIndicesPerSlashableVote() { return MAX_INDICES_PER_SLASHABLE_VOTE; } - default UInt64 getMaxWithdrawalsPerEpoch() { - return MAX_WITHDRAWALS_PER_EPOCH; + default UInt64 getMaxExitDequesPerEpoch() { + return MAX_EXIT_DEQUEUES_PER_EPOCH; } default int getShuffleRoundCount() { diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/RewardAndPenaltyQuotients.java b/core/src/main/java/org/ethereum/beacon/core/spec/RewardAndPenaltyQuotients.java index e8bd49f0c..fbb2a7e8a 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/RewardAndPenaltyQuotients.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/RewardAndPenaltyQuotients.java @@ -13,8 +13,9 @@ public interface RewardAndPenaltyQuotients { UInt64 BASE_REWARD_QUOTIENT = UInt64.valueOf(1 << 5); // 1024 UInt64 WHISTLEBLOWER_REWARD_QUOTIENT = UInt64.valueOf(1 << 9); // 512 - UInt64 INCLUDER_REWARD_QUOTIENT = UInt64.valueOf(1 << 3); // 8 + UInt64 ATTESTATION_INCLUSION_REWARD_QUOTIENT = UInt64.valueOf(1 << 3); // 8 UInt64 INACTIVITY_PENALTY_QUOTIENT = UInt64.valueOf(1 << 24); // 16_777_216 + UInt64 MIN_PENALTY_QUOTIENT = UInt64.valueOf(1 << 5); // 32 /* Values defined in the spec. */ @@ -26,11 +27,15 @@ default UInt64 getWhistleblowerRewardQuotient() { return WHISTLEBLOWER_REWARD_QUOTIENT; } - default UInt64 getIncluderRewardQuotient() { - return INCLUDER_REWARD_QUOTIENT; + default UInt64 getAttestationInclusionRewardQuotient() { + return ATTESTATION_INCLUSION_REWARD_QUOTIENT; } default UInt64 getInactivityPenaltyQuotient() { return INACTIVITY_PENALTY_QUOTIENT; } + + default UInt64 getMinPenaltyQuotient() { + return MIN_PENALTY_QUOTIENT; + } } diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/SignatureDomains.java b/core/src/main/java/org/ethereum/beacon/core/spec/SignatureDomains.java index 021718ea1..41f54fd1f 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/SignatureDomains.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/SignatureDomains.java @@ -20,4 +20,6 @@ public interface SignatureDomains { UInt64 EXIT = UInt64.valueOf(3); UInt64 RANDAO = UInt64.valueOf(4); + + UInt64 TRANSFER = UInt64.valueOf(5); } diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java b/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java index 914ae9313..e6d515b7c 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java @@ -15,7 +15,7 @@ public interface StateListLengths { SlotNumber LATEST_BLOCK_ROOTS_LENGTH = SlotNumber.of(1 << 13); // 8192 block roots EpochNumber LATEST_RANDAO_MIXES_LENGTH = EpochNumber.of(1 << 13); // 8192 randao mixes EpochNumber LATEST_ACTIVE_INDEX_ROOTS_LENGTH = EpochNumber.of(1 << 13); - EpochNumber LATEST_PENALIZED_EXIT_LENGTH = EpochNumber.of(1 << 13); // 8192 epochs + EpochNumber LATEST_SLASHED_EXIT_LENGTH = EpochNumber.of(1 << 13); // 8192 epochs default SlotNumber getLatestBlockRootsLength() { return LATEST_BLOCK_ROOTS_LENGTH; @@ -29,7 +29,7 @@ default EpochNumber getLatestActiveIndexRootsLength() { return LATEST_ACTIVE_INDEX_ROOTS_LENGTH; } - default EpochNumber getLatestPenalizedExitLength() { - return LATEST_PENALIZED_EXIT_LENGTH; + default EpochNumber getSlashedExitLength() { + return LATEST_SLASHED_EXIT_LENGTH; } } diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/TimeParameters.java b/core/src/main/java/org/ethereum/beacon/core/spec/TimeParameters.java index 610ec5975..0671bd62d 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/TimeParameters.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/TimeParameters.java @@ -15,38 +15,38 @@ */ public interface TimeParameters { - Time SLOT_DURATION = Time.of(6); // 6 seconds + Time SECONDS_PER_SLOT = Time.of(6); // 6 seconds SlotNumber MIN_ATTESTATION_INCLUSION_DELAY = SlotNumber.of(1 << 2); // 4 slots - EpochLength EPOCH_LENGTH = new EpochLength(UInt64.valueOf(1 << 6)); // 64 slots - EpochNumber SEED_LOOKAHEAD = EpochNumber.of(1); - EpochNumber ENTRY_EXIT_DELAY = EpochNumber.of(1 << 2); - EpochNumber ETH1_DATA_VOTING_PERIOD = EpochNumber.of(1 << 4); + EpochLength SLOTS_PER_EPOCH = new EpochLength(UInt64.valueOf(1 << 6)); // 64 slots + EpochNumber MIN_SEED_LOOKAHEAD = EpochNumber.of(1); + EpochNumber ACTIVATION_EXIT_DELAY = EpochNumber.of(1 << 2); + EpochNumber EPOCHS_PER_ETH1_VOTING_PERIOD = EpochNumber.of(1 << 4); EpochNumber MIN_VALIDATOR_WITHDRAWABILITY_DELAY = EpochNumber.of(1 << 8); /* Values defined in the spec. */ - default Time getSlotDuration() { - return SLOT_DURATION; + default Time getSecondsPerSlot() { + return SECONDS_PER_SLOT; } default SlotNumber getMinAttestationInclusionDelay() { return MIN_ATTESTATION_INCLUSION_DELAY; } - default EpochLength getEpochLength() { - return EPOCH_LENGTH; + default EpochLength getSlotsPerEpoch() { + return SLOTS_PER_EPOCH; } - default EpochNumber getSeedLookahead() { - return SEED_LOOKAHEAD; + default EpochNumber getMinSeedLookahead() { + return MIN_SEED_LOOKAHEAD; } - default EpochNumber getEntryExitDelay() { - return ENTRY_EXIT_DELAY; + default EpochNumber getActivationExitDelay() { + return ACTIVATION_EXIT_DELAY; } default EpochNumber getEth1DataVotingPeriod() { - return ETH1_DATA_VOTING_PERIOD; + return EPOCHS_PER_ETH1_VOTING_PERIOD; } default EpochNumber getMinValidatorWithdrawabilityDelay() { diff --git a/core/src/main/java/org/ethereum/beacon/core/types/SlotNumber.java b/core/src/main/java/org/ethereum/beacon/core/types/SlotNumber.java index 52a020106..652f74fc9 100644 --- a/core/src/main/java/org/ethereum/beacon/core/types/SlotNumber.java +++ b/core/src/main/java/org/ethereum/beacon/core/types/SlotNumber.java @@ -93,19 +93,19 @@ public String toString( String extraInfo = ""; if (spec != null) { extraInfo += "time " + (beaconStart == null ? - Duration.ofSeconds(spec.getSlotDuration().times(num).getValue()).toString() + Duration.ofSeconds(spec.getSecondsPerSlot().times(num).getValue()).toString() + " from genesis" - : spec.getSlotDuration().times((int)num).plus(beaconStart)); + : spec.getSecondsPerSlot().times((int)num).plus(beaconStart)); extraInfo += ", "; - int numInEpoch = this.modulo(spec.getEpochLength()).getIntValue(); + int numInEpoch = this.modulo(spec.getSlotsPerEpoch()).getIntValue(); if (numInEpoch == 0) { extraInfo += "first"; - } else if (numInEpoch + 1 == spec.getEpochLength().getIntValue()) { + } else if (numInEpoch + 1 == spec.getSlotsPerEpoch().getIntValue()) { extraInfo += "last"; } else { extraInfo += "#" + numInEpoch; } - extraInfo += " in epoch " + this.dividedBy(spec.getEpochLength()).minus(spec.getGenesisEpoch()); + extraInfo += " in epoch " + this.dividedBy(spec.getSlotsPerEpoch()).minus(spec.getGenesisEpoch()); } return "#" + num + (extraInfo.isEmpty() ? "" : " (" + extraInfo + ")"); } diff --git a/start/cli/src/main/resources/config/default-chainSpec.yml b/start/cli/src/main/resources/config/default-chainSpec.yml index 6bb40d834..b85589a41 100644 --- a/start/cli/src/main/resources/config/default-chainSpec.yml +++ b/start/cli/src/main/resources/config/default-chainSpec.yml @@ -1,8 +1,6 @@ depositContractParameters: DEPOSIT_CONTRACT_ADDRESS: 0x0000000000000000000000000000000000000000 DEPOSIT_CONTRACT_TREE_DEPTH: 32 - MIN_DEPOSIT_AMOUNT: 1000000000 - MAX_DEPOSIT_AMOUNT: 32000000000 honestValidatorParameters: ETH1_FOLLOW_DISTANCE: 1024 initialValues: @@ -19,29 +17,35 @@ maxOperationsPerBlock: MAX_ATTESTATIONS: 128 MAX_DEPOSITS: 16 MAX_VOLUNTARY_EXITS: 16 + MAX_TRANSFERS: 16 miscParameters: SHARD_COUNT: 1024 TARGET_COMMITTEE_SIZE: 128 - EJECTION_BALANCE: 16 MAX_BALANCE_CHURN_QUOTIENT: 32 BEACON_CHAIN_SHARD_NUMBER: 18446744073709551615 MAX_INDICES_PER_SLASHABLE_VOTE: 4096 - MAX_WITHDRAWALS_PER_EPOCH: 4 + MAX_EXIT_DEQUEUES_PER_EPOCH: 4 +gweiValues: + MIN_DEPOSIT_AMOUNT: 1000000000 + MAX_DEPOSIT_AMOUNT: 32000000000 + FORK_CHOICE_BALANCE_INCREMENT: 1000000000 + EJECTION_BALANCE: 16000000000 rewardAndPenaltyQuotients: BASE_REWARD_QUOTIENT: 1024 WHISTLEBLOWER_REWARD_QUOTIENT: 512 - INCLUDER_REWARD_QUOTIENT: 8 + ATTESTATION_INCLUSION_REWARD_QUOTIENT: 8 INACTIVITY_PENALTY_QUOTIENT: 16777216 + MIN_PENALTY_QUOTIENT: 32 stateListLengths: LATEST_BLOCK_ROOTS_LENGTH: 8192 LATEST_RANDAO_MIXES_LENGTH: 8192 LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 8192 - LATEST_PENALIZED_EXIT_LENGTH: 8192 + LATEST_SLASHED_EXIT_LENGTH: 8192 timeParameters: - SLOT_DURATION: 6 + SECONDS_PER_SLOT: 6 MIN_ATTESTATION_INCLUSION_DELAY: 4 - EPOCH_LENGTH: 64 - SEED_LOOKAHEAD: 1 - ENTRY_EXIT_DELAY: 4 - ETH1_DATA_VOTING_PERIOD: 16 + SLOTS_PER_EPOCH: 64 + MIN_SEED_LOOKAHEAD: 1 + ACTIVATION_EXIT_DELAY: 4 + EPOCHS_PER_ETH1_VOTING_PERIOD: 16 MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256 diff --git a/start/cli/src/test/resources/config/fast-chainSpec.yml b/start/cli/src/test/resources/config/fast-chainSpec.yml index 0d887d6cc..94ef0349f 100644 --- a/start/cli/src/test/resources/config/fast-chainSpec.yml +++ b/start/cli/src/test/resources/config/fast-chainSpec.yml @@ -3,6 +3,6 @@ initialValues: miscParameters: TARGET_COMMITTEE_SIZE: 1 timeParameters: - SLOT_DURATION: 10 + SECONDS_PER_SLOT: 10 MIN_ATTESTATION_INCLUSION_DELAY: 1 - EPOCH_LENGTH: 2 \ No newline at end of file + SLOTS_PER_EPOCH: 2 \ No newline at end of file diff --git a/start/common/src/test/java/org/ethereum/beacon/LocalMultiValidatorTest.java b/start/common/src/test/java/org/ethereum/beacon/LocalMultiValidatorTest.java index a00d85ef5..2f00d662e 100644 --- a/start/common/src/test/java/org/ethereum/beacon/LocalMultiValidatorTest.java +++ b/start/common/src/test/java/org/ethereum/beacon/LocalMultiValidatorTest.java @@ -80,11 +80,11 @@ public static void main(String[] args) throws Exception { ChainSpec chainSpec = new ChainSpec() { @Override - public SlotNumber.EpochLength getEpochLength() { + public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(epochLength)); } @Override - public Time getSlotDuration() { + public Time getSecondsPerSlot() { return Time.of(10); } diff --git a/start/common/src/test/java/org/ethereum/beacon/LocalNetTest.java b/start/common/src/test/java/org/ethereum/beacon/LocalNetTest.java index 11f1b8dd3..ca06825ae 100644 --- a/start/common/src/test/java/org/ethereum/beacon/LocalNetTest.java +++ b/start/common/src/test/java/org/ethereum/beacon/LocalNetTest.java @@ -133,11 +133,11 @@ public static void main(String[] args) throws Exception { ChainSpec chainSpec = new ChainSpec() { @Override - public SlotNumber.EpochLength getEpochLength() { + public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(epochLength)); } @Override - public Time getSlotDuration() { + public Time getSecondsPerSlot() { return Time.of(10); } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java index f527865ce..aff9f3be4 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java @@ -23,6 +23,7 @@ public class ChainSpecData implements Config { private InitialValuesData initialValues; private MaxOperationsPerBlockData maxOperationsPerBlock; private MiscParametersData miscParameters; + private GweiValuesData gweiValues; private RewardAndPenaltyQuotientsData rewardAndPenaltyQuotients; private StateListLengthsData stateListLengths; private TimeParametersData timeParameters; @@ -41,12 +42,22 @@ public UInt64 getDepositContractTreeDepth() { @Override public Gwei getMinDepositAmount() { - return depositContractParameters.getMinDepositAmount(); + return gweiValues.getMinDepositAmount(); } @Override public Gwei getMaxDepositAmount() { - return depositContractParameters.getMaxDepositAmount(); + return gweiValues.getMaxDepositAmount(); + } + + @Override + public Gwei getForkChoiceBalanceIncrement() { + return gweiValues.getForkChoiceBalanceIncrement(); + } + + @Override + public UInt64 getMinPenaltyQuotient() { + return rewardAndPenaltyQuotients.getMinPenaltyQuotient(); } @Override @@ -126,7 +137,7 @@ public ValidatorIndex getTargetCommitteeSize() { @Override public Gwei getEjectionBalance() { - return miscParameters.getEjectionBalance(); + return gweiValues.getEjectionBalance(); } @Override @@ -145,8 +156,8 @@ public UInt64 getMaxIndicesPerSlashableVote() { } @Override - public UInt64 getMaxWithdrawalsPerEpoch() { - return miscParameters.getMaxWithdrawalsPerEpoch(); + public UInt64 getMaxExitDequesPerEpoch() { + return miscParameters.getMaxExitDequesPerEpoch(); } @Override @@ -160,8 +171,8 @@ public UInt64 getWhistleblowerRewardQuotient() { } @Override - public UInt64 getIncluderRewardQuotient() { - return rewardAndPenaltyQuotients.getIncluderRewardQuotient(); + public UInt64 getAttestationInclusionRewardQuotient() { + return rewardAndPenaltyQuotients.getAttestationInclusionRewardQuotient(); } @Override @@ -185,13 +196,13 @@ public EpochNumber getLatestActiveIndexRootsLength() { } @Override - public EpochNumber getLatestPenalizedExitLength() { - return stateListLengths.getLatestPenalizedExitLength(); + public EpochNumber getSlashedExitLength() { + return stateListLengths.getSlashedExitLength(); } @Override - public Time getSlotDuration() { - return timeParameters.getSlotDuration(); + public Time getSecondsPerSlot() { + return timeParameters.getSecondsPerSlot(); } @Override @@ -200,18 +211,18 @@ public SlotNumber getMinAttestationInclusionDelay() { } @Override - public SlotNumber.EpochLength getEpochLength() { - return timeParameters.getEpochLength(); + public SlotNumber.EpochLength getSlotsPerEpoch() { + return timeParameters.getSlotsPerEpoch(); } @Override - public EpochNumber getSeedLookahead() { - return timeParameters.getSeedLookahead(); + public EpochNumber getMinSeedLookahead() { + return timeParameters.getMinSeedLookahead(); } @Override - public EpochNumber getEntryExitDelay() { - return timeParameters.getEntryExitDelay(); + public EpochNumber getActivationExitDelay() { + return timeParameters.getActivationExitDelay(); } @Override @@ -266,6 +277,14 @@ public void setMiscParameters(MiscParametersData miscParameters) { this.miscParameters = miscParameters; } + public GweiValuesData getGweiValues() { + return gweiValues; + } + + public void setGweiValues(GweiValuesData gweiValues) { + this.gweiValues = gweiValues; + } + public RewardAndPenaltyQuotientsData getRewardAndPenaltyQuotients() { return rewardAndPenaltyQuotients; } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/DepositContractParametersData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/DepositContractParametersData.java index 596806783..8ccb3e298 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/DepositContractParametersData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/DepositContractParametersData.java @@ -13,10 +13,6 @@ public class DepositContractParametersData implements DepositContractParameters private String DEPOSIT_CONTRACT_ADDRESS; @JsonProperty("DEPOSIT_CONTRACT_TREE_DEPTH") private String DEPOSIT_CONTRACT_TREE_DEPTH; - @JsonProperty("MIN_DEPOSIT_AMOUNT") - private String MIN_DEPOSIT_AMOUNT; - @JsonProperty("MAX_DEPOSIT_AMOUNT") - private String MAX_DEPOSIT_AMOUNT; @Override @JsonIgnore @@ -30,18 +26,6 @@ public UInt64 getDepositContractTreeDepth() { return UInt64.valueOf(getDEPOSIT_CONTRACT_TREE_DEPTH()); } - @Override - @JsonIgnore - public Gwei getMinDepositAmount() { - return Gwei.castFrom(UInt64.valueOf(getMIN_DEPOSIT_AMOUNT())); - } - - @Override - @JsonIgnore - public Gwei getMaxDepositAmount() { - return Gwei.castFrom(UInt64.valueOf(getMAX_DEPOSIT_AMOUNT())); - } - @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) public String getDEPOSIT_CONTRACT_ADDRESS() { return DEPOSIT_CONTRACT_ADDRESS; @@ -59,22 +43,4 @@ public String getDEPOSIT_CONTRACT_TREE_DEPTH() { public void setDEPOSIT_CONTRACT_TREE_DEPTH(String DEPOSIT_CONTRACT_TREE_DEPTH) { this.DEPOSIT_CONTRACT_TREE_DEPTH = DEPOSIT_CONTRACT_TREE_DEPTH; } - - @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getMIN_DEPOSIT_AMOUNT() { - return MIN_DEPOSIT_AMOUNT; - } - - public void setMIN_DEPOSIT_AMOUNT(String MIN_DEPOSIT_AMOUNT) { - this.MIN_DEPOSIT_AMOUNT = MIN_DEPOSIT_AMOUNT; - } - - @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getMAX_DEPOSIT_AMOUNT() { - return MAX_DEPOSIT_AMOUNT; - } - - public void setMAX_DEPOSIT_AMOUNT(String MAX_DEPOSIT_AMOUNT) { - this.MAX_DEPOSIT_AMOUNT = MAX_DEPOSIT_AMOUNT; - } } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/GweiValuesData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/GweiValuesData.java new file mode 100644 index 000000000..eaa6a2efe --- /dev/null +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/GweiValuesData.java @@ -0,0 +1,79 @@ +package org.ethereum.beacon.emulator.config.chainspec; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.ethereum.beacon.core.spec.GweiValues; +import org.ethereum.beacon.core.types.Gwei; +import tech.pegasys.artemis.util.uint.UInt64; + +public class GweiValuesData implements GweiValues { + + @JsonProperty("MIN_DEPOSIT_AMOUNT") + private String MIN_DEPOSIT_AMOUNT; + @JsonProperty("MAX_DEPOSIT_AMOUNT") + private String MAX_DEPOSIT_AMOUNT; + @JsonProperty("FORK_CHOICE_BALANCE_INCREMENT") + private String FORK_CHOICE_BALANCE_INCREMENT; + @JsonProperty("EJECTION_BALANCE") + private String EJECTION_BALANCE; + + @Override + @JsonIgnore + public Gwei getMinDepositAmount() { + return Gwei.castFrom(UInt64.valueOf(getMIN_DEPOSIT_AMOUNT())); + } + + @Override + @JsonIgnore + public Gwei getMaxDepositAmount() { + return Gwei.castFrom(UInt64.valueOf(getMAX_DEPOSIT_AMOUNT())); + } + + @Override + @JsonIgnore + public Gwei getForkChoiceBalanceIncrement() { + return Gwei.castFrom(UInt64.valueOf(getFORK_CHOICE_BALANCE_INCREMENT())); + } + + @Override + @JsonIgnore + public Gwei getEjectionBalance() { + return Gwei.castFrom(UInt64.valueOf(getEJECTION_BALANCE())); + } + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + public String getMIN_DEPOSIT_AMOUNT() { + return MIN_DEPOSIT_AMOUNT; + } + + public void setMIN_DEPOSIT_AMOUNT(String MIN_DEPOSIT_AMOUNT) { + this.MIN_DEPOSIT_AMOUNT = MIN_DEPOSIT_AMOUNT; + } + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + public String getMAX_DEPOSIT_AMOUNT() { + return MAX_DEPOSIT_AMOUNT; + } + + public void setMAX_DEPOSIT_AMOUNT(String MAX_DEPOSIT_AMOUNT) { + this.MAX_DEPOSIT_AMOUNT = MAX_DEPOSIT_AMOUNT; + } + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + public String getFORK_CHOICE_BALANCE_INCREMENT() { + return FORK_CHOICE_BALANCE_INCREMENT; + } + + public void setFORK_CHOICE_BALANCE_INCREMENT(String FORK_CHOICE_BALANCE_INCREMENT) { + this.FORK_CHOICE_BALANCE_INCREMENT = FORK_CHOICE_BALANCE_INCREMENT; + } + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + public String getEJECTION_BALANCE() { + return EJECTION_BALANCE; + } + + public void setEJECTION_BALANCE(String EJECTION_BALANCE) { + this.EJECTION_BALANCE = EJECTION_BALANCE; + } +} diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MaxOperationsPerBlockData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MaxOperationsPerBlockData.java index a14861c54..c3b99f92e 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MaxOperationsPerBlockData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MaxOperationsPerBlockData.java @@ -16,6 +16,8 @@ public class MaxOperationsPerBlockData implements MaxOperationsPerBlock { private Integer MAX_DEPOSITS; @JsonProperty("MAX_VOLUNTARY_EXITS") private Integer MAX_VOLUNTARY_EXITS; + @JsonProperty("MAX_TRANSFERS") + private Integer MAX_TRANSFERS; @Override @JsonIgnore @@ -47,6 +49,12 @@ public int getMaxVoluntaryExits() { return getMAX_VOLUNTARY_EXITS(); } + @Override + @JsonIgnore + public int getMaxTransfers() { + return getMAX_TRANSFERS(); + } + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) public Integer getMAX_PROPOSER_SLASHINGS() { return MAX_PROPOSER_SLASHINGS; @@ -91,4 +99,13 @@ public Integer getMAX_VOLUNTARY_EXITS() { public void setMAX_VOLUNTARY_EXITS(Integer MAX_VOLUNTARY_EXITS) { this.MAX_VOLUNTARY_EXITS = MAX_VOLUNTARY_EXITS; } + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + public Integer getMAX_TRANSFERS() { + return MAX_TRANSFERS; + } + + public void setMAX_TRANSFERS(Integer MAX_TRANSFERS) { + this.MAX_TRANSFERS = MAX_TRANSFERS; + } } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MiscParametersData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MiscParametersData.java index 87b722169..aa8f9ccea 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MiscParametersData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/MiscParametersData.java @@ -14,16 +14,14 @@ public class MiscParametersData implements MiscParameters { private String SHARD_COUNT; @JsonProperty("TARGET_COMMITTEE_SIZE") private String TARGET_COMMITTEE_SIZE; - @JsonProperty("EJECTION_BALANCE") - private String EJECTION_BALANCE; @JsonProperty("MAX_BALANCE_CHURN_QUOTIENT") private String MAX_BALANCE_CHURN_QUOTIENT; @JsonProperty("BEACON_CHAIN_SHARD_NUMBER") private String BEACON_CHAIN_SHARD_NUMBER; @JsonProperty("MAX_INDICES_PER_SLASHABLE_VOTE") private String MAX_INDICES_PER_SLASHABLE_VOTE; - @JsonProperty("MAX_WITHDRAWALS_PER_EPOCH") - private String MAX_WITHDRAWALS_PER_EPOCH; + @JsonProperty("MAX_EXIT_DEQUEUES_PER_EPOCH") + private String MAX_EXIT_DEQUEUES_PER_EPOCH; @Override @JsonIgnore @@ -37,12 +35,6 @@ public ValidatorIndex getTargetCommitteeSize() { return new ValidatorIndex(UInt64.valueOf(getTARGET_COMMITTEE_SIZE())); } - @Override - @JsonIgnore - public Gwei getEjectionBalance() { - return Gwei.castFrom(UInt64.valueOf(getEJECTION_BALANCE())); - } - @Override @JsonIgnore public UInt64 getMaxBalanceChurnQuotient() { @@ -63,8 +55,8 @@ public UInt64 getMaxIndicesPerSlashableVote() { @Override @JsonIgnore - public UInt64 getMaxWithdrawalsPerEpoch() { - return UInt64.valueOf(getMAX_WITHDRAWALS_PER_EPOCH()); + public UInt64 getMaxExitDequesPerEpoch() { + return UInt64.valueOf(getMAX_EXIT_DEQUEUES_PER_EPOCH()); } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @@ -85,15 +77,6 @@ public void setTARGET_COMMITTEE_SIZE(String TARGET_COMMITTEE_SIZE) { this.TARGET_COMMITTEE_SIZE = TARGET_COMMITTEE_SIZE; } - @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getEJECTION_BALANCE() { - return EJECTION_BALANCE; - } - - public void setEJECTION_BALANCE(String EJECTION_BALANCE) { - this.EJECTION_BALANCE = EJECTION_BALANCE; - } - @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) public String getMAX_BALANCE_CHURN_QUOTIENT() { return MAX_BALANCE_CHURN_QUOTIENT; @@ -122,11 +105,11 @@ public void setMAX_INDICES_PER_SLASHABLE_VOTE(String MAX_INDICES_PER_SLASHABLE_V } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getMAX_WITHDRAWALS_PER_EPOCH() { - return MAX_WITHDRAWALS_PER_EPOCH; + public String getMAX_EXIT_DEQUEUES_PER_EPOCH() { + return MAX_EXIT_DEQUEUES_PER_EPOCH; } - public void setMAX_WITHDRAWALS_PER_EPOCH(String MAX_WITHDRAWALS_PER_EPOCH) { - this.MAX_WITHDRAWALS_PER_EPOCH = MAX_WITHDRAWALS_PER_EPOCH; + public void setMAX_EXIT_DEQUEUES_PER_EPOCH(String MAX_EXIT_DEQUEUES_PER_EPOCH) { + this.MAX_EXIT_DEQUEUES_PER_EPOCH = MAX_EXIT_DEQUEUES_PER_EPOCH; } } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/RewardAndPenaltyQuotientsData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/RewardAndPenaltyQuotientsData.java index 453b6bfa3..dec845440 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/RewardAndPenaltyQuotientsData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/RewardAndPenaltyQuotientsData.java @@ -11,10 +11,12 @@ public class RewardAndPenaltyQuotientsData implements RewardAndPenaltyQuotients private String BASE_REWARD_QUOTIENT; @JsonProperty("WHISTLEBLOWER_REWARD_QUOTIENT") private String WHISTLEBLOWER_REWARD_QUOTIENT; - @JsonProperty("INCLUDER_REWARD_QUOTIENT") - private String INCLUDER_REWARD_QUOTIENT; + @JsonProperty("ATTESTATION_INCLUSION_REWARD_QUOTIENT") + private String ATTESTATION_INCLUSION_REWARD_QUOTIENT; @JsonProperty("INACTIVITY_PENALTY_QUOTIENT") private String INACTIVITY_PENALTY_QUOTIENT; + @JsonProperty("MIN_PENALTY_QUOTIENT") + private String MIN_PENALTY_QUOTIENT; @Override @JsonIgnore @@ -30,8 +32,8 @@ public UInt64 getWhistleblowerRewardQuotient() { @Override @JsonIgnore - public UInt64 getIncluderRewardQuotient() { - return UInt64.valueOf(getINCLUDER_REWARD_QUOTIENT()); + public UInt64 getAttestationInclusionRewardQuotient() { + return UInt64.valueOf(getATTESTATION_INCLUSION_REWARD_QUOTIENT()); } @Override @@ -40,6 +42,12 @@ public UInt64 getInactivityPenaltyQuotient() { return UInt64.valueOf(getINACTIVITY_PENALTY_QUOTIENT()); } + @Override + @JsonIgnore + public UInt64 getMinPenaltyQuotient() { + return UInt64.valueOf(getMIN_PENALTY_QUOTIENT()); + } + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) public String getBASE_REWARD_QUOTIENT() { return BASE_REWARD_QUOTIENT; @@ -59,12 +67,12 @@ public void setWHISTLEBLOWER_REWARD_QUOTIENT(String WHISTLEBLOWER_REWARD_QUOTIEN } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getINCLUDER_REWARD_QUOTIENT() { - return INCLUDER_REWARD_QUOTIENT; + public String getATTESTATION_INCLUSION_REWARD_QUOTIENT() { + return ATTESTATION_INCLUSION_REWARD_QUOTIENT; } - public void setINCLUDER_REWARD_QUOTIENT(String INCLUDER_REWARD_QUOTIENT) { - this.INCLUDER_REWARD_QUOTIENT = INCLUDER_REWARD_QUOTIENT; + public void setATTESTATION_INCLUSION_REWARD_QUOTIENT(String ATTESTATION_INCLUSION_REWARD_QUOTIENT) { + this.ATTESTATION_INCLUSION_REWARD_QUOTIENT = ATTESTATION_INCLUSION_REWARD_QUOTIENT; } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @@ -75,4 +83,13 @@ public String getINACTIVITY_PENALTY_QUOTIENT() { public void setINACTIVITY_PENALTY_QUOTIENT(String INACTIVITY_PENALTY_QUOTIENT) { this.INACTIVITY_PENALTY_QUOTIENT = INACTIVITY_PENALTY_QUOTIENT; } + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + public String getMIN_PENALTY_QUOTIENT() { + return MIN_PENALTY_QUOTIENT; + } + + public void setMIN_PENALTY_QUOTIENT(String MIN_PENALTY_QUOTIENT) { + this.MIN_PENALTY_QUOTIENT = MIN_PENALTY_QUOTIENT; + } } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java index 136127b90..abe818849 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java @@ -15,8 +15,8 @@ public class StateListLengthsData implements StateListLengths { private String LATEST_RANDAO_MIXES_LENGTH; @JsonProperty("LATEST_ACTIVE_INDEX_ROOTS_LENGTH") private String LATEST_ACTIVE_INDEX_ROOTS_LENGTH; - @JsonProperty("LATEST_PENALIZED_EXIT_LENGTH") - private String LATEST_PENALIZED_EXIT_LENGTH; + @JsonProperty("LATEST_SLASHED_EXIT_LENGTH") + private String LATEST_SLASHED_EXIT_LENGTH; @Override @JsonIgnore @@ -38,8 +38,8 @@ public EpochNumber getLatestActiveIndexRootsLength() { @Override @JsonIgnore - public EpochNumber getLatestPenalizedExitLength() { - return new EpochNumber(UInt64.valueOf(getLATEST_PENALIZED_EXIT_LENGTH())); + public EpochNumber getSlashedExitLength() { + return new EpochNumber(UInt64.valueOf(getLATEST_SLASHED_EXIT_LENGTH())); } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @@ -70,11 +70,11 @@ public void setLATEST_ACTIVE_INDEX_ROOTS_LENGTH(String LATEST_ACTIVE_INDEX_ROOTS } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getLATEST_PENALIZED_EXIT_LENGTH() { - return LATEST_PENALIZED_EXIT_LENGTH; + public String getLATEST_SLASHED_EXIT_LENGTH() { + return LATEST_SLASHED_EXIT_LENGTH; } - public void setLATEST_PENALIZED_EXIT_LENGTH(String LATEST_PENALIZED_EXIT_LENGTH) { - this.LATEST_PENALIZED_EXIT_LENGTH = LATEST_PENALIZED_EXIT_LENGTH; + public void setLATEST_SLASHED_EXIT_LENGTH(String LATEST_SLASHED_EXIT_LENGTH) { + this.LATEST_SLASHED_EXIT_LENGTH = LATEST_SLASHED_EXIT_LENGTH; } } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/TimeParametersData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/TimeParametersData.java index ede82aa84..bc987e524 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/TimeParametersData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/TimeParametersData.java @@ -11,25 +11,25 @@ public class TimeParametersData implements TimeParameters { - @JsonProperty("SLOT_DURATION") - private String SLOT_DURATION; + @JsonProperty("SECONDS_PER_SLOT") + private String SECONDS_PER_SLOT; @JsonProperty("MIN_ATTESTATION_INCLUSION_DELAY") private String MIN_ATTESTATION_INCLUSION_DELAY; - @JsonProperty("EPOCH_LENGTH") - private String EPOCH_LENGTH; - @JsonProperty("SEED_LOOKAHEAD") - private String SEED_LOOKAHEAD; - @JsonProperty("ENTRY_EXIT_DELAY") - private String ENTRY_EXIT_DELAY; - @JsonProperty("ETH1_DATA_VOTING_PERIOD") - private String ETH1_DATA_VOTING_PERIOD; + @JsonProperty("SLOTS_PER_EPOCH") + private String SLOTS_PER_EPOCH; + @JsonProperty("MIN_SEED_LOOKAHEAD") + private String MIN_SEED_LOOKAHEAD; + @JsonProperty("ACTIVATION_EXIT_DELAY") + private String ACTIVATION_EXIT_DELAY; + @JsonProperty("EPOCHS_PER_ETH1_VOTING_PERIOD") + private String EPOCHS_PER_ETH1_VOTING_PERIOD; @JsonProperty("MIN_VALIDATOR_WITHDRAWABILITY_DELAY") private String MIN_VALIDATOR_WITHDRAWABILITY_DELAY; @Override @JsonIgnore - public Time getSlotDuration() { - return Time.castFrom(UInt64.valueOf(getSLOT_DURATION())); + public Time getSecondsPerSlot() { + return Time.castFrom(UInt64.valueOf(getSECONDS_PER_SLOT())); } @Override @@ -40,26 +40,26 @@ public SlotNumber getMinAttestationInclusionDelay() { @Override @JsonIgnore - public EpochLength getEpochLength() { - return new EpochLength(UInt64.valueOf(getEPOCH_LENGTH())); + public EpochLength getSlotsPerEpoch() { + return new EpochLength(UInt64.valueOf(getSLOTS_PER_EPOCH())); } @Override @JsonIgnore - public EpochNumber getSeedLookahead() { - return new EpochNumber(UInt64.valueOf(getSEED_LOOKAHEAD())); + public EpochNumber getMinSeedLookahead() { + return new EpochNumber(UInt64.valueOf(getMIN_SEED_LOOKAHEAD())); } @Override @JsonIgnore - public EpochNumber getEntryExitDelay() { - return new EpochNumber(UInt64.valueOf(getENTRY_EXIT_DELAY())); + public EpochNumber getActivationExitDelay() { + return new EpochNumber(UInt64.valueOf(getACTIVATION_EXIT_DELAY())); } @Override @JsonIgnore public EpochNumber getEth1DataVotingPeriod() { - return new EpochNumber(UInt64.valueOf(getETH1_DATA_VOTING_PERIOD())); + return new EpochNumber(UInt64.valueOf(getEPOCHS_PER_ETH1_VOTING_PERIOD())); } @Override @@ -69,12 +69,12 @@ public EpochNumber getMinValidatorWithdrawabilityDelay() { } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getSLOT_DURATION() { - return SLOT_DURATION; + public String getSECONDS_PER_SLOT() { + return SECONDS_PER_SLOT; } - public void setSLOT_DURATION(String SLOT_DURATION) { - this.SLOT_DURATION = SLOT_DURATION; + public void setSECONDS_PER_SLOT(String SECONDS_PER_SLOT) { + this.SECONDS_PER_SLOT = SECONDS_PER_SLOT; } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @@ -87,39 +87,39 @@ public void setMIN_ATTESTATION_INCLUSION_DELAY(String MIN_ATTESTATION_INCLUSION_ } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getEPOCH_LENGTH() { - return EPOCH_LENGTH; + public String getSLOTS_PER_EPOCH() { + return SLOTS_PER_EPOCH; } - public void setEPOCH_LENGTH(String EPOCH_LENGTH) { - this.EPOCH_LENGTH = EPOCH_LENGTH; + public void setSLOTS_PER_EPOCH(String SLOTS_PER_EPOCH) { + this.SLOTS_PER_EPOCH = SLOTS_PER_EPOCH; } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getSEED_LOOKAHEAD() { - return SEED_LOOKAHEAD; + public String getMIN_SEED_LOOKAHEAD() { + return MIN_SEED_LOOKAHEAD; } - public void setSEED_LOOKAHEAD(String SEED_LOOKAHEAD) { - this.SEED_LOOKAHEAD = SEED_LOOKAHEAD; + public void setMIN_SEED_LOOKAHEAD(String MIN_SEED_LOOKAHEAD) { + this.MIN_SEED_LOOKAHEAD = MIN_SEED_LOOKAHEAD; } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getENTRY_EXIT_DELAY() { - return ENTRY_EXIT_DELAY; + public String getACTIVATION_EXIT_DELAY() { + return ACTIVATION_EXIT_DELAY; } - public void setENTRY_EXIT_DELAY(String ENTRY_EXIT_DELAY) { - this.ENTRY_EXIT_DELAY = ENTRY_EXIT_DELAY; + public void setACTIVATION_EXIT_DELAY(String ACTIVATION_EXIT_DELAY) { + this.ACTIVATION_EXIT_DELAY = ACTIVATION_EXIT_DELAY; } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) - public String getETH1_DATA_VOTING_PERIOD() { - return ETH1_DATA_VOTING_PERIOD; + public String getEPOCHS_PER_ETH1_VOTING_PERIOD() { + return EPOCHS_PER_ETH1_VOTING_PERIOD; } - public void setETH1_DATA_VOTING_PERIOD(String ETH1_DATA_VOTING_PERIOD) { - this.ETH1_DATA_VOTING_PERIOD = ETH1_DATA_VOTING_PERIOD; + public void setEPOCHS_PER_ETH1_VOTING_PERIOD(String EPOCHS_PER_ETH1_VOTING_PERIOD) { + this.EPOCHS_PER_ETH1_VOTING_PERIOD = EPOCHS_PER_ETH1_VOTING_PERIOD; } @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) diff --git a/start/config/src/test/java/org/ethereum/beacon/emulator/config/ConfigBuilderTest.java b/start/config/src/test/java/org/ethereum/beacon/emulator/config/ConfigBuilderTest.java index fb0b6098d..28ff3c885 100644 --- a/start/config/src/test/java/org/ethereum/beacon/emulator/config/ConfigBuilderTest.java +++ b/start/config/src/test/java/org/ethereum/beacon/emulator/config/ConfigBuilderTest.java @@ -57,13 +57,13 @@ public void testChainSpec() { ChainSpec chainSpecDefault = ChainSpec.DEFAULT; assertEquals(chainSpecDefault.getGenesisEpoch(), chainSpec.getGenesisEpoch()); assertEquals(chainSpecDefault.getEmptySignature(), chainSpec.getEmptySignature()); - assertEquals(chainSpecDefault.getEpochLength(), chainSpec.getEpochLength()); - assertEquals(chainSpecDefault.getSlotDuration(), chainSpec.getSlotDuration()); + assertEquals(chainSpecDefault.getSlotsPerEpoch(), chainSpec.getSlotsPerEpoch()); + assertEquals(chainSpecDefault.getSecondsPerSlot(), chainSpec.getSecondsPerSlot()); - configBuilder.addConfigOverride("timeParameters.SLOT_DURATION", "10"); + configBuilder.addConfigOverride("timeParameters.SECONDS_PER_SLOT", "10"); ChainSpecData overriden = (ChainSpecData) configBuilder.build(); ChainSpec chainSpec2 = overriden.build(); - assertNotEquals(chainSpecDefault.getSlotDuration(), chainSpec2.getSlotDuration()); - assertEquals(UInt64.valueOf(10), chainSpec2.getSlotDuration()); + assertNotEquals(chainSpecDefault.getSecondsPerSlot(), chainSpec2.getSecondsPerSlot()); + assertEquals(UInt64.valueOf(10), chainSpec2.getSecondsPerSlot()); } } diff --git a/start/config/src/test/resources/chainSpec.yml b/start/config/src/test/resources/chainSpec.yml index 6f8aa2845..b85589a41 100644 --- a/start/config/src/test/resources/chainSpec.yml +++ b/start/config/src/test/resources/chainSpec.yml @@ -1,8 +1,6 @@ depositContractParameters: DEPOSIT_CONTRACT_ADDRESS: 0x0000000000000000000000000000000000000000 DEPOSIT_CONTRACT_TREE_DEPTH: 32 - MIN_DEPOSIT_AMOUNT: 1 - MAX_DEPOSIT_AMOUNT: 32 honestValidatorParameters: ETH1_FOLLOW_DISTANCE: 1024 initialValues: @@ -19,29 +17,35 @@ maxOperationsPerBlock: MAX_ATTESTATIONS: 128 MAX_DEPOSITS: 16 MAX_VOLUNTARY_EXITS: 16 + MAX_TRANSFERS: 16 miscParameters: SHARD_COUNT: 1024 TARGET_COMMITTEE_SIZE: 128 - EJECTION_BALANCE: 16 MAX_BALANCE_CHURN_QUOTIENT: 32 BEACON_CHAIN_SHARD_NUMBER: 18446744073709551615 MAX_INDICES_PER_SLASHABLE_VOTE: 4096 - MAX_WITHDRAWALS_PER_EPOCH: 4 + MAX_EXIT_DEQUEUES_PER_EPOCH: 4 +gweiValues: + MIN_DEPOSIT_AMOUNT: 1000000000 + MAX_DEPOSIT_AMOUNT: 32000000000 + FORK_CHOICE_BALANCE_INCREMENT: 1000000000 + EJECTION_BALANCE: 16000000000 rewardAndPenaltyQuotients: BASE_REWARD_QUOTIENT: 1024 WHISTLEBLOWER_REWARD_QUOTIENT: 512 - INCLUDER_REWARD_QUOTIENT: 8 + ATTESTATION_INCLUSION_REWARD_QUOTIENT: 8 INACTIVITY_PENALTY_QUOTIENT: 16777216 + MIN_PENALTY_QUOTIENT: 32 stateListLengths: LATEST_BLOCK_ROOTS_LENGTH: 8192 LATEST_RANDAO_MIXES_LENGTH: 8192 LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 8192 - LATEST_PENALIZED_EXIT_LENGTH: 8192 + LATEST_SLASHED_EXIT_LENGTH: 8192 timeParameters: - SLOT_DURATION: 6 + SECONDS_PER_SLOT: 6 MIN_ATTESTATION_INCLUSION_DELAY: 4 - EPOCH_LENGTH: 64 - SEED_LOOKAHEAD: 1 - ENTRY_EXIT_DELAY: 4 - ETH1_DATA_VOTING_PERIOD: 16 + SLOTS_PER_EPOCH: 64 + MIN_SEED_LOOKAHEAD: 1 + ACTIVATION_EXIT_DELAY: 4 + EPOCHS_PER_ETH1_VOTING_PERIOD: 16 MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256 diff --git a/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java b/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java index ed92acdff..f7122097a 100644 --- a/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java +++ b/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java @@ -104,13 +104,13 @@ List getCommittee(BeaconState state, ShardNumber shard) { /* Note: This can be looked up in the state using - get_block_root(state, head.slot - head.slot % EPOCH_LENGTH). + get_block_root(state, head.slot - head.slot % SLOTS_PER_EPOCH). */ @VisibleForTesting Hash32 getEpochBoundaryRoot(BeaconState state, BeaconBlock head) { SlotNumber ancestorMaxSlot = head.getSlot().decrement(); SlotNumber epochBoundarySlot = - ancestorMaxSlot.minus(ancestorMaxSlot.modulo(chainSpec.getEpochLength())); + ancestorMaxSlot.minus(ancestorMaxSlot.modulo(chainSpec.getSlotsPerEpoch())); return specHelpers.get_block_root(state, epochBoundarySlot); } diff --git a/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java b/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java index a353a0c54..2e51800f6 100644 --- a/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java +++ b/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java @@ -209,7 +209,7 @@ private BeaconBlockBody getBlockBody(BeaconState state, PendingOperations operat List attestations = operations.peekAggregatedAttestations( chainSpec.getMaxAttestations(), - state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay()).minus(chainSpec.getEpochLength()), + state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay()).minus(chainSpec.getSlotsPerEpoch()), state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay())); List voluntaryExits = operations.peekExits(chainSpec.getMaxVoluntaryExits()); List transfers = operations.peekTransfers(chainSpec.getMaxTransfers()); diff --git a/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java b/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java index 915594a5d..d7200aeaf 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java @@ -119,7 +119,7 @@ public void proposeABlockWithOperations() { initialState .getSlot() .minus(specHelpers.getChainSpec().getMinAttestationInclusionDelay()) - .minus(specHelpers.getChainSpec().getEpochLength()), + .minus(specHelpers.getChainSpec().getSlotsPerEpoch()), initialState .getSlot() .minus(specHelpers.getChainSpec().getMinAttestationInclusionDelay())); @@ -223,7 +223,7 @@ public void proposeABlockWithEpochTransition() { // set slot to the end of the epoch MutableBeaconState modifiedState = initialObservedState.getLatestSlotState().createMutableCopy(); - modifiedState.setSlot(specHelpers.getChainSpec().getEpochLength().decrement()); + modifiedState.setSlot(specHelpers.getChainSpec().getSlotsPerEpoch().decrement()); ObservableBeaconState endOfTheEpoch = new ObservableBeaconState( From f17c56d4ea458611f23803e342fdf2eb01c8af68 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 1 Mar 2019 16:09:53 +0600 Subject: [PATCH 07/21] Add beacon_state.deposit_index --- .../consensus/transition/DelegateBeaconState.java | 6 ++++++ .../consensus/transition/InitialStateTransition.java | 2 ++ .../verifier/block/DepositListVerifier.java | 9 ++++++++- .../verifier/block/OperationListVerifier.java | 9 +++++---- .../java/org/ethereum/beacon/core/BeaconState.java | 5 ++++- .../org/ethereum/beacon/core/MutableBeaconState.java | 3 +++ .../ethereum/beacon/core/state/BeaconStateImpl.java | 12 ++++++++++++ 7 files changed, 40 insertions(+), 6 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java index 770298675..dcee5c491 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java @@ -19,6 +19,7 @@ import org.ethereum.beacon.core.types.ValidatorIndex; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.collections.ReadList; +import tech.pegasys.artemis.util.uint.UInt64; public class DelegateBeaconState implements BeaconState { private final BeaconState delegate; @@ -160,6 +161,11 @@ public ReadList getEth1DataVotes() { return delegate.getEth1DataVotes(); } + @Override + public UInt64 getDepositIndex() { + return delegate.getDepositIndex(); + } + @Override public MutableBeaconState createMutableCopy() { return delegate.createMutableCopy(); diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java index 6db6fbe3d..b34dab763 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java @@ -24,6 +24,7 @@ import org.ethereum.beacon.core.types.ValidatorIndex; import org.ethereum.beacon.pow.DepositContract; import tech.pegasys.artemis.ethereum.core.Hash32; +import tech.pegasys.artemis.util.uint.UInt64; /** * Produces initial beacon state. @@ -110,6 +111,7 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { // handle initial deposits and activations final List initialDeposits = depositContractStart.getInitialDeposits(); + initialState.setDepositIndex(UInt64.valueOf(initialDeposits.size())); initialDeposits.forEach( deposit -> { diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/DepositListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/DepositListVerifier.java index 58ba8e709..32cb514a5 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/DepositListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/DepositListVerifier.java @@ -20,9 +20,16 @@ public DepositListVerifier(OperationVerifier operationVerifier, ChainSp super(operationVerifier, block -> block.getBody().getDeposits(), chainSpec.getMaxDeposits()); addCustomVerifier( - deposits -> { + (deposits, state) -> { if (ReadList.sizeOf(deposits) > 0) { UInt64 expectedIndex = deposits.iterator().next().getIndex(); + + if (!expectedIndex.equals(state.getDepositIndex())) { + return failedResult( + "index of the first deposit is incorrect, expected %d but got %d", + state.getDepositIndex(), expectedIndex); + } + for (Deposit deposit : deposits) { if (!deposit.getIndex().equals(expectedIndex)) { return failedResult( diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/OperationListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/OperationListVerifier.java index 211a21f33..eebbbf90b 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/OperationListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/OperationListVerifier.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.BiFunction; import java.util.function.Function; import org.ethereum.beacon.consensus.verifier.BeaconBlockVerifier; import org.ethereum.beacon.consensus.verifier.OperationVerifier; @@ -38,7 +39,7 @@ public abstract class OperationListVerifier implements BeaconBlockVerifier { private OperationVerifier operationVerifier; private Function> operationListExtractor; private int maxOperationsInList; - private List, VerificationResult>> customVerifiers; + private List, BeaconState, VerificationResult>> customVerifiers; protected OperationListVerifier( OperationVerifier operationVerifier, @@ -60,8 +61,8 @@ public VerificationResult verify(BeaconBlock block, BeaconState state) { getType().getSimpleName(), maxOperationsInList, ReadList.sizeOf(operations)); } - for (Function, VerificationResult> verifier : customVerifiers) { - VerificationResult result = verifier.apply(operations); + for (BiFunction, BeaconState, VerificationResult> verifier : customVerifiers) { + VerificationResult result = verifier.apply(operations, state); if (result != PASSED) { return failedResult( "%s list verification failed: %s", getType().getSimpleName(), result.getMessage()); @@ -81,7 +82,7 @@ public VerificationResult verify(BeaconBlock block, BeaconState state) { } protected OperationListVerifier addCustomVerifier( - Function, VerificationResult> verifier) { + BiFunction, BeaconState, VerificationResult> verifier) { this.customVerifiers.add(verifier); return this; } diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconState.java b/core/src/main/java/org/ethereum/beacon/core/BeaconState.java index 5542b2b2a..15c043a79 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconState.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconState.java @@ -2,9 +2,9 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.state.BeaconStateImpl; -import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.ForkData; @@ -119,6 +119,9 @@ static BeaconState getEmpty() { /** Eth1 data that voting is still in progress for. */ ReadList getEth1DataVotes(); + /** The most recent Eth1 deposit index */ + UInt64 getDepositIndex(); + /** * Returns mutable copy of this state. Any changes made to returned copy shouldn't affect this * instance diff --git a/core/src/main/java/org/ethereum/beacon/core/MutableBeaconState.java b/core/src/main/java/org/ethereum/beacon/core/MutableBeaconState.java index d56677868..585e8ff18 100644 --- a/core/src/main/java/org/ethereum/beacon/core/MutableBeaconState.java +++ b/core/src/main/java/org/ethereum/beacon/core/MutableBeaconState.java @@ -15,6 +15,7 @@ import org.ethereum.beacon.core.types.ValidatorIndex; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.collections.WriteList; +import tech.pegasys.artemis.util.uint.UInt64; public interface MutableBeaconState extends BeaconState { @@ -78,5 +79,7 @@ public interface MutableBeaconState extends BeaconState { @Override WriteList getEth1DataVotes(); + void setDepositIndex(UInt64 depositIndex); + BeaconState createImmutable(); } diff --git a/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java b/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java index 96d30af3a..2ff4abed4 100644 --- a/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java +++ b/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java @@ -17,6 +17,7 @@ import org.ethereum.beacon.ssz.annotation.SSZSerializable; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.collections.WriteList; +import tech.pegasys.artemis.util.uint.UInt64; @SSZSerializable public class BeaconStateImpl implements MutableBeaconState { @@ -63,6 +64,7 @@ public class BeaconStateImpl implements MutableBeaconState { @SSZ private Eth1Data latestEth1Data = Eth1Data.EMPTY; @SSZ private List eth1DataVotesList = new ArrayList<>(); + @SSZ private UInt64 depositIndex; public BeaconStateImpl() {} @@ -398,6 +400,16 @@ public WriteList getEth1DataVotes() { return WriteList.wrap(getEth1DataVotesList(), Integer::valueOf); } + @Override + public UInt64 getDepositIndex() { + return depositIndex; + } + + @Override + public void setDepositIndex(UInt64 depositIndex) { + this.depositIndex = depositIndex; + } + /********* List Getters/Setter for serialization **********/ @Override From cd08a133a63ca5c4999e12c02221cdaa6b01da79 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 1 Mar 2019 17:31:32 +0600 Subject: [PATCH 08/21] Update SpecHelpers up to generate_seed method with spec:0.4.0 --- .../beacon/consensus/SpecHelpers.java | 178 ++++++++++-------- .../pegasys/artemis/util/bytes/Bytes8.java | 20 ++ .../artemis/util/bytes/BytesValues.java | 19 ++ .../pegasys/artemis/util/uint/UInt64.java | 10 + 4 files changed, 148 insertions(+), 79 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 87cc83108..8fa2e5096 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -165,6 +165,9 @@ public int get_current_epoch_committee_count(BeaconState state) { /* def get_next_epoch_committee_count(state: BeaconState) -> int: + """ + Return the number of committees in the next epoch of the given ``state``. + """ next_active_validators = get_active_validator_indices( state.validator_registry, get_current_epoch(state) + 1, @@ -184,118 +187,118 @@ public List get_crosslink_committees_at_slot( } /* - Returns the list of ``(committee, shard)`` tuples for the ``slot``. + Return the list of ``(committee, shard)`` tuples for the ``slot``. + Note: There are two possible shufflings for crosslink committees for a + ``slot`` in the next epoch -- with and without a `registry_change` */ public List get_crosslink_committees_at_slot( BeaconState state, SlotNumber slot, boolean registry_change) { - SlotNumber state_epoch_slot = state.getSlot().minus(state.getSlot().modulo(spec.getSlotsPerEpoch())); - assertTrue(state_epoch_slot.lessEqual(slot.plus(spec.getSlotsPerEpoch()))); - assertTrue(slot.less(state_epoch_slot.plus(spec.getSlotsPerEpoch()))); - - // epoch = slot_to_epoch(slot) - // current_epoch = get_current_epoch(state) - // previous_epoch = current_epoch - 1 if current_epoch > GENESIS_EPOCH else current_epoch - // next_epoch = current_epoch + 1 EpochNumber epoch = slot_to_epoch(slot); - EpochNumber current_epoch = get_current_epoch(state); - EpochNumber previous_epoch = - current_epoch.greater(spec.getGenesisEpoch()) ? current_epoch.decrement() : current_epoch; - EpochNumber next_epoch = current_epoch.increment(); - // assert previous_epoch <= epoch <= next_epoch - assertTrue(previous_epoch.lessEqual(epoch)); - assertTrue(epoch.lessEqual(next_epoch)); - /* - if epoch == previous_epoch: - committees_per_epoch = get_previous_epoch_committee_count(state) - seed = state.previous_shuffling_seed - shuffling_epoch = state.previous_shuffling_epoch - shuffling_start_shard = state.previous_shuffling_start_shard - */ - int committees_per_epoch; + EpochNumber currentEpoch = get_current_epoch(state); + EpochNumber previousEpoch = get_previous_epoch(state); + EpochNumber nextEpoch = currentEpoch.increment(); + + assertTrue(previousEpoch.lessEqual(epoch) && epoch.lessEqual(nextEpoch)); + Hash32 seed; + int committees_per_epoch; EpochNumber shuffling_epoch; ShardNumber shuffling_start_shard; - if (epoch.equals(previous_epoch)) { - committees_per_epoch = get_previous_epoch_committee_count(state); - seed = state.getPreviousShufflingSeed(); - shuffling_epoch = state.getPreviousShufflingEpoch(); - shuffling_start_shard = state.getPreviousShufflingStartShard(); - } else if (epoch.equals(current_epoch)) { + if (epoch.equals(currentEpoch)) { /* - elif epoch == current_epoch: - committees_per_epoch = get_current_epoch_committee_count(state) - seed = state.current_shuffling_seed - shuffling_epoch = state.current_shuffling_epoch + if epoch == current_epoch: + committees_per_epoch = get_current_epoch_committee_count(state) + seed = state.current_shuffling_seed + shuffling_epoch = state.current_shuffling_epoch + shuffling_start_shard = state.current_shuffling_start_shard */ - */ committees_per_epoch = get_current_epoch_committee_count(state); seed = state.getCurrentShufflingSeed(); shuffling_epoch = state.getCurrentShufflingEpoch(); shuffling_start_shard = state.getCurrentShufflingStartShard(); + } else if (epoch.equals(previousEpoch)) { + /* + elif epoch == previous_epoch: + committees_per_epoch = get_previous_epoch_committee_count(state) + seed = state.previous_shuffling_seed + shuffling_epoch = state.previous_shuffling_epoch + shuffling_start_shard = state.previous_shuffling_start_shard */ + committees_per_epoch = get_previous_epoch_committee_count(state); + seed = state.getPreviousShufflingSeed(); + shuffling_epoch = state.getPreviousShufflingEpoch(); + shuffling_start_shard = state.getPreviousShufflingStartShard(); } else { - assertTrue(epoch.equals(next_epoch)); /* - elif epoch == next_epoch: - current_committees_per_epoch = get_current_epoch_committee_count(state) - committees_per_epoch = get_next_epoch_committee_count(state) - shuffling_epoch = next_epoch - epochs_since_last_registry_update = current_epoch - state.validator_registry_update_epoch + elif epoch == next_epoch: + current_committees_per_epoch = get_current_epoch_committee_count(state) + committees_per_epoch = get_next_epoch_committee_count(state) + shuffling_epoch = next_epoch + + epochs_since_last_registry_update = current_epoch - state.validator_registry_update_epoch */ - */ int current_committees_per_epoch = get_current_epoch_committee_count(state); committees_per_epoch = get_next_epoch_committee_count(state); - shuffling_epoch = next_epoch; - EpochNumber epochs_since_last_registry_update = current_epoch - .minus(state.getValidatorRegistryUpdateEpoch()); - /* - if registry_change: - seed = generate_seed(state, next_epoch) - shuffling_start_shard = (state.current_shuffling_start_shard + current_committees_per_epoch) % SHARD_COUNT - */ + shuffling_epoch = nextEpoch; + + EpochNumber epochs_since_last_registry_update = + currentEpoch.minus(state.getValidatorRegistryUpdateEpoch()); + if (registry_change) { - seed = generate_seed(state, next_epoch); - shuffling_start_shard = state.getCurrentShufflingStartShard() - .plusModulo(current_committees_per_epoch, spec.getShardCount()); + /* + if registry_change: + seed = generate_seed(state, next_epoch) + shuffling_start_shard = (state.current_shuffling_start_shard + current_committees_per_epoch) % SHARD_COUNT */ + seed = generate_seed(state, nextEpoch); + shuffling_start_shard = ShardNumber.of(state.getCurrentShufflingStartShard() + .plus(current_committees_per_epoch).modulo(spec.getShardCount())); } else if (epochs_since_last_registry_update.greater(EpochNumber.of(1)) && is_power_of_two(epochs_since_last_registry_update)) { /* elif epochs_since_last_registry_update > 1 and is_power_of_two(epochs_since_last_registry_update): seed = generate_seed(state, next_epoch) - shuffling_start_shard = state.current_shuffling_start_shard - */ - seed = generate_seed(state, next_epoch); + shuffling_start_shard = state.current_shuffling_start_shard */ + seed = generate_seed(state, nextEpoch); shuffling_start_shard = state.getCurrentShufflingStartShard(); } else { /* else: seed = state.current_shuffling_seed - shuffling_start_shard = state.current_shuffling_start_shard - */ + shuffling_start_shard = state.current_shuffling_start_shard */ seed = state.getCurrentShufflingSeed(); shuffling_start_shard = state.getCurrentShufflingStartShard(); } } - List> shuffling = get_shuffling(seed, state.getValidatorRegistry(), - shuffling_epoch); - // offset = slot % SLOTS_PER_EPOCH + /* + shuffling = get_shuffling( + seed, + state.validator_registry, + shuffling_epoch, + ) */ + List> shuffling = get_shuffling( + seed, + state.getValidatorRegistry(), + shuffling_epoch + ); + + /* + offset = slot % SLOTS_PER_EPOCH + committees_per_slot = committees_per_epoch // SLOTS_PER_EPOCH + slot_start_shard = (shuffling_start_shard + committees_per_slot * offset) % SHARD_COUNT */ SlotNumber offset = slot.modulo(spec.getSlotsPerEpoch()); - // committees_per_slot = committees_per_epoch // SLOTS_PER_EPOCH UInt64 committees_per_slot = UInt64.valueOf(committees_per_epoch).dividedBy(spec.getSlotsPerEpoch()); - // slot_start_shard = (shuffling_start_shard + committees_per_slot * offset) % SHARD_COUNT - ShardNumber slot_start_shard = shuffling_start_shard - .plusModulo(committees_per_slot.times(offset), spec.getShardCount()); + ShardNumber slot_start_shard = ShardNumber.of( + shuffling_start_shard.plus(committees_per_slot).times(offset).modulo(spec.getShardCount())); /* - return [ + return [ ( shuffling[committees_per_slot * offset + i], (slot_start_shard + i) % SHARD_COUNT, ) for i in range(committees_per_slot) - ] - */ + ] */ List ret = new ArrayList<>(); for(int i = 0; i < committees_per_slot.intValue(); i++) { ShardCommittee committee = new ShardCommittee( @@ -499,7 +502,11 @@ public BytesValue int_to_bytes1(int value) { } public BytesValue int_to_bytes4(long value) { - return BytesValues.ofUnsignedInt(value); + return BytesValues.ofUnsignedIntLittleEndian(value); + } + + public BytesValue int_to_bytes32(UInt64 value) { + return value.toBytes8LittleEndian(); } /* @@ -1089,20 +1096,21 @@ Hash32 get_active_index_root(BeaconState state, EpochNumber epoch) { /* def generate_seed(state: BeaconState, - epoch: EpochNumber) -> Bytes32: - """ - Generate a seed for the given ``epoch``. - """ - - return hash( - get_randao_mix(state, epoch - MIN_SEED_LOOKAHEAD) + - get_active_index_root(state, epoch) - ) + epoch: Epoch) -> Bytes32: + """ + Generate a seed for the given ``epoch``. + """ + return hash( + get_randao_mix(state, epoch - MIN_SEED_LOOKAHEAD) + + get_active_index_root(state, epoch) + + int_to_bytes32(epoch) + ) */ public Hash32 generate_seed(BeaconState state, EpochNumber epoch) { return hash( get_randao_mix(state, epoch.minus(spec.getMinSeedLookahead())) - .concat(get_active_index_root(state, epoch))); + .concat(get_active_index_root(state, epoch)) + .concat(int_to_bytes32(epoch))); } public boolean bls_verify(BLSPubkey publicKey, Hash32 message, BLSSignature signature, Bytes8 domain) { @@ -1469,6 +1477,18 @@ def slot_to_epoch(slot: SlotNumber) -> EpochNumber: public EpochNumber slot_to_epoch(SlotNumber slot) { return slot.dividedBy(spec.getSlotsPerEpoch()); } + + /* + def get_previous_epoch(state: BeaconState) -> Epoch: + """` + Return the previous epoch of the given ``state``. + """ + return max(get_current_epoch(state) - 1, GENESIS_EPOCH) + */ + public EpochNumber get_previous_epoch(BeaconState state) { + return UInt64s.max(get_current_epoch(state).decrement(), spec.getGenesisEpoch()); + } + /* def get_current_epoch(state: BeaconState) -> EpochNumber: return slot_to_epoch(state.slot) diff --git a/types/src/main/java/tech/pegasys/artemis/util/bytes/Bytes8.java b/types/src/main/java/tech/pegasys/artemis/util/bytes/Bytes8.java index 84d7b9b32..7f1408fa6 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/bytes/Bytes8.java +++ b/types/src/main/java/tech/pegasys/artemis/util/bytes/Bytes8.java @@ -50,6 +50,26 @@ static Bytes8 longToBytes8(long seed) { return Bytes8.wrap(bytes); } + /** + * Converts long to little-endian Bytes8. + * + * @param seed converted + * @return converted Bytes8 + * @throws IllegalArgumentException if seed is a negative value. + */ + static Bytes8 longToBytes8LittleEndian(long seed) { + byte[] bytes = new byte[8]; + bytes[0] = (byte) seed; + bytes[1] = (byte) (seed >> 8); + bytes[2] = (byte) (seed >> 16); + bytes[3] = (byte) (seed >> 24); + bytes[4] = (byte) (seed >> 32); + bytes[5] = (byte) (seed >> 40); + bytes[6] = (byte) (seed >> 48); + bytes[7] = (byte) (seed >> 56); + return Bytes8.wrap(bytes); + } + /** * Wraps the provided byte array, which must be of length 8, as a {@link Bytes8}. * diff --git a/types/src/main/java/tech/pegasys/artemis/util/bytes/BytesValues.java b/types/src/main/java/tech/pegasys/artemis/util/bytes/BytesValues.java index 6b82eabcf..a456cdc5a 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/bytes/BytesValues.java +++ b/types/src/main/java/tech/pegasys/artemis/util/bytes/BytesValues.java @@ -141,6 +141,25 @@ public static BytesValue ofUnsignedInt(long v) { res[3] = b(v); return BytesValue.wrap(res); } + /** + * Returns a 4 bytes little-endian value corresponding to the provided value interpreted as an + * unsigned int value. + * + * @param v The value, which must fit an unsigned int. + * @return A 4 bytes value corresponding to {@code v}. + * @throws IllegalArgumentException if {@code v < 0} or {@code v} is too big to fit an unsigned + * 4-bytes int (that is, if {@code v >= (1L << 32)}). + */ + public static BytesValue ofUnsignedIntLittleEndian(long v) { + checkArgument(v >= 0 && v <= MAX_UNSIGNED_INT, + "Value %s cannot be represented as an unsigned int (it is negative or too big)", v); + byte[] res = new byte[4]; + res[0] = b(v); + res[1] = b(v >> 8); + res[2] = b(v >> 16); + res[3] = b(v >> 24); + return BytesValue.wrap(res); + } /** * Extracts the int value corresponding to the provide bytes, which must be 4 bytes or less. diff --git a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java index 8be16751b..fad1c7efc 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java +++ b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt64.java @@ -340,6 +340,16 @@ public Bytes8 toBytes8() { return Bytes8.longToBytes8(value); } + /** + * Converts value to {@link Bytes8} little endian value. + * Uses {@link Bytes8#longToBytes8LittleEndian(long)} method. + * + * @return a {@link Bytes8} value. + */ + public Bytes8 toBytes8LittleEndian() { + return Bytes8.longToBytes8LittleEndian(value); + } + // TODO should be type safe with the respect to custom types @Override public int compareTo(UInt64 uint) { From fe1c7b4749115de42e08ef534c35b142c000baf9 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Mon, 4 Mar 2019 15:39:53 +0600 Subject: [PATCH 09/21] Update SpecHelper functions to spec:0.4.0 --- .../beacon/consensus/SpecHelpers.java | 86 ++++++++++++------- .../transition/InitialStateTransition.java | 2 +- .../transition/PerBlockTransition.java | 8 +- .../transition/PerEpochTransition.java | 4 +- .../verifier/operation/ExitVerifier.java | 4 +- .../beacon/core/spec/StateListLengths.java | 2 +- .../config/chainspec/ChainSpecData.java | 4 +- .../chainspec/StateListLengthsData.java | 2 +- 8 files changed, 68 insertions(+), 44 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 8fa2e5096..4b5f40516 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -598,6 +598,18 @@ public Gwei get_effective_balance(BeaconState state, ValidatorIndex validatorIdx spec.getMaxDepositAmount()); } + /* + def get_total_balance(state: BeaconState, validators: List[ValidatorIndex]) -> Gwei: + """ + Return the combined effective balance of an array of validators. + """ + return sum([get_effective_balance(state, i) for i in validators]) + */ + public Gwei get_total_balance(BeaconState state, List validators) { + return validators.stream().map(index -> get_effective_balance(state, index)) + .reduce(Gwei.ZERO, Gwei::plus); + } + /* def integer_squareroot(n: int) -> int: """ @@ -758,14 +770,14 @@ public ValidatorIndex process_deposit( } /* - def get_entry_exit_effect_epoch(epoch: EpochNumber) -> EpochNumber: + def get_delayed_activation_exit_epoch(epoch: EpochNumber) -> EpochNumber: """ An entry or exit triggered in the ``epoch`` given by the input takes effect at the epoch given by the output. """ return epoch + 1 + ACTIVATION_EXIT_DELAY */ - public EpochNumber get_entry_exit_effect_epoch(EpochNumber epoch) { + public EpochNumber get_delayed_activation_exit_epoch(EpochNumber epoch) { return epoch.plus(1).plus(spec.getActivationExitDelay()); } @@ -786,29 +798,36 @@ def activate_validator(state: BeaconState, index: int, genesis: bool) -> None: */ public void activate_validator(MutableBeaconState state, ValidatorIndex index, boolean genesis) { EpochNumber activationSlot = - genesis ? spec.getGenesisEpoch() : get_entry_exit_effect_epoch(get_current_epoch(state)); + genesis ? spec.getGenesisEpoch() : get_delayed_activation_exit_epoch(get_current_epoch(state)); state .getValidatorRegistry() .update(index, v -> v.builder().withActivationEpoch(activationSlot).build()); } /* - def penalize_validator(state: BeaconState, index: int) -> None: - exit_validator(state, index) - validator = state.validator_registry[index] - state.latest_slashed_balances[get_current_epoch(state) % LATEST_SLASHED_EXIT_LENGTH] - += get_effective_balance(state, index) - - whistleblower_index = get_beacon_proposer_index(state, state.slot) - whistleblower_reward = get_effective_balance(state, index) // WHISTLEBLOWER_REWARD_QUOTIENT - state.validator_balances[whistleblower_index] += whistleblower_reward - state.validator_balances[index] -= whistleblower_reward - validator.initiated_exit = get_current_epoch(state) + def slash_validator(state: BeaconState, index: ValidatorIndex) -> None: + """ + Slash the validator with index ``index``. + Note that this function mutates ``state``. + """ + validator = state.validator_registry[index] + assert state.slot < get_epoch_start_slot(validator.withdrawable_epoch) # [TO BE REMOVED IN PHASE 2] + exit_validator(state, index) + state.latest_slashed_balances[get_current_epoch(state) % LATEST_SLASHED_EXIT_LENGTH] += get_effective_balance(state, index) + + whistleblower_index = get_beacon_proposer_index(state, state.slot) + whistleblower_reward = get_effective_balance(state, index) // WHISTLEBLOWER_REWARD_QUOTIENT + state.validator_balances[whistleblower_index] += whistleblower_reward + state.validator_balances[index] -= whistleblower_reward + validator.slashed = True + validator.withdrawable_epoch = get_current_epoch(state) + LATEST_SLASHED_EXIT_LENGTH */ - public void penalize_validator(MutableBeaconState state, ValidatorIndex index) { + public void slash_validator(MutableBeaconState state, ValidatorIndex index) { + ValidatorRecord validator = state.getValidatorRegistry().get(index); + assertTrue(state.getSlot().less(get_epoch_start_slot(validator.getWithdrawableEpoch()))); exit_validator(state, index); state.getLatestSlashedBalances().update( - get_current_epoch(state).modulo(spec.getSlashedExitLength()), + get_current_epoch(state).modulo(spec.getLatestSlashedExitLength()), balance -> balance.plus(get_effective_balance(state, index))); ValidatorIndex whistleblower_index = get_beacon_proposer_index(state, state.getSlot()); @@ -820,14 +839,14 @@ public void penalize_validator(MutableBeaconState state, ValidatorIndex index) { oldVal -> oldVal.minus(whistleblower_reward)); state.getValidatorRegistry().update(index, v -> v.builder().withSlashed(Boolean.TRUE) - .withWithdrawableEpoch(get_current_epoch(state).plus(spec.getSlashedExitLength())) + .withWithdrawableEpoch(get_current_epoch(state).plus(spec.getLatestSlashedExitLength())) .build()); } /* def initiate_validator_exit(state: BeaconState, index: int) -> None: validator = state.validator_registry[index] - validator.slashed = True + validator.initiated_exit = True */ public void initiate_validator_exit(MutableBeaconState state, ValidatorIndex index) { state @@ -849,19 +868,19 @@ def exit_validator(state: BeaconState, index: ValidatorIndex) -> None: validator = state.validator_registry[index] # The following updates only occur if not previous exited - if validator.exit_epoch <= get_entry_exit_effect_epoch(get_current_epoch(state)): + if validator.exit_epoch <= get_delayed_activation_exit_epoch(get_current_epoch(state)): return - validator.exit_epoch = get_entry_exit_effect_epoch(get_current_epoch(state)) + validator.exit_epoch = get_delayed_activation_exit_epoch(get_current_epoch(state)) */ public void exit_validator(MutableBeaconState state, ValidatorIndex index) { ValidatorRecord validator = state.getValidatorRegistry().get(index); - if (validator.getExitEpoch().lessEqual(get_entry_exit_effect_epoch(get_current_epoch(state)))) { + if (validator.getExitEpoch().lessEqual(get_delayed_activation_exit_epoch(get_current_epoch(state)))) { return; } state.getValidatorRegistry().update(index, v -> v.builder().withExitEpoch( - get_entry_exit_effect_epoch(get_current_epoch(state)) + get_delayed_activation_exit_epoch(get_current_epoch(state)) ).build()); } @@ -901,10 +920,10 @@ public void update_validator_registry(MutableBeaconState state) { Gwei balance_churn = Gwei.ZERO; for (ValidatorIndex index : state.getValidatorRegistry().size()) { ValidatorRecord validator = state.getValidatorRegistry().get(index); - // if validator.activation_epoch > get_entry_exit_effect_epoch(current_epoch) + // if validator.activation_epoch > get_delayed_activation_exit_epoch(current_epoch) // and state.validator_balances[index] >= MAX_DEPOSIT_AMOUNT: if (validator.getActivationEpoch().greater( - get_entry_exit_effect_epoch(current_epoch)) + get_delayed_activation_exit_epoch(current_epoch)) && state.getValidatorBalances().get(index).greaterEqual( spec.getMaxDepositAmount())) { @@ -930,7 +949,7 @@ public void update_validator_registry(MutableBeaconState state) { // for index, validator in enumerate(state.validator_registry): for (ValidatorIndex index : state.getValidatorRegistry().size().iterateFromZero()) { ValidatorRecord validator = state.getValidatorRegistry().get(index); - // if validator.exit_epoch > get_entry_exit_effect_epoch(current_epoch) + // if validator.exit_epoch > get_delayed_activation_exit_epoch(current_epoch) // and validator.slashed: if (validator.getActivationEpoch().equals(spec.getFarFutureEpoch()) && validator.getInitiatedExit()) { @@ -954,9 +973,14 @@ public void update_validator_registry(MutableBeaconState state) { } /* - def prepare_validator_for_withdrawal(state: BeaconState, index: int) -> None: - validator = state.validator_registry[index] - validator.slashed = False + def prepare_validator_for_withdrawal(state: BeaconState, index: ValidatorIndex) -> None: + """ + Set the validator with the given ``index`` as withdrawable + ``MIN_VALIDATOR_WITHDRAWABILITY_DELAY`` after the current epoch. + Note that this function mutates ``state``. + """ + validator = state.validator_registry[index] + validator.withdrawable_epoch = get_current_epoch(state) + MIN_VALIDATOR_WITHDRAWABILITY_DELAY */ public void prepare_validator_for_withdrawal(MutableBeaconState state, ValidatorIndex index) { state @@ -995,13 +1019,13 @@ public void process_penalties_and_exits(MutableBeaconState state) { // if validator.slashed and current_epoch == // validator.withdrawable_epoch - LATEST_SLASHED_EXIT_LENGTH // 2: if (validator.getSlashed() && current_epoch.equals( - validator.getWithdrawableEpoch().minus(spec.getSlashedExitLength().half()))) { + validator.getWithdrawableEpoch().minus(spec.getLatestSlashedExitLength().half()))) { // epoch_index = current_epoch % LATEST_SLASHED_EXIT_LENGTH - EpochNumber epoch_index = current_epoch.modulo(spec.getSlashedExitLength()); + EpochNumber epoch_index = current_epoch.modulo(spec.getLatestSlashedExitLength()); // total_at_start = state.latest_slashed_balances[(epoch_index + 1) % LATEST_SLASHED_EXIT_LENGTH] Gwei total_at_start = state.getLatestSlashedBalances().get( - epoch_index.increment().modulo(spec.getSlashedExitLength())); + epoch_index.increment().modulo(spec.getLatestSlashedExitLength())); // total_at_end = state.latest_slashed_balances[epoch_index] Gwei total_at_end = state.getLatestSlashedBalances().get(epoch_index); // total_penalties = total_at_end - total_at_start diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java index b34dab763..60eba5b2f 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java @@ -101,7 +101,7 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { initialState.getLatestActiveIndexRoots().addAll( nCopies(chainSpec.getLatestActiveIndexRootsLength().getIntValue(), Hash32.ZERO)); initialState.getLatestSlashedBalances().addAll( - nCopies(chainSpec.getSlashedExitLength().getIntValue(), Gwei.ZERO)); + nCopies(chainSpec.getLatestSlashedExitLength().getIntValue(), Gwei.ZERO)); initialState.getLatestAttestations().clear(); initialState.getBatchedBlockRoots().clear(); diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java index fea4f1eb1..5fbdf89bb 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java @@ -88,10 +88,10 @@ a new Eth1DataVote(eth1_data=block.eth1_data, vote_count=1). /* For each proposer_slashing in block.body.proposer_slashings: - Run penalize_validator(state, proposer_slashing.proposer_index). + Run slash_validator(state, proposer_slashing.proposer_index). */ for (ProposerSlashing proposer_slashing : block.getBody().getProposerSlashings()) { - specHelpers.penalize_validator(state, proposer_slashing.getProposerIndex()); + specHelpers.slash_validator(state, proposer_slashing.getProposerIndex()); } /* @@ -101,7 +101,7 @@ Run penalize_validator(state, proposer_slashing.proposer_index). Let slashable_indices = [index for index in slashable_attestation_1.validator_indices if index in slashable_attestation_2.validator_indices and state.validator_registry[index].initiated_exit > get_current_epoch(state)]. - Run penalize_validator(state, index) for each index in slashable_indices. + Run slash_validator(state, index) for each index in slashable_indices. */ for (AttesterSlashing attester_slashing : block.getBody().getAttesterSlashings()) { ReadList intersection = @@ -109,7 +109,7 @@ Run penalize_validator(state, index) for each index in slashable_indices. attester_slashing.getSlashableAttestation2().getValidatorIndices()); for (ValidatorIndex index : intersection) { if (!state.getValidatorRegistry().get(index).getSlashed()) { - specHelpers.penalize_validator(state, index); + specHelpers.slash_validator(state, index); } } } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java index 87a3d44d5..70bb5481f 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java @@ -958,9 +958,9 @@ def process_ejections(state: BeaconState) -> None: next_epoch.plus(specConst.getActivationExitDelay())))); // Set state.latest_slashed_balances[(next_epoch) % LATEST_SLASHED_EXIT_LENGTH] = // state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH]. - state.getLatestSlashedBalances().set(next_epoch.modulo(specConst.getSlashedExitLength()), + state.getLatestSlashedBalances().set(next_epoch.modulo(specConst.getLatestSlashedExitLength()), state.getLatestSlashedBalances().get( - current_epoch.modulo(specConst.getSlashedExitLength()))); + current_epoch.modulo(specConst.getLatestSlashedExitLength()))); // Set state.latest_randao_mixes[next_epoch % LATEST_RANDAO_MIXES_LENGTH] = // get_randao_mix(state, current_epoch). state.getLatestRandaoMixes().set(next_epoch.modulo(specConst.getLatestRandaoMixesLength()), diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java index b89b2b3e4..ba9329b93 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java @@ -36,9 +36,9 @@ public VerificationResult verify(VoluntaryExit voluntaryExit, BeaconState state) ValidatorRecord validator = state.getValidatorRegistry().get(voluntaryExit.getValidatorIndex()); - // Verify that validator.exit_epoch > get_entry_exit_effect_epoch(get_current_epoch(state)) + // Verify that validator.exit_epoch > get_delayed_activation_exit_epoch(get_current_epoch(state)) if (!validator.getExitEpoch().greater( - specHelpers.get_entry_exit_effect_epoch(specHelpers.get_current_epoch(state)))) { + specHelpers.get_delayed_activation_exit_epoch(specHelpers.get_current_epoch(state)))) { return failedResult( "ACTIVATION_EXIT_DELAY exceeded, min exit epoch %s, got %s", state.getSlot().plus(chainSpec.getActivationExitDelay()), validator.getExitEpoch()); diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java b/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java index e6d515b7c..f52cb7fed 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/StateListLengths.java @@ -29,7 +29,7 @@ default EpochNumber getLatestActiveIndexRootsLength() { return LATEST_ACTIVE_INDEX_ROOTS_LENGTH; } - default EpochNumber getSlashedExitLength() { + default EpochNumber getLatestSlashedExitLength() { return LATEST_SLASHED_EXIT_LENGTH; } } diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java index aff9f3be4..42d1c7d3a 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java @@ -196,8 +196,8 @@ public EpochNumber getLatestActiveIndexRootsLength() { } @Override - public EpochNumber getSlashedExitLength() { - return stateListLengths.getSlashedExitLength(); + public EpochNumber getLatestSlashedExitLength() { + return stateListLengths.getLatestSlashedExitLength(); } @Override diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java index abe818849..7ede2de30 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/StateListLengthsData.java @@ -38,7 +38,7 @@ public EpochNumber getLatestActiveIndexRootsLength() { @Override @JsonIgnore - public EpochNumber getSlashedExitLength() { + public EpochNumber getLatestSlashedExitLength() { return new EpochNumber(UInt64.valueOf(getLATEST_SLASHED_EXIT_LENGTH())); } From f9c1a88c57010b7d0390ffcc6de39e6d61e5111e Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Mon, 4 Mar 2019 16:29:59 +0600 Subject: [PATCH 10/21] Rename ChainSpec to SpecConstants --- .../beacon/chain/DefaultBeaconChain.java | 34 ++--- .../beacon/chain/LMDGhostHeadFunction.java | 8 +- .../org/ethereum/beacon/chain/SlotTicker.java | 12 +- .../chain/observer/ObservableBeaconState.java | 5 +- .../ObservableStateProcessorImpl.java | 29 ++--- .../chain/observer/PendingOperations.java | 4 +- .../beacon/chain/DefaultBeaconChainTest.java | 10 +- .../beacon/chain/SlotTickerTests.java | 11 +- .../util/ObservableBeaconStateTestUtil.java | 4 +- .../chain/util/SampleObservableState.java | 27 ++-- .../beacon/consensus/BeaconStateEx.java | 6 +- .../beacon/consensus/SpecHelpers.java | 123 +++++++++--------- .../transition/DelegateBeaconState.java | 6 +- .../transition/InitialStateTransition.java | 69 +++++----- .../transition/PerBlockTransition.java | 33 +++-- .../transition/PerEpochTransition.java | 43 +++--- .../transition/PerSlotTransition.java | 19 ++- .../verifier/BeaconBlockVerifier.java | 8 +- .../verifier/BeaconStateRootMatcher.java | 10 +- .../block/AttestationListVerifier.java | 6 +- .../verifier/block/DepositListVerifier.java | 6 +- .../verifier/block/ExitListVerifier.java | 6 +- .../block/ProposerSignatureVerifier.java | 21 ++- .../block/ProposerSlashingListVerifier.java | 6 +- .../verifier/block/RandaoVerifier.java | 14 +- .../operation/AttestationVerifier.java | 47 ++++--- .../operation/AttesterSlashingVerifier.java | 22 ++-- .../verifier/operation/DepositVerifier.java | 15 +-- .../verifier/operation/ExitVerifier.java | 23 ++-- .../operation/ProposerSlashingVerifier.java | 28 ++-- .../beacon/consensus/SpecHelpersTest.java | 17 ++- .../ethereum/beacon/consensus/TestUtils.java | 4 +- .../InitialStateTransitionTest.java | 6 +- .../transition/PerEpochTransitionTest.java | 10 +- .../transition/PerSlotTransitionTest.java | 12 +- .../org/ethereum/beacon/core/BeaconBlock.java | 30 ++--- .../ethereum/beacon/core/BeaconBlocks.java | 13 +- .../org/ethereum/beacon/core/BeaconState.java | 4 +- .../beacon/core/operations/Attestation.java | 6 +- .../ethereum/beacon/core/operations/Exit.java | 4 +- .../core/operations/ProposerSlashing.java | 4 +- .../beacon/core/operations/VoluntaryExit.java | 4 +- .../attestation/AttestationData.java | 4 +- .../operations/attestation/Crosslink.java | 4 +- .../operations/slashing/AttesterSlashing.java | 4 +- .../core/operations/slashing/Proposal.java | 4 +- .../slashing/SlashableAttestation.java | 4 +- .../{ChainSpec.java => SpecConstants.java} | 4 +- .../ethereum/beacon/core/state/ForkData.java | 5 +- .../core/state/PendingAttestationRecord.java | 7 +- .../beacon/core/types/EpochNumber.java | 4 +- .../beacon/core/types/ShardNumber.java | 4 +- .../beacon/core/types/SlotNumber.java | 6 +- .../beacon/core/util/AttestationTestUtil.java | 8 +- .../beacon/core/util/DepositTestUtil.java | 6 +- .../core/util/ProposerSlashingTestUtil.java | 6 +- .../ValidatorRegistrationServiceImpl.java | 39 +++--- .../org/ethereum/beacon/ReusableOptions.java | 20 +-- .../java/org/ethereum/beacon/Simulator.java | 4 +- .../ethereum/beacon/SimulatorLauncher.java | 28 ++-- .../ethereum/beacon/util/SimulateUtils.java | 2 +- .../java/org/ethereum/beacon/Launcher.java | 34 +++-- .../beacon/MultiValidatorLauncher.java | 29 ++--- .../beacon/LocalMultiValidatorTest.java | 20 ++- .../org/ethereum/beacon/LocalNetTest.java | 23 ++-- .../config/chainspec/InitialValuesData.java | 2 +- ...inSpecData.java => SpecConstantsData.java} | 10 +- .../emulator/config/ConfigBuilderTest.java | 28 ++-- .../validator/BeaconChainValidator.java | 16 +-- .../validator/MultiValidatorService.java | 30 ++--- .../attester/BeaconChainAttesterImpl.java | 35 +++-- .../proposer/BeaconChainProposerImpl.java | 58 ++++----- .../validator/BeaconChainValidatorTest.java | 11 +- .../attester/BeaconChainAttesterTest.java | 8 +- .../attester/BeaconChainAttesterTestUtil.java | 3 +- .../proposer/BeaconChainProposerTest.java | 42 +++--- .../proposer/BeaconChainProposerTestUtil.java | 1 - 77 files changed, 616 insertions(+), 666 deletions(-) rename core/src/main/java/org/ethereum/beacon/core/spec/{ChainSpec.java => SpecConstants.java} (85%) rename start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/{ChainSpecData.java => SpecConstantsData.java} (97%) diff --git a/chain/src/main/java/org/ethereum/beacon/chain/DefaultBeaconChain.java b/chain/src/main/java/org/ethereum/beacon/chain/DefaultBeaconChain.java index 58c03242e..5e0701bc1 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/DefaultBeaconChain.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/DefaultBeaconChain.java @@ -29,7 +29,7 @@ public class DefaultBeaconChain implements MutableBeaconChain { private static final Logger logger = LogManager.getLogger(DefaultBeaconChain.class); - private final SpecHelpers specHelpers; + private final SpecHelpers spec; private final BlockTransition initialTransition; private final StateTransition perSlotTransition; private final BlockTransition perBlockTransition; @@ -46,7 +46,7 @@ public class DefaultBeaconChain implements MutableBeaconChain { private BeaconTuple recentlyProcessed; public DefaultBeaconChain( - SpecHelpers specHelpers, + SpecHelpers spec, BlockTransition initialTransition, StateTransition perSlotTransition, BlockTransition perBlockTransition, @@ -55,7 +55,7 @@ public DefaultBeaconChain( BeaconStateVerifier stateVerifier, BeaconChainStorage chainStorage, Schedulers schedulers) { - this.specHelpers = specHelpers; + this.spec = spec; this.initialTransition = initialTransition; this.perSlotTransition = perSlotTransition; this.perBlockTransition = perBlockTransition; @@ -91,12 +91,12 @@ private BeaconTuple fetchRecentTuple() { } private void initializeStorage() { - BeaconBlock initialGenesis = BeaconBlocks.createGenesis(specHelpers.getChainSpec()); + BeaconBlock initialGenesis = BeaconBlocks.createGenesis(spec.getConstants()); BeaconStateEx initialState = initialTransition.apply(BeaconStateEx.getEmpty(), initialGenesis); - Hash32 initialStateRoot = specHelpers.hash_tree_root(initialState); + Hash32 initialStateRoot = spec.hash_tree_root(initialState); BeaconBlock genesis = initialGenesis.withStateRoot(initialStateRoot); - Hash32 genesisRoot = specHelpers.hash_tree_root(genesis); + Hash32 genesisRoot = spec.hash_tree_root(genesis); BeaconTuple tuple = BeaconTuple.of(genesis, initialState); tupleStorage.put(tuple); @@ -125,13 +125,13 @@ public synchronized boolean insert(BeaconBlock block) { blockVerifier.verify(block, preBlockState); if (!blockVerification.isPassed()) { logger.warn("Block verification failed: " + blockVerification + ": " + - block.toString(specHelpers.getChainSpec(), parentState.getGenesisTime(), specHelpers::hash_tree_root)); + block.toString(spec.getConstants(), parentState.getGenesisTime(), spec::hash_tree_root)); return false; } BeaconStateEx postBlockState = perBlockTransition.apply(preBlockState, block); BeaconStateEx postEpochState; - if (specHelpers.is_epoch_end(block.getSlot())) { + if (spec.is_epoch_end(block.getSlot())) { postEpochState = perEpochTransition.apply(postBlockState); } else { postEpochState = postBlockState; @@ -158,9 +158,9 @@ public synchronized boolean insert(BeaconBlock block) { newTuple .getBlock() .toString( - specHelpers.getChainSpec(), + spec.getConstants(), newTuple.getState().getGenesisTime(), - specHelpers::hash_tree_root)); + spec::hash_tree_root)); return true; } @@ -173,14 +173,14 @@ public BeaconTuple getRecentlyProcessed() { private void updateFinality(BeaconState previous, BeaconState current) { if (previous.getFinalizedEpoch().less(current.getFinalizedEpoch())) { Hash32 finalizedRoot = - specHelpers.get_block_root( - current, specHelpers.get_epoch_start_slot(current.getFinalizedEpoch())); + spec.get_block_root( + current, spec.get_epoch_start_slot(current.getFinalizedEpoch())); chainStorage.getFinalizedStorage().set(finalizedRoot); } if (previous.getJustifiedEpoch().less(current.getJustifiedEpoch())) { Hash32 justifiedRoot = - specHelpers.get_block_root( - current, specHelpers.get_epoch_start_slot(current.getJustifiedEpoch())); + spec.get_block_root( + current, spec.get_epoch_start_slot(current.getJustifiedEpoch())); chainStorage.getJustifiedStorage().set(justifiedRoot); } } @@ -194,7 +194,7 @@ private BeaconStateEx pullParentState(BeaconBlock block) { } private boolean exist(BeaconBlock block) { - Hash32 blockHash = specHelpers.hash_tree_root(block); + Hash32 blockHash = spec.hash_tree_root(block); return chainStorage.getBlockStorage().get(blockHash).isPresent(); } @@ -210,7 +210,7 @@ private boolean hasParent(BeaconBlock block) { */ private boolean rejectedByTime(BeaconBlock block) { SlotNumber nextToCurrentSlot = - specHelpers.get_current_slot(recentlyProcessed.getState()).increment(); + spec.get_current_slot(recentlyProcessed.getState()).increment(); return block.getSlot().greater(nextToCurrentSlot); } @@ -219,7 +219,7 @@ private BeaconStateEx applyEmptySlotTransitionsTillBlock(BeaconStateEx source, B BeaconStateEx result = source; for (SlotNumber slot : result.getSlot().increment().iterateTo(block.getSlot())) { result = perSlotTransition.apply(result); - if (specHelpers.is_epoch_end(result.getSlot())) { + if (spec.is_epoch_end(result.getSlot())) { result = perEpochTransition.apply(result); } } diff --git a/chain/src/main/java/org/ethereum/beacon/chain/LMDGhostHeadFunction.java b/chain/src/main/java/org/ethereum/beacon/chain/LMDGhostHeadFunction.java index 4eddef770..bd599aeab 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/LMDGhostHeadFunction.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/LMDGhostHeadFunction.java @@ -21,12 +21,12 @@ public class LMDGhostHeadFunction implements HeadFunction { private final BeaconChainStorage chainStorage; - private final SpecHelpers specHelpers; + private final SpecHelpers spec; private final int SEARCH_LIMIT = Integer.MAX_VALUE; - public LMDGhostHeadFunction(BeaconChainStorage chainStorage, SpecHelpers specHelpers) { + public LMDGhostHeadFunction(BeaconChainStorage chainStorage, SpecHelpers spec) { this.chainStorage = chainStorage; - this.specHelpers = specHelpers; + this.spec = spec; } @Override @@ -46,7 +46,7 @@ public BeaconBlock getHead( Function> getChildrenBlocks = (hash) -> chainStorage.getBlockStorage().getChildren(hash, SEARCH_LIMIT); BeaconBlock newHead = - specHelpers.lmd_ghost( + spec.lmd_ghost( justifiedTuple.getBlock(), justifiedTuple.getState(), chainStorage.getBlockStorage()::get, diff --git a/chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java b/chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java index d93fdae3e..6eb243eae 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java @@ -18,7 +18,7 @@ * start must subscribe to this service and use values from it */ public class SlotTicker implements Ticker { - private final SpecHelpers specHelpers; + private final SpecHelpers spec; private final BeaconState state; private final Schedulers schedulers; @@ -29,8 +29,8 @@ public class SlotTicker implements Ticker { private Scheduler scheduler; - public SlotTicker(SpecHelpers specHelpers, BeaconState state, Schedulers schedulers) { - this.specHelpers = specHelpers; + public SlotTicker(SpecHelpers spec, BeaconState state, Schedulers schedulers) { + this.spec = spec; this.state = state; this.schedulers = schedulers; @@ -45,8 +45,8 @@ public SlotTicker(SpecHelpers specHelpers, BeaconState state, Schedulers schedul public void start() { this.scheduler = schedulers.newSingleThreadDaemon("slot-ticker"); - SlotNumber nextSlot = specHelpers.get_current_slot(state).increment(); - Time period = specHelpers.getChainSpec().getSecondsPerSlot(); + SlotNumber nextSlot = spec.get_current_slot(state).increment(); + Time period = spec.getConstants().getSecondsPerSlot(); startImpl(nextSlot, period, scheduler); } @@ -56,7 +56,7 @@ public void stop() {} private void startImpl(SlotNumber startSlot, Time period, Scheduler scheduler) { this.startSlot = startSlot; - Time startSlotTime = specHelpers.get_slot_start_time(state, startSlot); + Time startSlotTime = spec.get_slot_start_time(state, startSlot); long delayMillis = Math.max(0, startSlotTime.getMillis().getValue() - schedulers.getCurrentTime()); Flux.interval( diff --git a/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableBeaconState.java b/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableBeaconState.java index fec604b47..1777f8f71 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableBeaconState.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableBeaconState.java @@ -5,7 +5,6 @@ import org.ethereum.beacon.consensus.BeaconStateEx; import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.core.BeaconBlock; -import org.ethereum.beacon.core.BeaconState; /** An observable chain state. */ public class ObservableBeaconState { @@ -68,8 +67,8 @@ public String toString(@Nullable SpecHelpers spec) { + (spec != null ? spec.hash_tree_root(head).toStringShort() : head.toString(null ,null, null)) + ", latestState: " + committee - + latestSlotState.toStringShort(spec == null ? null : spec.getChainSpec()) - + ", pendingOps: " + getPendingOperations().toStringMedium(spec == null ? null : spec.getChainSpec()) + + latestSlotState.toStringShort(spec == null ? null : spec.getConstants()) + + ", pendingOps: " + getPendingOperations().toStringMedium(spec == null ? null : spec.getConstants()) + "]"; } } diff --git a/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableStateProcessorImpl.java b/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableStateProcessorImpl.java index d684b81cc..85dcf7447 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableStateProcessorImpl.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/observer/ObservableStateProcessorImpl.java @@ -20,7 +20,6 @@ import org.ethereum.beacon.core.BeaconBlock; import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.operations.Attestation; -import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.state.PendingAttestationRecord; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.SlotNumber; @@ -40,8 +39,7 @@ public class ObservableStateProcessorImpl implements ObservableStateProcessor { private BeaconStateEx latestState; - private final SpecHelpers specHelpers; - private final ChainSpec chainSpec; + private final SpecHelpers spec; private final StateTransition perSlotTransition; private final StateTransition perEpochTransition; @@ -73,16 +71,15 @@ public ObservableStateProcessorImpl( Publisher slotTicker, Publisher attestationPublisher, Publisher beaconPublisher, - SpecHelpers specHelpers, + SpecHelpers spec, StateTransition perSlotTransition, StateTransition perEpochTransition, Schedulers schedulers) { this.tupleStorage = chainStorage.getTupleStorage(); - this.specHelpers = specHelpers; - this.chainSpec = specHelpers.getChainSpec(); + this.spec = spec; this.perSlotTransition = perSlotTransition; this.perEpochTransition = perEpochTransition; - this.headFunction = new LMDGhostHeadFunction(chainStorage, specHelpers); + this.headFunction = new LMDGhostHeadFunction(chainStorage, spec); this.slotTicker = slotTicker; this.attestationPublisher = attestationPublisher; this.beaconPublisher = beaconPublisher; @@ -126,8 +123,8 @@ private void onNewSlot(SlotNumber newSlot) { // state.slot - MIN_ATTESTATION_INCLUSION_DELAY - SLOTS_PER_EPOCH < attestation.data.slot SlotNumber slotMinimum = newSlot - .minus(chainSpec.getSlotsPerEpoch()) - .minus(chainSpec.getMinAttestationInclusionDelay()); + .minus(spec.getConstants().getSlotsPerEpoch()) + .minus(spec.getConstants().getMinAttestationInclusionDelay()); runTaskInSeparateThread( () -> { purgeAttestations(slotMinimum); @@ -140,10 +137,10 @@ private void doHardWork() { for (Attestation attestation : attestations) { List participants = - specHelpers.get_attestation_participants( + spec.get_attestation_participants( latestState, attestation.getData(), attestation.getAggregationBitfield()); - List pubKeys = specHelpers.mapIndicesToPubKeys(latestState, participants); + List pubKeys = spec.mapIndicesToPubKeys(latestState, participants); for (BLSPubkey pubKey : pubKeys) { addValidatorAttestation(pubKey, attestation); @@ -183,11 +180,11 @@ private void addAttestationsFromState(BeaconState beaconState) { beaconState.getLatestAttestations(); for (PendingAttestationRecord pendingAttestationRecord : pendingAttestationRecords) { List participants = - specHelpers.get_attestation_participants( + spec.get_attestation_participants( beaconState, pendingAttestationRecord.getData(), pendingAttestationRecord.getAggregationBitfield()); - List pubKeys = specHelpers.mapIndicesToPubKeys(beaconState, participants); + List pubKeys = spec.mapIndicesToPubKeys(beaconState, participants); SlotNumber slot = pendingAttestationRecord.getData().getSlot(); pubKeys.forEach( pubKey -> { @@ -237,7 +234,7 @@ private void updateCurrentObservableState(SlotNumber newSlot) { private BeaconStateEx applyEpochTransitionIfNeeded( BeaconStateEx originalState, BeaconStateEx stateWithoutEpoch) { - if (specHelpers.is_epoch_end(stateWithoutEpoch.getSlot()) + if (spec.is_epoch_end(stateWithoutEpoch.getSlot()) && originalState.getSlot().less(stateWithoutEpoch.getSlot())) { return perEpochTransition.apply(stateWithoutEpoch); } else { @@ -258,7 +255,7 @@ private BeaconStateEx applySlotTransitionsWithoutEpoch( BeaconStateEx state = source; for (SlotNumber slot : source.getSlot().increment().iterateTo(targetSlot.increment())) { state = perSlotTransition.apply(state); - if (specHelpers.is_epoch_end(slot) && !slot.equals(targetSlot)) { + if (spec.is_epoch_end(slot) && !slot.equals(targetSlot)) { state = perEpochTransition.apply(state); } } @@ -274,7 +271,7 @@ private void updateHead(PendingOperations pendingOperations) { } BeaconTuple newHeadTuple = tupleStorage - .get(specHelpers.hash_tree_root(newHead)) + .get(spec.hash_tree_root(newHead)) .orElseThrow(() -> new IllegalStateException("Beacon tuple not found for new head ")); this.head = BeaconChainHead.of(newHeadTuple); diff --git a/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperations.java b/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperations.java index 816d1233b..73d9d2c5a 100644 --- a/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperations.java +++ b/chain/src/main/java/org/ethereum/beacon/chain/observer/PendingOperations.java @@ -7,7 +7,7 @@ import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.SlotNumber; @@ -34,7 +34,7 @@ default String toStringShort() { + "]"; } - default String toStringMedium(ChainSpec spec) { + default String toStringMedium(SpecConstants spec) { String ret = "PendingOperations["; if (!getAttestations().isEmpty()) { ret += "attest (slot/shard/beaconBlock): ["; diff --git a/chain/src/test/java/org/ethereum/beacon/chain/DefaultBeaconChainTest.java b/chain/src/test/java/org/ethereum/beacon/chain/DefaultBeaconChainTest.java index 03a7eb32b..8a93f8375 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/DefaultBeaconChainTest.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/DefaultBeaconChainTest.java @@ -18,7 +18,7 @@ import org.ethereum.beacon.core.BeaconBlock; import org.ethereum.beacon.core.BeaconBlockBody; import org.ethereum.beacon.core.BeaconState; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.db.Database; @@ -35,7 +35,7 @@ public class DefaultBeaconChainTest { public void insertAChain() { Schedulers schedulers = Schedulers.createDefault(); - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, schedulers::getCurrentTime); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, schedulers::getCurrentTime); StateTransition perSlotTransition = StateTransitionTestUtil.createNextSlotTransition(); MutableBeaconChain beaconChain = createBeaconChain(specHelpers, perSlotTransition, schedulers); @@ -43,7 +43,7 @@ public void insertAChain() { beaconChain.init(); BeaconTuple initialTuple = beaconChain.getRecentlyProcessed(); Assert.assertEquals( - specHelpers.getChainSpec().getGenesisSlot(), initialTuple.getBlock().getSlot()); + specHelpers.getConstants().getGenesisSlot(), initialTuple.getBlock().getSlot()); IntStream.range(0, 10) .forEach( @@ -66,9 +66,9 @@ private BeaconBlock createBlock( specHelpers.get_current_slot(parent.getState()), specHelpers.hash_tree_root(parent.getBlock()), Hash32.ZERO, - specHelpers.getChainSpec().getEmptySignature(), + specHelpers.getConstants().getEmptySignature(), Eth1Data.EMPTY, - specHelpers.getChainSpec().getEmptySignature(), + specHelpers.getConstants().getEmptySignature(), BeaconBlockBody.EMPTY); BeaconState state = perSlotTransition diff --git a/chain/src/test/java/org/ethereum/beacon/chain/SlotTickerTests.java b/chain/src/test/java/org/ethereum/beacon/chain/SlotTickerTests.java index 522d1f4e8..8b0455e07 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/SlotTickerTests.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/SlotTickerTests.java @@ -3,10 +3,9 @@ import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.core.types.Time; -import org.ethereum.beacon.schedulers.ControlledSchedulers; import org.ethereum.beacon.schedulers.Schedulers; import org.junit.Test; import reactor.core.publisher.Flux; @@ -32,8 +31,8 @@ public SlotTickerTests() throws InterruptedException { } beaconState.setGenesisTime( Time.of(schedulers.getCurrentTime() / MILLIS_IN_SECOND).minus(Time.of(2))); - ChainSpec chainSpec = - new ChainSpec() { + SpecConstants specConstants = + new SpecConstants() { @Override public SlotNumber getGenesisSlot() { return SlotNumber.of(12345); @@ -44,8 +43,8 @@ public Time getSecondsPerSlot() { return Time.of(1); } }; - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(chainSpec, schedulers::getCurrentTime); - genesisSlot = specHelpers.getChainSpec().getGenesisSlot(); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(specConstants, schedulers::getCurrentTime); + genesisSlot = specHelpers.getConstants().getGenesisSlot(); slotTicker = new SlotTicker(specHelpers, beaconState, Schedulers.createDefault()); } diff --git a/chain/src/test/java/org/ethereum/beacon/chain/util/ObservableBeaconStateTestUtil.java b/chain/src/test/java/org/ethereum/beacon/chain/util/ObservableBeaconStateTestUtil.java index dcb2fc494..fce38635d 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/util/ObservableBeaconStateTestUtil.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/util/ObservableBeaconStateTestUtil.java @@ -6,12 +6,10 @@ import org.ethereum.beacon.chain.observer.PendingOperations; import org.ethereum.beacon.consensus.BeaconStateEx; import org.ethereum.beacon.consensus.SpecHelpers; -import org.ethereum.beacon.consensus.TransitionType; import org.ethereum.beacon.consensus.transition.BeaconStateExImpl; import org.ethereum.beacon.consensus.transition.InitialStateTransition; import org.ethereum.beacon.core.BeaconBlock; import org.ethereum.beacon.core.BeaconBlocks; -import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.SlotNumber; @@ -43,7 +41,7 @@ public static ObservableBeaconState createInitialState( public static ObservableBeaconState createInitialState( Random random, SpecHelpers specHelpers, PendingOperations operations) { - BeaconBlock genesis = BeaconBlocks.createGenesis(specHelpers.getChainSpec()); + BeaconBlock genesis = BeaconBlocks.createGenesis(specHelpers.getConstants()); ChainStart chainStart = new ChainStart( Time.ZERO, diff --git a/chain/src/test/java/org/ethereum/beacon/chain/util/SampleObservableState.java b/chain/src/test/java/org/ethereum/beacon/chain/util/SampleObservableState.java index 93b6db13b..88e27892d 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/util/SampleObservableState.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/util/SampleObservableState.java @@ -21,14 +21,13 @@ import org.ethereum.beacon.consensus.verifier.VerificationResult; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.crypto.BLS381.KeyPair; import org.ethereum.beacon.db.InMemoryDatabase; import org.ethereum.beacon.pow.DepositContract.ChainStart; -import org.ethereum.beacon.schedulers.ControlledSchedulers; import org.ethereum.beacon.schedulers.Schedulers; import org.javatuples.Pair; import org.reactivestreams.Publisher; @@ -36,7 +35,7 @@ import tech.pegasys.artemis.util.uint.UInt64; public class SampleObservableState { - private final SpecHelpers specHelpers; + private final SpecHelpers spec; public List deposits; public List depositKeys; @@ -57,8 +56,8 @@ public SampleObservableState( Publisher attestationsSteam, Schedulers schedulers) { - ChainSpec chainSpec = - new ChainSpec() { + SpecConstants specConstants = + new SpecConstants() { @Override public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(validatorCount)); @@ -74,20 +73,20 @@ public SlotNumber getGenesisSlot() { return SlotNumber.of(genesisSlot); } }; - this.specHelpers = SpecHelpers.createWithSSZHasher(chainSpec, schedulers::getCurrentTime); + this.spec = SpecHelpers.createWithSSZHasher(specConstants, schedulers::getCurrentTime); Pair, List> anyDeposits = TestUtils - .getAnyDeposits(rnd, specHelpers, 8); + .getAnyDeposits(rnd, spec, 8); deposits = anyDeposits.getValue0(); depositKeys = anyDeposits.getValue1(); eth1Data = new Eth1Data(Hash32.random(rnd), Hash32.random(rnd)); chainStart = new ChainStart(Time.of(genesisTime.getSeconds()), eth1Data, deposits); - InitialStateTransition initialTransition = new InitialStateTransition(chainStart, specHelpers); - PerSlotTransition perSlotTransition = new PerSlotTransition(specHelpers); - PerBlockTransition perBlockTransition = new PerBlockTransition(specHelpers); - PerEpochTransition perEpochTransition = new PerEpochTransition(specHelpers); + InitialStateTransition initialTransition = new InitialStateTransition(chainStart, spec); + PerSlotTransition perSlotTransition = new PerSlotTransition(spec); + PerBlockTransition perBlockTransition = new PerBlockTransition(spec); + PerEpochTransition perEpochTransition = new PerEpochTransition(spec); db = new InMemoryDatabase(); beaconChainStorage = BeaconChainStorageFactory.get().create(db); @@ -98,7 +97,7 @@ public SlotNumber getGenesisSlot() { BeaconStateVerifier stateVerifier = (block, state) -> VerificationResult.PASSED; beaconChain = new DefaultBeaconChain( - specHelpers, + spec, initialTransition, perSlotTransition, perBlockTransition, @@ -109,7 +108,7 @@ public SlotNumber getGenesisSlot() { schedulers); beaconChain.init(); - slotTicker = new SlotTicker(specHelpers, beaconChain.getRecentlyProcessed().getState(), + slotTicker = new SlotTicker(spec, beaconChain.getRecentlyProcessed().getState(), schedulers); slotTicker.start(); @@ -118,7 +117,7 @@ public SlotNumber getGenesisSlot() { slotTicker.getTickerStream(), attestationsSteam, beaconChain.getBlockStatesStream(), - specHelpers, + spec, perSlotTransition, perEpochTransition, schedulers); diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/BeaconStateEx.java b/consensus/src/main/java/org/ethereum/beacon/consensus/BeaconStateEx.java index 189971163..a7581c60a 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/BeaconStateEx.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/BeaconStateEx.java @@ -3,7 +3,7 @@ import javax.annotation.Nullable; import org.ethereum.beacon.consensus.transition.BeaconStateExImpl; import org.ethereum.beacon.core.BeaconState; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import tech.pegasys.artemis.ethereum.core.Hash32; /** @@ -21,9 +21,9 @@ static BeaconStateEx getEmpty() { TransitionType getTransition(); default String toString( - @Nullable ChainSpec spec) { + @Nullable SpecConstants constants) { return "BeaconStateEx[headBlock=" + getHeadBlockHash().toStringShort() + (getTransition() == TransitionType.UNKNOWN ? "" : ", lastTransition=" + getTransition()) - + ", " + toStringShort(spec); + + ", " + toStringShort(constants); } } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 4b5f40516..e2a214027 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -10,7 +10,7 @@ import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; import org.ethereum.beacon.core.operations.deposit.DepositInput; import org.ethereum.beacon.core.operations.slashing.SlashableAttestation; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.spec.SignatureDomains; import org.ethereum.beacon.core.state.ForkData; import org.ethereum.beacon.core.state.ShardCommittee; @@ -61,41 +61,41 @@ * https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#helper-functions */ public class SpecHelpers { - private final ChainSpec spec; + private final SpecConstants constants; private final ObjectHasher objectHasher; private final Function hashFunction; private final Supplier systemTimeSupplier; /** - * Creates a SpecHelpers instance with given {@link ChainSpec} and time supplier, + * Creates a SpecHelpers instance with given {@link SpecConstants} and time supplier, * {@link Hashes#keccak256(BytesValue)} as a hash function and {@link SSZObjectHasher} as an object * hasher. * - * @param spec a chain spec. + * @param constants a chain constants. * @param systemTimeSupplier The current system time supplier. Normally the * Schedulers::currentTime is passed * @return spec helpers instance. */ - public static SpecHelpers createWithSSZHasher(@Nonnull ChainSpec spec, @Nonnull Supplier systemTimeSupplier) { - Objects.requireNonNull(spec); + public static SpecHelpers createWithSSZHasher(@Nonnull SpecConstants constants, @Nonnull Supplier systemTimeSupplier) { + Objects.requireNonNull(constants); Function hashFunction = Hashes::keccak256; ObjectHasher sszHasher = SSZObjectHasher.create(hashFunction); - return new SpecHelpers(spec, hashFunction, sszHasher, systemTimeSupplier); + return new SpecHelpers(constants, hashFunction, sszHasher, systemTimeSupplier); } - public SpecHelpers(ChainSpec spec, + public SpecHelpers(SpecConstants constants, Function hashFunction, ObjectHasher objectHasher, Supplier systemTimeSupplier) { - this.spec = spec; + this.constants = constants; this.objectHasher = objectHasher; this.hashFunction = hashFunction; this.systemTimeSupplier = systemTimeSupplier; } - public ChainSpec getChainSpec() { - return spec; + public SpecConstants getConstants() { + return constants; } public Hash32 hash(BytesValue data) { @@ -118,11 +118,11 @@ def get_epoch_committee_count(active_validator_count: int) -> int: int get_epoch_committee_count(int active_validator_count) { return UInt64s.max(UInt64.valueOf(1), UInt64s.min( - spec.getShardCount().dividedBy(spec.getSlotsPerEpoch()), + constants.getShardCount().dividedBy(constants.getSlotsPerEpoch()), UInt64.valueOf(active_validator_count) - .dividedBy(spec.getSlotsPerEpoch()) - .dividedBy(spec.getTargetCommitteeSize()) - )).times(spec.getSlotsPerEpoch()).intValue(); + .dividedBy(constants.getSlotsPerEpoch()) + .dividedBy(constants.getTargetCommitteeSize()) + )).times(constants.getSlotsPerEpoch()).intValue(); } @@ -251,7 +251,7 @@ public List get_crosslink_committees_at_slot( shuffling_start_shard = (state.current_shuffling_start_shard + current_committees_per_epoch) % SHARD_COUNT */ seed = generate_seed(state, nextEpoch); shuffling_start_shard = ShardNumber.of(state.getCurrentShufflingStartShard() - .plus(current_committees_per_epoch).modulo(spec.getShardCount())); + .plus(current_committees_per_epoch).modulo(constants.getShardCount())); } else if (epochs_since_last_registry_update.greater(EpochNumber.of(1)) && is_power_of_two(epochs_since_last_registry_update)) { /* @@ -286,10 +286,10 @@ public List get_crosslink_committees_at_slot( offset = slot % SLOTS_PER_EPOCH committees_per_slot = committees_per_epoch // SLOTS_PER_EPOCH slot_start_shard = (shuffling_start_shard + committees_per_slot * offset) % SHARD_COUNT */ - SlotNumber offset = slot.modulo(spec.getSlotsPerEpoch()); - UInt64 committees_per_slot = UInt64.valueOf(committees_per_epoch).dividedBy(spec.getSlotsPerEpoch()); + SlotNumber offset = slot.modulo(constants.getSlotsPerEpoch()); + UInt64 committees_per_slot = UInt64.valueOf(committees_per_epoch).dividedBy(constants.getSlotsPerEpoch()); ShardNumber slot_start_shard = ShardNumber.of( - shuffling_start_shard.plus(committees_per_slot).times(offset).modulo(spec.getShardCount())); + shuffling_start_shard.plus(committees_per_slot).times(offset).modulo(constants.getShardCount())); /* return [ @@ -303,7 +303,7 @@ public List get_crosslink_committees_at_slot( for(int i = 0; i < committees_per_slot.intValue(); i++) { ShardCommittee committee = new ShardCommittee( shuffling.get(committees_per_slot.times(offset).plus(i).getIntValue()), - slot_start_shard.plusModulo(i, spec.getShardCount())); + slot_start_shard.plusModulo(i, constants.getShardCount())); ret.add(committee); } @@ -365,10 +365,10 @@ assert get_current_epoch(state) - LATEST_RANDAO_MIXES_LENGTH < epoch <= get_curr return state.latest_randao_mixes[epoch % LATEST_RANDAO_MIXES_LENGTH] */ public Hash32 get_randao_mix(BeaconState state, EpochNumber epoch) { - assertTrue(get_current_epoch(state).minus(spec.getLatestRandaoMixesLength()).less(epoch)); + assertTrue(get_current_epoch(state).minus(constants.getLatestRandaoMixesLength()).less(epoch)); assertTrue(epoch.lessEqual(get_current_epoch(state))); return state.getLatestRandaoMixes().get( - epoch.modulo(spec.getLatestRandaoMixesLength())); + epoch.modulo(constants.getLatestRandaoMixesLength())); } /* @@ -478,7 +478,7 @@ public UInt64 get_permuted_index(UInt64 index, UInt64 listSize, Bytes32 seed) { assertTrue(index.compareTo(listSize) < 0); assertTrue(listSize.compareTo(UInt64.valueOf(1L << 40)) <= 0); - for (int round = 0; round < spec.getShuffleRoundCount(); round++) { + for (int round = 0; round < constants.getShuffleRoundCount(); round++) { Bytes8 pivotBytes = Bytes8.wrap(hash(seed.concat(int_to_bytes1(round))), 0); UInt64 pivot = bytes_to_int(pivotBytes).modulo(listSize); UInt64 flip = pivot.minus(index).modulo(listSize); @@ -595,7 +595,7 @@ Returns the effective balance (also known as "balance at stake") for a ``validat public Gwei get_effective_balance(BeaconState state, ValidatorIndex validatorIdx) { return UInt64s.min( state.getValidatorBalances().get(validatorIdx), - spec.getMaxDepositAmount()); + constants.getMaxDepositAmount()); } /* @@ -676,7 +676,7 @@ public boolean validate_proof_of_possession( Hash32 withdrawal_credentials) { DepositInput deposit_input = - new DepositInput(pubkey, withdrawal_credentials, spec.getEmptySignature()); + new DepositInput(pubkey, withdrawal_credentials, constants.getEmptySignature()); return bls_verify( pubkey, @@ -740,9 +740,9 @@ public ValidatorIndex process_deposit( ValidatorRecord validator = new ValidatorRecord( pubkey, withdrawal_credentials, - spec.getFarFutureEpoch(), - spec.getFarFutureEpoch(), - spec.getFarFutureEpoch(), + constants.getFarFutureEpoch(), + constants.getFarFutureEpoch(), + constants.getFarFutureEpoch(), Boolean.FALSE, Boolean.FALSE); @@ -778,7 +778,7 @@ def get_delayed_activation_exit_epoch(epoch: EpochNumber) -> EpochNumber: return epoch + 1 + ACTIVATION_EXIT_DELAY */ public EpochNumber get_delayed_activation_exit_epoch(EpochNumber epoch) { - return epoch.plus(1).plus(spec.getActivationExitDelay()); + return epoch.plus(1).plus(constants.getActivationExitDelay()); } /* @@ -798,7 +798,7 @@ def activate_validator(state: BeaconState, index: int, genesis: bool) -> None: */ public void activate_validator(MutableBeaconState state, ValidatorIndex index, boolean genesis) { EpochNumber activationSlot = - genesis ? spec.getGenesisEpoch() : get_delayed_activation_exit_epoch(get_current_epoch(state)); + genesis ? constants.getGenesisEpoch() : get_delayed_activation_exit_epoch(get_current_epoch(state)); state .getValidatorRegistry() .update(index, v -> v.builder().withActivationEpoch(activationSlot).build()); @@ -827,19 +827,19 @@ public void slash_validator(MutableBeaconState state, ValidatorIndex index) { assertTrue(state.getSlot().less(get_epoch_start_slot(validator.getWithdrawableEpoch()))); exit_validator(state, index); state.getLatestSlashedBalances().update( - get_current_epoch(state).modulo(spec.getLatestSlashedExitLength()), + get_current_epoch(state).modulo(constants.getLatestSlashedExitLength()), balance -> balance.plus(get_effective_balance(state, index))); ValidatorIndex whistleblower_index = get_beacon_proposer_index(state, state.getSlot()); Gwei whistleblower_reward = get_effective_balance(state, index) - .dividedBy(spec.getWhistleblowerRewardQuotient()); + .dividedBy(constants.getWhistleblowerRewardQuotient()); state.getValidatorBalances().update(whistleblower_index, oldVal -> oldVal.plus(whistleblower_reward)); state.getValidatorBalances().update(index, oldVal -> oldVal.minus(whistleblower_reward)); state.getValidatorRegistry().update(index, v -> v.builder().withSlashed(Boolean.TRUE) - .withWithdrawableEpoch(get_current_epoch(state).plus(spec.getLatestSlashedExitLength())) + .withWithdrawableEpoch(get_current_epoch(state).plus(constants.getLatestSlashedExitLength())) .build()); } @@ -911,8 +911,8 @@ public void update_validator_registry(MutableBeaconState state) { // MAX_DEPOSIT_AMOUNT, // total_balance // (2 * MAX_BALANCE_CHURN_QUOTIENT) // ) - Gwei max_balance_churn = UInt64s.max(spec.getMaxDepositAmount(), - total_balance.dividedBy(spec.getMaxBalanceChurnQuotient().times(2))); + Gwei max_balance_churn = UInt64s.max(constants.getMaxDepositAmount(), + total_balance.dividedBy(constants.getMaxBalanceChurnQuotient().times(2))); // # Activate validators within the allowable balance churn // balance_churn = 0 @@ -925,7 +925,7 @@ public void update_validator_registry(MutableBeaconState state) { if (validator.getActivationEpoch().greater( get_delayed_activation_exit_epoch(current_epoch)) && state.getValidatorBalances().get(index).greaterEqual( - spec.getMaxDepositAmount())) { + constants.getMaxDepositAmount())) { // # Check the balance churn would be within the allowance // balance_churn += get_effective_balance(state, index) @@ -951,7 +951,7 @@ public void update_validator_registry(MutableBeaconState state) { ValidatorRecord validator = state.getValidatorRegistry().get(index); // if validator.exit_epoch > get_delayed_activation_exit_epoch(current_epoch) // and validator.slashed: - if (validator.getActivationEpoch().equals(spec.getFarFutureEpoch()) + if (validator.getActivationEpoch().equals(constants.getFarFutureEpoch()) && validator.getInitiatedExit()) { // # Check the balance churn would be within the allowance // balance_churn += get_effective_balance(state, index) @@ -990,7 +990,7 @@ public void prepare_validator_for_withdrawal(MutableBeaconState state, Validator v -> v.builder() .withWithdrawableEpoch( - get_current_epoch(state).plus(spec.getMinValidatorWithdrawabilityDelay())) + get_current_epoch(state).plus(constants.getMinValidatorWithdrawabilityDelay())) .build()); } @@ -1019,13 +1019,13 @@ public void process_penalties_and_exits(MutableBeaconState state) { // if validator.slashed and current_epoch == // validator.withdrawable_epoch - LATEST_SLASHED_EXIT_LENGTH // 2: if (validator.getSlashed() && current_epoch.equals( - validator.getWithdrawableEpoch().minus(spec.getLatestSlashedExitLength().half()))) { + validator.getWithdrawableEpoch().minus(constants.getLatestSlashedExitLength().half()))) { // epoch_index = current_epoch % LATEST_SLASHED_EXIT_LENGTH - EpochNumber epoch_index = current_epoch.modulo(spec.getLatestSlashedExitLength()); + EpochNumber epoch_index = current_epoch.modulo(constants.getLatestSlashedExitLength()); // total_at_start = state.latest_slashed_balances[(epoch_index + 1) % LATEST_SLASHED_EXIT_LENGTH] Gwei total_at_start = state.getLatestSlashedBalances().get( - epoch_index.increment().modulo(spec.getLatestSlashedExitLength())); + epoch_index.increment().modulo(constants.getLatestSlashedExitLength())); // total_at_end = state.latest_slashed_balances[epoch_index] Gwei total_at_end = state.getLatestSlashedBalances().get(epoch_index); // total_penalties = total_at_end - total_at_start @@ -1055,11 +1055,11 @@ def eligible(index): List eligible_indices = new ArrayList<>(); for (ValidatorIndex index : state.getValidatorRegistry().size().iterateFromZero()) { ValidatorRecord validator = state.getValidatorRegistry().get(index); - if (validator.getWithdrawableEpoch().equals(spec.getFarFutureEpoch())) { + if (validator.getWithdrawableEpoch().equals(constants.getFarFutureEpoch())) { eligible_indices.add(index); } else { if (get_current_epoch(state).greaterEqual( - validator.getExitEpoch().plus(spec.getMinValidatorWithdrawabilityDelay()))) { + validator.getExitEpoch().plus(constants.getMinValidatorWithdrawabilityDelay()))) { eligible_indices.add(index); } } @@ -1085,7 +1085,7 @@ def eligible(index): withdrawn_so_far++; // if withdrawn_so_far >= MAX_EXIT_DEQUEUES_PER_EPOCH: // break - if (withdrawn_so_far >= spec.getMaxExitDequesPerEpoch().getIntValue()) { + if (withdrawn_so_far >= constants.getMaxExitDequesPerEpoch().getIntValue()) { break; } } @@ -1112,10 +1112,11 @@ assert get_current_epoch(state) - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_ return state.latest_active_index_roots[epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] */ Hash32 get_active_index_root(BeaconState state, EpochNumber epoch) { - assertTrue(get_current_epoch(state).minus(spec.getLatestActiveIndexRootsLength()).plus(spec.getActivationExitDelay()) + assertTrue(get_current_epoch(state).minus(constants.getLatestActiveIndexRootsLength()).plus( + constants.getActivationExitDelay()) .less(epoch)); - assertTrue(epoch.lessEqual(get_current_epoch(state).plus(spec.getActivationExitDelay()))); - return state.getLatestActiveIndexRoots().get(epoch.modulo(spec.getLatestActiveIndexRootsLength())); + assertTrue(epoch.lessEqual(get_current_epoch(state).plus(constants.getActivationExitDelay()))); + return state.getLatestActiveIndexRoots().get(epoch.modulo(constants.getLatestActiveIndexRootsLength())); } /* @@ -1132,7 +1133,7 @@ def generate_seed(state: BeaconState, */ public Hash32 generate_seed(BeaconState state, EpochNumber epoch) { return hash( - get_randao_mix(state, epoch.minus(spec.getMinSeedLookahead())) + get_randao_mix(state, epoch.minus(constants.getMinSeedLookahead())) .concat(get_active_index_root(state, epoch)) .concat(int_to_bytes32(epoch))); } @@ -1283,7 +1284,7 @@ public boolean verify_slashable_attestation(BeaconState state, SlashableAttestat // if len(slashable_attestation.validator_indices) > MAX_INDICES_PER_SLASHABLE_VOTE: // return False if (UInt64.valueOf(slashable_attestation.getValidatorIndices().size()). - compareTo(spec.getMaxIndicesPerSlashableVote()) > 0) { + compareTo(constants.getMaxIndicesPerSlashableVote()) > 0) { return false; } @@ -1379,9 +1380,9 @@ def get_block_root(state: BeaconState, return state.latest_block_roots[slot % LATEST_BLOCK_ROOTS_LENGTH] */ public Hash32 get_block_root(BeaconState state, SlotNumber slot) { - assertTrue(state.getSlot().lessEqual(slot.plus(spec.getLatestBlockRootsLength()))); + assertTrue(state.getSlot().lessEqual(slot.plus(constants.getLatestBlockRootsLength()))); assertTrue(slot.less(state.getSlot())); - return state.getLatestBlockRoots().get(slot.modulo(spec.getLatestBlockRootsLength())); + return state.getLatestBlockRoots().get(slot.modulo(constants.getLatestBlockRootsLength())); } /* @@ -1476,8 +1477,8 @@ public SlotNumber get_current_slot(BeaconState state) { Millis currentTime = Millis.of(systemTimeSupplier.get()); assertTrue(state.getGenesisTime().lessEqual(currentTime.getSeconds())); Time sinceGenesis = currentTime.getSeconds().minus(state.getGenesisTime()); - return SlotNumber.castFrom(sinceGenesis.dividedBy(spec.getSecondsPerSlot())) - .plus(getChainSpec().getGenesisSlot()); + return SlotNumber.castFrom(sinceGenesis.dividedBy(constants.getSecondsPerSlot())) + .plus(getConstants().getGenesisSlot()); } public boolean is_current_slot(BeaconState state) { @@ -1487,11 +1488,11 @@ public boolean is_current_slot(BeaconState state) { public Time get_slot_start_time(BeaconState state, SlotNumber slot) { return state .getGenesisTime() - .plus(spec.getSecondsPerSlot().times(slot.minus(getChainSpec().getGenesisSlot()))); + .plus(constants.getSecondsPerSlot().times(slot.minus(getConstants().getGenesisSlot()))); } public Time get_slot_middle_time(BeaconState state, SlotNumber slot) { - return get_slot_start_time(state, slot).plus(spec.getSecondsPerSlot().dividedBy(2)); + return get_slot_start_time(state, slot).plus(constants.getSecondsPerSlot().dividedBy(2)); } /* @@ -1499,7 +1500,7 @@ def slot_to_epoch(slot: SlotNumber) -> EpochNumber: return slot // SLOTS_PER_EPOCH */ public EpochNumber slot_to_epoch(SlotNumber slot) { - return slot.dividedBy(spec.getSlotsPerEpoch()); + return slot.dividedBy(constants.getSlotsPerEpoch()); } /* @@ -1510,7 +1511,7 @@ def get_previous_epoch(state: BeaconState) -> Epoch: return max(get_current_epoch(state) - 1, GENESIS_EPOCH) */ public EpochNumber get_previous_epoch(BeaconState state) { - return UInt64s.max(get_current_epoch(state).decrement(), spec.getGenesisEpoch()); + return UInt64s.max(get_current_epoch(state).decrement(), constants.getGenesisEpoch()); } /* @@ -1525,11 +1526,11 @@ def get_epoch_start_slot(epoch: EpochNumber) -> SlotNumber: return epoch * SLOTS_PER_EPOCH */ public SlotNumber get_epoch_start_slot(EpochNumber epoch) { - return epoch.mul(spec.getSlotsPerEpoch()); + return epoch.mul(constants.getSlotsPerEpoch()); } public EpochNumber get_genesis_epoch() { - return slot_to_epoch(spec.getGenesisSlot()); + return slot_to_epoch(constants.getGenesisSlot()); } public void checkIndexRange(BeaconState state, ValidatorIndex index) { @@ -1541,7 +1542,7 @@ public void checkIndexRange(BeaconState state, Iterable indices) } public void checkShardRange(ShardNumber shard) { - assertTrue(shard.less(spec.getShardCount())); + assertTrue(shard.less(constants.getShardCount())); } public List mapIndicesToPubKeys(BeaconState state, Iterable indices) { @@ -1678,7 +1679,7 @@ private Optional get_ancestor( } public boolean is_epoch_end(SlotNumber slot) { - return slot.increment().modulo(spec.getSlotsPerEpoch()).equals(SlotNumber.ZERO); + return slot.increment().modulo(constants.getSlotsPerEpoch()).equals(SlotNumber.ZERO); } private static void assertTrue(boolean assertion) { diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java index dcee5c491..b4cc81fbb 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/DelegateBeaconState.java @@ -3,7 +3,7 @@ import javax.annotation.Nullable; import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; @@ -172,7 +172,7 @@ public MutableBeaconState createMutableCopy() { } @Override - public String toStringShort(@Nullable ChainSpec spec) { - return delegate.toStringShort(spec); + public String toStringShort(@Nullable SpecConstants constants) { + return delegate.toStringShort(constants); } } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java index 60eba5b2f..d9061b8b1 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java @@ -15,7 +15,6 @@ import org.ethereum.beacon.core.operations.Deposit; import org.ethereum.beacon.core.operations.deposit.DepositData; import org.ethereum.beacon.core.operations.deposit.DepositInput; -import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.ForkData; import org.ethereum.beacon.core.types.Bitfield64; @@ -43,14 +42,12 @@ public class InitialStateTransition implements BlockTransition { private static final Logger logger = LogManager.getLogger(InitialStateTransition.class); private final DepositContract.ChainStart depositContractStart; - private final ChainSpec chainSpec; - private final SpecHelpers specHelpers; + private final SpecHelpers spec; public InitialStateTransition(DepositContract.ChainStart depositContractStart, - SpecHelpers specHelpers) { + SpecHelpers spec) { this.depositContractStart = depositContractStart; - this.specHelpers = specHelpers; - this.chainSpec = specHelpers.getChainSpec(); + this.spec = spec; } public BeaconStateEx apply(BeaconBlock block) { @@ -59,49 +56,49 @@ public BeaconStateEx apply(BeaconBlock block) { @Override public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { - assert block.getSlot().equals(chainSpec.getGenesisSlot()); + assert block.getSlot().equals(spec.getConstants().getGenesisSlot()); MutableBeaconState initialState = BeaconState.getEmpty().createMutableCopy(); // Misc - initialState.setSlot(chainSpec.getGenesisSlot()); + initialState.setSlot(spec.getConstants().getGenesisSlot()); initialState.setGenesisTime(depositContractStart.getTime()); initialState.setForkData( new ForkData( - chainSpec.getGenesisForkVersion(), - chainSpec.getGenesisForkVersion(), - chainSpec.getGenesisEpoch())); + spec.getConstants().getGenesisForkVersion(), + spec.getConstants().getGenesisForkVersion(), + spec.getConstants().getGenesisEpoch())); // Validator registry initialState.getValidatorRegistry().clear(); initialState.getValidatorBalances().clear(); - initialState.setValidatorRegistryUpdateEpoch(chainSpec.getGenesisEpoch()); + initialState.setValidatorRegistryUpdateEpoch(spec.getConstants().getGenesisEpoch()); // Randomness and committees initialState.getLatestRandaoMixes().addAll( - nCopies(chainSpec.getLatestRandaoMixesLength().getIntValue(), Hash32.ZERO)); - initialState.setPreviousShufflingStartShard(chainSpec.getGenesisStartShard()); - initialState.setCurrentShufflingStartShard(chainSpec.getGenesisStartShard()); - initialState.setPreviousShufflingEpoch(chainSpec.getGenesisEpoch()); - initialState.setCurrentShufflingEpoch(chainSpec.getGenesisEpoch()); + nCopies(spec.getConstants().getLatestRandaoMixesLength().getIntValue(), Hash32.ZERO)); + initialState.setPreviousShufflingStartShard(spec.getConstants().getGenesisStartShard()); + initialState.setCurrentShufflingStartShard(spec.getConstants().getGenesisStartShard()); + initialState.setPreviousShufflingEpoch(spec.getConstants().getGenesisEpoch()); + initialState.setCurrentShufflingEpoch(spec.getConstants().getGenesisEpoch()); initialState.setPreviousShufflingSeed(Hash32.ZERO); initialState.setCurrentShufflingSeed(Hash32.ZERO); // Finality - initialState.setPreviousJustifiedEpoch(chainSpec.getGenesisEpoch()); - initialState.setJustifiedEpoch(chainSpec.getGenesisEpoch()); + initialState.setPreviousJustifiedEpoch(spec.getConstants().getGenesisEpoch()); + initialState.setJustifiedEpoch(spec.getConstants().getGenesisEpoch()); initialState.setJustificationBitfield(Bitfield64.ZERO); - initialState.setFinalizedEpoch(chainSpec.getGenesisEpoch()); + initialState.setFinalizedEpoch(spec.getConstants().getGenesisEpoch()); // Recent state initialState.getLatestCrosslinks().addAll( - nCopies(chainSpec.getShardCount().getIntValue(), Crosslink.EMPTY)); + nCopies(spec.getConstants().getShardCount().getIntValue(), Crosslink.EMPTY)); initialState.getLatestBlockRoots().addAll( - nCopies(chainSpec.getLatestBlockRootsLength().getIntValue(), Hash32.ZERO)); + nCopies(spec.getConstants().getLatestBlockRootsLength().getIntValue(), Hash32.ZERO)); initialState.getLatestActiveIndexRoots().addAll( - nCopies(chainSpec.getLatestActiveIndexRootsLength().getIntValue(), Hash32.ZERO)); + nCopies(spec.getConstants().getLatestActiveIndexRootsLength().getIntValue(), Hash32.ZERO)); initialState.getLatestSlashedBalances().addAll( - nCopies(chainSpec.getLatestSlashedExitLength().getIntValue(), Gwei.ZERO)); + nCopies(spec.getConstants().getLatestSlashedExitLength().getIntValue(), Gwei.ZERO)); initialState.getLatestAttestations().clear(); initialState.getBatchedBlockRoots().clear(); @@ -117,7 +114,7 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { deposit -> { DepositData depositData = deposit.getDepositData(); DepositInput depositInput = depositData.getDepositInput(); - ValidatorIndex index = specHelpers.process_deposit(initialState, + ValidatorIndex index = spec.process_deposit(initialState, depositInput.getPubKey(), depositData.getAmount(), depositInput.getProofOfPossession(), @@ -128,32 +125,32 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { for (ValidatorIndex validatorIndex : initialState.getValidatorRegistry().size().iterateFromZero()) { - Gwei balance = specHelpers.get_effective_balance(initialState, validatorIndex); + Gwei balance = spec.get_effective_balance(initialState, validatorIndex); - if (balance.greaterEqual(chainSpec.getMaxDepositAmount())) { - specHelpers.activate_validator(initialState, validatorIndex, true); + if (balance.greaterEqual(spec.getConstants().getMaxDepositAmount())) { + spec.activate_validator(initialState, validatorIndex, true); } } - Hash32 genesis_active_index_root = specHelpers.hash_tree_root( - specHelpers.get_active_validator_indices( - initialState.getValidatorRegistry(), chainSpec.getGenesisEpoch())); + Hash32 genesis_active_index_root = spec.hash_tree_root( + spec.get_active_validator_indices( + initialState.getValidatorRegistry(), spec.getConstants().getGenesisEpoch())); - for (EpochNumber index : chainSpec.getLatestActiveIndexRootsLength().iterateFromZero()) { + for (EpochNumber index : spec.getConstants().getLatestActiveIndexRootsLength().iterateFromZero()) { initialState.getLatestActiveIndexRoots().set(index, genesis_active_index_root); } initialState.setCurrentShufflingSeed( - specHelpers.generate_seed(initialState, chainSpec.getGenesisEpoch())); + spec.generate_seed(initialState, spec.getConstants().getGenesisEpoch())); BeaconState validatorsState = initialState.createImmutable(); - BeaconBlock genesisBlock = block.withStateRoot(specHelpers.hash_tree_root(validatorsState)); + BeaconBlock genesisBlock = block.withStateRoot(spec.hash_tree_root(validatorsState)); BeaconStateExImpl ret = new BeaconStateExImpl( - validatorsState, specHelpers.hash_tree_root(genesisBlock), TransitionType.INITIAL); + validatorsState, spec.hash_tree_root(genesisBlock), TransitionType.INITIAL); logger.debug(() -> "Slot transition result state: (" + - specHelpers.hash_tree_root(ret).toStringShort() + ") " + ret.toString(chainSpec)); + spec.hash_tree_root(ret).toStringShort() + ") " + ret.toString(spec.getConstants())); return ret; } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java index 5fbdf89bb..cc31c906e 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java @@ -15,7 +15,6 @@ import org.ethereum.beacon.core.operations.deposit.DepositData; import org.ethereum.beacon.core.operations.deposit.DepositInput; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; -import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.PendingAttestationRecord; import org.ethereum.beacon.core.types.ValidatorIndex; @@ -34,20 +33,18 @@ public class PerBlockTransition implements BlockTransition { private static final Logger logger = LogManager.getLogger(PerBlockTransition.class); - private final ChainSpec spec; - private final SpecHelpers specHelpers; + private final SpecHelpers spec; - public PerBlockTransition(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; - this.spec = specHelpers.getChainSpec(); + public PerBlockTransition(SpecHelpers spec) { + this.spec = spec; } @Override public BeaconStateEx apply(BeaconStateEx stateEx, BeaconBlock block) { logger.trace(() -> "Applying block transition to state: (" + - specHelpers.hash_tree_root(stateEx).toStringShort() + ") " - + stateEx.toString(spec) + ", Block: " - + block.toString(spec, stateEx.getGenesisTime(), specHelpers::hash_tree_root)); + spec.hash_tree_root(stateEx).toStringShort() + ") " + + stateEx.toString(spec.getConstants()) + ", Block: " + + block.toString(spec.getConstants(), stateEx.getGenesisTime(), spec::hash_tree_root)); TransitionType.BLOCK.checkCanBeAppliedAfter(stateEx.getTransition()); @@ -59,10 +56,10 @@ public BeaconStateEx apply(BeaconStateEx stateEx, BeaconBlock block) { xor(get_randao_mix(state, get_current_epoch(state)), hash(block.randao_reveal)). */ state.getLatestRandaoMixes().update( - specHelpers.get_current_epoch(state).modulo(spec.getLatestRandaoMixesLength()), + spec.get_current_epoch(state).modulo(spec.getConstants().getLatestRandaoMixesLength()), rm -> Hash32.wrap(Bytes32s.xor( - specHelpers.get_randao_mix(state, specHelpers.get_current_epoch(state)), - specHelpers.hash(block.getRandaoReveal())))); + spec.get_randao_mix(state, spec.get_current_epoch(state)), + spec.hash(block.getRandaoReveal())))); /* Eth1 data @@ -91,7 +88,7 @@ a new Eth1DataVote(eth1_data=block.eth1_data, vote_count=1). Run slash_validator(state, proposer_slashing.proposer_index). */ for (ProposerSlashing proposer_slashing : block.getBody().getProposerSlashings()) { - specHelpers.slash_validator(state, proposer_slashing.getProposerIndex()); + spec.slash_validator(state, proposer_slashing.getProposerIndex()); } /* @@ -109,7 +106,7 @@ Run slash_validator(state, index) for each index in slashable_indices. attester_slashing.getSlashableAttestation2().getValidatorIndices()); for (ValidatorIndex index : intersection) { if (!state.getValidatorRegistry().get(index).getSlashed()) { - specHelpers.slash_validator(state, index); + spec.slash_validator(state, index); } } } @@ -152,7 +149,7 @@ Append PendingAttestationRecord( for (Deposit deposit : block.getBody().getDeposits()) { DepositData depositData = deposit.getDepositData(); DepositInput depositInput = depositData.getDepositInput(); - specHelpers.process_deposit(state, + spec.process_deposit(state, depositInput.getPubKey(), depositData.getAmount(), depositInput.getProofOfPossession(), @@ -167,14 +164,14 @@ Append PendingAttestationRecord( Run initiate_validator_exit(state, exit.validator_index). */ for (VoluntaryExit voluntaryExit : block.getBody().getExits()) { - specHelpers.initiate_validator_exit(state, voluntaryExit.getValidatorIndex()); + spec.initiate_validator_exit(state, voluntaryExit.getValidatorIndex()); } BeaconStateEx ret = new BeaconStateExImpl(state.createImmutable(), - specHelpers.hash_tree_root(block), TransitionType.BLOCK); + spec.hash_tree_root(block), TransitionType.BLOCK); logger.trace(() -> "Block transition result state: (" + - specHelpers.hash_tree_root(ret).toStringShort() + ") " + ret.toString(spec)); + spec.hash_tree_root(ret).toStringShort() + ") " + ret.toString(spec.getConstants())); return ret; } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java index 70bb5481f..7da923d45 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java @@ -18,7 +18,7 @@ import org.ethereum.beacon.consensus.StateTransition; import org.ethereum.beacon.consensus.TransitionType; import org.ethereum.beacon.core.MutableBeaconState; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.PendingAttestationRecord; @@ -43,12 +43,10 @@ public class PerEpochTransition implements StateTransition { private static final Logger logger = LogManager.getLogger(PerEpochTransition.class); - private final ChainSpec specConst; private final SpecHelpers spec; - public PerEpochTransition(SpecHelpers specHelpers) { - this.spec = specHelpers; - this.specConst = specHelpers.getChainSpec(); + public PerEpochTransition(SpecHelpers spec) { + this.spec = spec; } @Override @@ -64,7 +62,8 @@ public EpochTransitionSummary applyWithSummary(BeaconStateEx stateEx) { private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summary) { logger.debug(() -> "Applying epoch transition to state: (" + - spec.hash_tree_root(origState).toStringShort() + ") " + origState.toString(specConst)); + spec.hash_tree_root(origState).toStringShort() + ") " + + origState.toString(spec.getConstants())); TransitionType.EPOCH.checkCanBeAppliedAfter(origState.getTransition()); @@ -382,10 +381,10 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ set state.latest_eth1_data = eth1_data_vote.eth1_data. Set state.eth1_data_votes = []. */ - if (next_epoch.modulo(specConst.getEth1DataVotingPeriod()).equals(EpochNumber.ZERO)) { + if (next_epoch.modulo(spec.getConstants().getEth1DataVotingPeriod()).equals(EpochNumber.ZERO)) { for (Eth1DataVote eth1_data_vote : state.getEth1DataVotes()) { if (SlotNumber.castFrom(eth1_data_vote.getVoteCount().times(2)) - .greater(specConst.getEth1DataVotingPeriod().mul(specConst.getSlotsPerEpoch()))) { + .greater(spec.getConstants().getEth1DataVotingPeriod().mul(spec.getConstants().getSlotsPerEpoch()))) { state.setLatestEth1Data(eth1_data_vote.getEth1Data()); logger.debug(() -> "Latest Eth1Data changed to " + state.getLatestEth1Data()); break; @@ -509,7 +508,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // integer_squareroot(previous_total_balance) // BASE_REWARD_QUOTIENT. Gwei base_reward_quotient = Gwei.castFrom( spec.integer_squareroot(previous_total_balance) - .dividedBy(specConst.getBaseRewardQuotient())); + .dividedBy(spec.getConstants().getBaseRewardQuotient())); // Let base_reward(state, index) = get_effective_balance(state, index) // // base_reward_quotient // 5 for any validator with the given index @@ -526,7 +525,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: base_reward.apply(index).plus( spec.get_effective_balance(state, index) .times(epochs_since_finality) - .dividedBy(specConst.getInactivityPenaltyQuotient()) + .dividedBy(spec.getConstants().getInactivityPenaltyQuotient()) .dividedBy(2)); /* @@ -673,7 +672,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // inclusion_distance(state, index) for (ValidatorIndex index : previous_epoch_attester_indices) { Gwei reward = base_reward.apply(index) - .times(specConst.getMinAttestationInclusionDelay()) + .times(spec.getConstants().getMinAttestationInclusionDelay()) .dividedBy(inclusion_distance.get(index)); state.getValidatorBalances().update(index, balance -> balance.plus(reward)); if (summary != null) { @@ -771,7 +770,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: Gwei penalty = base_reward.apply(index) .minus( base_reward.apply(index) - .times(specConst.getMinAttestationInclusionDelay()) + .times(spec.getConstants().getMinAttestationInclusionDelay()) .dividedBy(inclusion_distance.get(index))); state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); if (summary != null) { @@ -795,7 +794,7 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: for (ValidatorIndex index : previous_epoch_attester_indices) { ValidatorIndex proposer_index = spec .get_beacon_proposer_index(state, inclusion_slot.get(index)); - Gwei reward = base_reward.apply(index).dividedBy(specConst.getAttestationInclusionRewardQuotient()); + Gwei reward = base_reward.apply(index).dividedBy(spec.getConstants().getAttestationInclusionRewardQuotient()); state.getValidatorBalances().update(proposer_index, balance -> balance.plus(reward)); attestation_inclusion_gainers.add(proposer_index); @@ -866,7 +865,7 @@ def process_ejections(state: BeaconState) -> None: Set exit_validators = new HashSet<>(); for (ValidatorIndex index : spec.get_active_validator_indices( state.getValidatorRegistry(), current_epoch)) { - if (state.getValidatorBalances().get(index).less(specConst.getEjectionBalance())) { + if (state.getValidatorBalances().get(index).less(spec.getConstants().getEjectionBalance())) { spec.exit_validator(state, index); exit_validators.add(index); if (summary != null) { @@ -905,7 +904,7 @@ def process_ejections(state: BeaconState) -> None: state.getFinalizedEpoch().greater(state.getValidatorRegistryUpdateEpoch()); for (int i = 0; i < spec.get_current_epoch_committee_count(state); i++) { - ShardNumber shard = state.getCurrentShufflingStartShard().plusModulo(i, specConst.getShardCount()); + ShardNumber shard = state.getCurrentShufflingStartShard().plusModulo(i, spec.getConstants().getShardCount()); if (!state.getLatestCrosslinks().get(shard).getEpoch().greater( state.getValidatorRegistryUpdateEpoch())) { updateRegistry = false; @@ -921,7 +920,7 @@ def process_ejections(state: BeaconState) -> None: // Set state.current_shuffling_start_shard = (state.current_shuffling_start_shard + // get_current_epoch_committee_count(state)) % SHARD_COUNT state.setCurrentShufflingStartShard(state.getCurrentShufflingStartShard().plusModulo( - spec.get_current_epoch_committee_count(state), specConst.getShardCount())); + spec.get_current_epoch_committee_count(state), spec.getConstants().getShardCount())); // Set state.current_shuffling_seed = generate_seed(state, state.current_shuffling_epoch) state.setCurrentShufflingSeed(spec.generate_seed(state, state.getCurrentShufflingEpoch())); @@ -953,17 +952,17 @@ def process_ejections(state: BeaconState) -> None: // Set state.latest_active_index_roots[(next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] = // hash_tree_root(get_active_validator_indices(state, next_epoch + ACTIVATION_EXIT_DELAY)). state.getLatestActiveIndexRoots().set( - next_epoch.plus(specConst.getActivationExitDelay()).modulo(specConst.getLatestActiveIndexRootsLength()), + next_epoch.plus(spec.getConstants().getActivationExitDelay()).modulo(spec.getConstants().getLatestActiveIndexRootsLength()), spec.hash_tree_root(spec.get_active_validator_indices(state.getValidatorRegistry(), - next_epoch.plus(specConst.getActivationExitDelay())))); + next_epoch.plus(spec.getConstants().getActivationExitDelay())))); // Set state.latest_slashed_balances[(next_epoch) % LATEST_SLASHED_EXIT_LENGTH] = // state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH]. - state.getLatestSlashedBalances().set(next_epoch.modulo(specConst.getLatestSlashedExitLength()), + state.getLatestSlashedBalances().set(next_epoch.modulo(spec.getConstants().getLatestSlashedExitLength()), state.getLatestSlashedBalances().get( - current_epoch.modulo(specConst.getLatestSlashedExitLength()))); + current_epoch.modulo(spec.getConstants().getLatestSlashedExitLength()))); // Set state.latest_randao_mixes[next_epoch % LATEST_RANDAO_MIXES_LENGTH] = // get_randao_mix(state, current_epoch). - state.getLatestRandaoMixes().set(next_epoch.modulo(specConst.getLatestRandaoMixesLength()), + state.getLatestRandaoMixes().set(next_epoch.modulo(spec.getConstants().getLatestRandaoMixesLength()), spec.get_randao_mix(state, current_epoch)); // Remove any attestation in state.latest_attestations such that // slot_to_epoch(attestation.data.slot) < current_epoch. @@ -978,7 +977,7 @@ def process_ejections(state: BeaconState) -> None: } logger.debug(() -> "Epoch transition result state: (" + - spec.hash_tree_root(ret).toStringShort() + ") " + ret.toString(specConst)); + spec.hash_tree_root(ret).toStringShort() + ") " + ret.toString(spec.getConstants())); return ret; } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerSlotTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerSlotTransition.java index 074bc2c3d..4f97051d9 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerSlotTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerSlotTransition.java @@ -7,7 +7,6 @@ import org.ethereum.beacon.consensus.StateTransition; import org.ethereum.beacon.consensus.TransitionType; import org.ethereum.beacon.core.MutableBeaconState; -import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.types.SlotNumber; /** @@ -20,18 +19,16 @@ public class PerSlotTransition implements StateTransition { private static final Logger logger = LogManager.getLogger(PerSlotTransition.class); - private final SpecHelpers specHelpers; - private final ChainSpec spec; + private final SpecHelpers spec; - public PerSlotTransition(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; - this.spec = specHelpers.getChainSpec(); + public PerSlotTransition(SpecHelpers spec) { + this.spec = spec; } @Override public BeaconStateEx apply(BeaconStateEx stateEx) { logger.trace(() -> "Applying slot transition to state: (" + - specHelpers.hash_tree_root(stateEx).toStringShort() + ") " + stateEx.toString(spec)); + spec.hash_tree_root(stateEx).toStringShort() + ") " + stateEx.toString(spec.getConstants())); TransitionType.SLOT.checkCanBeAppliedAfter(stateEx.getTransition()); MutableBeaconState state = stateEx.createMutableCopy(); @@ -42,13 +39,13 @@ public BeaconStateEx apply(BeaconStateEx stateEx) { // Set state.latest_block_roots[(state.slot - 1) % LATEST_BLOCK_ROOTS_LENGTH] = previous_block_root. state.getLatestBlockRoots().set( - state.getSlot().decrement().modulo(spec.getLatestBlockRootsLength()), + state.getSlot().decrement().modulo(spec.getConstants().getLatestBlockRootsLength()), stateEx.getHeadBlockHash()); // If state.slot % LATEST_BLOCK_ROOTS_LENGTH == 0 // append merkle_root(state.latest_block_roots) to state.batched_block_roots - if (state.getSlot().modulo(spec.getLatestBlockRootsLength()).getIntValue() == 0) { - state.getBatchedBlockRoots().add(specHelpers.merkle_root(state.getLatestBlockRoots())); + if (state.getSlot().modulo(spec.getConstants().getLatestBlockRootsLength()).getIntValue() == 0) { + state.getBatchedBlockRoots().add(spec.merkle_root(state.getLatestBlockRoots())); } BeaconStateEx ret = @@ -56,7 +53,7 @@ public BeaconStateEx apply(BeaconStateEx stateEx) { state.createImmutable(), stateEx.getHeadBlockHash(), TransitionType.SLOT); logger.trace(() -> "Slot transition result state: (" + - specHelpers.hash_tree_root(ret).toStringShort() + ") " + ret.toString(spec)); + spec.hash_tree_root(ret).toStringShort() + ") " + ret.toString(spec.getConstants())); return ret; } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java index 645bbaac9..1eccb46cd 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java @@ -21,10 +21,10 @@ static BeaconBlockVerifier createDefault(SpecHelpers specHelpers) { return CompositeBlockVerifier.Builder.createNew() .with(new RandaoVerifier(specHelpers)) .with(new ProposerSignatureVerifier(specHelpers)) - .with(new AttestationListVerifier(new AttestationVerifier(specHelpers), specHelpers.getChainSpec())) - .with(new DepositListVerifier(new DepositVerifier(specHelpers), specHelpers.getChainSpec())) - .with(new ExitListVerifier(new ExitVerifier(specHelpers), specHelpers.getChainSpec())) - .with(new ProposerSlashingListVerifier(new ProposerSlashingVerifier(specHelpers), specHelpers.getChainSpec())) + .with(new AttestationListVerifier(new AttestationVerifier(specHelpers), specHelpers.getConstants())) + .with(new DepositListVerifier(new DepositVerifier(specHelpers), specHelpers.getConstants())) + .with(new ExitListVerifier(new ExitVerifier(specHelpers), specHelpers.getConstants())) + .with(new ProposerSlashingListVerifier(new ProposerSlashingVerifier(specHelpers), specHelpers.getConstants())) .build(); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconStateRootMatcher.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconStateRootMatcher.java index f66b26908..dd8a7eff0 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconStateRootMatcher.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconStateRootMatcher.java @@ -11,20 +11,20 @@ */ public class BeaconStateRootMatcher implements BeaconStateVerifier { - private final SpecHelpers specHelpers; + private final SpecHelpers spec; - public BeaconStateRootMatcher(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; + public BeaconStateRootMatcher(SpecHelpers spec) { + this.spec = spec; } @Override public VerificationResult verify(BeaconState state, BeaconBlock block) { - if (block.getStateRoot().equals(specHelpers.hash_tree_root(state))) { + if (block.getStateRoot().equals(spec.hash_tree_root(state))) { return VerificationResult.PASSED; } else { return VerificationResult.failedResult( "State root doesn't match, expected %s but got %s", - block.getStateRoot(), specHelpers.hash_tree_root(state)); + block.getStateRoot(), spec.hash_tree_root(state)); } } } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/AttestationListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/AttestationListVerifier.java index 185b54fd4..aea847fd9 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/AttestationListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/AttestationListVerifier.java @@ -2,7 +2,7 @@ import org.ethereum.beacon.consensus.verifier.OperationVerifier; import org.ethereum.beacon.core.operations.Attestation; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; /** * Verifies attestation list. @@ -12,11 +12,11 @@ public class AttestationListVerifier extends OperationListVerifier { public AttestationListVerifier( - OperationVerifier operationVerifier, ChainSpec chainSpec) { + OperationVerifier operationVerifier, SpecConstants specConstants) { super( operationVerifier, block -> block.getBody().getAttestations(), - chainSpec.getMaxAttestations()); + specConstants.getMaxAttestations()); } @Override diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/DepositListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/DepositListVerifier.java index 32cb514a5..65f4b09c6 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/DepositListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/DepositListVerifier.java @@ -5,7 +5,7 @@ import org.ethereum.beacon.consensus.verifier.OperationVerifier; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import tech.pegasys.artemis.util.collections.ReadList; import tech.pegasys.artemis.util.uint.UInt64; @@ -16,8 +16,8 @@ */ public class DepositListVerifier extends OperationListVerifier { - public DepositListVerifier(OperationVerifier operationVerifier, ChainSpec chainSpec) { - super(operationVerifier, block -> block.getBody().getDeposits(), chainSpec.getMaxDeposits()); + public DepositListVerifier(OperationVerifier operationVerifier, SpecConstants specConstants) { + super(operationVerifier, block -> block.getBody().getDeposits(), specConstants.getMaxDeposits()); addCustomVerifier( (deposits, state) -> { diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java index afcf35406..12428b797 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java @@ -2,7 +2,7 @@ import org.ethereum.beacon.consensus.verifier.OperationVerifier; import org.ethereum.beacon.core.operations.VoluntaryExit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; /** * Verifies exit operation list. @@ -11,8 +11,8 @@ */ public class ExitListVerifier extends OperationListVerifier { - public ExitListVerifier(OperationVerifier operationVerifier, ChainSpec chainSpec) { - super(operationVerifier, block -> block.getBody().getExits(), chainSpec.getMaxVoluntaryExits()); + public ExitListVerifier(OperationVerifier operationVerifier, SpecConstants specConstants) { + super(operationVerifier, block -> block.getBody().getExits(), specConstants.getMaxVoluntaryExits()); } @Override diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSignatureVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSignatureVerifier.java index 3b3aa9904..16024bdab 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSignatureVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSignatureVerifier.java @@ -6,7 +6,6 @@ import org.ethereum.beacon.core.BeaconBlock; import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.operations.slashing.Proposal; -import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.ValidatorIndex; import tech.pegasys.artemis.ethereum.core.Hash32; @@ -23,12 +22,10 @@ */ public class ProposerSignatureVerifier implements BeaconBlockVerifier { - private ChainSpec chainSpec; - private SpecHelpers specHelpers; + private SpecHelpers spec; - public ProposerSignatureVerifier(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; - this.chainSpec = specHelpers.getChainSpec(); + public ProposerSignatureVerifier(SpecHelpers spec) { + this.spec = spec; } @Override @@ -39,22 +36,22 @@ public VerificationResult verify(BeaconBlock block, BeaconState state) { Proposal proposal = new Proposal( state.getSlot(), - chainSpec.getBeaconChainShardNumber(), - specHelpers.signed_root(block, "signature"), + spec.getConstants().getBeaconChainShardNumber(), + spec.signed_root(block, "signature"), block.getSignature()); - Hash32 proposalRoot = specHelpers.signed_root(proposal, "signature"); + Hash32 proposalRoot = spec.signed_root(proposal, "signature"); // Verify that bls_verify( // pubkey=state.validator_registry[get_beacon_proposer_index(state, state.slot)].pubkey, // message=proposal_root, // signature=block.signature, // domain=get_domain(state.fork, get_current_epoch(state), DOMAIN_PROPOSAL)). - ValidatorIndex proposerIndex = specHelpers.get_beacon_proposer_index(state, state.getSlot()); + ValidatorIndex proposerIndex = spec.get_beacon_proposer_index(state, state.getSlot()); BLSPubkey publicKey = state.getValidatorRegistry().get(proposerIndex).getPubKey(); Bytes8 domain = - specHelpers.get_domain(state.getForkData(), specHelpers.get_current_epoch(state), PROPOSAL); + spec.get_domain(state.getForkData(), spec.get_current_epoch(state), PROPOSAL); - if (specHelpers.bls_verify(publicKey, proposalRoot, proposal.getSignature(), domain)) { + if (spec.bls_verify(publicKey, proposalRoot, proposal.getSignature(), domain)) { return VerificationResult.PASSED; } else { return VerificationResult.failedResult( diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSlashingListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSlashingListVerifier.java index 6b9fd6b4e..00f140fd1 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSlashingListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSlashingListVerifier.java @@ -2,7 +2,7 @@ import org.ethereum.beacon.consensus.verifier.OperationVerifier; import org.ethereum.beacon.core.operations.ProposerSlashing; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; /** * Verifies proposer slashing list. @@ -12,11 +12,11 @@ public class ProposerSlashingListVerifier extends OperationListVerifier { public ProposerSlashingListVerifier( - OperationVerifier operationVerifier, ChainSpec chainSpec) { + OperationVerifier operationVerifier, SpecConstants specConstants) { super( operationVerifier, block -> block.getBody().getProposerSlashings(), - chainSpec.getMaxProposerSlashings()); + specConstants.getMaxProposerSlashings()); } @Override diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/RandaoVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/RandaoVerifier.java index 52884cc8d..5131aabff 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/RandaoVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/RandaoVerifier.java @@ -20,10 +20,10 @@ */ public class RandaoVerifier implements BeaconBlockVerifier { - private SpecHelpers specHelpers; + private SpecHelpers spec; - public RandaoVerifier(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; + public RandaoVerifier(SpecHelpers spec) { + this.spec = spec; } @Override @@ -32,18 +32,18 @@ public VerificationResult verify(BeaconBlock block, BeaconState state) { ValidatorRecord proposer = state .getValidatorRegistry() - .get(specHelpers.get_beacon_proposer_index(state, state.getSlot())); + .get(spec.get_beacon_proposer_index(state, state.getSlot())); /* Verify that bls_verify(pubkey=proposer.pubkey, message=int_to_bytes32(get_current_epoch(state)), signature=block.randao_reveal, domain=get_domain(state.fork, get_current_epoch(state), DOMAIN_RANDAO)) */ - if (!specHelpers.bls_verify( + if (!spec.bls_verify( proposer.getPubKey(), - Hash32.wrap(Bytes32.leftPad(specHelpers.get_current_epoch(state).toBytesBigEndian())), + Hash32.wrap(Bytes32.leftPad(spec.get_current_epoch(state).toBytesBigEndian())), block.getRandaoReveal(), - specHelpers.get_domain(state.getForkData(), specHelpers.get_current_epoch(state), RANDAO))) { + spec.get_domain(state.getForkData(), spec.get_current_epoch(state), RANDAO))) { return VerificationResult.failedResult("RANDAO reveal verification failed"); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java index 7c3bd813e..3472852b1 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java @@ -15,7 +15,6 @@ import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; -import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.state.ShardCommittee; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.ValidatorIndex; @@ -32,32 +31,30 @@ */ public class AttestationVerifier implements OperationVerifier { - private ChainSpec chainSpec; - private SpecHelpers specHelpers; + private SpecHelpers spec; - public AttestationVerifier(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; - this.chainSpec = specHelpers.getChainSpec(); + public AttestationVerifier(SpecHelpers spec) { + this.spec = spec; } @Override public VerificationResult verify(Attestation attestation, BeaconState state) { AttestationData data = attestation.getData(); - specHelpers.checkShardRange(data.getShard()); + spec.checkShardRange(data.getShard()); // Verify that attestation.data.slot <= state.slot - MIN_ATTESTATION_INCLUSION_DELAY // < attestation.data.slot + SLOTS_PER_EPOCH if (!(data.getSlot() - .lessEqual(state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay())) + .lessEqual(state.getSlot().minus(spec.getConstants().getMinAttestationInclusionDelay())) && state .getSlot() - .minus(chainSpec.getMinAttestationInclusionDelay()) - .less(data.getSlot().plus(chainSpec.getSlotsPerEpoch())))) { + .minus(spec.getConstants().getMinAttestationInclusionDelay()) + .less(data.getSlot().plus(spec.getConstants().getSlotsPerEpoch())))) { return failedResult( "MIN_ATTESTATION_INCLUSION_DELAY violated, inclusion slot starts from %s but got %s", - data.getSlot().plus(chainSpec.getMinAttestationInclusionDelay()), state.getSlot()); + data.getSlot().plus(spec.getConstants().getMinAttestationInclusionDelay()), state.getSlot()); } // Verify that attestation.data.justified_epoch is equal to @@ -65,7 +62,7 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { // if slot_to_epoch(attestation.data.slot + 1) >= get_current_epoch(state) // else state.previous_justified_epoch. if (!data.getJustifiedEpoch().equals( - specHelpers.slot_to_epoch(data.getSlot().increment()).greaterEqual(specHelpers.get_current_epoch(state)) ? + spec.slot_to_epoch(data.getSlot().increment()).greaterEqual(spec.get_current_epoch(state)) ? state.getJustifiedEpoch() : state.getPreviousJustifiedEpoch())) { return failedResult( "Attestation.data.justified_epoch is invalid"); @@ -73,8 +70,8 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { // Verify that attestation.data.justified_block_root is equal to // get_block_root(state, get_epoch_start_slot(attestation.data.justified_epoch)) - Hash32 blockRootAtJustifiedSlot = specHelpers.get_block_root(state, - specHelpers.get_epoch_start_slot(data.getJustifiedEpoch())); + Hash32 blockRootAtJustifiedSlot = spec.get_block_root(state, + spec.get_epoch_start_slot(data.getJustifiedEpoch())); if (!data.getJustifiedBlockRoot().equals(blockRootAtJustifiedSlot)) { return failedResult( "attestation_data.justified_block_root must be equal to block_root at state.justified_slot, " @@ -110,7 +107,7 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { // committee for committee, shard in get_crosslink_committees_at_slot(state, attestation.data.slot) // if shard == attestation.data.shard // ][0] - Optional crosslink_committee_opt = specHelpers + Optional crosslink_committee_opt = spec .get_crosslink_committees_at_slot(state, data.getSlot()).stream() .filter(c -> c.getShard().equals(data.getShard())) .findFirst(); @@ -132,11 +129,11 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { // participants = get_attestation_participants(state, attestation.data, attestation.aggregation_bitfield) List participants = - specHelpers.get_attestation_participants(state, data, attestation.getAggregationBitfield()); + spec.get_attestation_participants(state, data, attestation.getAggregationBitfield()); // custody_bit_1_participants = get_attestation_participants(state, attestation.data, attestation.custody_bitfield) List custody_bit_1_participants = - specHelpers.get_attestation_participants(state, data, attestation.getCustodyBitfield()); + spec.get_attestation_participants(state, data, attestation.getCustodyBitfield()); // custody_bit_0_participants = [i in participants for i not in custody_bit_1_participants] List custody_bit_0_participants = participants.stream() .filter(i -> !custody_bit_1_participants.contains(i)).collect(Collectors.toList()); @@ -153,17 +150,17 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { // signature=attestation.aggregate_signature, // domain=get_domain(state.fork, slot_to_epoch(attestation.data.slot), DOMAIN_ATTESTATION), // ) - List pubKeys1 = specHelpers.mapIndicesToPubKeys(state, custody_bit_0_participants); - PublicKey groupPublicKey1 = specHelpers.bls_aggregate_pubkeys(pubKeys1); - List pubKeys2 = specHelpers.mapIndicesToPubKeys(state, custody_bit_1_participants); - PublicKey groupPublicKey2 = specHelpers.bls_aggregate_pubkeys(pubKeys2); - if (!specHelpers.bls_verify_multiple( + List pubKeys1 = spec.mapIndicesToPubKeys(state, custody_bit_0_participants); + PublicKey groupPublicKey1 = spec.bls_aggregate_pubkeys(pubKeys1); + List pubKeys2 = spec.mapIndicesToPubKeys(state, custody_bit_1_participants); + PublicKey groupPublicKey2 = spec.bls_aggregate_pubkeys(pubKeys2); + if (!spec.bls_verify_multiple( Arrays.asList(groupPublicKey1, groupPublicKey2), Arrays.asList( - specHelpers.hash_tree_root(new AttestationDataAndCustodyBit(data, false)), - specHelpers.hash_tree_root(new AttestationDataAndCustodyBit(data, true))), + spec.hash_tree_root(new AttestationDataAndCustodyBit(data, false)), + spec.hash_tree_root(new AttestationDataAndCustodyBit(data, true))), attestation.getAggregateSignature(), - specHelpers.get_domain(state.getForkData(), specHelpers.slot_to_epoch(data.getSlot()), ATTESTATION))) { + spec.get_domain(state.getForkData(), spec.slot_to_epoch(data.getSlot()), ATTESTATION))) { return failedResult("failed to verify aggregated signature"); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttesterSlashingVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttesterSlashingVerifier.java index ef3885025..83082d296 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttesterSlashingVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttesterSlashingVerifier.java @@ -22,10 +22,10 @@ */ public class AttesterSlashingVerifier implements OperationVerifier { - private SpecHelpers specHelpers; + private SpecHelpers spec; - public AttesterSlashingVerifier(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; + public AttesterSlashingVerifier(SpecHelpers spec) { + this.spec = spec; } @Override @@ -33,26 +33,26 @@ public VerificationResult verify(AttesterSlashing attesterSlashing, BeaconState SlashableAttestation slashableAttestation1 = attesterSlashing.getSlashableAttestation1(); SlashableAttestation slashableAttestation2 = attesterSlashing.getSlashableAttestation2(); - specHelpers.checkIndexRange(state, slashableAttestation1.getValidatorIndices()); - specHelpers.checkIndexRange(state, slashableAttestation2.getValidatorIndices()); - specHelpers.checkShardRange(slashableAttestation1.getData().getShard()); - specHelpers.checkShardRange(slashableAttestation2.getData().getShard()); + spec.checkIndexRange(state, slashableAttestation1.getValidatorIndices()); + spec.checkIndexRange(state, slashableAttestation2.getValidatorIndices()); + spec.checkShardRange(slashableAttestation1.getData().getShard()); + spec.checkShardRange(slashableAttestation2.getData().getShard()); if (slashableAttestation1.getData().equals(slashableAttestation2.getData())) { return failedResult("slashable_vote_data_1 != slashable_vote_data_2"); } - if (!(specHelpers.is_double_vote(slashableAttestation1.getData(), slashableAttestation2.getData()) - || specHelpers.is_surround_vote( + if (!(spec.is_double_vote(slashableAttestation1.getData(), slashableAttestation2.getData()) + || spec.is_surround_vote( slashableAttestation1.getData(), slashableAttestation2.getData()))) { return failedResult("no slashing conditions found"); } - if (!specHelpers.verify_slashable_attestation(state, slashableAttestation1)) { + if (!spec.verify_slashable_attestation(state, slashableAttestation1)) { return failedResult("slashableAttestation1 is incorrect"); } - if (!specHelpers.verify_slashable_attestation(state, slashableAttestation2)) { + if (!spec.verify_slashable_attestation(state, slashableAttestation2)) { return failedResult("slashableAttestation2 is incorrect"); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/DepositVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/DepositVerifier.java index bebb3b6e6..35b99bada 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/DepositVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/DepositVerifier.java @@ -9,7 +9,6 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.operations.Deposit; import org.ethereum.beacon.core.operations.deposit.DepositData; -import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.ssz.Serializer; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.bytes.BytesValue; @@ -24,13 +23,11 @@ */ public class DepositVerifier implements OperationVerifier { - private final ChainSpec chainSpec; - private final SpecHelpers specHelpers; + private final SpecHelpers spec; private final Serializer ssz = Serializer.annotationSerializer(); - public DepositVerifier(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; - this.chainSpec = specHelpers.getChainSpec(); + public DepositVerifier(SpecHelpers spec) { + this.spec = spec; } BytesValue serialize(DepositData depositData) { @@ -49,12 +46,12 @@ BytesValue serialize(DepositData depositData) { @Override public VerificationResult verify(Deposit deposit, BeaconState state) { BytesValue serializedDepositData = serialize(deposit.getDepositData()); - Hash32 serializedDataHash = specHelpers.hash(serializedDepositData); + Hash32 serializedDataHash = spec.hash(serializedDepositData); - if (!specHelpers.verify_merkle_branch( + if (!spec.verify_merkle_branch( serializedDataHash, deposit.getBranch(), - chainSpec.getDepositContractTreeDepth(), + spec.getConstants().getDepositContractTreeDepth(), deposit.getIndex(), state.getLatestEth1Data().getDepositRoot())) { diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java index ba9329b93..d77bd9e7b 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java @@ -9,7 +9,6 @@ import org.ethereum.beacon.consensus.verifier.VerificationResult; import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.operations.VoluntaryExit; -import org.ethereum.beacon.core.spec.ChainSpec; import org.ethereum.beacon.core.state.ValidatorRecord; /** @@ -22,30 +21,28 @@ */ public class ExitVerifier implements OperationVerifier { - private ChainSpec chainSpec; - private SpecHelpers specHelpers; + private SpecHelpers spec; - public ExitVerifier(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; - this.chainSpec = specHelpers.getChainSpec(); + public ExitVerifier(SpecHelpers spec) { + this.spec = spec; } @Override public VerificationResult verify(VoluntaryExit voluntaryExit, BeaconState state) { - specHelpers.checkIndexRange(state, voluntaryExit.getValidatorIndex()); + spec.checkIndexRange(state, voluntaryExit.getValidatorIndex()); ValidatorRecord validator = state.getValidatorRegistry().get(voluntaryExit.getValidatorIndex()); // Verify that validator.exit_epoch > get_delayed_activation_exit_epoch(get_current_epoch(state)) if (!validator.getExitEpoch().greater( - specHelpers.get_delayed_activation_exit_epoch(specHelpers.get_current_epoch(state)))) { + spec.get_delayed_activation_exit_epoch(spec.get_current_epoch(state)))) { return failedResult( "ACTIVATION_EXIT_DELAY exceeded, min exit epoch %s, got %s", - state.getSlot().plus(chainSpec.getActivationExitDelay()), validator.getExitEpoch()); + state.getSlot().plus(spec.getConstants().getActivationExitDelay()), validator.getExitEpoch()); } // Verify that get_current_epoch(state) >= exit.epoch - if (!specHelpers.get_current_epoch(state).greaterEqual(voluntaryExit.getEpoch())) { + if (!spec.get_current_epoch(state).greaterEqual(voluntaryExit.getEpoch())) { return failedResult( "exit.epoch must be greater or equal to current_epoch"); } @@ -60,11 +57,11 @@ public VerificationResult verify(VoluntaryExit voluntaryExit, BeaconState state) // message=exit_message, // signature=exit.signature, // domain=get_domain(state.fork, exit.epoch, DOMAIN_EXIT)). - if (!specHelpers.bls_verify( + if (!spec.bls_verify( validator.getPubKey(), - specHelpers.signed_root(voluntaryExit, "signature"), + spec.signed_root(voluntaryExit, "signature"), voluntaryExit.getSignature(), - specHelpers.get_domain(state.getForkData(), voluntaryExit.getEpoch(), EXIT))) { + spec.get_domain(state.getForkData(), voluntaryExit.getEpoch(), EXIT))) { return failedResult("failed to verify signature"); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ProposerSlashingVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ProposerSlashingVerifier.java index be229a42f..1b49ca26d 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ProposerSlashingVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ProposerSlashingVerifier.java @@ -21,17 +21,17 @@ */ public class ProposerSlashingVerifier implements OperationVerifier { - private SpecHelpers specHelpers; + private SpecHelpers spec; - public ProposerSlashingVerifier(SpecHelpers specHelpers) { - this.specHelpers = specHelpers; + public ProposerSlashingVerifier(SpecHelpers spec) { + this.spec = spec; } @Override public VerificationResult verify(ProposerSlashing proposerSlashing, BeaconState state) { - specHelpers.checkIndexRange(state, proposerSlashing.getProposerIndex()); - specHelpers.checkShardRange(proposerSlashing.getProposal1().getShard()); - specHelpers.checkShardRange(proposerSlashing.getProposal2().getShard()); + spec.checkIndexRange(state, proposerSlashing.getProposerIndex()); + spec.checkShardRange(proposerSlashing.getProposal1().getShard()); + spec.checkShardRange(proposerSlashing.getProposal2().getShard()); if (!proposerSlashing .getProposal1() @@ -62,24 +62,24 @@ public VerificationResult verify(ProposerSlashing proposerSlashing, BeaconState "proposer was already slashed"); } - if (!specHelpers.bls_verify( + if (!spec.bls_verify( proposer.getPubKey(), - specHelpers.signed_root(proposerSlashing.getProposal1(), "signature"), + spec.signed_root(proposerSlashing.getProposal1(), "signature"), proposerSlashing.getProposal1().getSignature(), - specHelpers.get_domain( + spec.get_domain( state.getForkData(), - specHelpers.slot_to_epoch(proposerSlashing.getProposal1().getSlot()), + spec.slot_to_epoch(proposerSlashing.getProposal1().getSlot()), PROPOSAL))) { return failedResult("proposal_1.signature is invalid"); } - if (!specHelpers.bls_verify( + if (!spec.bls_verify( proposer.getPubKey(), - specHelpers.signed_root(proposerSlashing.getProposal2(), "signature"), + spec.signed_root(proposerSlashing.getProposal2(), "signature"), proposerSlashing.getProposal2().getSignature(), - specHelpers.get_domain( + spec.get_domain( state.getForkData(), - specHelpers.slot_to_epoch(proposerSlashing.getProposal2().getSlot()), + spec.slot_to_epoch(proposerSlashing.getProposal2().getSlot()), PROPOSAL))) { return failedResult("proposal_2.signature is invalid"); } diff --git a/consensus/src/test/java/org/ethereum/beacon/consensus/SpecHelpersTest.java b/consensus/src/test/java/org/ethereum/beacon/consensus/SpecHelpersTest.java index 94477465c..376241ccb 100644 --- a/consensus/src/test/java/org/ethereum/beacon/consensus/SpecHelpersTest.java +++ b/consensus/src/test/java/org/ethereum/beacon/consensus/SpecHelpersTest.java @@ -7,9 +7,8 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.operations.deposit.DepositInput; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; -import org.ethereum.beacon.core.state.ShardCommittee; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.ShardNumber; @@ -40,7 +39,7 @@ public class SpecHelpersTest { @Test public void shuffleTest0() throws Exception { - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); int[] sample = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; @@ -85,7 +84,7 @@ public void shuffleTest1() throws Exception { } } - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); Map map = Arrays.stream(statuses).boxed().collect (Collectors.groupingBy(Function.identity(), Collectors.counting())); @@ -106,7 +105,7 @@ private DepositInput createDepositInput() { @Test public void testHashTreeRoot1() { - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); Hash32 expected = Hash32.fromHexString("0x8fc89d0f1f435b07543b15fdf687e7fce4a754ecd9e5afbf8f0e83928a7f798f"); Hash32 actual = specHelpers.hash_tree_root(createDepositInput()); @@ -126,8 +125,8 @@ public void committeeTest1() { Eth1Data eth1Data = new Eth1Data(Hash32.random(rnd), Hash32.random(rnd)); - ChainSpec chainSpec = - new ChainSpec() { + SpecConstants specConstants = + new SpecConstants() { @Override public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(epochLength)); @@ -149,7 +148,7 @@ public ShardNumber getShardCount() { } }; SpecHelpers specHelpers = new SpecHelpers( - chainSpec, Hashes::keccak256, SSZObjectHasher.create(Hashes::keccak256), () -> 0L) { + specConstants, Hashes::keccak256, SSZObjectHasher.create(Hashes::keccak256), () -> 0L) { @Override public boolean bls_verify(BLSPubkey publicKey, Hash32 message, BLSSignature signature, Bytes8 domain) { @@ -163,7 +162,7 @@ public boolean bls_verify(BLSPubkey publicKey, Hash32 message, BLSSignature sign specHelpers); BeaconState initialState = initialStateTransition.apply( - BeaconBlocks.createGenesis(specHelpers.getChainSpec())); + BeaconBlocks.createGenesis(specHelpers.getConstants())); MutableBeaconState state = initialState.createMutableCopy(); for(int i = 1; i < 128; i++) { diff --git a/consensus/src/test/java/org/ethereum/beacon/consensus/TestUtils.java b/consensus/src/test/java/org/ethereum/beacon/consensus/TestUtils.java index 7181b580f..eb1b495dd 100644 --- a/consensus/src/test/java/org/ethereum/beacon/consensus/TestUtils.java +++ b/consensus/src/test/java/org/ethereum/beacon/consensus/TestUtils.java @@ -62,7 +62,7 @@ private synchronized static Pair, List> generateRandomDep Collections.singletonList(Hash32.random(rnd)), UInt64.ZERO, new DepositData( - specHelpers.getChainSpec().getMaxDepositAmount(), + specHelpers.getConstants().getMaxDepositAmount(), Time.of(0), new DepositInput( BLSPubkey.wrap(Bytes48.leftPad(keyPair.getPublic().getEncodedBytes())), @@ -88,7 +88,7 @@ public static List generateRandomDepositsWithoutSig(Random rnd, SpecHel Collections.singletonList(Hash32.random(rnd)), counter, new DepositData( - specHelpers.getChainSpec().getMaxDepositAmount(), + specHelpers.getConstants().getMaxDepositAmount(), Time.of(0), new DepositInput(pubkey, proofOfPosession, BLSSignature.ZERO))); deposits.add(deposit); diff --git a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/InitialStateTransitionTest.java b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/InitialStateTransitionTest.java index cddddcd8e..6de441c24 100644 --- a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/InitialStateTransitionTest.java +++ b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/InitialStateTransitionTest.java @@ -7,7 +7,7 @@ import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.core.BeaconBlocks; import org.ethereum.beacon.core.BeaconState; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.pow.DepositContract.ChainStart; @@ -23,7 +23,7 @@ public void handleChainStartCorrectly() { Time genesisTime = Time.castFrom(UInt64.random(rnd)); Eth1Data eth1Data = new Eth1Data(Hash32.random(rnd), Hash32.random(rnd)); - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); InitialStateTransition initialStateTransition = new InitialStateTransition( new ChainStart(genesisTime, eth1Data, Collections.emptyList()), @@ -31,7 +31,7 @@ public void handleChainStartCorrectly() { BeaconState initialState = initialStateTransition.apply( - BeaconBlocks.createGenesis(ChainSpec.DEFAULT)); + BeaconBlocks.createGenesis(SpecConstants.DEFAULT)); assertThat(initialState.getGenesisTime()).isEqualTo(genesisTime); assertThat(initialState.getLatestEth1Data()).isEqualTo(eth1Data); diff --git a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerEpochTransitionTest.java b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerEpochTransitionTest.java index a763adf47..2a4aef013 100644 --- a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerEpochTransitionTest.java +++ b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerEpochTransitionTest.java @@ -7,7 +7,7 @@ import org.ethereum.beacon.consensus.TestUtils; import org.ethereum.beacon.core.BeaconBlocks; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.Gwei; import org.ethereum.beacon.core.types.SlotNumber; @@ -26,15 +26,15 @@ public void test1() { Random rnd = new Random(); Time genesisTime = Time.castFrom(UInt64.random(rnd)); Eth1Data eth1Data = new Eth1Data(Hash32.random(rnd), Hash32.random(rnd)); - ChainSpec chainSpec = - new ChainSpec() { + SpecConstants specConstants = + new SpecConstants() { @Override public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(8)); } }; - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(chainSpec, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(specConstants, () -> 0L); List deposits = TestUtils.getAnyDeposits(rnd, specHelpers, 8).getValue0(); @@ -43,7 +43,7 @@ public SlotNumber.EpochLength getSlotsPerEpoch() { BeaconStateEx[] states = new BeaconStateExImpl[9]; - states[0] = initialStateTransition.apply(BeaconBlocks.createGenesis(chainSpec)); + states[0] = initialStateTransition.apply(BeaconBlocks.createGenesis(specConstants)); for (int i = 1; i < 9; i++) { states[i] = new PerSlotTransition(specHelpers).apply(states[i - 1]); } diff --git a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerSlotTransitionTest.java b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerSlotTransitionTest.java index 3f7b6014c..ef351e423 100644 --- a/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerSlotTransitionTest.java +++ b/consensus/src/test/java/org/ethereum/beacon/consensus/transition/PerSlotTransitionTest.java @@ -7,7 +7,7 @@ import org.ethereum.beacon.consensus.TestUtils; import org.ethereum.beacon.core.BeaconBlocks; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.core.types.Time; @@ -24,14 +24,14 @@ public void test1() { Random rnd = new Random(); Time genesisTime = Time.castFrom(UInt64.random(rnd)); Eth1Data eth1Data = new Eth1Data(Hash32.random(rnd), Hash32.random(rnd)); - ChainSpec chainSpec = - new ChainSpec() { + SpecConstants specConstants = + new SpecConstants() { @Override public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(8)); } }; - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(chainSpec, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(specConstants, () -> 0L); List deposits = TestUtils.getAnyDeposits(rnd, specHelpers, 8).getValue0(); @@ -41,11 +41,11 @@ public SlotNumber.EpochLength getSlotsPerEpoch() { specHelpers); BeaconStateEx initialState = - initialStateTransition.apply(BeaconBlocks.createGenesis(chainSpec)); + initialStateTransition.apply(BeaconBlocks.createGenesis(specConstants)); BeaconStateEx s1State = new PerSlotTransition(specHelpers).apply(initialState); BeaconStateEx s2State = new PerSlotTransition(specHelpers).apply(s1State); BeaconStateEx s3State = new PerSlotTransition(specHelpers).apply(s2State); - Assert.assertEquals(chainSpec.getGenesisSlot().plus(3), s3State.getSlot()); + Assert.assertEquals(specConstants.getGenesisSlot().plus(3), s3State.getSlot()); } } diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java b/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java index 869bf6b58..989eee5f5 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java @@ -9,7 +9,7 @@ import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.SlotNumber; @@ -123,37 +123,37 @@ public String toString() { return toString(null, null, null); } - public String toStringFull(@Nullable ChainSpec spec,@Nullable Time beaconStart, + public String toStringFull(@Nullable SpecConstants constants, @Nullable Time beaconStart, @Nullable Function hasher) { StringBuilder ret = new StringBuilder("Block[" - + toStringPriv(spec, beaconStart, hasher) + + toStringPriv(constants, beaconStart, hasher) + "]:\n"); for (Attestation attestation : body.getAttestations()) { - ret.append(" " + attestation.toString(spec, beaconStart) + "\n"); + ret.append(" " + attestation.toString(constants, beaconStart) + "\n"); } for (Deposit deposit : body.getDeposits()) { ret.append(" " + deposit.toString() + "\n"); } for (VoluntaryExit voluntaryExit : body.getExits()) { - ret.append(" " + voluntaryExit.toString(spec) + "\n"); + ret.append(" " + voluntaryExit.toString(constants) + "\n"); } for (ProposerSlashing proposerSlashing : body.getProposerSlashings()) { - ret.append(" " + proposerSlashing.toString(spec, beaconStart) + "\n"); + ret.append(" " + proposerSlashing.toString(constants, beaconStart) + "\n"); } for (AttesterSlashing attesterSlashing : body.getAttesterSlashings()) { - ret.append(" " + attesterSlashing.toString(spec, beaconStart) + "\n"); + ret.append(" " + attesterSlashing.toString(constants, beaconStart) + "\n"); } return ret.toString(); } - public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart, + public String toString(@Nullable SpecConstants constants, @Nullable Time beaconStart, @Nullable Function hasher) { - String ret = "Block[" + toStringPriv(spec, beaconStart, hasher); + String ret = "Block[" + toStringPriv(constants, beaconStart, hasher); if (!body.getAttestations().isEmpty()) { ret += ", atts: [" + body.getAttestations().stream() - .map(a -> a.toStringShort(spec)) + .map(a -> a.toStringShort(constants)) .collect(Collectors.joining(", ")) + "]"; } if (!body.getDeposits().isEmpty()) { @@ -163,17 +163,17 @@ public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart, } if (!body.getExits().isEmpty()) { ret += ", exits: [" + body.getExits().stream() - .map(a -> a.toString(spec)) + .map(a -> a.toString(constants)) .collect(Collectors.joining(", ")) + "]"; } if (!body.getAttesterSlashings().isEmpty()) { ret += ", attSlash: [" + body.getAttesterSlashings().stream() - .map(a -> a.toString(spec, beaconStart)) + .map(a -> a.toString(constants, beaconStart)) .collect(Collectors.joining(", ")) + "]"; } if (!body.getProposerSlashings().isEmpty()) { ret += ", propSlash: [" + body.getProposerSlashings().stream() - .map(a -> a.toString(spec, beaconStart)) + .map(a -> a.toString(constants, beaconStart)) .collect(Collectors.joining(", ")) + "]"; } ret += "]"; @@ -181,11 +181,11 @@ public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart, return ret; } - private String toStringPriv(@Nullable ChainSpec spec,@Nullable Time beaconStart, + private String toStringPriv(@Nullable SpecConstants constants, @Nullable Time beaconStart, @Nullable Function hasher) { return (hasher == null ? "?" : hasher.apply(this).toStringShort()) + " <~ " + parentRoot.toStringShort() - + ", @slot " + slot.toString(spec, beaconStart) + + ", @slot " + slot.toString(constants, beaconStart) + ", state=" + stateRoot.toStringShort() + ", randao=" + randaoReveal.toString() + ", " + eth1Data diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconBlocks.java b/core/src/main/java/org/ethereum/beacon/core/BeaconBlocks.java index b89a0e7be..f27d0e4d7 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconBlocks.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconBlocks.java @@ -1,9 +1,8 @@ package org.ethereum.beacon.core; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import tech.pegasys.artemis.ethereum.core.Hash32; -import tech.pegasys.artemis.util.bytes.Bytes96; /** A class holding various utility methods to work with {@link BeaconBlock}. */ public abstract class BeaconBlocks { @@ -15,17 +14,17 @@ private BeaconBlocks() {} *

Note: it assumed that {@link BeaconBlock#stateRoot} will be set later on, * hence, it's set to {@link Hash32#ZERO}. * - * @param chainSpec beacon chain spec. + * @param specConstants beacon chain spec. * @return a genesis block. */ - public static BeaconBlock createGenesis(ChainSpec chainSpec) { + public static BeaconBlock createGenesis(SpecConstants specConstants) { return BeaconBlock.Builder.createEmpty() - .withSlot(chainSpec.getGenesisSlot()) + .withSlot(specConstants.getGenesisSlot()) .withParentRoot(Hash32.ZERO) .withStateRoot(Hash32.ZERO) - .withRandaoReveal(chainSpec.getEmptySignature()) + .withRandaoReveal(specConstants.getEmptySignature()) .withEth1Data(Eth1Data.EMPTY) - .withSignature(chainSpec.getEmptySignature()) + .withSignature(specConstants.getEmptySignature()) .withBody(BeaconBlockBody.EMPTY) .build(); } diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconState.java b/core/src/main/java/org/ethereum/beacon/core/BeaconState.java index 15c043a79..30ab892e3 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconState.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconState.java @@ -3,7 +3,7 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; import org.ethereum.beacon.core.operations.attestation.Crosslink; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.BeaconStateImpl; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; @@ -128,7 +128,7 @@ static BeaconState getEmpty() { */ MutableBeaconState createMutableCopy(); - default String toStringShort(@Nullable ChainSpec spec) { + default String toStringShort(@Nullable SpecConstants spec) { String ret = "BeaconState[" + "@ " + getSlot().toString(spec, getGenesisTime()) + ", " + getForkData().toString(spec) diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/Attestation.java b/core/src/main/java/org/ethereum/beacon/core/operations/Attestation.java index 521e104c1..e92f58514 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/Attestation.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/Attestation.java @@ -5,7 +5,7 @@ import javax.annotation.Nullable; import org.ethereum.beacon.core.BeaconBlockBody; import org.ethereum.beacon.core.operations.attestation.AttestationData; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Bitfield; import org.ethereum.beacon.core.types.Time; @@ -89,7 +89,7 @@ private String getSignerIndices() { return aggregationBitfield.getBits().stream().map(i -> "" + i).collect(Collectors.joining("+")); } - public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart) { + public String toString(@Nullable SpecConstants spec,@Nullable Time beaconStart) { return "Attestation[" + data.toString(spec, beaconStart) + ", attesters=" + getSignerIndices() @@ -98,7 +98,7 @@ public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart) { + "]"; } - public String toStringShort(@Nullable ChainSpec spec) { + public String toStringShort(@Nullable SpecConstants spec) { return getData().getSlot().toStringNumber(spec) + "/" + getData().getShard().toString(spec) + "/" + getData().getBeaconBlockRoot().toStringShort() + "/" diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/Exit.java b/core/src/main/java/org/ethereum/beacon/core/operations/Exit.java index 708e2dd77..d146b0d0e 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/Exit.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/Exit.java @@ -3,7 +3,7 @@ import com.google.common.base.Objects; import javax.annotation.Nullable; import org.ethereum.beacon.core.BeaconBlockBody; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.EpochNumber; import org.ethereum.beacon.core.types.ValidatorIndex; @@ -72,7 +72,7 @@ public String toString() { return toString(null); } - public String toString(@Nullable ChainSpec spec) { + public String toString(@Nullable SpecConstants spec) { return "Exit[" + "epoch=" + epoch.toString(spec) + ", validator=" + validatorIndex diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/ProposerSlashing.java b/core/src/main/java/org/ethereum/beacon/core/operations/ProposerSlashing.java index 20c6a6b48..695f5b406 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/ProposerSlashing.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/ProposerSlashing.java @@ -4,7 +4,7 @@ import javax.annotation.Nullable; import org.ethereum.beacon.core.operations.slashing.Proposal; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.core.types.ValidatorIndex; import org.ethereum.beacon.ssz.annotation.SSZ; @@ -52,7 +52,7 @@ public String toString() { return toString(null, null); } - public String toString(@Nullable ChainSpec spec, @Nullable Time beaconStart) { + public String toString(@Nullable SpecConstants spec, @Nullable Time beaconStart) { return "ProposerSlashing[" + "proposer: " + proposerIndex + ", data1: " + proposal1.toString(spec, beaconStart) diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/VoluntaryExit.java b/core/src/main/java/org/ethereum/beacon/core/operations/VoluntaryExit.java index ae8ca715d..481bce595 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/VoluntaryExit.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/VoluntaryExit.java @@ -3,7 +3,7 @@ import com.google.common.base.Objects; import javax.annotation.Nullable; import org.ethereum.beacon.core.BeaconBlockBody; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.EpochNumber; import org.ethereum.beacon.core.types.ValidatorIndex; @@ -72,7 +72,7 @@ public String toString() { return toString(null); } - public String toString(@Nullable ChainSpec spec) { + public String toString(@Nullable SpecConstants spec) { return "VoluntaryExit[" + "epoch=" + epoch.toString(spec) + ", validator=" + validatorIndex diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/attestation/AttestationData.java b/core/src/main/java/org/ethereum/beacon/core/operations/attestation/AttestationData.java index da5725279..341b79d18 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/attestation/AttestationData.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/attestation/AttestationData.java @@ -3,7 +3,7 @@ import com.google.common.base.Objects; import javax.annotation.Nullable; import org.ethereum.beacon.core.operations.Attestation; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.EpochNumber; import org.ethereum.beacon.core.types.ShardNumber; import org.ethereum.beacon.core.types.SlotNumber; @@ -124,7 +124,7 @@ public String toString() { return toString(null, null); } - public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart) { + public String toString(@Nullable SpecConstants spec,@Nullable Time beaconStart) { return "AttestationData[slot=" + slot.toString(spec, beaconStart) + ", shard=" + shard.toString(spec) diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/attestation/Crosslink.java b/core/src/main/java/org/ethereum/beacon/core/operations/attestation/Crosslink.java index dd331b546..97cfa34c0 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/attestation/Crosslink.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/attestation/Crosslink.java @@ -2,7 +2,7 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Objects; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.EpochNumber; import org.ethereum.beacon.ssz.annotation.SSZ; import org.ethereum.beacon.ssz.annotation.SSZSerializable; @@ -61,7 +61,7 @@ public String toString() { return toString(null); } - public String toString(ChainSpec spec) { + public String toString(SpecConstants spec) { return MoreObjects.toStringHelper(this) .add("epoch", epoch.toString(spec)) .add("crosslinkDataRoot", crosslinkDataRoot.toStringShort()) diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/slashing/AttesterSlashing.java b/core/src/main/java/org/ethereum/beacon/core/operations/slashing/AttesterSlashing.java index 81f9b862a..437794ada 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/slashing/AttesterSlashing.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/slashing/AttesterSlashing.java @@ -1,7 +1,7 @@ package org.ethereum.beacon.core.operations.slashing; import javax.annotation.Nullable; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.ssz.annotation.SSZ; import org.ethereum.beacon.ssz.annotation.SSZSerializable; @@ -40,7 +40,7 @@ public String toString() { return toString(null, null); } - public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart) { + public String toString(@Nullable SpecConstants spec,@Nullable Time beaconStart) { return "AttesterSlashing[" + "att1=" + slashableAttestation1.toString(spec, beaconStart) + "att2=" + slashableAttestation2.toString(spec, beaconStart) diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/slashing/Proposal.java b/core/src/main/java/org/ethereum/beacon/core/operations/slashing/Proposal.java index 68cea7045..c2b05ff49 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/slashing/Proposal.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/slashing/Proposal.java @@ -2,7 +2,7 @@ import com.google.common.base.Objects; import javax.annotation.Nullable; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.ShardNumber; import org.ethereum.beacon.core.types.SlotNumber; @@ -58,7 +58,7 @@ public boolean equals(Object o) { && Objects.equal(blockRoot, that.blockRoot); } - public String toString(@Nullable ChainSpec spec, @Nullable Time beaconStart) { + public String toString(@Nullable SpecConstants spec, @Nullable Time beaconStart) { return "Proposal[" + "slot=" + slot.toString(spec, beaconStart) + "shard=" + shard.toString(spec) diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/slashing/SlashableAttestation.java b/core/src/main/java/org/ethereum/beacon/core/operations/slashing/SlashableAttestation.java index 077f7f03f..9c9c37ccd 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/slashing/SlashableAttestation.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/slashing/SlashableAttestation.java @@ -4,7 +4,7 @@ import java.util.List; import javax.annotation.Nullable; import org.ethereum.beacon.core.operations.attestation.AttestationData; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Bitfield; import org.ethereum.beacon.core.types.Time; @@ -70,7 +70,7 @@ public String toString() { return toString(null, null); } - public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart) { + public String toString(@Nullable SpecConstants spec,@Nullable Time beaconStart) { return "SlashableAttestation[" + "data=" + data.toString(spec, beaconStart) + ", validators=" + validatorIndicesList diff --git a/core/src/main/java/org/ethereum/beacon/core/spec/ChainSpec.java b/core/src/main/java/org/ethereum/beacon/core/spec/SpecConstants.java similarity index 85% rename from core/src/main/java/org/ethereum/beacon/core/spec/ChainSpec.java rename to core/src/main/java/org/ethereum/beacon/core/spec/SpecConstants.java index b1882b8ec..234294e98 100644 --- a/core/src/main/java/org/ethereum/beacon/core/spec/ChainSpec.java +++ b/core/src/main/java/org/ethereum/beacon/core/spec/SpecConstants.java @@ -2,7 +2,7 @@ import org.ethereum.beacon.core.types.EpochNumber; -public interface ChainSpec +public interface SpecConstants extends InitialValues, MiscParameters, StateListLengths, @@ -13,7 +13,7 @@ public interface ChainSpec HonestValidatorParameters, GweiValues { - ChainSpec DEFAULT = new ChainSpec() {}; + SpecConstants DEFAULT = new SpecConstants() {}; @Override default EpochNumber getGenesisEpoch() { diff --git a/core/src/main/java/org/ethereum/beacon/core/state/ForkData.java b/core/src/main/java/org/ethereum/beacon/core/state/ForkData.java index 29cbaea33..5b9d0f4e1 100644 --- a/core/src/main/java/org/ethereum/beacon/core/state/ForkData.java +++ b/core/src/main/java/org/ethereum/beacon/core/state/ForkData.java @@ -3,9 +3,8 @@ import com.google.common.base.Objects; import javax.annotation.Nullable; import org.ethereum.beacon.core.BeaconState; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.EpochNumber; -import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.ssz.annotation.SSZ; import org.ethereum.beacon.ssz.annotation.SSZSerializable; import tech.pegasys.artemis.util.uint.UInt64; @@ -64,7 +63,7 @@ public String toString() { } public String toString( - @Nullable ChainSpec spec) { + @Nullable SpecConstants spec) { return "Fork[" + epoch.toString(spec) + ", " + previousVersion + " => " + currentVersion + "]"; } } diff --git a/core/src/main/java/org/ethereum/beacon/core/state/PendingAttestationRecord.java b/core/src/main/java/org/ethereum/beacon/core/state/PendingAttestationRecord.java index 4acbb5388..8b6b0a10e 100644 --- a/core/src/main/java/org/ethereum/beacon/core/state/PendingAttestationRecord.java +++ b/core/src/main/java/org/ethereum/beacon/core/state/PendingAttestationRecord.java @@ -5,13 +5,12 @@ import javax.annotation.Nullable; import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.operations.attestation.AttestationData; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.Bitfield; import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.ssz.annotation.SSZ; import org.ethereum.beacon.ssz.annotation.SSZSerializable; -import tech.pegasys.artemis.util.bytes.BytesValue; /** * An attestation data that have not been processed yet. @@ -78,7 +77,7 @@ public String toString() { return toString(null, null); } - public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart) { + public String toString(@Nullable SpecConstants spec,@Nullable Time beaconStart) { return "Attestation[" + data.toString(spec, beaconStart) + ", attesters=" + getSignerIndices() @@ -87,7 +86,7 @@ public String toString(@Nullable ChainSpec spec,@Nullable Time beaconStart) { + "]"; } - public String toStringShort(@Nullable ChainSpec spec) { + public String toStringShort(@Nullable SpecConstants spec) { return "#" + getData().getSlot().toStringNumber(spec) + "/" + "#" + getInclusionSlot().toStringNumber(spec) + "/" + getData().getShard().toString(spec) + "/" diff --git a/core/src/main/java/org/ethereum/beacon/core/types/EpochNumber.java b/core/src/main/java/org/ethereum/beacon/core/types/EpochNumber.java index 53468dc5e..0c5d6d0d8 100644 --- a/core/src/main/java/org/ethereum/beacon/core/types/EpochNumber.java +++ b/core/src/main/java/org/ethereum/beacon/core/types/EpochNumber.java @@ -1,7 +1,7 @@ package org.ethereum.beacon.core.types; import javax.annotation.Nullable; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.SlotNumber.EpochLength; import org.ethereum.beacon.ssz.annotation.SSZSerializable; import tech.pegasys.artemis.util.uint.UInt64; @@ -64,7 +64,7 @@ public EpochNumber zeroElement() { return ZERO; } - public String toString(@Nullable ChainSpec spec) { + public String toString(@Nullable SpecConstants spec) { return spec == null ? super.toString() : this.minus(spec.getGenesisEpoch()).toString(); } } diff --git a/core/src/main/java/org/ethereum/beacon/core/types/ShardNumber.java b/core/src/main/java/org/ethereum/beacon/core/types/ShardNumber.java index 05ede3021..d1c499841 100644 --- a/core/src/main/java/org/ethereum/beacon/core/types/ShardNumber.java +++ b/core/src/main/java/org/ethereum/beacon/core/types/ShardNumber.java @@ -2,7 +2,7 @@ import java.util.function.Function; import javax.annotation.Nullable; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.ssz.annotation.SSZSerializable; import tech.pegasys.artemis.util.uint.UInt64; @@ -56,7 +56,7 @@ public String toString() { return toString(null); } - public String toString(@Nullable ChainSpec spec) { + public String toString(@Nullable SpecConstants spec) { return spec == null ? super.toString() : spec.getBeaconChainShardNumber().equals(this) ? "Beacon" : super.toString(); } diff --git a/core/src/main/java/org/ethereum/beacon/core/types/SlotNumber.java b/core/src/main/java/org/ethereum/beacon/core/types/SlotNumber.java index 652f74fc9..a5611292b 100644 --- a/core/src/main/java/org/ethereum/beacon/core/types/SlotNumber.java +++ b/core/src/main/java/org/ethereum/beacon/core/types/SlotNumber.java @@ -2,7 +2,7 @@ import java.time.Duration; import javax.annotation.Nullable; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.ssz.annotation.SSZSerializable; import tech.pegasys.artemis.util.uint.UInt64; @@ -86,7 +86,7 @@ public SlotNumber zeroElement() { public String toString( - @Nullable ChainSpec spec, + @Nullable SpecConstants spec, @Nullable Time beaconStart) { long num = spec == null ? getValue() : this.minus(spec.getGenesisSlot()).getValue(); @@ -110,7 +110,7 @@ public String toString( return "#" + num + (extraInfo.isEmpty() ? "" : " (" + extraInfo + ")"); } - public String toStringNumber(@Nullable ChainSpec spec) { + public String toStringNumber(@Nullable SpecConstants spec) { return "" + (spec == null ? getValue() : this.minus(spec.getGenesisSlot()).getValue()); } diff --git a/core/src/test/java/org/ethereum/beacon/core/util/AttestationTestUtil.java b/core/src/test/java/org/ethereum/beacon/core/util/AttestationTestUtil.java index 2f8a0fbee..934a4dc0d 100644 --- a/core/src/test/java/org/ethereum/beacon/core/util/AttestationTestUtil.java +++ b/core/src/test/java/org/ethereum/beacon/core/util/AttestationTestUtil.java @@ -6,7 +6,7 @@ import java.util.stream.Stream; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.attestation.AttestationData; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Bitfield; @@ -34,13 +34,13 @@ public static Attestation createRandomAttestation(Random random) { public static AttestationData createRandomAttestationData(Random random) { return new AttestationData( - ChainSpec.GENESIS_SLOT, - ChainSpec.BEACON_CHAIN_SHARD_NUMBER, + SpecConstants.GENESIS_SLOT, + SpecConstants.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), Hash32.random(random), Hash32.random(random), new Crosslink(EpochNumber.ZERO, Hash32.random(random)), - ChainSpec.DEFAULT.getGenesisEpoch(), + SpecConstants.DEFAULT.getGenesisEpoch(), Hash32.random(random)); } } diff --git a/core/src/test/java/org/ethereum/beacon/core/util/DepositTestUtil.java b/core/src/test/java/org/ethereum/beacon/core/util/DepositTestUtil.java index 6988d2c9b..ccf3ed057 100644 --- a/core/src/test/java/org/ethereum/beacon/core/util/DepositTestUtil.java +++ b/core/src/test/java/org/ethereum/beacon/core/util/DepositTestUtil.java @@ -7,7 +7,7 @@ import org.ethereum.beacon.core.operations.Deposit; import org.ethereum.beacon.core.operations.deposit.DepositData; import org.ethereum.beacon.core.operations.deposit.DepositInput; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Time; @@ -20,7 +20,7 @@ public abstract class DepositTestUtil { private DepositTestUtil() {} public static List createRandomList( - Random random, ChainSpec spec, UInt64 startIndex, int maxCount) { + Random random, SpecConstants spec, UInt64 startIndex, int maxCount) { List deposits = new ArrayList<>(); int count = Math.abs(random.nextInt()) % maxCount + 1; for (int i = 0; i < count; i++) { @@ -29,7 +29,7 @@ public static List createRandomList( return deposits; } - public static Deposit createRandom(Random random, ChainSpec spec, UInt64 depositIndex) { + public static Deposit createRandom(Random random, SpecConstants spec, UInt64 depositIndex) { DepositInput depositInput = new DepositInput( BLSPubkey.wrap(Bytes48.random(random)), diff --git a/core/src/test/java/org/ethereum/beacon/core/util/ProposerSlashingTestUtil.java b/core/src/test/java/org/ethereum/beacon/core/util/ProposerSlashingTestUtil.java index d0c9a0ac1..04f9db179 100644 --- a/core/src/test/java/org/ethereum/beacon/core/util/ProposerSlashingTestUtil.java +++ b/core/src/test/java/org/ethereum/beacon/core/util/ProposerSlashingTestUtil.java @@ -6,7 +6,7 @@ import java.util.stream.Stream; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.Proposal; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.ValidatorIndex; import tech.pegasys.artemis.ethereum.core.Hash32; @@ -24,11 +24,11 @@ public static List createRandomList(Random random, int maxCoun public static ProposerSlashing createRandom(Random random) { Proposal signedData1 = new Proposal( - ChainSpec.GENESIS_SLOT, ChainSpec.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), + SpecConstants.GENESIS_SLOT, SpecConstants.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), BLSSignature.wrap(Bytes96.random(random))); Proposal signedData2 = new Proposal( - ChainSpec.GENESIS_SLOT, ChainSpec.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), + SpecConstants.GENESIS_SLOT, SpecConstants.BEACON_CHAIN_SHARD_NUMBER, Hash32.random(random), BLSSignature.wrap(Bytes96.random(random))); return new ProposerSlashing( ValidatorIndex.ZERO, diff --git a/pow/validator/src/main/java/org/ethereum/beacon/pow/validator/ValidatorRegistrationServiceImpl.java b/pow/validator/src/main/java/org/ethereum/beacon/pow/validator/ValidatorRegistrationServiceImpl.java index 0996a211a..815e9d65e 100644 --- a/pow/validator/src/main/java/org/ethereum/beacon/pow/validator/ValidatorRegistrationServiceImpl.java +++ b/pow/validator/src/main/java/org/ethereum/beacon/pow/validator/ValidatorRegistrationServiceImpl.java @@ -50,7 +50,7 @@ public class ValidatorRegistrationServiceImpl implements ValidatorRegistrationSe private final SingleValueSource stagePersistence; private final Schedulers schedulers; - private final SpecHelpers specHelpers; + private final SpecHelpers spec; private final Serializer sszSerializer; private Disposable depositSubscription = null; @@ -73,14 +73,14 @@ public ValidatorRegistrationServiceImpl( DepositContract depositContract, Publisher observablePublisher, SingleValueSource registrationStagePersistence, - SpecHelpers specHelpers, + SpecHelpers spec, Schedulers schedulers) { this.transactionBuilder = transactionBuilder; this.transactionGateway = transactionGateway; this.depositContract = depositContract; this.observablePublisher = observablePublisher; this.stagePersistence = registrationStagePersistence; - this.specHelpers = specHelpers; + this.spec = spec; this.schedulers = schedulers; sszSerializer = Serializer.annotationSerializer(); } @@ -139,8 +139,8 @@ private Optional findRegistrationStage() { } this.validatorRecord = validatorRecordOptional.get(); - EpochNumber currentEpoch = specHelpers.get_current_epoch(latestState); - if (specHelpers.is_active_validator(validatorRecord, currentEpoch)) { + EpochNumber currentEpoch = spec.get_current_epoch(latestState); + if (spec.is_active_validator(validatorRecord, currentEpoch)) { return Optional.of(RegistrationStage.VALIDATOR_START); } else { return Optional.of(RegistrationStage.AWAIT_ACTIVATION); @@ -182,8 +182,8 @@ private void awaitActivation() { .subscribe( observableBeaconState -> { BeaconState latestState = observableBeaconState.getLatestSlotState(); - EpochNumber currentEpoch = specHelpers.get_current_epoch(latestState); - if (specHelpers.is_active_validator(validatorRecord, currentEpoch)) { + EpochNumber currentEpoch = spec.get_current_epoch(latestState); + if (spec.is_active_validator(validatorRecord, currentEpoch)) { changeCurrentStage(RegistrationStage.VALIDATOR_START); } }); @@ -191,20 +191,19 @@ private void awaitActivation() { private void startValidator() { if (validatorService == null) { - BlockTransition blockTransition = new PerBlockTransition(specHelpers); - StateTransition epochTransition = new PerEpochTransition(specHelpers); + BlockTransition blockTransition = new PerBlockTransition(spec); + StateTransition epochTransition = new PerEpochTransition(spec); BeaconChainProposer proposer = new BeaconChainProposerImpl( - specHelpers, - specHelpers.getChainSpec(), + spec, blockTransition, epochTransition, depositContract); BeaconChainAttester attester = - new BeaconChainAttesterImpl(specHelpers, specHelpers.getChainSpec()); + new BeaconChainAttesterImpl(spec); validatorService = new BeaconChainValidator( - blsCredentials, proposer, attester, specHelpers, observablePublisher, schedulers); + blsCredentials, proposer, attester, spec, observablePublisher, schedulers); validatorService.start(); changeCurrentStage(RegistrationStage.COMPLETE); } @@ -272,11 +271,11 @@ private DepositInput createDepositInput() { new DepositInput(blsCredentials.getPubkey(), withdrawalCredentials, BLSSignature.ZERO); // Let proof_of_possession be the result of bls_sign of the hash_tree_root(deposit_input) with // domain=DOMAIN_DEPOSIT. - Hash32 hash = specHelpers.signed_root(preDepositInput, "proofOfPossession"); + Hash32 hash = spec.signed_root(preDepositInput, "proofOfPossession"); BeaconState latestState = getLatestState(); Bytes8 domain = - specHelpers.get_domain( - latestState.getForkData(), specHelpers.get_current_epoch(latestState), DEPOSIT); + spec.get_domain( + latestState.getForkData(), spec.get_current_epoch(latestState), DEPOSIT); BLSSignature signature = blsCredentials.getSigner().sign(hash, domain); // Set deposit_input.proof_of_possession = proof_of_possession. DepositInput depositInput = new DepositInput(blsCredentials.getPubkey(), withdrawalCredentials, signature); @@ -293,17 +292,17 @@ private CompletableFuture createTransaction( Address eth1From, BytesValue eth1PrivKey, DepositInput depositInput, Gwei amount) { // Let amount be the amount in Gwei to be deposited by the validator where MIN_DEPOSIT_AMOUNT <= // amount <= MAX_DEPOSIT_AMOUNT. - if (amount.compareTo(specHelpers.getChainSpec().getMinDepositAmount()) < 0) { + if (amount.compareTo(spec.getConstants().getMinDepositAmount()) < 0) { throw new RuntimeException( String.format( "Deposit amount should be equal or greater than %s (defined by spec)", - specHelpers.getChainSpec().getMinDepositAmount())); + spec.getConstants().getMinDepositAmount())); } - if (amount.compareTo(specHelpers.getChainSpec().getMaxDepositAmount()) > 0) { + if (amount.compareTo(spec.getConstants().getMaxDepositAmount()) > 0) { throw new RuntimeException( String.format( "Deposit amount should be equal or less than %s (defined by spec)", - specHelpers.getChainSpec().getMaxDepositAmount())); + spec.getConstants().getMaxDepositAmount())); } // Send a transaction on the Ethereum 1.0 chain to DEPOSIT_CONTRACT_ADDRESS executing deposit // along with serialize(deposit_input) as the singular bytes input along with a deposit amount diff --git a/start/cli/src/main/java/org/ethereum/beacon/ReusableOptions.java b/start/cli/src/main/java/org/ethereum/beacon/ReusableOptions.java index a3a0d15a4..92fdbb827 100644 --- a/start/cli/src/main/java/org/ethereum/beacon/ReusableOptions.java +++ b/start/cli/src/main/java/org/ethereum/beacon/ReusableOptions.java @@ -4,7 +4,7 @@ import org.ethereum.beacon.emulator.config.Config; import org.ethereum.beacon.emulator.config.ConfigBuilder; import org.ethereum.beacon.emulator.config.YamlPrinter; -import org.ethereum.beacon.emulator.config.chainspec.ChainSpecData; +import org.ethereum.beacon.emulator.config.chainspec.SpecConstantsData; import org.ethereum.beacon.emulator.config.main.MainConfig; import org.javatuples.Pair; import picocli.CommandLine; @@ -89,8 +89,8 @@ private MainConfig prepareConfig(String extraConfig) { return configBuilder.build(); } - private ChainSpecData prepareChainSpec(@Nullable String extraChainSpec) { - ConfigBuilder configBuilder = new ConfigBuilder<>(ChainSpecData.class); + private SpecConstantsData prepareChainSpec(@Nullable String extraChainSpec) { + ConfigBuilder configBuilder = new ConfigBuilder<>(SpecConstantsData.class); configBuilder.addYamlConfig( ClassLoader.class.getResourceAsStream("/config/default-chainSpec.yml")); if (extraChainSpec != null) { @@ -109,14 +109,14 @@ private ChainSpecData prepareChainSpec(@Nullable String extraChainSpec) { return configBuilder.build(); } - Pair prepareAndPrintConfigs(Task action, String extraConfig) { + Pair prepareAndPrintConfigs(Task action, String extraConfig) { return prepareAndPrintConfigs(action, extraConfig, null); } - Pair prepareAndPrintConfigs( + Pair prepareAndPrintConfigs( Task action, String extraConfig, @Nullable String extraChainSpec) { MainConfig mainConfig = prepareConfig(extraConfig); - ChainSpecData chainSpecData = prepareChainSpec(extraChainSpec); + SpecConstantsData specConstantsData = prepareChainSpec(extraChainSpec); // Print if needed if (action.equals(Task.config)) { @@ -124,8 +124,8 @@ Pair prepareAndPrintConfigs( System.out.println("Main config:"); System.out.println(new YamlPrinter(mainConfig).getString()); if (verbose) { - System.out.println("Chain specifications:"); - System.out.println(new YamlPrinter(chainSpecData).getString()); + System.out.println("Spec constants:"); + System.out.println(new YamlPrinter(specConstantsData).getString()); } else { System.out.println("To see chain specifications use verbose `-v` option."); } @@ -138,10 +138,10 @@ Pair prepareAndPrintConfigs( } if (chainspec != null) { System.out.println("Saving chain specification to file: " + chainspec); - saveConfigToFile(chainSpecData, chainspec); + saveConfigToFile(specConstantsData, chainspec); } - return Pair.with(mainConfig, chainSpecData); + return Pair.with(mainConfig, specConstantsData); } // Overrides without prompt diff --git a/start/cli/src/main/java/org/ethereum/beacon/Simulator.java b/start/cli/src/main/java/org/ethereum/beacon/Simulator.java index dc536f936..43708486a 100644 --- a/start/cli/src/main/java/org/ethereum/beacon/Simulator.java +++ b/start/cli/src/main/java/org/ethereum/beacon/Simulator.java @@ -1,6 +1,6 @@ package org.ethereum.beacon; -import org.ethereum.beacon.emulator.config.chainspec.ChainSpecData; +import org.ethereum.beacon.emulator.config.chainspec.SpecConstantsData; import org.ethereum.beacon.emulator.config.main.MainConfig; import org.javatuples.Pair; import picocli.CommandLine; @@ -40,7 +40,7 @@ public Void call() throws Exception { if (validators != null) { configPathValues.add(Pair.with("plan.validator[0].count", validators)); } - Pair configs = + Pair configs = prepareAndPrintConfigs(action, "/config/simulator-config.yml"); if (action.equals(Task.run)) { diff --git a/start/cli/src/main/java/org/ethereum/beacon/SimulatorLauncher.java b/start/cli/src/main/java/org/ethereum/beacon/SimulatorLauncher.java index 0750fe401..85170e54a 100644 --- a/start/cli/src/main/java/org/ethereum/beacon/SimulatorLauncher.java +++ b/start/cli/src/main/java/org/ethereum/beacon/SimulatorLauncher.java @@ -10,7 +10,7 @@ import org.ethereum.beacon.chain.storage.impl.MemBeaconChainStorageFactory; import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.crypto.BLS381; @@ -43,8 +43,8 @@ public class SimulatorLauncher implements Runnable { private final ActionSimulate simulateConfig; private final MainConfig mainConfig; - private final ChainSpec chainSpec; - private final SpecHelpers specHelpers; + private final SpecConstants specConstants; + private final SpecHelpers spec; private final Level logLevel; private final Consumer onUpdateConfig; @@ -52,18 +52,18 @@ public class SimulatorLauncher implements Runnable { * Creates Simulator launcher with following settings * * @param mainConfig Configuration and run plan - * @param chainSpec Chain specification + * @param specConstants Chain specification * @param logLevel Log level, Apache log4j type * @param onUpdateConfig Callback to run when mainConfig is updated */ public SimulatorLauncher( MainConfig mainConfig, - ChainSpec chainSpec, + SpecConstants specConstants, Level logLevel, Consumer onUpdateConfig) { this.mainConfig = mainConfig; - this.chainSpec = chainSpec; - this.specHelpers = SpecHelpers.createWithSSZHasher(chainSpec, () -> 0L); + this.specConstants = specConstants; + this.spec = SpecHelpers.createWithSSZHasher(specConstants, () -> 0L); List actions = mainConfig.getPlan().getValidator(); Optional actionSimulate = actions.stream() @@ -110,10 +110,10 @@ private Pair, List> getValidatorDeposits() { for (String pKey : simulateConfig.getPrivateKeys()) { keyPairs.add(BLS381.KeyPair.create(BLS381.PrivateKey.create(Bytes32.fromHexString(pKey)))); } - return Pair.with(SimulateUtils.getDepositsForKeyPairs(keyPairs, specHelpers), keyPairs); + return Pair.with(SimulateUtils.getDepositsForKeyPairs(keyPairs, spec), keyPairs); } else { Pair, List> anyDeposits = - SimulateUtils.getAnyDeposits(specHelpers, simulateConfig.getCount()); + SimulateUtils.getAnyDeposits(spec, simulateConfig.getCount()); List pKeysEncoded = new ArrayList<>(); anyDeposits .getValue1() @@ -150,7 +150,7 @@ public void run() { for (int i = 0; i < keyPairs.size(); i++) { ControlledSchedulers schedulers = controlledSchedulers.createNew(); SpecHelpers specHelpers = - SpecHelpers.createWithSSZHasher(chainSpec, schedulers::getCurrentTime); + SpecHelpers.createWithSSZHasher(specConstants, schedulers::getCurrentTime); WireApi wireApi = localWireHub.createNewPeer("" + i); Launcher launcher = @@ -167,7 +167,7 @@ public void run() { .subscribe( slot -> System.out.println( - " #" + finalI + " Slot: " + slot.toString(chainSpec, genesisTime))); + " #" + finalI + " Slot: " + slot.toString(specConstants, genesisTime))); Flux.from(launcher.observableStateProcessor.getObservableStateStream()) .subscribe( os -> { @@ -181,7 +181,7 @@ public void run() { "#" + finalI + " !!! New block: " - + block.toString(chainSpec, genesisTime, specHelpers::hash_tree_root))); + + block.toString(specConstants, genesisTime, specHelpers::hash_tree_root))); Flux.from(launcher.beaconChainValidator.getAttestationsStream()) .subscribe( attest -> @@ -189,7 +189,7 @@ public void run() { "#" + finalI + " !!! New attestation: " - + attest.toString(chainSpec, genesisTime))); + + attest.toString(specConstants, genesisTime))); Flux.from(launcher.beaconChain.getBlockStatesStream()) .subscribe( blockState -> @@ -199,7 +199,7 @@ public void run() { + " Block imported: " + blockState .getBlock() - .toString(chainSpec, genesisTime, specHelpers::hash_tree_root))); + .toString(specConstants, genesisTime, specHelpers::hash_tree_root))); } System.out.println("Peers created"); diff --git a/start/cli/src/main/java/org/ethereum/beacon/util/SimulateUtils.java b/start/cli/src/main/java/org/ethereum/beacon/util/SimulateUtils.java index 67cca1a2d..6cd9c26dc 100644 --- a/start/cli/src/main/java/org/ethereum/beacon/util/SimulateUtils.java +++ b/start/cli/src/main/java/org/ethereum/beacon/util/SimulateUtils.java @@ -61,7 +61,7 @@ public static synchronized List getDepositsForKeyPairs( Collections.singletonList(Hash32.random(rnd)), UInt64.ZERO, new DepositData( - specHelpers.getChainSpec().getMaxDepositAmount(), + specHelpers.getConstants().getMaxDepositAmount(), Time.of(0), new DepositInput( BLSPubkey.wrap(Bytes48.leftPad(keyPair.getPublic().getEncodedBytes())), diff --git a/start/common/src/main/java/org/ethereum/beacon/Launcher.java b/start/common/src/main/java/org/ethereum/beacon/Launcher.java index 3845a2fd4..a4f66a8ff 100644 --- a/start/common/src/main/java/org/ethereum/beacon/Launcher.java +++ b/start/common/src/main/java/org/ethereum/beacon/Launcher.java @@ -16,7 +16,6 @@ import org.ethereum.beacon.consensus.transition.PerSlotTransition; import org.ethereum.beacon.consensus.verifier.BeaconBlockVerifier; import org.ethereum.beacon.consensus.verifier.BeaconStateVerifier; -import org.ethereum.beacon.consensus.verifier.VerificationResult; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.crypto.BLS381; import org.ethereum.beacon.crypto.BLS381.KeyPair; @@ -35,7 +34,7 @@ import reactor.core.publisher.Mono; public class Launcher { - final SpecHelpers specHelpers; + final SpecHelpers spec; final DepositContract depositContract; final BLS381.KeyPair validatorSig; final WireApi wireApi; @@ -52,14 +51,14 @@ public class Launcher { Schedulers schedulers; public Launcher( - SpecHelpers specHelpers, + SpecHelpers spec, DepositContract depositContract, KeyPair validatorSig, WireApi wireApi, BeaconChainStorageFactory storageFactory, Schedulers schedulers) { - this.specHelpers = specHelpers; + this.spec = spec; this.depositContract = depositContract; this.validatorSig = validatorSig; this.wireApi = wireApi; @@ -72,19 +71,19 @@ public Launcher( } void chainStarted(ChainStart chainStartEvent) { - InitialStateTransition initialTransition = new InitialStateTransition(chainStartEvent, specHelpers); - PerSlotTransition perSlotTransition = new PerSlotTransition(specHelpers); - PerBlockTransition perBlockTransition = new PerBlockTransition(specHelpers); - PerEpochTransition perEpochTransition = new PerEpochTransition(specHelpers); + InitialStateTransition initialTransition = new InitialStateTransition(chainStartEvent, spec); + PerSlotTransition perSlotTransition = new PerSlotTransition(spec); + PerBlockTransition perBlockTransition = new PerBlockTransition(spec); + PerEpochTransition perEpochTransition = new PerEpochTransition(spec); db = new InMemoryDatabase(); beaconChainStorage = storageFactory.create(db); - BeaconBlockVerifier blockVerifier = BeaconBlockVerifier.createDefault(specHelpers); - BeaconStateVerifier stateVerifier = BeaconStateVerifier.createDefault(specHelpers); + BeaconBlockVerifier blockVerifier = BeaconBlockVerifier.createDefault(spec); + BeaconStateVerifier stateVerifier = BeaconStateVerifier.createDefault(spec); beaconChain = new DefaultBeaconChain( - specHelpers, + spec, initialTransition, perSlotTransition, perBlockTransition, @@ -96,7 +95,7 @@ void chainStarted(ChainStart chainStartEvent) { beaconChain.init(); slotTicker = - new SlotTicker(specHelpers, beaconChain.getRecentlyProcessed().getState(), schedulers); + new SlotTicker(spec, beaconChain.getRecentlyProcessed().getState(), schedulers); slotTicker.start(); DirectProcessor allAttestations = DirectProcessor.create(); @@ -109,22 +108,21 @@ void chainStarted(ChainStart chainStartEvent) { slotTicker.getTickerStream(), allAttestations, beaconChain.getBlockStatesStream(), - specHelpers, + spec, perSlotTransition, perEpochTransition, schedulers); observableStateProcessor.start(); - beaconChainProposer = new BeaconChainProposerImpl(specHelpers, - specHelpers.getChainSpec(), perBlockTransition, perEpochTransition, depositContract); - beaconChainAttester = new BeaconChainAttesterImpl(specHelpers, - specHelpers.getChainSpec()); + beaconChainProposer = new BeaconChainProposerImpl(spec, + perBlockTransition, perEpochTransition, depositContract); + beaconChainAttester = new BeaconChainAttesterImpl(spec); beaconChainValidator = new BeaconChainValidator( BLS381Credentials.createWithInsecureSigner(validatorSig), beaconChainProposer, beaconChainAttester, - specHelpers, + spec, observableStateProcessor.getObservableStateStream(), schedulers); beaconChainValidator.start(); diff --git a/start/common/src/main/java/org/ethereum/beacon/MultiValidatorLauncher.java b/start/common/src/main/java/org/ethereum/beacon/MultiValidatorLauncher.java index 37737b5ab..013e3f372 100644 --- a/start/common/src/main/java/org/ethereum/beacon/MultiValidatorLauncher.java +++ b/start/common/src/main/java/org/ethereum/beacon/MultiValidatorLauncher.java @@ -37,7 +37,7 @@ import reactor.core.publisher.Mono; public class MultiValidatorLauncher { - private final SpecHelpers specHelpers; + private final SpecHelpers spec; private final DepositContract depositContract; private final List validatorSigs; private final WireApi wireApi; @@ -54,14 +54,14 @@ public class MultiValidatorLauncher { Schedulers schedulers; public MultiValidatorLauncher( - SpecHelpers specHelpers, + SpecHelpers spec, DepositContract depositContract, List validatorSigs, WireApi wireApi, BeaconChainStorageFactory storageFactory, Schedulers schedulers) { - this.specHelpers = specHelpers; + this.spec = spec; this.depositContract = depositContract; this.validatorSigs = validatorSigs; this.wireApi = wireApi; @@ -74,10 +74,10 @@ public MultiValidatorLauncher( } void chainStarted(ChainStart chainStartEvent) { - InitialStateTransition initialTransition = new InitialStateTransition(chainStartEvent, specHelpers); - PerSlotTransition perSlotTransition = new PerSlotTransition(specHelpers); - PerBlockTransition perBlockTransition = new PerBlockTransition(specHelpers); - PerEpochTransition perEpochTransition = new PerEpochTransition(specHelpers); + InitialStateTransition initialTransition = new InitialStateTransition(chainStartEvent, spec); + PerSlotTransition perSlotTransition = new PerSlotTransition(spec); + PerBlockTransition perBlockTransition = new PerBlockTransition(spec); + PerEpochTransition perEpochTransition = new PerEpochTransition(spec); db = new InMemoryDatabase(); beaconChainStorage = storageFactory.create(db); @@ -88,7 +88,7 @@ void chainStarted(ChainStart chainStartEvent) { BeaconStateVerifier stateVerifier = (block, state) -> VerificationResult.PASSED; beaconChain = new DefaultBeaconChain( - specHelpers, + spec, initialTransition, perSlotTransition, perBlockTransition, @@ -100,7 +100,7 @@ void chainStarted(ChainStart chainStartEvent) { beaconChain.init(); slotTicker = - new SlotTicker(specHelpers, beaconChain.getRecentlyProcessed().getState(), schedulers); + new SlotTicker(spec, beaconChain.getRecentlyProcessed().getState(), schedulers); slotTicker.start(); DirectProcessor allAttestations = DirectProcessor.create(); @@ -113,16 +113,15 @@ void chainStarted(ChainStart chainStartEvent) { slotTicker.getTickerStream(), allAttestations, beaconChain.getBlockStatesStream(), - specHelpers, + spec, perSlotTransition, perEpochTransition, schedulers); observableStateProcessor.start(); - beaconChainProposer = new BeaconChainProposerImpl(specHelpers, - specHelpers.getChainSpec(), perBlockTransition, perEpochTransition, depositContract); - beaconChainAttester = new BeaconChainAttesterImpl(specHelpers, - specHelpers.getChainSpec()); + beaconChainProposer = new BeaconChainProposerImpl(spec, + perBlockTransition, perEpochTransition, depositContract); + beaconChainAttester = new BeaconChainAttesterImpl(spec); List credentials = validatorSigs.stream() @@ -133,7 +132,7 @@ void chainStarted(ChainStart chainStartEvent) { credentials, beaconChainProposer, beaconChainAttester, - specHelpers, + spec, observableStateProcessor.getObservableStateStream(), schedulers); beaconChainValidator.start(); diff --git a/start/common/src/test/java/org/ethereum/beacon/LocalMultiValidatorTest.java b/start/common/src/test/java/org/ethereum/beacon/LocalMultiValidatorTest.java index 2f00d662e..59ccd8e2a 100644 --- a/start/common/src/test/java/org/ethereum/beacon/LocalMultiValidatorTest.java +++ b/start/common/src/test/java/org/ethereum/beacon/LocalMultiValidatorTest.java @@ -1,7 +1,6 @@ package org.ethereum.beacon; import java.time.Duration; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -10,7 +9,7 @@ import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.consensus.TestUtils; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.core.types.Time; @@ -19,7 +18,6 @@ import org.ethereum.beacon.pow.DepositContract; import org.ethereum.beacon.pow.DepositContract.ChainStart; import org.ethereum.beacon.schedulers.ControlledSchedulers; -import org.ethereum.beacon.schedulers.LoggerMDCExecutor; import org.ethereum.beacon.schedulers.Schedulers; import org.ethereum.beacon.wire.LocalWireHub; import org.ethereum.beacon.wire.WireApi; @@ -77,8 +75,8 @@ public static void main(String[] args) throws Exception { Eth1Data eth1Data = new Eth1Data(Hash32.random(rnd), Hash32.random(rnd)); - ChainSpec chainSpec = - new ChainSpec() { + SpecConstants specConstants = + new SpecConstants() { @Override public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(epochLength)); @@ -105,7 +103,7 @@ public SlotNumber getMinAttestationInclusionDelay() { }; Pair, List> anyDeposits = TestUtils.getAnyDeposits( - rnd, SpecHelpers.createWithSSZHasher(chainSpec, () -> 0L), validatorCount); + rnd, SpecHelpers.createWithSSZHasher(specConstants, () -> 0L), validatorCount); List deposits = anyDeposits.getValue0(); LocalWireHub localWireHub = new LocalWireHub(s -> {}); @@ -116,7 +114,7 @@ public SlotNumber getMinAttestationInclusionDelay() { ControlledSchedulers schedulers = Schedulers.createControlled(); schedulers.setCurrentTime(genesisTime.getMillis().getValue() + 1000); SpecHelpers specHelpers = SpecHelpers - .createWithSSZHasher(chainSpec, schedulers::getCurrentTime); + .createWithSSZHasher(specConstants, schedulers::getCurrentTime); WireApi wireApi = localWireHub.createNewPeer("multi-peer"); MultiValidatorLauncher launcher = @@ -129,20 +127,20 @@ public SlotNumber getMinAttestationInclusionDelay() { schedulers); Flux.from(launcher.slotTicker.getTickerStream()) - .subscribe(slot -> System.out.println("Slot: " + slot.toString(chainSpec, genesisTime))); + .subscribe(slot -> System.out.println("Slot: " + slot.toString(specConstants, genesisTime))); Flux.from(launcher.observableStateProcessor.getObservableStateStream()) .subscribe(os -> { System.out.println("New observable state: " + os.toString(specHelpers)); }); Flux.from(launcher.beaconChainValidator.getProposedBlocksStream()) .subscribe(block ->System.out.println(" !!!New block: " + - block.toString(chainSpec, genesisTime, specHelpers::hash_tree_root))); + block.toString(specConstants, genesisTime, specHelpers::hash_tree_root))); Flux.from(launcher.beaconChainValidator.getAttestationsStream()) .subscribe(attest ->System.out.println(" !!!New attestation: " + - attest.toString(chainSpec, genesisTime))); + attest.toString(specConstants, genesisTime))); Flux.from(launcher.beaconChain.getBlockStatesStream()) .subscribe(blockState ->System.out.println("Block imported: " + - blockState.getBlock().toString(chainSpec, genesisTime, specHelpers::hash_tree_root))); + blockState.getBlock().toString(specConstants, genesisTime, specHelpers::hash_tree_root))); System.out.println("Multi validator started"); while (true) { diff --git a/start/common/src/test/java/org/ethereum/beacon/LocalNetTest.java b/start/common/src/test/java/org/ethereum/beacon/LocalNetTest.java index ca06825ae..dd98a652a 100644 --- a/start/common/src/test/java/org/ethereum/beacon/LocalNetTest.java +++ b/start/common/src/test/java/org/ethereum/beacon/LocalNetTest.java @@ -19,7 +19,7 @@ import org.ethereum.beacon.consensus.hasher.SSZObjectHasher; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.PendingAttestationRecord; import org.ethereum.beacon.core.state.ShardCommittee; @@ -130,8 +130,8 @@ public static void main(String[] args) throws Exception { Eth1Data eth1Data = new Eth1Data(Hash32.random(rnd), Hash32.random(rnd)); - ChainSpec chainSpec = - new ChainSpec() { + SpecConstants specConstants = + new SpecConstants() { @Override public SlotNumber.EpochLength getSlotsPerEpoch() { return new SlotNumber.EpochLength(UInt64.valueOf(epochLength)); @@ -163,7 +163,7 @@ public ShardNumber getShardCount() { }; Pair, List> anyDeposits = TestUtils.getAnyDeposits( - rnd, createLightSpecHelpers(chainSpec, () -> 0L), validatorCount); + rnd, createLightSpecHelpers(specConstants, () -> 0L), validatorCount); List deposits = anyDeposits.getValue0(); LocalWireHub localWireHub = new LocalWireHub(s -> {}); @@ -174,7 +174,7 @@ public ShardNumber getShardCount() { List peers = new ArrayList<>(); for(int i = 0; i < validatorCount; i++) { ControlledSchedulers schedulers = controlledSchedulers.createNew(); - SpecHelpers specHelpers = createLightSpecHelpers(chainSpec, schedulers::getCurrentTime); + SpecHelpers specHelpers = createLightSpecHelpers(specConstants, schedulers::getCurrentTime); WireApi wireApi = localWireHub.createNewPeer("" + i); Launcher launcher = new Launcher(specHelpers, depositContract, anyDeposits.getValue1().get(i), @@ -183,20 +183,21 @@ public ShardNumber getShardCount() { int finalI = i; Flux.from(launcher.slotTicker.getTickerStream()) - .subscribe(slot -> System.out.println(" #" + finalI + " Slot: " + slot.toString(chainSpec, genesisTime))); + .subscribe(slot -> System.out.println(" #" + finalI + " Slot: " + slot.toString( + specConstants, genesisTime))); Flux.from(launcher.observableStateProcessor.getObservableStateStream()) .subscribe(os -> { System.out.println(" #" + finalI + " New observable state: " + os.toString(specHelpers)); }); Flux.from(launcher.beaconChainValidator.getProposedBlocksStream()) .subscribe(block ->System.out.println("#" + finalI + " !!! New block: " + - block.toString(chainSpec, genesisTime, specHelpers::hash_tree_root))); + block.toString(specConstants, genesisTime, specHelpers::hash_tree_root))); Flux.from(launcher.beaconChainValidator.getAttestationsStream()) .subscribe(attest ->System.out.println("#" + finalI + " !!! New attestation: " + - attest.toString(chainSpec, genesisTime))); + attest.toString(specConstants, genesisTime))); Flux.from(launcher.beaconChain.getBlockStatesStream()) .subscribe(blockState ->System.out.println(" #" + finalI + " Block imported: " + - blockState.getBlock().toString(chainSpec, genesisTime, specHelpers::hash_tree_root))); + blockState.getBlock().toString(specConstants, genesisTime, specHelpers::hash_tree_root))); } System.out.println("Peers created"); @@ -246,7 +247,7 @@ public ShardNumber getShardCount() { }); Map slotStates = new HashMap<>(); - SpecHelpers specHelpers = peers.get(0).specHelpers; + SpecHelpers specHelpers = peers.get(0).spec; Flux.from(peers.get(0).observableStateProcessor.getObservableStateStream()) .subscribe((ObservableBeaconState state) -> { @@ -302,7 +303,7 @@ static List fromPending(PendingAttestationRecord attestation) { BLSSignature.ZERO)); } - static SpecHelpers createLightSpecHelpers(ChainSpec spec, Supplier time) { + static SpecHelpers createLightSpecHelpers(SpecConstants spec, Supplier time) { return new SpecHelpers(spec, Hashes::keccak256, SSZObjectHasher.create(Hashes::keccak256), time) { @Override public boolean bls_verify(BLSPubkey publicKey, Hash32 message, BLSSignature signature, Bytes8 domain) { diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/InitialValuesData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/InitialValuesData.java index 40bd4f12a..d5f7ca90f 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/InitialValuesData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/InitialValuesData.java @@ -44,7 +44,7 @@ public SlotNumber getGenesisSlot() { @Override @JsonIgnore public EpochNumber getGenesisEpoch() { - return null;// XXX: is set in final ChainSpec construction + return null;// XXX: is set in final SpecConstants construction } @Override diff --git a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/SpecConstantsData.java similarity index 97% rename from start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java rename to start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/SpecConstantsData.java index 42d1c7d3a..e16c5673d 100644 --- a/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/ChainSpecData.java +++ b/start/config/src/main/java/org/ethereum/beacon/emulator/config/chainspec/SpecConstantsData.java @@ -1,7 +1,7 @@ package org.ethereum.beacon.emulator.config.chainspec; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.EpochNumber; import org.ethereum.beacon.core.types.Gwei; @@ -15,9 +15,9 @@ import tech.pegasys.artemis.util.bytes.Bytes1; import tech.pegasys.artemis.util.uint.UInt64; -/** ChainSpec settings object, creates {@link ChainSpec} from user data */ +/** SpecConstants settings object, creates {@link SpecConstants} from user data */ @JsonIgnoreProperties(ignoreUnknown = true) -public class ChainSpecData implements Config { +public class SpecConstantsData implements Config { private DepositContractParametersData depositContractParameters; private HonestValidatorParametersData honestValidatorParameters; private InitialValuesData initialValues; @@ -28,8 +28,8 @@ public class ChainSpecData implements Config { private StateListLengthsData stateListLengths; private TimeParametersData timeParameters; - public ChainSpec build() { - return new ChainSpec() { + public SpecConstants build() { + return new SpecConstants() { @Override public Address getDepositContractAddress() { return depositContractParameters.getDepositContractAddress(); diff --git a/start/config/src/test/java/org/ethereum/beacon/emulator/config/ConfigBuilderTest.java b/start/config/src/test/java/org/ethereum/beacon/emulator/config/ConfigBuilderTest.java index 28ff3c885..73def5e0b 100644 --- a/start/config/src/test/java/org/ethereum/beacon/emulator/config/ConfigBuilderTest.java +++ b/start/config/src/test/java/org/ethereum/beacon/emulator/config/ConfigBuilderTest.java @@ -1,7 +1,7 @@ package org.ethereum.beacon.emulator.config; -import org.ethereum.beacon.core.spec.ChainSpec; -import org.ethereum.beacon.emulator.config.chainspec.ChainSpecData; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.emulator.config.chainspec.SpecConstantsData; import org.ethereum.beacon.emulator.config.main.Configuration; import org.ethereum.beacon.emulator.config.main.MainConfig; import org.ethereum.beacon.emulator.config.main.action.ActionSimulate; @@ -46,24 +46,24 @@ public void test1() { @Test public void testChainSpec() { - ConfigBuilder configBuilder = new ConfigBuilder(ChainSpecData.class); + ConfigBuilder configBuilder = new ConfigBuilder(SpecConstantsData.class); File testYamlConfig = new File(getClass().getClassLoader().getResource("chainSpec.yml").getFile()); configBuilder.addYamlConfig(testYamlConfig); - ChainSpecData unmodified = (ChainSpecData) configBuilder.build(); - ChainSpec chainSpec = unmodified.build(); + SpecConstantsData unmodified = (SpecConstantsData) configBuilder.build(); + SpecConstants specConstants = unmodified.build(); - ChainSpec chainSpecDefault = ChainSpec.DEFAULT; - assertEquals(chainSpecDefault.getGenesisEpoch(), chainSpec.getGenesisEpoch()); - assertEquals(chainSpecDefault.getEmptySignature(), chainSpec.getEmptySignature()); - assertEquals(chainSpecDefault.getSlotsPerEpoch(), chainSpec.getSlotsPerEpoch()); - assertEquals(chainSpecDefault.getSecondsPerSlot(), chainSpec.getSecondsPerSlot()); + SpecConstants specConstantsDefault = SpecConstants.DEFAULT; + assertEquals(specConstantsDefault.getGenesisEpoch(), specConstants.getGenesisEpoch()); + assertEquals(specConstantsDefault.getEmptySignature(), specConstants.getEmptySignature()); + assertEquals(specConstantsDefault.getSlotsPerEpoch(), specConstants.getSlotsPerEpoch()); + assertEquals(specConstantsDefault.getSecondsPerSlot(), specConstants.getSecondsPerSlot()); configBuilder.addConfigOverride("timeParameters.SECONDS_PER_SLOT", "10"); - ChainSpecData overriden = (ChainSpecData) configBuilder.build(); - ChainSpec chainSpec2 = overriden.build(); - assertNotEquals(chainSpecDefault.getSecondsPerSlot(), chainSpec2.getSecondsPerSlot()); - assertEquals(UInt64.valueOf(10), chainSpec2.getSecondsPerSlot()); + SpecConstantsData overriden = (SpecConstantsData) configBuilder.build(); + SpecConstants specConstants2 = overriden.build(); + assertNotEquals(specConstantsDefault.getSecondsPerSlot(), specConstants2.getSecondsPerSlot()); + assertEquals(UInt64.valueOf(10), specConstants2.getSecondsPerSlot()); } } diff --git a/validator/src/main/java/org/ethereum/beacon/validator/BeaconChainValidator.java b/validator/src/main/java/org/ethereum/beacon/validator/BeaconChainValidator.java index d149e111d..e85b96602 100644 --- a/validator/src/main/java/org/ethereum/beacon/validator/BeaconChainValidator.java +++ b/validator/src/main/java/org/ethereum/beacon/validator/BeaconChainValidator.java @@ -52,7 +52,7 @@ public class BeaconChainValidator implements ValidatorService { /** Attester logic. */ private BeaconChainAttester attester; /** The spec. */ - private SpecHelpers specHelpers; + private SpecHelpers spec; private Publisher stateStream; @@ -70,13 +70,13 @@ public BeaconChainValidator( BLS381Credentials blsCredentials, BeaconChainProposer proposer, BeaconChainAttester attester, - SpecHelpers specHelpers, + SpecHelpers spec, Publisher stateStream, Schedulers schedulers) { this.blsCredentials = blsCredentials; this.proposer = proposer; this.attester = attester; - this.specHelpers = specHelpers; + this.spec = spec; this.stateStream = stateStream; this.schedulers = schedulers; @@ -108,7 +108,7 @@ public void stop() {} */ @VisibleForTesting void init(BeaconState state) { - this.validatorIndex = specHelpers.get_validator_index_by_pubkey(state, blsCredentials.getPubkey()); + this.validatorIndex = spec.get_validator_index_by_pubkey(state, blsCredentials.getPubkey()); } /** @@ -186,7 +186,7 @@ void runTasks(final ObservableBeaconState observableState) { // trigger attester at a halfway through the slot if (getValidatorCommittee(state).isPresent()) { - Time startAt = specHelpers.get_slot_middle_time(state, state.getSlot()); + Time startAt = spec.get_slot_middle_time(state, state.getSlot()); schedule(startAt, this::attest); } } @@ -264,7 +264,7 @@ private void setSlotProcessed(BeaconState state) { */ private boolean isEligibleToPropose(BeaconStateEx state) { return state.getTransition() == TransitionType.SLOT - && validatorIndex.equals(specHelpers.get_beacon_proposer_index(state, state.getSlot())); + && validatorIndex.equals(spec.get_beacon_proposer_index(state, state.getSlot())); } /** @@ -272,7 +272,7 @@ private boolean isEligibleToPropose(BeaconStateEx state) { */ private Optional getValidatorCommittee(BeaconState state) { List committees = - specHelpers.get_crosslink_committees_at_slot(state, state.getSlot()); + spec.get_crosslink_committees_at_slot(state, state.getSlot()); return committees.stream().filter(sc -> sc.getCommittee().contains(validatorIndex)).findFirst(); } @@ -297,7 +297,7 @@ private boolean isSlotProcessed(BeaconState state) { * @return {@link true} if current moment belongs to a slot, {@link false} otherwise. */ private boolean isCurrentSlot(BeaconState state) { - return specHelpers.is_current_slot(state); + return spec.is_current_slot(state); } /** diff --git a/validator/src/main/java/org/ethereum/beacon/validator/MultiValidatorService.java b/validator/src/main/java/org/ethereum/beacon/validator/MultiValidatorService.java index e039a7397..83fb885a7 100644 --- a/validator/src/main/java/org/ethereum/beacon/validator/MultiValidatorService.java +++ b/validator/src/main/java/org/ethereum/beacon/validator/MultiValidatorService.java @@ -1,18 +1,12 @@ package org.ethereum.beacon.validator; import com.google.common.annotations.VisibleForTesting; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; @@ -55,7 +49,7 @@ public class MultiValidatorService implements ValidatorService { /** Attester logic. */ private BeaconChainAttester attester; /** The spec. */ - private SpecHelpers specHelpers; + private SpecHelpers spec; private Publisher stateStream; @@ -77,7 +71,7 @@ public MultiValidatorService( List blsCredentials, BeaconChainProposer proposer, BeaconChainAttester attester, - SpecHelpers specHelpers, + SpecHelpers spec, Publisher stateStream, Schedulers schedulers) { this.uninitialized = @@ -85,7 +79,7 @@ public MultiValidatorService( .collect(Collectors.toMap(BLS381Credentials::getPubkey, Function.identity())); this.proposer = proposer; this.attester = attester; - this.specHelpers = specHelpers; + this.spec = spec; this.stateStream = stateStream; this.schedulers = schedulers; @@ -201,15 +195,15 @@ void runTasks(final ObservableBeaconState observableState) { BeaconState state = observableState.getLatestSlotState(); // trigger proposer - ValidatorIndex proposerIndex = specHelpers.get_beacon_proposer_index(state, state.getSlot()); + ValidatorIndex proposerIndex = spec.get_beacon_proposer_index(state, state.getSlot()); if (initialized.containsKey(proposerIndex)) { runAsync(() -> propose(proposerIndex, observableState)); } // trigger attester at a halfway through the slot - Time startAt = specHelpers.get_slot_middle_time(state, state.getSlot()); + Time startAt = spec.get_slot_middle_time(state, state.getSlot()); List committees = - specHelpers.get_crosslink_committees_at_slot(state, state.getSlot()); + spec.get_crosslink_committees_at_slot(state, state.getSlot()); for (ShardCommittee sc : committees) { sc.getCommittee().stream() .filter(initialized::containsKey) @@ -255,9 +249,9 @@ private void propose(ValidatorIndex index, final ObservableBeaconState observabl "validator {}: proposed a {}", index, newBlock.toString( - specHelpers.getChainSpec(), + spec.getConstants(), observableState.getLatestSlotState().getGenesisTime(), - specHelpers::hash_tree_root)); + spec::hash_tree_root)); } } @@ -288,9 +282,9 @@ private void attest(ValidatorIndex index) { observableState .getHead() .toString( - specHelpers.getChainSpec(), + spec.getConstants(), observableState.getLatestSlotState().getGenesisTime(), - specHelpers::hash_tree_root), + spec::hash_tree_root), state.getSlot()); } } @@ -309,7 +303,7 @@ private void setSlotProcessed(BeaconState state) { /** Returns committee where the validator participates if any */ private Optional getValidatorCommittee(ValidatorIndex index, BeaconState state) { List committees = - specHelpers.get_crosslink_committees_at_slot(state, state.getSlot()); + spec.get_crosslink_committees_at_slot(state, state.getSlot()); return committees.stream().filter(sc -> sc.getCommittee().contains(index)).findFirst(); } @@ -334,7 +328,7 @@ private boolean isSlotProcessed(BeaconState state) { * @return {@link true} if current moment belongs to a slot, {@link false} otherwise. */ private boolean isCurrentSlot(BeaconState state) { - return specHelpers.is_current_slot(state); + return spec.is_current_slot(state); } /** diff --git a/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java b/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java index f7122097a..56d7439a7 100644 --- a/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java +++ b/validator/src/main/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterImpl.java @@ -12,7 +12,7 @@ import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Bitfield; @@ -37,13 +37,10 @@ public class BeaconChainAttesterImpl implements BeaconChainAttester { /** The spec. */ - private SpecHelpers specHelpers; - /** Chain parameters. */ - private ChainSpec chainSpec; + private SpecHelpers spec; - public BeaconChainAttesterImpl(SpecHelpers specHelpers, ChainSpec chainSpec) { - this.specHelpers = specHelpers; - this.chainSpec = chainSpec; + public BeaconChainAttesterImpl(SpecHelpers spec) { + this.spec = spec; } @Override @@ -55,7 +52,7 @@ public Attestation attest( BeaconState state = observableState.getLatestSlotState(); SlotNumber slot = state.getSlot(); - Hash32 beaconBlockRoot = specHelpers.hash_tree_root(observableState.getHead()); + Hash32 beaconBlockRoot = spec.hash_tree_root(observableState.getHead()); Hash32 epochBoundaryRoot = getEpochBoundaryRoot(state, observableState.getHead()); Hash32 crosslinkDataRoot = Hash32.ZERO; // Note: This is a stub for phase 0. Crosslink latestCrosslink = getLatestCrosslink(state, shard); @@ -90,10 +87,10 @@ public Attestation attest( */ @VisibleForTesting List getCommittee(BeaconState state, ShardNumber shard) { - if (shard.equals(chainSpec.getBeaconChainShardNumber())) { - return specHelpers.get_crosslink_committees_at_slot(state, state.getSlot()).get(0).getCommittee(); + if (shard.equals(spec.getConstants().getBeaconChainShardNumber())) { + return spec.get_crosslink_committees_at_slot(state, state.getSlot()).get(0).getCommittee(); } else { - return specHelpers + return spec .get_crosslink_committees_at_slot(state, state.getSlot()).stream() .filter(sc -> sc.getShard().equals(shard)) .findFirst() @@ -110,8 +107,8 @@ List getCommittee(BeaconState state, ShardNumber shard) { Hash32 getEpochBoundaryRoot(BeaconState state, BeaconBlock head) { SlotNumber ancestorMaxSlot = head.getSlot().decrement(); SlotNumber epochBoundarySlot = - ancestorMaxSlot.minus(ancestorMaxSlot.modulo(chainSpec.getSlotsPerEpoch())); - return specHelpers.get_block_root(state, epochBoundarySlot); + ancestorMaxSlot.minus(ancestorMaxSlot.modulo(spec.getConstants().getSlotsPerEpoch())); + return spec.get_block_root(state, epochBoundarySlot); } /* @@ -120,7 +117,7 @@ Hash32 getEpochBoundaryRoot(BeaconState state, BeaconBlock head) { */ @VisibleForTesting Crosslink getLatestCrosslink(BeaconState state, ShardNumber shard) { - if (shard.equals(chainSpec.getBeaconChainShardNumber())) { + if (shard.equals(spec.getConstants().getBeaconChainShardNumber())) { return Crosslink.EMPTY; } else { return state.getLatestCrosslinks().get(shard); @@ -135,8 +132,8 @@ Crosslink getLatestCrosslink(BeaconState state, ShardNumber shard) { */ @VisibleForTesting Hash32 getJustifiedBlockRoot(BeaconState state) { - SlotNumber slot = specHelpers.get_epoch_start_slot(state.getJustifiedEpoch()); - return specHelpers.get_block_root(state, slot); + SlotNumber slot = spec.get_epoch_start_slot(state.getJustifiedEpoch()); + return spec.get_block_root(state, slot); } /* @@ -178,9 +175,9 @@ private BLSSignature getAggregateSignature( BeaconState state, AttestationData data, MessageSigner signer) { AttestationDataAndCustodyBit attestationDataAndCustodyBit = new AttestationDataAndCustodyBit(data, false); - Hash32 hash = specHelpers.hash_tree_root(attestationDataAndCustodyBit); - Bytes8 domain = specHelpers.get_domain(state.getForkData(), - specHelpers.get_current_epoch(state), ATTESTATION); + Hash32 hash = spec.hash_tree_root(attestationDataAndCustodyBit); + Bytes8 domain = spec.get_domain(state.getForkData(), + spec.get_current_epoch(state), ATTESTATION); return signer.sign(hash, domain); } } diff --git a/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java b/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java index 2e51800f6..22f6e4c2c 100644 --- a/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java +++ b/validator/src/main/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerImpl.java @@ -18,12 +18,12 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; +import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.Transfer; import org.ethereum.beacon.core.operations.VoluntaryExit; -import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.operations.slashing.Proposal; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.types.BLSSignature; @@ -47,9 +47,7 @@ public class BeaconChainProposerImpl implements BeaconChainProposer { /** The spec. */ - private SpecHelpers specHelpers; - /** Chain parameters. */ - private ChainSpec chainSpec; + private SpecHelpers spec; /** Per-block state transition. */ private BlockTransition perBlockTransition; /** Per-epoch state transition. */ @@ -58,13 +56,11 @@ public class BeaconChainProposerImpl implements BeaconChainProposer { private DepositContract depositContract; public BeaconChainProposerImpl( - SpecHelpers specHelpers, - ChainSpec chainSpec, + SpecHelpers spec, BlockTransition perBlockTransition, StateTransition perEpochTransition, DepositContract depositContract) { - this.specHelpers = specHelpers; - this.chainSpec = chainSpec; + this.spec = spec; this.perBlockTransition = perBlockTransition; this.perEpochTransition = perEpochTransition; this.depositContract = depositContract; @@ -75,7 +71,7 @@ public BeaconBlock propose( ObservableBeaconState observableState, MessageSigner signer) { BeaconStateEx state = observableState.getLatestSlotState(); - Hash32 parentRoot = specHelpers.get_block_root(state, state.getSlot().decrement()); + Hash32 parentRoot = spec.get_block_root(state, state.getSlot().decrement()); BLSSignature randaoReveal = getRandaoReveal(state, signer); Eth1Data eth1Data = getEth1Data(state); BeaconBlockBody blockBody = getBlockBody(state, observableState.getPendingOperations()); @@ -88,13 +84,13 @@ public BeaconBlock propose( .withStateRoot(Hash32.ZERO) .withRandaoReveal(randaoReveal) .withEth1Data(eth1Data) - .withSignature(chainSpec.getEmptySignature()) + .withSignature(spec.getConstants().getEmptySignature()) .withBody(blockBody); // calculate state_root BeaconBlock newBlock = builder.build(); BeaconState newState = applyStateTransition(state, newBlock); - builder.withStateRoot(specHelpers.hash_tree_root(newState)); + builder.withStateRoot(spec.hash_tree_root(newState)); // sign off on proposal BeaconBlock blockWithoutSignature = builder.build(); @@ -106,7 +102,7 @@ public BeaconBlock propose( private BeaconStateEx applyStateTransition(BeaconStateEx sourceEx, BeaconBlock block) { BeaconStateEx blockState = perBlockTransition.apply(sourceEx, block); - if (specHelpers.is_epoch_end(blockState.getSlot())) { + if (spec.is_epoch_end(blockState.getSlot())) { return perEpochTransition.apply(blockState); } else { return blockState; @@ -126,12 +122,12 @@ private BLSSignature getProposalSignature( Proposal proposal = new Proposal( state.getSlot(), - chainSpec.getBeaconChainShardNumber(), - specHelpers.signed_root(block, "signature"), + spec.getConstants().getBeaconChainShardNumber(), + spec.signed_root(block, "signature"), block.getSignature()); - Hash32 proposalRoot = specHelpers.signed_root(proposal, "signature"); - Bytes8 domain = specHelpers.get_domain(state.getForkData(), - specHelpers.get_current_epoch(state), PROPOSAL); + Hash32 proposalRoot = spec.signed_root(proposal, "signature"); + Bytes8 domain = spec.get_domain(state.getForkData(), + spec.get_current_epoch(state), PROPOSAL); return signer.sign(proposalRoot, domain); } @@ -144,9 +140,9 @@ private BLSSignature getProposalSignature( */ private BLSSignature getRandaoReveal(BeaconState state, MessageSigner signer) { Hash32 hash = - Hash32.wrap(Bytes32.leftPad(specHelpers.get_current_epoch(state).toBytesBigEndian())); - Bytes8 domain = specHelpers.get_domain(state.getForkData(), - specHelpers.get_current_epoch(state), RANDAO); + Hash32.wrap(Bytes32.leftPad(spec.get_current_epoch(state).toBytesBigEndian())); + Bytes8 domain = spec.get_domain(state.getForkData(), + spec.get_current_epoch(state), RANDAO); return signer.sign(hash, domain); } @@ -203,22 +199,26 @@ private Eth1Data getEth1Data(BeaconState state) { */ private BeaconBlockBody getBlockBody(BeaconState state, PendingOperations operations) { List proposerSlashings = - operations.peekProposerSlashings(chainSpec.getMaxProposerSlashings()); + operations.peekProposerSlashings(spec.getConstants().getMaxProposerSlashings()); List attesterSlashings = - operations.peekAttesterSlashings(chainSpec.getMaxAttesterSlashings()); + operations.peekAttesterSlashings(spec.getConstants().getMaxAttesterSlashings()); List attestations = operations.peekAggregatedAttestations( - chainSpec.getMaxAttestations(), - state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay()).minus(chainSpec.getSlotsPerEpoch()), - state.getSlot().minus(chainSpec.getMinAttestationInclusionDelay())); - List voluntaryExits = operations.peekExits(chainSpec.getMaxVoluntaryExits()); - List transfers = operations.peekTransfers(chainSpec.getMaxTransfers()); + spec.getConstants().getMaxAttestations(), + state.getSlot().minus(spec.getConstants().getMinAttestationInclusionDelay()).minus( + spec.getConstants().getSlotsPerEpoch()), + state.getSlot().minus(spec.getConstants().getMinAttestationInclusionDelay())); + List voluntaryExits = + operations.peekExits(spec.getConstants().getMaxVoluntaryExits()); + List transfers = operations.peekTransfers(spec.getConstants().getMaxTransfers()); Eth1Data latestProcessedDeposit = null; // TODO wait for spec update to include this to state List deposits = depositContract .peekDeposits( - chainSpec.getMaxDeposits(), latestProcessedDeposit, state.getLatestEth1Data()) + spec.getConstants().getMaxDeposits(), + latestProcessedDeposit, + state.getLatestEth1Data()) .stream() .map(DepositInfo::getDeposit) .collect(Collectors.toList()); diff --git a/validator/src/test/java/org/ethereum/beacon/validator/BeaconChainValidatorTest.java b/validator/src/test/java/org/ethereum/beacon/validator/BeaconChainValidatorTest.java index b95cafd5a..6c4447e98 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/BeaconChainValidatorTest.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/BeaconChainValidatorTest.java @@ -6,10 +6,9 @@ import org.ethereum.beacon.chain.observer.ObservableBeaconState; import org.ethereum.beacon.chain.util.ObservableBeaconStateTestUtil; import org.ethereum.beacon.consensus.SpecHelpers; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.core.types.ValidatorIndex; -import org.ethereum.beacon.schedulers.DefaultSchedulers; import org.ethereum.beacon.schedulers.Schedulers; import org.ethereum.beacon.validator.util.ValidatorServiceTestUtil; import org.junit.Assert; @@ -23,7 +22,7 @@ public void recentStateIsKept() { Random random = new Random(); Schedulers schedulers = Schedulers.createDefault(); SpecHelpers specHelpers = - Mockito.spy(SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, schedulers::getCurrentTime)); + Mockito.spy(SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, schedulers::getCurrentTime)); BeaconChainValidator validator = ValidatorServiceTestUtil.mockBeaconChainValidator(random, specHelpers); @@ -51,7 +50,7 @@ public void outboundRecentStateIsIgnored() { Random random = new Random(); Schedulers schedulers = Schedulers.createDefault(); SpecHelpers specHelpers = - Mockito.spy(SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, schedulers::getCurrentTime)); + Mockito.spy(SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, schedulers::getCurrentTime)); BeaconChainValidator validator = ValidatorServiceTestUtil.mockBeaconChainValidator(random, specHelpers); @@ -84,7 +83,7 @@ public void initService() { Random random = new Random(); Schedulers schedulers = Schedulers.createDefault(); SpecHelpers specHelpers = - Mockito.spy(SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, schedulers::getCurrentTime)); + Mockito.spy(SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, schedulers::getCurrentTime)); BeaconChainValidator validator = ValidatorServiceTestUtil.mockBeaconChainValidator(random, specHelpers); @@ -125,7 +124,7 @@ public void runValidatorTasks() { Random random = new Random(); Schedulers schedulers = Schedulers.createDefault(); SpecHelpers specHelpers = - Mockito.spy(SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, schedulers::getCurrentTime)); + Mockito.spy(SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, schedulers::getCurrentTime)); BeaconChainValidator validator = ValidatorServiceTestUtil.mockBeaconChainValidator(random, specHelpers); diff --git a/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java b/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java index 4954b87ba..3e8bf5c5c 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java @@ -13,7 +13,7 @@ import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.spec.SignatureDomains; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.ShardNumber; @@ -31,7 +31,7 @@ public class BeaconChainAttesterTest { public void attestASlot() { Random random = new Random(); - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); MessageSigner signer = MessageSignerTestUtil.createBLSSigner(); BeaconChainAttesterImpl attester = BeaconChainAttesterTestUtil.mockAttester(specHelpers); @@ -39,13 +39,13 @@ public void attestASlot() { ObservableBeaconStateTestUtil.createInitialState(random, specHelpers); List committee = - getCommittee(specHelpers.getChainSpec().getTargetCommitteeSize().getIntValue()); + getCommittee(specHelpers.getConstants().getTargetCommitteeSize().getIntValue()); int indexIntoCommittee = Math.abs(random.nextInt() % committee.size()); ValidatorIndex validatorIndex = committee.get(indexIntoCommittee); Hash32 epochBoundaryRoot = Hash32.random(random); Hash32 latestCrosslinkRoot = Hash32.random(random); Hash32 justifiedBlockRoot = Hash32.random(random); - ShardNumber shard = specHelpers.getChainSpec().getBeaconChainShardNumber(); + ShardNumber shard = specHelpers.getConstants().getBeaconChainShardNumber(); Mockito.doReturn(committee).when(attester).getCommittee(any(), any()); Mockito.doReturn(epochBoundaryRoot).when(attester).getEpochBoundaryRoot(any(), any()); diff --git a/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTestUtil.java b/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTestUtil.java index 7dbf7d18f..b644eb895 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTestUtil.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTestUtil.java @@ -1,12 +1,11 @@ package org.ethereum.beacon.validator.attester; import org.ethereum.beacon.consensus.SpecHelpers; -import org.ethereum.beacon.validator.BeaconChainAttester; import org.mockito.Mockito; public class BeaconChainAttesterTestUtil { public static BeaconChainAttesterImpl mockAttester(SpecHelpers specHelpers) { - return Mockito.spy(new BeaconChainAttesterImpl(specHelpers, specHelpers.getChainSpec())); + return Mockito.spy(new BeaconChainAttesterImpl(specHelpers)); } } diff --git a/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java b/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java index d7200aeaf..bd4d4c64a 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTest.java @@ -26,7 +26,7 @@ import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.operations.slashing.Proposal; -import org.ethereum.beacon.core.spec.ChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.spec.SignatureDomains; import org.ethereum.beacon.core.state.Eth1Data; import org.ethereum.beacon.core.types.BLSSignature; @@ -54,7 +54,7 @@ public class BeaconChainProposerTest { public void proposeABlock() { Random random = new Random(); - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); DepositContract depositContract = DepositContractTestUtil.mockDepositContract(random, Collections.emptyList()); BlockTransition perBlockTransition = @@ -82,7 +82,7 @@ public void proposeABlock() { public void proposeABlockWithOperations() { Random random = new Random(); - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); DepositContract depositContract = DepositContractTestUtil.mockDepositContract(random, Collections.emptyList()); BlockTransition perBlockTransition = @@ -95,15 +95,15 @@ public void proposeABlockWithOperations() { List attestations = AttestationTestUtil.createRandomList( - random, specHelpers.getChainSpec().getMaxAttestations()); + random, specHelpers.getConstants().getMaxAttestations()); List proposerSlashings = ProposerSlashingTestUtil.createRandomList( - random, specHelpers.getChainSpec().getMaxProposerSlashings()); + random, specHelpers.getConstants().getMaxProposerSlashings()); List casperSlashings = AttesterSlashingTestUtil.createRandomList( - random, specHelpers.getChainSpec().getMaxAttesterSlashings()); + random, specHelpers.getConstants().getMaxAttesterSlashings()); List voluntaryExits = - ExitTestUtil.createRandomList(random, specHelpers.getChainSpec().getMaxVoluntaryExits()); + ExitTestUtil.createRandomList(random, specHelpers.getConstants().getMaxVoluntaryExits()); PendingOperations pendingOperations = PendingOperationsTestUtil.mockPendingOperations( @@ -115,20 +115,20 @@ public void proposeABlockWithOperations() { Mockito.verify(pendingOperations) .peekAggregatedAttestations( - specHelpers.getChainSpec().getMaxAttestations(), + specHelpers.getConstants().getMaxAttestations(), initialState .getSlot() - .minus(specHelpers.getChainSpec().getMinAttestationInclusionDelay()) - .minus(specHelpers.getChainSpec().getSlotsPerEpoch()), + .minus(specHelpers.getConstants().getMinAttestationInclusionDelay()) + .minus(specHelpers.getConstants().getSlotsPerEpoch()), initialState .getSlot() - .minus(specHelpers.getChainSpec().getMinAttestationInclusionDelay())); + .minus(specHelpers.getConstants().getMinAttestationInclusionDelay())); Mockito.verify(pendingOperations) - .peekProposerSlashings(specHelpers.getChainSpec().getMaxProposerSlashings()); + .peekProposerSlashings(specHelpers.getConstants().getMaxProposerSlashings()); Mockito.verify(pendingOperations) - .peekAttesterSlashings(specHelpers.getChainSpec().getMaxAttesterSlashings()); - Mockito.verify(pendingOperations).peekExits(specHelpers.getChainSpec().getMaxVoluntaryExits()); + .peekAttesterSlashings(specHelpers.getConstants().getMaxAttesterSlashings()); + Mockito.verify(pendingOperations).peekExits(specHelpers.getConstants().getMaxVoluntaryExits()); BeaconStateEx stateAfterBlock = perBlockTransition.apply(new BeaconStateExImpl(initialState, Hash32.ZERO), block); @@ -147,14 +147,14 @@ public void proposeABlockWithOperations() { public void proposeABlockWithDeposits() { Random random = new Random(); - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); List deposits = DepositTestUtil.createRandomList( random, - specHelpers.getChainSpec(), + specHelpers.getConstants(), UInt64.ZERO, - specHelpers.getChainSpec().getMaxDeposits()); + specHelpers.getConstants().getMaxDeposits()); Eth1Data eth1Data = Eth1DataTestUtil.createRandom(random); List depositInfos = deposits.stream() @@ -178,7 +178,7 @@ public void proposeABlockWithDeposits() { Mockito.verify(depositContract) .peekDeposits( - Mockito.eq(specHelpers.getChainSpec().getMaxDeposits()), + Mockito.eq(specHelpers.getConstants().getMaxDeposits()), Mockito.any(), Mockito.eq(initialState.getLatestEth1Data())); @@ -199,7 +199,7 @@ public void proposeABlockWithDeposits() { public void proposeABlockWithEpochTransition() { Random random = new Random(); - SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(ChainSpec.DEFAULT, () -> 0L); + SpecHelpers specHelpers = SpecHelpers.createWithSSZHasher(SpecConstants.DEFAULT, () -> 0L); DepositContract depositContract = DepositContractTestUtil.mockDepositContract(random, Collections.emptyList()); BlockTransition perBlockTransition = @@ -223,7 +223,7 @@ public void proposeABlockWithEpochTransition() { // set slot to the end of the epoch MutableBeaconState modifiedState = initialObservedState.getLatestSlotState().createMutableCopy(); - modifiedState.setSlot(specHelpers.getChainSpec().getSlotsPerEpoch().decrement()); + modifiedState.setSlot(specHelpers.getConstants().getSlotsPerEpoch().decrement()); ObservableBeaconState endOfTheEpoch = new ObservableBeaconState( @@ -251,7 +251,7 @@ private boolean verifySignature( Proposal signedData = new Proposal( initialState.getSlot(), - specHelpers.getChainSpec().getBeaconChainShardNumber(), + specHelpers.getConstants().getBeaconChainShardNumber(), specHelpers.signed_root(block, "signature"), block.getSignature()); BLSSignature expectedSignature = diff --git a/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTestUtil.java b/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTestUtil.java index 700867891..add361cc5 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTestUtil.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/proposer/BeaconChainProposerTestUtil.java @@ -18,7 +18,6 @@ public static BeaconChainProposerImpl mockProposer( return Mockito.spy( new BeaconChainProposerImpl( specHelpers, - specHelpers.getChainSpec(), perBlockTransition, perEpochTransition, depositContract)); From 5bcb51a2152b60dc448cd3cca24b728ce8dd5073 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Mon, 4 Mar 2019 16:58:40 +0600 Subject: [PATCH 11/21] Update SpecHelpers.process_deposit to the 0.4.0 version --- .../beacon/consensus/SpecHelpers.java | 145 +++++++++--------- .../transition/InitialStateTransition.java | 16 +- .../transition/PerBlockTransition.java | 11 +- .../beacon/core/state/ValidatorRecord.java | 14 +- 4 files changed, 80 insertions(+), 106 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index e2a214027..5c95c7a9d 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -1,17 +1,34 @@ package org.ethereum.beacon.consensus; +import static java.lang.Math.min; +import static java.util.stream.Collectors.toList; +import static org.ethereum.beacon.core.spec.SignatureDomains.ATTESTATION; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import javax.annotation.Nonnull; import org.ethereum.beacon.consensus.hasher.ObjectHasher; import org.ethereum.beacon.consensus.hasher.SSZObjectHasher; import org.ethereum.beacon.core.BeaconBlock; import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.operations.Attestation; +import org.ethereum.beacon.core.operations.Deposit; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; import org.ethereum.beacon.core.operations.deposit.DepositInput; import org.ethereum.beacon.core.operations.slashing.SlashableAttestation; -import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.spec.SignatureDomains; +import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.ForkData; import org.ethereum.beacon.core.state.ShardCommittee; import org.ethereum.beacon.core.state.ValidatorRecord; @@ -40,23 +57,6 @@ import tech.pegasys.artemis.util.uint.UInt64; import tech.pegasys.artemis.util.uint.UInt64s; -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import static java.lang.Math.min; -import static java.util.stream.Collectors.toList; -import static org.ethereum.beacon.core.spec.SignatureDomains.ATTESTATION; - /** * https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#helper-functions */ @@ -686,57 +686,58 @@ public boolean validate_proof_of_possession( } /* - def process_deposit(state: BeaconState, - pubkey: BLSPubkey, - amount: Gwei, - proof_of_possession: BLSSignature, - withdrawal_credentials: Hash32) -> None: - """ - Process a deposit from Ethereum 1.0. - Note that this function mutates ``state``. - """ + def process_deposit(state: BeaconState, deposit: Deposit) -> None: + """ + Process a deposit from Ethereum 1.0. + Note that this function mutates ``state``. + """ */ - public ValidatorIndex process_deposit( + public void process_deposit( MutableBeaconState state, - BLSPubkey pubkey, - Gwei amount, - BLSSignature proof_of_possession, - Hash32 withdrawal_credentials) { + Deposit deposit) { + + /* deposit_input = deposit.deposit_data.deposit_input + + proof_is_valid = bls_verify( + pubkey=deposit_input.pubkey, + message_hash=signed_root(deposit_input, "proof_of_possession"), + signature=deposit_input.proof_of_possession, + domain=get_domain( + state.fork, + get_current_epoch(state), + DOMAIN_DEPOSIT, + ) + ) - // # Validate the given `proof_of_possession` - // assert validate_proof_of_possession( - // state, - // pubkey, - // proof_of_possession, - // withdrawal_credentials, - // ) - assertTrue( - validate_proof_of_possession(state, pubkey, proof_of_possession, withdrawal_credentials)); - - // validator_pubkeys = [v.pubkey for v in state.validator_registry] - ValidatorIndex index = null; - for (ValidatorIndex i : state.getValidatorRegistry().size()) { - if (state.getValidatorRegistry().get(i).getPubKey().equals(pubkey)) { - index = i; - break; - } - } + if not proof_is_valid: + return */ - // if pubkey not in validator_pubkeys: - if (index == null) { - // # Add new validator - /* - validator = Validator( - pubkey=pubkey, - withdrawal_credentials=withdrawal_credentials, - activation_epoch=FAR_FUTURE_EPOCH, - exit_epoch=FAR_FUTURE_EPOCH, - withdrawable_epoch=FAR_FUTURE_EPOCH, - initiated_exit=False, - slashed=False, - ) - */ + DepositInput deposit_input = deposit.getDepositData().getDepositInput(); + boolean proof_is_valid = + bls_verify( + deposit_input.getPubKey(), + signed_root(deposit_input, "proof_of_possession"), + deposit_input.getProofOfPossession(), + get_domain(state.getForkData(), get_current_epoch(state), SignatureDomains.DEPOSIT)); + + if (!proof_is_valid) { + return; + } + + /* + validator_pubkeys = [v.pubkey for v in state.validator_registry] + pubkey = deposit_input.pubkey + amount = deposit.deposit_data.amount + withdrawal_credentials = deposit_input.withdrawal_credentials */ + + BLSPubkey pubkey = deposit_input.getPubKey(); + Gwei amount = deposit.getDepositData().getAmount(); + Hash32 withdrawal_credentials = deposit_input.getWithdrawalCredentials(); + ValidatorIndex index = get_validator_index_by_pubkey(state, pubkey); + + if (index.equals(ValidatorIndex.MAX)) { + // Add new validator ValidatorRecord validator = new ValidatorRecord( pubkey, withdrawal_credentials, @@ -746,27 +747,21 @@ public ValidatorIndex process_deposit( Boolean.FALSE, Boolean.FALSE); - // # Note: In phase 2 registry indices that has been withdrawn for a long time will be recycled. - // index = len(state.validator_registry) - index = state.getValidatorRegistry().size(); - // state.validator_registry.append(validator) + // Note: In phase 2 registry indices that have been withdrawn for a long time will be + // recycled. state.getValidatorRegistry().add(validator); - // state.validator_balances.append(amount) state.getValidatorBalances().add(amount); } else { - // # Increase balance by deposit amount - // index = validator_pubkeys.index(pubkey) - // assert state.validator_registry[index].withdrawal_credentials == withdrawal_credentials + // Increase balance by deposit amount assertTrue( state .getValidatorRegistry() .get(index) .getWithdrawalCredentials() .equals(withdrawal_credentials)); - // state.validator_balances[index] += amount - state.getValidatorBalances().update(index, balance -> balance.plus(amount)); + + state.getValidatorBalances().update(index, oldBalance -> oldBalance.plus(amount)); } - return index; } /* diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java index d9061b8b1..aad08c499 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/InitialStateTransition.java @@ -13,8 +13,6 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.deposit.DepositData; -import org.ethereum.beacon.core.operations.deposit.DepositInput; import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.ForkData; import org.ethereum.beacon.core.types.Bitfield64; @@ -110,17 +108,9 @@ public BeaconStateEx apply(BeaconStateEx state, BeaconBlock block) { final List initialDeposits = depositContractStart.getInitialDeposits(); initialState.setDepositIndex(UInt64.valueOf(initialDeposits.size())); - initialDeposits.forEach( - deposit -> { - DepositData depositData = deposit.getDepositData(); - DepositInput depositInput = depositData.getDepositInput(); - ValidatorIndex index = spec.process_deposit(initialState, - depositInput.getPubKey(), - depositData.getAmount(), - depositInput.getProofOfPossession(), - depositInput.getWithdrawalCredentials() - ); - }); + for (Deposit deposit : initialDeposits) { + spec.process_deposit(initialState, deposit); + } for (ValidatorIndex validatorIndex : initialState.getValidatorRegistry().size().iterateFromZero()) { diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java index cc31c906e..d8446e12d 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java @@ -12,8 +12,6 @@ import org.ethereum.beacon.core.operations.Deposit; import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; -import org.ethereum.beacon.core.operations.deposit.DepositData; -import org.ethereum.beacon.core.operations.deposit.DepositInput; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.PendingAttestationRecord; @@ -147,14 +145,7 @@ Append PendingAttestationRecord( ) */ for (Deposit deposit : block.getBody().getDeposits()) { - DepositData depositData = deposit.getDepositData(); - DepositInput depositInput = depositData.getDepositInput(); - spec.process_deposit(state, - depositInput.getPubKey(), - depositData.getAmount(), - depositInput.getProofOfPossession(), - depositInput.getWithdrawalCredentials() - ); + spec.process_deposit(state, deposit); } /* diff --git a/core/src/main/java/org/ethereum/beacon/core/state/ValidatorRecord.java b/core/src/main/java/org/ethereum/beacon/core/state/ValidatorRecord.java index 417856ced..982cf7c7b 100644 --- a/core/src/main/java/org/ethereum/beacon/core/state/ValidatorRecord.java +++ b/core/src/main/java/org/ethereum/beacon/core/state/ValidatorRecord.java @@ -8,8 +8,6 @@ import org.ethereum.beacon.ssz.annotation.SSZ; import org.ethereum.beacon.ssz.annotation.SSZSerializable; import tech.pegasys.artemis.ethereum.core.Hash32; -import tech.pegasys.artemis.util.uint.UInt64; -import java.util.function.Function; /** * A record denoting a validator in the validator registry. @@ -31,7 +29,7 @@ public class ValidatorRecord { /** Slot when validator exited */ @SSZ private final EpochNumber exitEpoch; /** Epoch when validator is eligible to withdraw */ - @SSZ private final EpochNumber WithdrawableEpoch; + @SSZ private final EpochNumber withdrawableEpoch; /** Did the validator initiate an exit */ @SSZ private final Boolean initiatedExit; /** Status flags. */ @@ -39,13 +37,13 @@ public class ValidatorRecord { public ValidatorRecord(BLSPubkey pubKey, Hash32 withdrawalCredentials, EpochNumber activationEpoch, - EpochNumber exitEpoch, EpochNumber WithdrawableEpoch, + EpochNumber exitEpoch, EpochNumber withdrawableEpoch, Boolean initiatedExit, Boolean slashed) { this.pubKey = pubKey; this.withdrawalCredentials = withdrawalCredentials; this.activationEpoch = activationEpoch; this.exitEpoch = exitEpoch; - this.WithdrawableEpoch = WithdrawableEpoch; + this.withdrawableEpoch = withdrawableEpoch; this.initiatedExit = initiatedExit; this.slashed = slashed; } @@ -67,7 +65,7 @@ public EpochNumber getExitEpoch() { } public EpochNumber getWithdrawableEpoch() { - return WithdrawableEpoch; + return withdrawableEpoch; } public Boolean getInitiatedExit() { @@ -87,7 +85,7 @@ public boolean equals(Object o) { && Objects.equal(withdrawalCredentials, that.withdrawalCredentials) && Objects.equal(activationEpoch, that.activationEpoch) && Objects.equal(exitEpoch, that.exitEpoch) - && Objects.equal(WithdrawableEpoch, that.WithdrawableEpoch) + && Objects.equal(withdrawableEpoch, that.withdrawableEpoch) && Objects.equal(initiatedExit, that.initiatedExit) && Objects.equal(slashed, that.slashed); } @@ -128,7 +126,7 @@ public static Builder fromRecord(ValidatorRecord record) { builder.withdrawalCredentials = record.withdrawalCredentials; builder.activationEpoch = record.activationEpoch; builder.exitEpoch = record.exitEpoch; - builder.withdrawableEpoch = record.WithdrawableEpoch; + builder.withdrawableEpoch = record.withdrawableEpoch; builder.initiatedExit = record.initiatedExit; builder.slashed = record.slashed; From 895a63764b9c0a9655dbc9f1bc3ffa0158df5812 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Mon, 4 Mar 2019 18:35:33 +0600 Subject: [PATCH 12/21] Align lmd_ghost with spec version 0.4.0 --- .../beacon/consensus/SpecHelpers.java | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 5c95c7a9d..026ddf16c 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -47,6 +47,7 @@ import org.ethereum.beacon.crypto.BLS381.Signature; import org.ethereum.beacon.crypto.Hashes; import org.ethereum.beacon.crypto.MessageParameters; +import org.javatuples.Pair; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.bytes.Bytes3; import tech.pegasys.artemis.util.bytes.Bytes32; @@ -1589,15 +1590,15 @@ public BeaconBlock lmd_ghost( List active_validator_indices = get_active_validator_indices(validators, get_current_epoch(state)); - List active_validators = new ArrayList<>(); + List> active_validators = new ArrayList<>(); for (ValidatorIndex index : active_validator_indices) { - active_validators.add(validators.get(index)); + active_validators.add(Pair.with(index, validators.get(index))); } - List attestation_targets = new ArrayList<>(); - for (ValidatorRecord validatorRecord : active_validators) { - get_latest_attestation_target(validatorRecord, get_latest_attestation, getBlock) - .ifPresent(attestation_targets::add); + List> attestation_targets = new ArrayList<>(); + for (Pair validatorRecord : active_validators) { + get_latest_attestation_target(validatorRecord.getValue1(), get_latest_attestation, getBlock) + .ifPresent(block -> attestation_targets.add(Pair.with(validatorRecord.getValue0(), block))); } BeaconBlock head = startBlock; @@ -1608,7 +1609,9 @@ public BeaconBlock lmd_ghost( } else { head = children.stream() - .max(Comparator.comparingInt(o -> get_vote_count(o, attestation_targets, getBlock))) + .max( + Comparator.comparing(o -> get_vote_count(state, o, attestation_targets, getBlock), + UInt64::compareTo)) .get(); } } @@ -1630,22 +1633,25 @@ private Optional get_latest_attestation_target( return latest.flatMap(at -> getBlock.apply(at.getData().getJustifiedBlockRoot())); } - /** - * def get_vote_count(block): return len([target for target in attestation_targets if - * get_ancestor(store, target, block.slot) == block]) + /* + def get_vote_count(block: BeaconBlock) -> int: + return sum( + get_effective_balance(start_state.validator_balances[validator_index]) // FORK_CHOICE_BALANCE_INCREMENT + for validator_index, target in attestation_targets + if get_ancestor(store, target, block.slot) == block + ) */ - private int get_vote_count( + private UInt64 get_vote_count( + BeaconState startState, BeaconBlock block, - List attestation_targets, + List> attestation_targets, Function> getBlock) { - int res = 0; - for (BeaconBlock target : attestation_targets) { - if (get_ancestor(target, block.getSlot(), getBlock).map(b -> b.equals(block)).orElse(false)) { - ++res; - } - } - return res; + return attestation_targets.stream().filter( + target -> get_ancestor(target.getValue1(), block.getSlot(), getBlock) + .filter(ancestor -> ancestor.equals(block)).isPresent()) + .map(target -> get_effective_balance(startState, target.getValue0()).dividedBy(constants.getForkChoiceBalanceIncrement())) + .reduce(Gwei.ZERO, Gwei::plus); } /* From 8ff885baf5a5a3998cb662c9bf5e2f6bafea3376 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Mon, 4 Mar 2019 18:52:04 +0600 Subject: [PATCH 13/21] Update per-block transition to spec version 0.4.0 --- .../verifier/BeaconBlockVerifier.java | 8 +++--- ...ifier.java => BlockSignatureVerifier.java} | 6 ++--- .../operation/AttestationVerifier.java | 27 +++++++++++-------- ...rifier.java => VoluntaryExitVerifier.java} | 22 ++++++++------- 4 files changed, 35 insertions(+), 28 deletions(-) rename consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/{ProposerSignatureVerifier.java => BlockSignatureVerifier.java} (89%) rename consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/{ExitVerifier.java => VoluntaryExitVerifier.java} (75%) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java index 1eccb46cd..d1890488d 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java @@ -4,12 +4,12 @@ import org.ethereum.beacon.consensus.verifier.block.AttestationListVerifier; import org.ethereum.beacon.consensus.verifier.block.DepositListVerifier; import org.ethereum.beacon.consensus.verifier.block.ExitListVerifier; -import org.ethereum.beacon.consensus.verifier.block.ProposerSignatureVerifier; +import org.ethereum.beacon.consensus.verifier.block.BlockSignatureVerifier; import org.ethereum.beacon.consensus.verifier.block.ProposerSlashingListVerifier; import org.ethereum.beacon.consensus.verifier.block.RandaoVerifier; import org.ethereum.beacon.consensus.verifier.operation.AttestationVerifier; import org.ethereum.beacon.consensus.verifier.operation.DepositVerifier; -import org.ethereum.beacon.consensus.verifier.operation.ExitVerifier; +import org.ethereum.beacon.consensus.verifier.operation.VoluntaryExitVerifier; import org.ethereum.beacon.consensus.verifier.operation.ProposerSlashingVerifier; import org.ethereum.beacon.core.BeaconBlock; import org.ethereum.beacon.core.BeaconState; @@ -20,10 +20,10 @@ public interface BeaconBlockVerifier { static BeaconBlockVerifier createDefault(SpecHelpers specHelpers) { return CompositeBlockVerifier.Builder.createNew() .with(new RandaoVerifier(specHelpers)) - .with(new ProposerSignatureVerifier(specHelpers)) + .with(new BlockSignatureVerifier(specHelpers)) .with(new AttestationListVerifier(new AttestationVerifier(specHelpers), specHelpers.getConstants())) .with(new DepositListVerifier(new DepositVerifier(specHelpers), specHelpers.getConstants())) - .with(new ExitListVerifier(new ExitVerifier(specHelpers), specHelpers.getConstants())) + .with(new ExitListVerifier(new VoluntaryExitVerifier(specHelpers), specHelpers.getConstants())) .with(new ProposerSlashingListVerifier(new ProposerSlashingVerifier(specHelpers), specHelpers.getConstants())) .build(); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSignatureVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/BlockSignatureVerifier.java similarity index 89% rename from consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSignatureVerifier.java rename to consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/BlockSignatureVerifier.java index 16024bdab..adc7ff141 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ProposerSignatureVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/BlockSignatureVerifier.java @@ -17,14 +17,14 @@ * Verifies proposer signature of the block. * * @see Block * signature in the spec. */ -public class ProposerSignatureVerifier implements BeaconBlockVerifier { +public class BlockSignatureVerifier implements BeaconBlockVerifier { private SpecHelpers spec; - public ProposerSignatureVerifier(SpecHelpers spec) { + public BlockSignatureVerifier(SpecHelpers spec) { this.spec = spec; } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java index 3472852b1..39e7333c2 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/AttestationVerifier.java @@ -15,6 +15,7 @@ import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.ShardCommittee; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.ValidatorIndex; @@ -41,6 +42,11 @@ public AttestationVerifier(SpecHelpers spec) { public VerificationResult verify(Attestation attestation, BeaconState state) { AttestationData data = attestation.getData(); + if (attestation.getData().getSlot().less(spec.getConstants().getGenesisSlot())) { + return failedResult("Attestation slot %s is less than GENESIS_SLOT %s", + attestation.getData().getSlot(), spec.getConstants().getGenesisSlot()); + } + spec.checkShardRange(data.getShard()); // Verify that attestation.data.slot <= state.slot - MIN_ATTESTATION_INCLUSION_DELAY @@ -79,17 +85,16 @@ public VerificationResult verify(Attestation attestation, BeaconState state) { data.getJustifiedBlockRoot(), blockRootAtJustifiedSlot); } - // Verify that either attestation.data.latest_crosslink_root or - // attestation.data.crosslink_data_root equals state.latest_crosslinks[shard].crosslink_data_root - Hash32 crosslinkDataRoot = - state.getLatestCrosslinks().get(data.getShard()).getCrosslinkDataRoot(); - if (!data.getLatestCrosslink().getCrosslinkDataRoot().equals(crosslinkDataRoot) - && !data.getCrosslinkDataRoot().equals(crosslinkDataRoot)) { - return failedResult( - "either attestation_data.justified_block_root or attestation_data.crosslink_data_root must be " - + "equal to latest_crosslink.crosslink_data_root, justified_block_root=%s, " - + "attestation_data.crosslink_data_root=%s, latest_crosslink.crosslink_data_root=%s", - data.getJustifiedBlockRoot(), data.getCrosslinkDataRoot(), crosslinkDataRoot); + // Verify that either + // (i) state.latest_crosslinks[attestation.data.shard] == attestation.data.latest_crosslink or + // (ii) state.latest_crosslinks[attestation.data.shard] == + // Crosslink(crosslink_data_root=attestation.data.crosslink_data_root, epoch=slot_to_epoch(attestation.data.slot)). + Crosslink latestCrosslink = + state.getLatestCrosslinks().get(data.getShard()); + if (!data.getLatestCrosslink().equals(latestCrosslink) + && !latestCrosslink.equals(new Crosslink(spec.slot_to_epoch(attestation.getData().getSlot()), + attestation.getData().getCrosslinkDataRoot()))) { + return failedResult("attestation.data.latest_crosslink is incorrect"); } // Verify bitfields and aggregate signature: diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/VoluntaryExitVerifier.java similarity index 75% rename from consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java rename to consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/VoluntaryExitVerifier.java index d77bd9e7b..28d75c036 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/ExitVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/VoluntaryExitVerifier.java @@ -16,14 +16,14 @@ * * @see VoluntaryExit * @see Exits - * in the spec. + * href="https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#voluntary-exits-1">Voluntary + * exits in the spec. */ -public class ExitVerifier implements OperationVerifier { +public class VoluntaryExitVerifier implements OperationVerifier { private SpecHelpers spec; - public ExitVerifier(SpecHelpers spec) { + public VoluntaryExitVerifier(SpecHelpers spec) { this.spec = spec; } @@ -33,18 +33,20 @@ public VerificationResult verify(VoluntaryExit voluntaryExit, BeaconState state) ValidatorRecord validator = state.getValidatorRegistry().get(voluntaryExit.getValidatorIndex()); - // Verify that validator.exit_epoch > get_delayed_activation_exit_epoch(get_current_epoch(state)) - if (!validator.getExitEpoch().greater( - spec.get_delayed_activation_exit_epoch(spec.get_current_epoch(state)))) { + // Verify that validator.exit_epoch > + // get_delayed_activation_exit_epoch(get_current_epoch(state)) + if (!validator + .getExitEpoch() + .greater(spec.get_delayed_activation_exit_epoch(spec.get_current_epoch(state)))) { return failedResult( "ACTIVATION_EXIT_DELAY exceeded, min exit epoch %s, got %s", - state.getSlot().plus(spec.getConstants().getActivationExitDelay()), validator.getExitEpoch()); + state.getSlot().plus(spec.getConstants().getActivationExitDelay()), + validator.getExitEpoch()); } // Verify that get_current_epoch(state) >= exit.epoch if (!spec.get_current_epoch(state).greaterEqual(voluntaryExit.getEpoch())) { - return failedResult( - "exit.epoch must be greater or equal to current_epoch"); + return failedResult("exit.epoch must be greater or equal to current_epoch"); } // Let exit_message = hash_tree_root( From c7a57c659c6c98ab0f2db7c7dae744cfcbf21a32 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Mon, 4 Mar 2019 21:01:40 +0600 Subject: [PATCH 14/21] Add Transfer beacon chain operation --- .../transition/PerBlockTransition.java | 26 +++- .../verifier/BeaconBlockVerifier.java | 4 +- .../verifier/block/TransferListVerifier.java | 25 ++++ ...er.java => VoluntaryExitListVerifier.java} | 4 +- .../verifier/operation/TransferVerifier.java | 116 ++++++++++++++++++ 5 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java rename consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/{ExitListVerifier.java => VoluntaryExitListVerifier.java} (71%) create mode 100644 consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/TransferVerifier.java diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java index d8446e12d..efa8ba7da 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerBlockTransition.java @@ -10,8 +10,9 @@ import org.ethereum.beacon.core.MutableBeaconState; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; +import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.PendingAttestationRecord; @@ -158,6 +159,29 @@ Run initiate_validator_exit(state, exit.validator_index). spec.initiate_validator_exit(state, voluntaryExit.getValidatorIndex()); } + /* + Transfers + + Set state.validator_balances[transfer.from] -= transfer.amount + transfer.fee + Set state.validator_balances[transfer.to] += transfer.amount. + Set state.validator_balances[get_beacon_proposer_index(state, state.slot)] += transfer.fee. + */ + for (Transfer transfer : block.getBody().getTransfers()) { + state + .getValidatorBalances() + .update( + transfer.getFrom(), + balance -> balance.minus(transfer.getAmount()).minus(transfer.getFee())); + state + .getValidatorBalances() + .update(transfer.getTo(), balance -> balance.plus(transfer.getAmount())); + state + .getValidatorBalances() + .update( + spec.get_beacon_proposer_index(state, state.getSlot()), + balance -> balance.plus(transfer.getFee())); + } + BeaconStateEx ret = new BeaconStateExImpl(state.createImmutable(), spec.hash_tree_root(block), TransitionType.BLOCK); diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java index d1890488d..03b7c5b7c 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/BeaconBlockVerifier.java @@ -3,7 +3,7 @@ import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.consensus.verifier.block.AttestationListVerifier; import org.ethereum.beacon.consensus.verifier.block.DepositListVerifier; -import org.ethereum.beacon.consensus.verifier.block.ExitListVerifier; +import org.ethereum.beacon.consensus.verifier.block.VoluntaryExitListVerifier; import org.ethereum.beacon.consensus.verifier.block.BlockSignatureVerifier; import org.ethereum.beacon.consensus.verifier.block.ProposerSlashingListVerifier; import org.ethereum.beacon.consensus.verifier.block.RandaoVerifier; @@ -23,7 +23,7 @@ static BeaconBlockVerifier createDefault(SpecHelpers specHelpers) { .with(new BlockSignatureVerifier(specHelpers)) .with(new AttestationListVerifier(new AttestationVerifier(specHelpers), specHelpers.getConstants())) .with(new DepositListVerifier(new DepositVerifier(specHelpers), specHelpers.getConstants())) - .with(new ExitListVerifier(new VoluntaryExitVerifier(specHelpers), specHelpers.getConstants())) + .with(new VoluntaryExitListVerifier(new VoluntaryExitVerifier(specHelpers), specHelpers.getConstants())) .with(new ProposerSlashingListVerifier(new ProposerSlashingVerifier(specHelpers), specHelpers.getConstants())) .build(); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java new file mode 100644 index 000000000..0ca5a67d9 --- /dev/null +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java @@ -0,0 +1,25 @@ +package org.ethereum.beacon.consensus.verifier.block; + +import org.ethereum.beacon.consensus.SpecHelpers; +import org.ethereum.beacon.consensus.verifier.OperationVerifier; +import org.ethereum.beacon.core.operations.Transfer; + +/** + * Verifies transfers list. + * + * @see Transfer + */ +public class TransferListVerifier extends OperationListVerifier { + + protected TransferListVerifier(OperationVerifier operationVerifier, SpecHelpers spec) { + super( + operationVerifier, + block -> block.getBody().getTransfers(), + spec.getConstants().getMaxTransfers()); + } + + @Override + protected Class getType() { + return Transfer.class; + } +} diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/VoluntaryExitListVerifier.java similarity index 71% rename from consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java rename to consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/VoluntaryExitListVerifier.java index 12428b797..ea25fd273 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/ExitListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/VoluntaryExitListVerifier.java @@ -9,9 +9,9 @@ * * @see VoluntaryExit */ -public class ExitListVerifier extends OperationListVerifier { +public class VoluntaryExitListVerifier extends OperationListVerifier { - public ExitListVerifier(OperationVerifier operationVerifier, SpecConstants specConstants) { + public VoluntaryExitListVerifier(OperationVerifier operationVerifier, SpecConstants specConstants) { super(operationVerifier, block -> block.getBody().getExits(), specConstants.getMaxVoluntaryExits()); } diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/TransferVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/TransferVerifier.java new file mode 100644 index 000000000..59339e8e5 --- /dev/null +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/TransferVerifier.java @@ -0,0 +1,116 @@ +package org.ethereum.beacon.consensus.verifier.operation; + +import static org.ethereum.beacon.consensus.verifier.VerificationResult.PASSED; +import static org.ethereum.beacon.consensus.verifier.VerificationResult.failedResult; + +import org.ethereum.beacon.consensus.SpecHelpers; +import org.ethereum.beacon.consensus.verifier.OperationVerifier; +import org.ethereum.beacon.consensus.verifier.VerificationResult; +import org.ethereum.beacon.core.BeaconState; +import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.core.spec.SignatureDomains; +import org.ethereum.beacon.core.state.ValidatorRecord; +import org.ethereum.beacon.core.types.Gwei; + +/** + * Verifies {@link Transfer} beacon chain operation. + * + * @see Transfers + * section in the spec. + */ +public class TransferVerifier implements OperationVerifier { + + private final SpecHelpers spec; + + public TransferVerifier(SpecHelpers spec) { + this.spec = spec; + } + + @Override + public VerificationResult verify(Transfer transfer, BeaconState state) { + + if (transfer.getFrom().greaterEqual(state.getValidatorRegistry().size())) { + return failedResult( + "sender index does not exist, registry size: %s", state.getValidatorRegistry().size()); + } + + if (transfer.getTo().greaterEqual(state.getValidatorRegistry().size())) { + return failedResult( + "recipient index does not exist, registry size: %s", state.getValidatorRegistry().size()); + } + + Gwei fromBalance = state.getValidatorBalances().get(transfer.getFrom()); + + // Verify that state.validator_balances[transfer.from] >= transfer.amount. + if (fromBalance.less(transfer.getAmount())) { + return failedResult( + "insufficient funds to cover amount, balance=%s when transfer.amount=%s", + fromBalance, transfer.getAmount()); + } + + // Verify that state.validator_balances[transfer.from] >= transfer.fee. + if (fromBalance.less(transfer.getFee())) { + return failedResult( + "insufficient funds to cover the fee, balance=%s when transfer.fee=%s", + fromBalance, transfer.getFee()); + } + + // Verify that state.validator_balances[transfer.from] == transfer.amount + transfer.fee or + // state.validator_balances[transfer.from] >= transfer.amount + transfer.fee + + // MIN_DEPOSIT_AMOUNT. + if (!fromBalance.less(transfer.getFee().plus(transfer.getAmount())) + && fromBalance.less( + transfer + .getAmount() + .plus(transfer.getFee()) + .plus(spec.getConstants().getMinDepositAmount()))) { + return failedResult( + "insufficient funds to cover transfer, balance=%s when transfer total=%s", + fromBalance, transfer.getFee().plus(transfer.getAmount())); + } + + // Verify that state.slot == transfer.slot. + if (!state.getSlot().equals(transfer.getSlot())) { + return failedResult("transfer slot is invalid, state.slot=%s when transfer.slot=%s"); + } + + ValidatorRecord sender = state.getValidatorRegistry().get(transfer.getFrom()); + + // Verify that get_current_epoch(state) >= + // state.validator_registry[transfer.from].withdrawable_epoch or + // state.validator_registry[transfer.from].activation_epoch == FAR_FUTURE_EPOCH. + if (spec.get_current_epoch(state).less(sender.getWithdrawableEpoch()) + && !sender.getActivationEpoch().equals(spec.getConstants().getFarFutureEpoch())) { + return failedResult("epoch validation failed"); + } + + // Verify that state.validator_registry[transfer.from].withdrawal_credentials == + // BLS_WITHDRAWAL_PREFIX_BYTE + hash(transfer.pubkey)[1:] + if (!sender + .getWithdrawalCredentials() + .equals( + spec.getConstants() + .getBlsWithdrawalPrefixByte() + .concat(spec.hash(transfer.getPubkey()).slice(1)))) { + return failedResult("withdrawal_credentials do not match"); + } + + // Verify that bls_verify(pubkey=transfer.pubkey, message_hash=signed_root(transfer, + // "signature"), + // signature=transfer.signature, domain=get_domain(state.fork, slot_to_epoch(transfer.slot), + // DOMAIN_TRANSFER)). + if (!spec.bls_verify( + transfer.getPubkey(), + spec.signed_root(transfer, "signature"), + transfer.getSignature(), + spec.get_domain( + state.getForkData(), + spec.slot_to_epoch(transfer.getSlot()), + SignatureDomains.TRANSFER))) { + return failedResult("signature verification failed"); + } + + return PASSED; + } +} From b993cbcfb6f2c1907e46e66834fb7c9c56cd3742 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Tue, 5 Mar 2019 11:49:34 +0600 Subject: [PATCH 15/21] Verify that transfers are distinct --- .../verifier/block/TransferListVerifier.java | 16 +++++++++++++ .../beacon/core/operations/Transfer.java | 24 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java index 0ca5a67d9..51abb6222 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java @@ -1,5 +1,8 @@ package org.ethereum.beacon.consensus.verifier.block; +import static org.ethereum.beacon.consensus.verifier.VerificationResult.PASSED; +import static org.ethereum.beacon.consensus.verifier.VerificationResult.failedResult; + import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.consensus.verifier.OperationVerifier; import org.ethereum.beacon.core.operations.Transfer; @@ -16,6 +19,19 @@ protected TransferListVerifier(OperationVerifier operationVerifier, Sp operationVerifier, block -> block.getBody().getTransfers(), spec.getConstants().getMaxTransfers()); + + addCustomVerifier( + ((transfers, state) -> { + for (Transfer t1 : transfers) { + for (Transfer t2 : transfers) { + if (t1.equals(t2)) { + return failedResult("two equal transfers have been found"); + } + } + } + + return PASSED; + })); } @Override diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java b/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java index 722b84136..0419f3949 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java @@ -1,5 +1,6 @@ package org.ethereum.beacon.core.operations; +import com.google.common.base.Objects; import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Gwei; @@ -76,4 +77,27 @@ public BLSPubkey getPubkey() { public BLSSignature getSignature() { return signature; } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + Transfer transfer = (Transfer) object; + return Objects.equal(from, transfer.from) + && Objects.equal(to, transfer.to) + && Objects.equal(amount, transfer.amount) + && Objects.equal(fee, transfer.fee) + && Objects.equal(slot, transfer.slot) + && Objects.equal(pubkey, transfer.pubkey) + && Objects.equal(signature, transfer.signature); + } + + @Override + public int hashCode() { + return Objects.hashCode(from, to, amount, fee, slot, pubkey, signature); + } } From a2da96de8401b2afe4c36958c51b1cf5e2387c40 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Tue, 5 Mar 2019 12:51:29 +0600 Subject: [PATCH 16/21] Update per epoch transition with spec changes of version 0.4.0 --- .../beacon/consensus/SpecHelpers.java | 61 ++++--- .../transition/PerEpochTransition.java | 159 ++++++++---------- 2 files changed, 101 insertions(+), 119 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 026ddf16c..3577399a7 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -606,7 +607,7 @@ def get_total_balance(state: BeaconState, validators: List[ValidatorIndex]) -> G """ return sum([get_effective_balance(state, i) for i in validators]) */ - public Gwei get_total_balance(BeaconState state, List validators) { + public Gwei get_total_balance(BeaconState state, Collection validators) { return validators.stream().map(index -> get_effective_balance(state, index)) .reduce(Gwei.ZERO, Gwei::plus); } @@ -896,11 +897,8 @@ public void update_validator_registry(MutableBeaconState state) { List active_validator_indices = get_active_validator_indices( state.getValidatorRegistry(), current_epoch); // # The total effective balance of active validators - // total_balance = sum([get_effective_balance(state, i) for i in active_validator_indices]) - Gwei total_balance = Gwei.ZERO; - for (ValidatorIndex i : active_validator_indices) { - total_balance = total_balance.plus(get_effective_balance(state, i)); - } + // total_balance = get_total_balance(state, active_validator_indices) + Gwei total_balance = get_total_balance(state, active_validator_indices); // # The maximum balance churn in Gwei (for deposits and exits separately) // max_balance_churn = max( @@ -916,10 +914,9 @@ public void update_validator_registry(MutableBeaconState state) { Gwei balance_churn = Gwei.ZERO; for (ValidatorIndex index : state.getValidatorRegistry().size()) { ValidatorRecord validator = state.getValidatorRegistry().get(index); - // if validator.activation_epoch > get_delayed_activation_exit_epoch(current_epoch) - // and state.validator_balances[index] >= MAX_DEPOSIT_AMOUNT: - if (validator.getActivationEpoch().greater( - get_delayed_activation_exit_epoch(current_epoch)) + // if validator.activation_epoch == FAR_FUTURE_EPOCH + // and state.validator_balances[index] >= MAX_DEPOSIT_AMOUNT: + if (validator.getActivationEpoch().equals(constants.getFarFutureEpoch()) && state.getValidatorBalances().get(index).greaterEqual( constants.getMaxDepositAmount())) { @@ -945,8 +942,8 @@ public void update_validator_registry(MutableBeaconState state) { // for index, validator in enumerate(state.validator_registry): for (ValidatorIndex index : state.getValidatorRegistry().size().iterateFromZero()) { ValidatorRecord validator = state.getValidatorRegistry().get(index); - // if validator.exit_epoch > get_delayed_activation_exit_epoch(current_epoch) - // and validator.slashed: + // if validator.activation_epoch == FAR_FUTURE_EPOCH + // and validator.initiated_exit: if (validator.getActivationEpoch().equals(constants.getFarFutureEpoch()) && validator.getInitiatedExit()) { // # Check the balance churn would be within the allowance @@ -991,9 +988,10 @@ public void prepare_validator_for_withdrawal(MutableBeaconState state, Validator } /* - def process_penalties_and_exits(state: BeaconState) -> None: + Process the slashings. + Note that this function mutates ``state``. */ - public void process_penalties_and_exits(MutableBeaconState state) { + public void process_slashings(MutableBeaconState state) { // current_epoch = get_current_epoch(state) EpochNumber current_epoch = get_current_epoch(state); @@ -1026,8 +1024,10 @@ public void process_penalties_and_exits(MutableBeaconState state) { Gwei total_at_end = state.getLatestSlashedBalances().get(epoch_index); // total_penalties = total_at_end - total_at_start Gwei total_penalties = total_at_end.minus(total_at_start); - // penalty = get_effective_balance(state, index) * - // min(total_penalties * 3, total_balance) // total_balance + // penalty = max( + // get_effective_balance(state, index) * min(total_penalties * 3, total_balance) // total_balance, + // get_effective_balance(state, index) // MIN_PENALTY_QUOTIENT + // ) Gwei penalty = get_effective_balance(state, index) .mulDiv(UInt64s.min(total_penalties.times(3), total_balance), total_balance); @@ -1035,18 +1035,25 @@ public void process_penalties_and_exits(MutableBeaconState state) { state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); } } + } + + /* + Process the exit queue. + Note that this function mutates ``state``. + */ + public void process_exit_queue(MutableBeaconState state) { /* def eligible(index): - validator = state.validator_registry[index] - if validator.initiated_exit <= current_epoch: - penalized_withdrawal_epochs = LATEST_SLASHED_EXIT_LENGTH // 2 - return current_epoch >= validator.initiated_exit + penalized_withdrawal_epochs + validator = state.validator_registry[index] + # Filter out dequeued validators + if validator.withdrawable_epoch != FAR_FUTURE_EPOCH: + return False + # Dequeue if the minimum amount of time has passed else: - return current_epoch >= validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY + return get_current_epoch(state) >= validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY - all_indices = list(range(len(state.validator_registry))) - eligible_indices = filter(eligible, all_indices) + eligible_indices = filter(eligible, list(range(len(state.validator_registry)))) */ List eligible_indices = new ArrayList<>(); for (ValidatorIndex index : state.getValidatorRegistry().size().iterateFromZero()) { @@ -1064,13 +1071,15 @@ def eligible(index): // # Sort in order of exit epoch, and validators that exit within the same epoch exit in order of validator index // sorted_indices = sorted(eligible_indices, // key=lambda index: state.validator_registry[index].exit_epoch) - - // sorted_indices = sorted(eligible_indices, - // key=lambda index: state.validator_registry[index].exit_count) eligible_indices.sort(Comparator.comparing(i -> state.getValidatorRegistry().get(i).getExitEpoch())); List sorted_indices = eligible_indices; + // for dequeues, index in enumerate(sorted_indices): + // if dequeues >= MAX_EXIT_DEQUEUES_PER_EPOCH: + // break + // prepare_validator_for_withdrawal(state, index) + // withdrawn_so_far = 0 int withdrawn_so_far = 0; // for index in sorted_indices: diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java index 7da923d45..fcda62183 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/transition/PerEpochTransition.java @@ -18,7 +18,6 @@ import org.ethereum.beacon.consensus.StateTransition; import org.ethereum.beacon.consensus.TransitionType; import org.ethereum.beacon.core.MutableBeaconState; -import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.state.Eth1DataVote; import org.ethereum.beacon.core.state.PendingAttestationRecord; @@ -76,12 +75,11 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ /* Let current_epoch = get_current_epoch(state). - Let previous_epoch = current_epoch - 1 if current_epoch > GENESIS_EPOCH else current_epoch. + Let previous_epoch = get_previous_epoch(state). Let next_epoch = current_epoch + 1. */ EpochNumber current_epoch = spec.get_current_epoch(state); - EpochNumber previous_epoch = current_epoch.greater(spec.get_genesis_epoch()) ? - current_epoch.decrement() : current_epoch; + EpochNumber previous_epoch = spec.get_previous_epoch(state); EpochNumber next_epoch = current_epoch.increment(); /* @@ -92,14 +90,11 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ Helpers: Validators attesting during the current epoch: */ - // Let current_total_balance = sum([get_effective_balance(state, i) - // for i in get_active_validator_indices(state.validator_registry, current_epoch)]) + // Let current_total_balance = get_total_balance(state, + // get_active_validator_indices(state.validator_registry, current_epoch)). List current_active_validator_indices = spec.get_active_validator_indices( state.getValidatorRegistry(), current_epoch); - Gwei current_total_balance = current_active_validator_indices.stream() - .map(i -> spec.get_effective_balance(state, i)) - .reduce(Gwei::plus) - .orElse(Gwei.ZERO); + Gwei current_total_balance = spec.get_total_balance(state, current_active_validator_indices); logger.trace(() -> current_active_validator_indices.size() + " active validators with total balance " + current_total_balance); // Let current_epoch_attestations = @@ -114,13 +109,11 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ // Validators justifying the epoch boundary block at the start of the current epoch: // Let current_epoch_boundary_attestations = [a for a in current_epoch_attestations - // if a.data.epoch_boundary_root == get_block_root(state, get_epoch_start_slot(current_epoch)) - // and a.data.justified_epoch == state.justified_epoch]. + // if a.data.epoch_boundary_root == get_block_root(state, get_epoch_start_slot(current_epoch)). List current_epoch_boundary_attestations = current_epoch_attestations.stream().filter(a -> a.getData().getEpochBoundaryRoot().equals( spec.get_block_root(state, spec.get_epoch_start_slot(current_epoch))) - && a.getData().getJustifiedEpoch().equals(state.getJustifiedEpoch()) ).collect(Collectors.toList()); // Let current_epoch_boundary_attester_indices be the union of the validator index sets @@ -136,12 +129,9 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ // Let current_epoch_boundary_attesting_balance = - // sum([get_effective_balance(state, i) for i in current_epoch_boundary_attester_indices]). - Gwei current_epoch_boundary_attesting_balance = current_epoch_boundary_attester_indices - .stream() - .map(i -> spec.get_effective_balance(state, i)) - .reduce(Gwei::plus) - .orElse(Gwei.ZERO); + // get_total_balance(state, current_epoch_boundary_attester_indices). + Gwei current_epoch_boundary_attesting_balance = spec.get_total_balance(state, + current_epoch_boundary_attester_indices); if (summary != null) { summary.currentEpochSummary.activeAttesters = current_active_validator_indices; @@ -156,12 +146,9 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ List previous_active_validator_indices = spec .get_active_validator_indices(state.getValidatorRegistry(), previous_epoch); - //Let previous_total_balance = sum([get_effective_balance(state, i) - // for i in get_active_validator_indices(state.validator_registry, previous_epoch)]). - Gwei previous_total_balance = previous_active_validator_indices.stream() - .map(i -> spec.get_effective_balance(state, i)) - .reduce(Gwei::plus) - .orElse(Gwei.ZERO); + // Let previous_total_balance = get_total_balance(state, + // get_active_validator_indices(state.validator_registry, previous_epoch)). + Gwei previous_total_balance = spec.get_total_balance(state, previous_active_validator_indices); // Validators that made an attestation during the previous epoch: @@ -184,37 +171,17 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ // Validators targeting the previous justified slot: - // Let previous_epoch_justified_attestations = - // [a for a in current_epoch_attestations + previous_epoch_attestations - // if a.data.justified_epoch == state.previous_justified_epoch]. - List previous_epoch_justified_attestations = Stream - .concat(current_epoch_attestations.stream(), previous_epoch_attestations.stream()) - .filter(a -> a.getData().getJustifiedEpoch().equals(state.getPreviousJustifiedEpoch())) - .collect(Collectors.toList()); - - // Let previous_epoch_justified_attester_indices be the union of the validator index sets given by - // [get_attestation_participants(state, a.data, a.aggregation_bitfield) - // for a in previous_epoch_justified_attestations]. - Set previous_epoch_justified_attester_indices = previous_epoch_justified_attestations - .stream() - .flatMap(a -> spec.get_attestation_participants( - state, a.getData(), a.getAggregationBitfield()).stream()) - .collect(Collectors.toSet()); - - // Let previous_epoch_justified_attesting_balance = sum([get_effective_balance(state, i) - // for i in previous_epoch_justified_attester_indices]). - Gwei previous_epoch_justified_attesting_balance = previous_epoch_justified_attester_indices - .stream() - .map(i -> spec.get_effective_balance(state, i)) - .reduce(Gwei::plus) - .orElse(Gwei.ZERO); + // Let previous_epoch_attesting_balance = + // get_total_balance(state, previous_epoch_attester_indices). + Gwei previous_epoch_attesting_balance = + spec.get_total_balance(state, previous_epoch_attester_indices); // Validators justifying the epoch boundary block at the start of the previous epoch: - // Let previous_epoch_boundary_attestations = [a for a in previous_epoch_justified_attestations + // Let previous_epoch_boundary_attestations = [a for a in previous_epoch_attestations // if a.data.epoch_boundary_root == get_block_root(state, get_epoch_start_slot(previous_epoch))]. List previous_epoch_boundary_attestations = - previous_epoch_justified_attestations.stream() + previous_epoch_attestations.stream() .filter(a -> a.getData().getEpochBoundaryRoot() .equals(spec.get_block_root(state, spec.get_epoch_start_slot(previous_epoch)))) .collect(Collectors.toList()); @@ -228,13 +195,10 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ state, a.getData(), a.getAggregationBitfield()).stream()) .collect(Collectors.toSet()); - // Let previous_epoch_boundary_attesting_balance = sum([get_effective_balance(state, i) - // for i in previous_epoch_boundary_attester_indices]). - Gwei previous_epoch_boundary_attesting_balance = previous_epoch_boundary_attester_indices - .stream() - .map(i -> spec.get_effective_balance(state, i)) - .reduce(Gwei::plus) - .orElse(Gwei.ZERO); + // Let previous_epoch_boundary_attesting_balance = + // get_total_balance(state, previous_epoch_boundary_attester_indices). + Gwei previous_epoch_boundary_attesting_balance = + spec.get_total_balance(state, previous_epoch_boundary_attester_indices); // Validators attesting to the expected beacon chain head during the previous epoch: @@ -254,12 +218,10 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ state, a.getData(), a.getAggregationBitfield()).stream()) .collect(Collectors.toSet()); - // Let previous_epoch_head_attesting_balance = sum([get_effective_balance(state, i) - // for i in previous_epoch_head_attester_indices]). - Gwei previous_epoch_head_attesting_balance = previous_epoch_head_attester_indices.stream() - .map(i -> spec.get_effective_balance(state, i)) - .reduce(Gwei::plus) - .orElse(Gwei.ZERO); + // Let previous_epoch_head_attesting_balance = + // get_total_balance(state, previous_epoch_head_attester_indices). + Gwei previous_epoch_head_attesting_balance = + spec.get_total_balance(state, previous_epoch_head_attester_indices); if (summary != null) { summary.previousEpochSummary.activeAttesters = current_active_validator_indices; @@ -268,8 +230,8 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ summary.previousEpochSummary.boundaryAttestingBalance = previous_epoch_boundary_attesting_balance; summary.headAttesters.addAll(previous_epoch_head_attester_indices); summary.headAttestingBalance = previous_epoch_head_attesting_balance; - summary.justifiedAttesters.addAll(previous_epoch_justified_attester_indices); - summary.justifiedAttestingBalance = previous_epoch_justified_attesting_balance; + summary.justifiedAttesters.addAll(previous_epoch_attester_indices); + summary.justifiedAttestingBalance = previous_epoch_attesting_balance; } @@ -308,15 +270,25 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ // Let winning_root(crosslink_committee) be equal to the value of crosslink_data_root // such that sum([get_effective_balance(state, i) // for i in attesting_validator_indices(crosslink_committee, crosslink_data_root)]) - // is maximized (ties broken by favoring lower crosslink_data_root values). + // is maximized (ties broken by favoring lexicographically smallest crosslink_data_root values). // TODO not sure this is correct implementation Gwei sum = attesting_validator_indices_tmp.stream() .map(i -> spec.get_effective_balance(state, i)) .reduce(Gwei::plus) .orElse(Gwei.ZERO); - winning_root_tmp.compute(crosslink_committee, (k, v) -> - v == null || sum.compareTo(v.getValue0()) > 0 ? - Pair.with(sum, crosslink_data_root) : v + winning_root_tmp.compute(crosslink_committee, (k, v) -> { + if (v == null) { + return Pair.with(sum, crosslink_data_root); + } + if (sum.greater(v.getValue0())) { + return Pair.with(sum, crosslink_data_root); + } + if (sum.equals(v.getValue0()) && crosslink_data_root.compareTo(v.getValue1()) > 0) { + return Pair.with(sum, crosslink_data_root); + } + + return v; + } ); } } @@ -476,10 +448,9 @@ private BeaconStateEx apply(BeaconStateEx origState, EpochTransitionSummary summ For every slot in range(get_epoch_start_slot(previous_epoch), get_epoch_start_slot(next_epoch)), let crosslink_committees_at_slot = get_crosslink_committees_at_slot(state, slot). For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: - Set state.latest_crosslinks[shard] = Crosslink( - epoch=current_epoch, - crosslink_data_root=winning_root(crosslink_committee)) - if 3 * total_attesting_balance(crosslink_committee) >= 2 * total_balance(crosslink_committee). + Set state.latest_crosslinks[shard] = Crosslink(epoch=slot_to_epoch(slot), + crosslink_data_root=winning_root(crosslink_committee)) + if 3 * total_attesting_balance(crosslink_committee) >= 2 * get_total_balance(crosslink_committee). */ for (SlotNumber slot : spec.get_epoch_start_slot(previous_epoch) .iterateTo(spec.get_epoch_start_slot(next_epoch))) { @@ -489,9 +460,9 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: List crosslink_committee = committee.getCommittee(); ShardNumber shard = committee.getShard(); if (total_attesting_balance.apply(crosslink_committee).times(3).greaterEqual( - total_balance.apply(crosslink_committee).times(2))) { + spec.get_total_balance(state, crosslink_committee).times(2))) { state.getLatestCrosslinks().set(shard, - new Crosslink(current_epoch, winning_root.get(crosslink_committee))); + new Crosslink(spec.slot_to_epoch(slot), winning_root.get(crosslink_committee))); } } } @@ -550,11 +521,11 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: // Expected FFG source: - // Any validator index in previous_epoch_justified_attester_indices gains - // base_reward(state, index) * previous_epoch_justified_attesting_balance // previous_total_balance. - for (ValidatorIndex index : previous_epoch_justified_attester_indices) { + // Any validator index in previous_epoch_attester_indices gains base_reward(state, index) * + // previous_epoch_attesting_balance // previous_total_balance. + for (ValidatorIndex index : previous_epoch_attester_indices) { Gwei reward = base_reward.apply(index) - .times(previous_epoch_justified_attesting_balance) + .times(previous_epoch_attesting_balance) .dividedBy(previous_total_balance); state.getValidatorBalances().update(index, balance -> balance.plus(reward)); @@ -563,17 +534,16 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: summary.attestationRewards.put(index, reward); } } - if (logger.isTraceEnabled() && !previous_epoch_justified_attester_indices.isEmpty()) { + if (logger.isTraceEnabled() && !previous_epoch_attester_indices.isEmpty()) { logger.trace("Rewarded: Previous epoch justified attesters: " - + previous_epoch_justified_attester_indices); + + previous_epoch_attester_indices); } - // Any active validator index not in previous_epoch_justified_attester_indices loses - // base_reward(state, index). + // Any active validator index not in previous_epoch_attester_indices loses base_reward(state, index). // FIXME 'active validator' - not exact meaning List previous_epoch_justified_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { - if (!previous_epoch_justified_attester_indices.contains(index)) { + if (!previous_epoch_attester_indices.contains(index)) { Gwei penalty = base_reward.apply(index); state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); @@ -689,11 +659,11 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: summary.noFinality = true; } - // Any active validator index not in previous_epoch_justified_attester_indices, loses + // Any active validator index not in previous_epoch_attester_indices, loses // inactivity_penalty(state, index, epochs_since_finality). List previous_epoch_justified_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { - if (!previous_epoch_justified_attester_indices.contains(index)) { + if (!previous_epoch_attester_indices.contains(index)) { Gwei penalty = inactivity_penalty.apply(index, epochs_since_finality); state.getValidatorBalances().update(index, balance -> balance.minus(penalty)); previous_epoch_justified_attester_loosers.add(index); @@ -744,8 +714,8 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: logger.debug("Penalized: Previous epoch head attesters: " + previous_epoch_head_attester_loosers); } - // Any active_validator index with validator.initiated_exit <= current_epoch, loses - // 2 * inactivity_penalty(state, index, epochs_since_finality) + base_reward(state, index). + // Any active validator index with validator.slashed == True, + // loses 2 * inactivity_penalty(state, index, epochs_since_finality) + base_reward(state, index). List inactive_attester_loosers = new ArrayList<>(); for (ValidatorIndex index : previous_active_validator_indices) { ValidatorRecord validator = state.getValidatorRegistry().get(index); @@ -813,10 +783,10 @@ For every (crosslink_committee, shard) in crosslink_committees_at_slot, compute: For every slot in range(get_epoch_start_slot(previous_epoch), get_epoch_start_slot(current_epoch)): Let crosslink_committees_at_slot = get_crosslink_committees_at_slot(state, slot). - For every (crosslink_committee, shard) in crosslink_committees_at_slot: + For every (crosslink_committee, shard) in crosslink_committees_at_slot and every index in crosslink_committee: If index in attesting_validators(crosslink_committee), state.validator_balances[index] += base_reward(state, index) * - total_attesting_balance(crosslink_committee) // total_balance(crosslink_committee)). + total_attesting_balance(crosslink_committee) // get_total_balance(state, crosslink_committee)). If index not in attesting_validators(crosslink_committee), state.validator_balances[index] -= base_reward(state, index). */ @@ -829,7 +799,9 @@ If index not in attesting_validators(crosslink_committee), Set attesting_validator_set = attesting_validators.apply(crosslink_committee); for (ValidatorIndex index : crosslink_committee) { if (attesting_validator_set.contains(index)) { - state.getValidatorBalances().update(index, vb -> vb.plus(base_reward.apply(index))); + state.getValidatorBalances().update(index, + vb -> vb.plus(base_reward.apply(index).mulDiv(total_attesting_balance.apply(crosslink_committee), + spec.get_total_balance(state, crosslink_committee)))); crosslink_attestation_gainers.add(index); } else { state.getValidatorBalances().update(index, vb -> vb.minus(base_reward.apply(index))); @@ -943,7 +915,8 @@ def process_ejections(state: BeaconState) -> None: } // Regardless of whether or not a validator set change happens, run the following: - spec.process_penalties_and_exits(state); + spec.process_slashings(state); + spec.process_exit_queue(state); /* Final updates From e745049379775af42cdf37dc450a20590f5e9637 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Tue, 5 Mar 2019 13:16:03 +0600 Subject: [PATCH 17/21] Add BooleanPrimitive codec to SSZ annotation serializer --- ssz/src/main/java/org/ethereum/beacon/ssz/Serializer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ssz/src/main/java/org/ethereum/beacon/ssz/Serializer.java b/ssz/src/main/java/org/ethereum/beacon/ssz/Serializer.java index 7799e866f..fa9992b6a 100644 --- a/ssz/src/main/java/org/ethereum/beacon/ssz/Serializer.java +++ b/ssz/src/main/java/org/ethereum/beacon/ssz/Serializer.java @@ -1,5 +1,6 @@ package org.ethereum.beacon.ssz; +import org.ethereum.beacon.ssz.type.BooleanPrimitive; import org.ethereum.beacon.ssz.type.BytesCodec; import org.ethereum.beacon.ssz.type.HashCodec; import org.ethereum.beacon.ssz.type.UIntCodec; @@ -24,6 +25,7 @@ public class Serializer { builder.addCodec(new HashCodec()); builder.addCodec(new UIntCodec()); builder.addCodec(new BytesCodec()); + builder.addCodec(new BooleanPrimitive()); ANNOTATION_SERIALIZER = builder.build(); } From bdbf5279e2be71a4a6619fa617b7d7ea1fcec941 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Tue, 5 Mar 2019 13:35:46 +0600 Subject: [PATCH 18/21] Fix SSZ tests --- .../org/ethereum/beacon/chain/DefaultBeaconChainTest.java | 4 ++-- .../beacon/chain/storage/BeaconBlockStorageTest.java | 2 +- .../main/java/org/ethereum/beacon/core/BeaconBlock.java | 8 ++++---- .../java/org/ethereum/beacon/core/BeaconBlockBody.java | 7 +++++++ .../org/ethereum/beacon/core/state/BeaconStateImpl.java | 2 +- .../org/ethereum/beacon/core/ModelsSerializeTest.java | 4 ++-- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/chain/src/test/java/org/ethereum/beacon/chain/DefaultBeaconChainTest.java b/chain/src/test/java/org/ethereum/beacon/chain/DefaultBeaconChainTest.java index 8a93f8375..2bd91e847 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/DefaultBeaconChainTest.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/DefaultBeaconChainTest.java @@ -68,8 +68,8 @@ private BeaconBlock createBlock( Hash32.ZERO, specHelpers.getConstants().getEmptySignature(), Eth1Data.EMPTY, - specHelpers.getConstants().getEmptySignature(), - BeaconBlockBody.EMPTY); + BeaconBlockBody.EMPTY, + specHelpers.getConstants().getEmptySignature()); BeaconState state = perSlotTransition .apply( diff --git a/chain/src/test/java/org/ethereum/beacon/chain/storage/BeaconBlockStorageTest.java b/chain/src/test/java/org/ethereum/beacon/chain/storage/BeaconBlockStorageTest.java index bff31ac59..89405af52 100644 --- a/chain/src/test/java/org/ethereum/beacon/chain/storage/BeaconBlockStorageTest.java +++ b/chain/src/test/java/org/ethereum/beacon/chain/storage/BeaconBlockStorageTest.java @@ -29,7 +29,7 @@ private BeaconBlock createBlock(long slot, BeaconBlock parent, Hash32 parentHash return new BeaconBlock(SlotNumber.of(slot), parent == null ? Hash32.ZERO : parentHash, Hash32.wrap(Bytes32.leftPad(BytesValues.toMinimalBytes(counter++))), - BLSSignature.ZERO, Eth1Data.EMPTY, BLSSignature.ZERO, BeaconBlockBody.EMPTY); + BLSSignature.ZERO, Eth1Data.EMPTY, BeaconBlockBody.EMPTY, BLSSignature.ZERO); } // TODO: Test smth diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java b/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java index 989eee5f5..370598f1f 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconBlock.java @@ -52,8 +52,8 @@ public BeaconBlock( Hash32 stateRoot, BLSSignature randaoReveal, Eth1Data eth1Data, - BLSSignature signature, - BeaconBlockBody body) { + BeaconBlockBody body, + BLSSignature signature) { this.slot = slot; this.parentRoot = parentRoot; this.stateRoot = stateRoot; @@ -64,7 +64,7 @@ public BeaconBlock( } public BeaconBlock withStateRoot(Hash32 stateRoot) { - return new BeaconBlock(slot, parentRoot, stateRoot, randaoReveal, eth1Data, signature, body); + return new BeaconBlock(slot, parentRoot, stateRoot, randaoReveal, eth1Data, body, signature); } public SlotNumber getSlot() { @@ -266,7 +266,7 @@ public BeaconBlock build() { assert body != null; return new BeaconBlock( - slot, parentRoot, stateRoot, randaoReveal, eth1Data, signature, body); + slot, parentRoot, stateRoot, randaoReveal, eth1Data, body, signature); } } } diff --git a/core/src/main/java/org/ethereum/beacon/core/BeaconBlockBody.java b/core/src/main/java/org/ethereum/beacon/core/BeaconBlockBody.java index d25a3d393..5451ac017 100644 --- a/core/src/main/java/org/ethereum/beacon/core/BeaconBlockBody.java +++ b/core/src/main/java/org/ethereum/beacon/core/BeaconBlockBody.java @@ -126,6 +126,13 @@ public List getExitsList() { return exitsList; } + /** + * @deprecated for serialization only + */ + public List getTransferList() { + return transferList; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java b/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java index 2ff4abed4..e430d4136 100644 --- a/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java +++ b/core/src/main/java/org/ethereum/beacon/core/state/BeaconStateImpl.java @@ -64,7 +64,7 @@ public class BeaconStateImpl implements MutableBeaconState { @SSZ private Eth1Data latestEth1Data = Eth1Data.EMPTY; @SSZ private List eth1DataVotesList = new ArrayList<>(); - @SSZ private UInt64 depositIndex; + @SSZ private UInt64 depositIndex = UInt64.ZERO; public BeaconStateImpl() {} diff --git a/core/src/test/java/org/ethereum/beacon/core/ModelsSerializeTest.java b/core/src/test/java/org/ethereum/beacon/core/ModelsSerializeTest.java index 2de052824..a09f12b6c 100644 --- a/core/src/test/java/org/ethereum/beacon/core/ModelsSerializeTest.java +++ b/core/src/test/java/org/ethereum/beacon/core/ModelsSerializeTest.java @@ -282,8 +282,8 @@ private BeaconBlock createBeaconBlock() { new Eth1Data( Hashes.keccak256(BytesValue.fromHexString("ddaa")), Hashes.keccak256(BytesValue.fromHexString("ddbb"))), - BLSSignature.wrap(Bytes96.fromHexString("aa")), - createBeaconBlockBody()); + createBeaconBlockBody(), + BLSSignature.wrap(Bytes96.fromHexString("aa"))); return beaconBlock; } From 83ef5502f7f899cc9177d2a91916051f9582558b Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Tue, 5 Mar 2019 13:50:15 +0600 Subject: [PATCH 19/21] Fix all the rest tests after the spec update --- .../beacon/consensus/SpecHelpers.java | 40 +-------- .../operation/VoluntaryExitVerifier.java | 2 +- .../ethereum/beacon/core/operations/Exit.java | 82 ------------------- .../core/SSZSerializableAnnotationTest.java | 4 +- start/config/src/test/resources/chainSpec.yml | 2 +- .../attester/BeaconChainAttesterTest.java | 6 +- 6 files changed, 9 insertions(+), 127 deletions(-) delete mode 100644 core/src/main/java/org/ethereum/beacon/core/operations/Exit.java diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java index 3577399a7..bc64d54be 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/SpecHelpers.java @@ -649,44 +649,6 @@ public boolean is_power_of_two(UInt64 value) { return Long.bitCount(value.getValue()) == 1; } - /* - def validate_proof_of_possession(state: BeaconState, - pubkey: int, - proof_of_possession: bytes, - withdrawal_credentials: Hash32) -> bool: - proof_of_possession_data = DepositInput( - pubkey=pubkey, - withdrawal_credentials=withdrawal_credentials, - proof_of_possession=EMPTY_SIGNATURE, - ) - - return bls_verify( - pubkey=pubkey, - message=hash_tree_root(proof_of_possession_data), - signature=proof_of_possession, - domain=get_domain( - state.fork, - get_current_epoch(state), - DOMAIN_DEPOSIT, - ) - ) - */ - public boolean validate_proof_of_possession( - MutableBeaconState state, - BLSPubkey pubkey, - BLSSignature proof_of_possession, - Hash32 withdrawal_credentials) { - - DepositInput deposit_input = - new DepositInput(pubkey, withdrawal_credentials, constants.getEmptySignature()); - - return bls_verify( - pubkey, - signed_root(deposit_input, "proofOfPossession"), - proof_of_possession, - get_domain(state.getForkData(), get_current_epoch(state), SignatureDomains.DEPOSIT)); - } - /* def process_deposit(state: BeaconState, deposit: Deposit) -> None: """ @@ -719,7 +681,7 @@ public void process_deposit( boolean proof_is_valid = bls_verify( deposit_input.getPubKey(), - signed_root(deposit_input, "proof_of_possession"), + signed_root(deposit_input, "proofOfPossession"), deposit_input.getProofOfPossession(), get_domain(state.getForkData(), get_current_epoch(state), SignatureDomains.DEPOSIT)); diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/VoluntaryExitVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/VoluntaryExitVerifier.java index 28d75c036..27050e2b9 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/VoluntaryExitVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/operation/VoluntaryExitVerifier.java @@ -50,7 +50,7 @@ public VerificationResult verify(VoluntaryExit voluntaryExit, BeaconState state) } // Let exit_message = hash_tree_root( - // Exit( + // VoluntaryExitVerifier( // epoch=exit.epoch, // validator_index=exit.validator_index, // signature=EMPTY_SIGNATURE)). diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/Exit.java b/core/src/main/java/org/ethereum/beacon/core/operations/Exit.java deleted file mode 100644 index d146b0d0e..000000000 --- a/core/src/main/java/org/ethereum/beacon/core/operations/Exit.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.ethereum.beacon.core.operations; - -import com.google.common.base.Objects; -import javax.annotation.Nullable; -import org.ethereum.beacon.core.BeaconBlockBody; -import org.ethereum.beacon.core.spec.SpecConstants; -import org.ethereum.beacon.core.types.BLSSignature; -import org.ethereum.beacon.core.types.EpochNumber; -import org.ethereum.beacon.core.types.ValidatorIndex; -import org.ethereum.beacon.ssz.annotation.SSZ; -import org.ethereum.beacon.ssz.annotation.SSZSerializable; - -/** - * Requests a quit from validator registry. - * - * @see BeaconBlockBody - * @see Exit - * in the spec - */ -@SSZSerializable -public class Exit { - - /** - * Minimum slot for processing exit. - */ - @SSZ - private final EpochNumber epoch; - /** - * Index of the exiting validator. - */ - @SSZ - private final ValidatorIndex validatorIndex; - /** - * Validator signature. - */ - @SSZ - private final BLSSignature signature; - - public Exit(EpochNumber epoch, ValidatorIndex validatorIndex, BLSSignature signature) { - this.epoch = epoch; - this.validatorIndex = validatorIndex; - this.signature = signature; - } - - public EpochNumber getEpoch() { - return epoch; - } - - public ValidatorIndex getValidatorIndex() { - return validatorIndex; - } - - public BLSSignature getSignature() { - return signature; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - Exit exit = (Exit) o; - return Objects.equal(epoch, exit.epoch) - && Objects.equal(validatorIndex, exit.validatorIndex) - && Objects.equal(signature, exit.signature); - } - - @Override - public String toString() { - return toString(null); - } - - public String toString(@Nullable SpecConstants spec) { - return "Exit[" - + "epoch=" + epoch.toString(spec) - + ", validator=" + validatorIndex - + ", sig=" + signature - +"]"; - } -} \ No newline at end of file diff --git a/core/src/test/java/org/ethereum/beacon/core/SSZSerializableAnnotationTest.java b/core/src/test/java/org/ethereum/beacon/core/SSZSerializableAnnotationTest.java index 5271fe960..733685a2d 100644 --- a/core/src/test/java/org/ethereum/beacon/core/SSZSerializableAnnotationTest.java +++ b/core/src/test/java/org/ethereum/beacon/core/SSZSerializableAnnotationTest.java @@ -11,6 +11,7 @@ import java.util.Set; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.Deposit; +import org.ethereum.beacon.core.operations.Transfer; import org.ethereum.beacon.core.operations.VoluntaryExit; import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.operations.attestation.AttestationData; @@ -144,7 +145,8 @@ public void testAnnotatedClassesHaveTests() throws Exception { SlotNumber.class, Time.class, Millis.class, - ValidatorIndex.class)); + ValidatorIndex.class, + Transfer.class)); Class[] allClasses = getClasses("org.ethereum.beacon.core"); for (Class clazz : allClasses) { diff --git a/start/config/src/test/resources/chainSpec.yml b/start/config/src/test/resources/chainSpec.yml index b85589a41..e44b47ae1 100644 --- a/start/config/src/test/resources/chainSpec.yml +++ b/start/config/src/test/resources/chainSpec.yml @@ -5,7 +5,7 @@ honestValidatorParameters: ETH1_FOLLOW_DISTANCE: 1024 initialValues: GENESIS_FORK_VERSION: 0 - GENESIS_SLOT: 524288 + GENESIS_SLOT: 4294967296 GENESIS_START_SHARD: 0 FAR_FUTURE_EPOCH: 18446744073709551615 ZERO_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 diff --git a/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java b/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java index 3e8bf5c5c..ad635b986 100644 --- a/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java +++ b/validator/src/test/java/org/ethereum/beacon/validator/attester/BeaconChainAttesterTest.java @@ -13,6 +13,7 @@ import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.operations.attestation.AttestationData; import org.ethereum.beacon.core.operations.attestation.AttestationDataAndCustodyBit; +import org.ethereum.beacon.core.operations.attestation.Crosslink; import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.spec.SignatureDomains; import org.ethereum.beacon.core.types.BLSSignature; @@ -43,13 +44,12 @@ public void attestASlot() { int indexIntoCommittee = Math.abs(random.nextInt() % committee.size()); ValidatorIndex validatorIndex = committee.get(indexIntoCommittee); Hash32 epochBoundaryRoot = Hash32.random(random); - Hash32 latestCrosslinkRoot = Hash32.random(random); Hash32 justifiedBlockRoot = Hash32.random(random); ShardNumber shard = specHelpers.getConstants().getBeaconChainShardNumber(); Mockito.doReturn(committee).when(attester).getCommittee(any(), any()); Mockito.doReturn(epochBoundaryRoot).when(attester).getEpochBoundaryRoot(any(), any()); - Mockito.doReturn(latestCrosslinkRoot).when(attester).getLatestCrosslink(any(), any()); + Mockito.doReturn(Crosslink.EMPTY).when(attester).getLatestCrosslink(any(), any()); Mockito.doReturn(justifiedBlockRoot).when(attester).getJustifiedBlockRoot(any()); Attestation attestation = @@ -64,7 +64,7 @@ public void attestASlot() { specHelpers.hash_tree_root(initiallyObservedState.getHead()), data.getBeaconBlockRoot()); Assert.assertEquals(epochBoundaryRoot, data.getEpochBoundaryRoot()); Assert.assertEquals(Hash32.ZERO, data.getCrosslinkDataRoot()); - Assert.assertEquals(latestCrosslinkRoot, data.getLatestCrosslink().getCrosslinkDataRoot()); + Assert.assertEquals(Hash32.ZERO, data.getLatestCrosslink().getCrosslinkDataRoot()); Assert.assertEquals(state.getJustifiedEpoch(), data.getJustifiedEpoch()); Assert.assertEquals(justifiedBlockRoot, data.getJustifiedBlockRoot()); From 5031ed2e23a901ccd0da6a5bea88f3e18a1223fc Mon Sep 17 00:00:00 2001 From: Dmitry S Date: Wed, 6 Mar 2019 14:24:11 +0600 Subject: [PATCH 20/21] Update core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java Co-Authored-By: mkalinin --- .../main/java/org/ethereum/beacon/core/operations/Transfer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java b/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java index 0419f3949..345993838 100644 --- a/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java +++ b/core/src/main/java/org/ethereum/beacon/core/operations/Transfer.java @@ -10,7 +10,7 @@ import org.ethereum.beacon.ssz.annotation.SSZSerializable; /** - * A value transfer between validator. + * A value transfer between validators. * * @see Transfers From 5f1be47a0609ac2809423983fa8d929c7f86ee6a Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 6 Mar 2019 14:33:50 +0600 Subject: [PATCH 21/21] Fix distinct transfers check in TransferListVerifier --- .../verifier/block/TransferListVerifier.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java index 51abb6222..3a29e016d 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/verifier/block/TransferListVerifier.java @@ -3,6 +3,10 @@ import static org.ethereum.beacon.consensus.verifier.VerificationResult.PASSED; import static org.ethereum.beacon.consensus.verifier.VerificationResult.failedResult; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import org.ethereum.beacon.consensus.SpecHelpers; import org.ethereum.beacon.consensus.verifier.OperationVerifier; import org.ethereum.beacon.core.operations.Transfer; @@ -22,12 +26,13 @@ protected TransferListVerifier(OperationVerifier operationVerifier, Sp addCustomVerifier( ((transfers, state) -> { - for (Transfer t1 : transfers) { - for (Transfer t2 : transfers) { - if (t1.equals(t2)) { - return failedResult("two equal transfers have been found"); - } - } + List allTransfers = + StreamSupport.stream(transfers.spliterator(), false).collect(Collectors.toList()); + Set distinctTransfers = + StreamSupport.stream(transfers.spliterator(), false).collect(Collectors.toSet()); + + if (allTransfers.size() > distinctTransfers.size()) { + return failedResult("two equal transfers have been found"); } return PASSED;