Skip to content

Commit

Permalink
Merge pull request #98 from harmony-dev/spec/0.4.0
Browse files Browse the repository at this point in the history
Update consensus up to spec version 0.4.0
  • Loading branch information
mkalinin authored Mar 6, 2019
2 parents fd44473 + 5f1be47 commit 77490de
Show file tree
Hide file tree
Showing 118 changed files with 2,649 additions and 1,922 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<BeaconStateEx> initialTransition;
private final StateTransition<BeaconStateEx> perSlotTransition;
private final BlockTransition<BeaconStateEx> perBlockTransition;
Expand All @@ -46,7 +46,7 @@ public class DefaultBeaconChain implements MutableBeaconChain {
private BeaconTuple recentlyProcessed;

public DefaultBeaconChain(
SpecHelpers specHelpers,
SpecHelpers spec,
BlockTransition<BeaconStateEx> initialTransition,
StateTransition<BeaconStateEx> perSlotTransition,
BlockTransition<BeaconStateEx> perBlockTransition,
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand All @@ -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);
}
}
Expand All @@ -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();
}

Expand All @@ -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);
}
Expand All @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -46,7 +46,7 @@ public BeaconBlock getHead(
Function<Hash32, List<BeaconBlock>> getChildrenBlocks =
(hash) -> chainStorage.getBlockStorage().getChildren(hash, SEARCH_LIMIT);
BeaconBlock newHead =
specHelpers.lmd_ghost(
spec.lmd_ghost(
justifiedTuple.getBlock(),
justifiedTuple.getState(),
chainStorage.getBlockStorage()::get,
Expand Down
12 changes: 6 additions & 6 deletions chain/src/main/java/org/ethereum/beacon/chain/SlotTicker.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* start must subscribe to this service and use values from it
*/
public class SlotTicker implements Ticker<SlotNumber> {
private final SpecHelpers specHelpers;
private final SpecHelpers spec;
private final BeaconState state;

private final Schedulers schedulers;
Expand All @@ -29,8 +29,8 @@ public class SlotTicker implements Ticker<SlotNumber> {

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;

Expand All @@ -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().getSlotDuration();
SlotNumber nextSlot = spec.get_current_slot(state).increment();
Time period = spec.getConstants().getSecondsPerSlot();
startImpl(nextSlot, period, scheduler);
}

Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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())
+ "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,7 +30,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 {
Expand All @@ -41,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<BeaconStateEx> perSlotTransition;
private final StateTransition<BeaconStateEx> perEpochTransition;

Expand Down Expand Up @@ -74,16 +71,15 @@ public ObservableStateProcessorImpl(
Publisher<SlotNumber> slotTicker,
Publisher<Attestation> attestationPublisher,
Publisher<BeaconTuple> beaconPublisher,
SpecHelpers specHelpers,
SpecHelpers spec,
StateTransition<BeaconStateEx> perSlotTransition,
StateTransition<BeaconStateEx> 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;
Expand Down Expand Up @@ -122,13 +118,13 @@ 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.getMinAttestationInclusionDelay());
.minus(spec.getConstants().getSlotsPerEpoch())
.minus(spec.getConstants().getMinAttestationInclusionDelay());
runTaskInSeparateThread(
() -> {
purgeAttestations(slotMinimum);
Expand All @@ -141,10 +137,10 @@ private void doHardWork() {
for (Attestation attestation : attestations) {

List<ValidatorIndex> participants =
specHelpers.get_attestation_participants(
spec.get_attestation_participants(
latestState, attestation.getData(), attestation.getAggregationBitfield());

List<BLSPubkey> pubKeys = specHelpers.mapIndicesToPubKeys(latestState, participants);
List<BLSPubkey> pubKeys = spec.mapIndicesToPubKeys(latestState, participants);

for (BLSPubkey pubKey : pubKeys) {
addValidatorAttestation(pubKey, attestation);
Expand Down Expand Up @@ -184,11 +180,11 @@ private void addAttestationsFromState(BeaconState beaconState) {
beaconState.getLatestAttestations();
for (PendingAttestationRecord pendingAttestationRecord : pendingAttestationRecords) {
List<ValidatorIndex> participants =
specHelpers.get_attestation_participants(
spec.get_attestation_participants(
beaconState,
pendingAttestationRecord.getData(),
pendingAttestationRecord.getAggregationBitfield());
List<BLSPubkey> pubKeys = specHelpers.mapIndicesToPubKeys(beaconState, participants);
List<BLSPubkey> pubKeys = spec.mapIndicesToPubKeys(beaconState, participants);
SlotNumber slot = pendingAttestationRecord.getData().getSlot();
pubKeys.forEach(
pubKey -> {
Expand Down Expand Up @@ -238,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 {
Expand All @@ -259,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);
}
}
Expand All @@ -275,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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
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;
import org.ethereum.beacon.core.spec.SpecConstants;
import org.ethereum.beacon.core.types.BLSPubkey;
import org.ethereum.beacon.core.types.SlotNumber;

Expand All @@ -23,15 +24,17 @@ public interface PendingOperations {

List<Attestation> peekAggregatedAttestations(int maxCount, SlotNumber minSlot, SlotNumber maxSlot);

List<Exit> peekExits(int maxCount);
List<VoluntaryExit> peekExits(int maxCount);

List<Transfer> peekTransfers(int maxCount);

default String toStringShort() {
return "PendingOperations["
+ (getAttestations().isEmpty() ? "" : "attest: " + getAttestations().size())
+ "]";
}

default String toStringMedium(ChainSpec spec) {
default String toStringMedium(SpecConstants spec) {
String ret = "PendingOperations[";
if (!getAttestations().isEmpty()) {
ret += "attest (slot/shard/beaconBlock): [";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -92,7 +93,12 @@ private Attestation aggregateAttestations(List<Attestation> attestations) {
}

@Override
public List<Exit> peekExits(int maxCount) {
public List<VoluntaryExit> peekExits(int maxCount) {
return Collections.emptyList();
}

@Override
public List<Transfer> peekTransfers(int maxCount) {
return Collections.emptyList();
}
}
Loading

0 comments on commit 77490de

Please sign in to comment.