下面列出了com.google.common.primitives.UnsignedLong#minus ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void onLatestBlockHead(final Block headBlock) {
final UnsignedLong headBlockNumber = UnsignedLong.valueOf(headBlock.getNumber());
if (headBlockNumber.compareTo(ETH1_FOLLOW_DISTANCE) < 0) {
LOG.debug("Not processing Eth1 blocks because chain has not reached minimum follow distance");
return;
}
final UnsignedLong newHeadAtFollowDistance = headBlockNumber.minus(ETH1_FOLLOW_DISTANCE);
if (headAtFollowDistance
.map(current -> current.compareTo(newHeadAtFollowDistance) < 0)
.orElse(true)) {
if (reachedHead.compareAndSet(false, true)) {
STATUS_LOG.eth1AtHead();
reachedHead.set(true);
}
headAtFollowDistance = Optional.of(newHeadAtFollowDistance);
LOG.debug("ETH1 block at follow distance updated to {}", newHeadAtFollowDistance);
subscribers.deliver(HeadUpdatedSubscriber::onHeadUpdated, newHeadAtFollowDistance);
}
}
RequestState(
final UnsignedLong startSlot,
final UnsignedLong step,
final UnsignedLong count,
final UnsignedLong headSlot,
final NavigableMap<UnsignedLong, Bytes32> knownBlockRoots,
final ResponseCallback<SignedBeaconBlock> callback) {
this.currentSlot = startSlot;
this.knownBlockRoots = knownBlockRoots;
// Minus 1 to account for sending the block at startSlot.
// We only decrement this when moving to the next slot but we're already at the first slot
this.remainingBlocks = count.minus(ONE);
this.step = step;
this.headSlot = headSlot;
this.callback = callback;
}
public SafeFuture<Optional<List<Committee>>> getCommitteesAtEpoch(final UnsignedLong epoch) {
if (!combinedChainDataClient.isChainDataFullyAvailable()) {
return chainUnavailable();
}
final UnsignedLong committeesCalculatedAtEpoch = epoch.equals(ZERO) ? ZERO : epoch.minus(ONE);
final UnsignedLong startingSlot = compute_start_slot_at_epoch(committeesCalculatedAtEpoch);
final UnsignedLong slot = compute_start_slot_at_epoch(epoch);
// one epoch in future is available, beyond that cannot be calculated
if (slot.compareTo(
recentChainData.getBestSlot().plus(UnsignedLong.valueOf(Constants.SLOTS_PER_EPOCH)))
> 0) {
return SafeFuture.completedFuture(Optional.empty());
}
return combinedChainDataClient
.getBlockAndStateInEffectAtSlot(startingSlot)
.thenApply(
maybeResult ->
maybeResult.map(
result ->
combinedChainDataClient.getCommitteesFromState(result.getState(), slot)
.stream()
.map(Committee::new)
.collect(Collectors.toList())));
}
@Test
public void getLatestFinalizedBlockSlot_postGenesisFinalizedBlockOutsideOfEpochBoundary()
throws Exception {
final UnsignedLong epoch = UnsignedLong.ONE;
final UnsignedLong epochBoundarySlot = compute_start_slot_at_epoch(epoch);
final UnsignedLong finalizedBlockSlot = epochBoundarySlot.minus(UnsignedLong.ONE);
final SignedBlockAndState finalizedBlock = chainBuilder.generateBlockAtSlot(finalizedBlockSlot);
saveBlock(storageClient, finalizedBlock);
// Start tx to update finalized checkpoint
final StoreTransaction tx = storageClient.startStoreTransaction();
// Initially finalized slot should match store
assertThat(tx.getLatestFinalizedBlockSlot()).isEqualTo(genesis.getSlot());
// Update checkpoint and check finalized slot accessors
tx.setFinalizedCheckpoint(new Checkpoint(epoch, finalizedBlock.getRoot()));
assertThat(tx.getLatestFinalizedBlockSlot()).isEqualTo(finalizedBlockSlot);
assertThat(storageClient.getStore().getLatestFinalizedBlockSlot()).isEqualTo(genesis.getSlot());
// Commit tx
tx.commit().reportExceptions();
assertThat(storageClient.getStore().getLatestFinalizedBlockSlot())
.isEqualTo(finalizedBlockSlot);
}
private UnsignedLong secondsBeforeCurrentVotingPeriodStartTime(
final UnsignedLong slot, final UnsignedLong genesisTime, final UnsignedLong valueToSubtract) {
final UnsignedLong currentVotingPeriodStartTime = getVotingPeriodStartTime(slot, genesisTime);
if (currentVotingPeriodStartTime.compareTo(valueToSubtract) > 0) {
return currentVotingPeriodStartTime.minus(valueToSubtract);
} else {
return UnsignedLong.ZERO;
}
}
private void prune(final UnsignedLong latestBlockTimestamp) {
if (latestBlockTimestamp.compareTo(cacheDuration) <= 0 || eth1ChainCache.isEmpty()) {
// Keep everything
return;
}
final UnsignedLong earliestBlockTimestampToKeep = latestBlockTimestamp.minus(cacheDuration);
// Make sure we have at least one entry prior to the cache period so that if we get an empty
// block before any deposit in the cached period, we can look back and get the deposit info
final UnsignedLong earliestKeyToKeep = eth1ChainCache.floorKey(earliestBlockTimestampToKeep);
if (earliestKeyToKeep == null) {
return;
}
eth1ChainCache.headMap(earliestKeyToKeep, false).clear();
}
@Override
public synchronized void onSlot(final UnsignedLong slot) {
final UnsignedLong attestationRetentionSlots =
UnsignedLong.valueOf(SLOTS_PER_EPOCH * ATTESTATION_RETENTION_EPOCHS);
if (slot.compareTo(attestationRetentionSlots) <= 0) {
return;
}
final UnsignedLong firstValidAttestationSlot = slot.minus(attestationRetentionSlots);
final Collection<Set<Bytes>> dataHashesToRemove =
dataHashBySlot.headMap(firstValidAttestationSlot, false).values();
dataHashesToRemove.stream().flatMap(Set::stream).forEach(attestationGroupByDataHash::remove);
dataHashesToRemove.clear();
}
/**
* Utility for streaming valid attestations available for inclusion at the given slot. This
* utility can be used to assign valid attestations to a generated block.
*
* @param slot The slot at which attestations are to be included
* @return A stream of valid attestations that can be included in a block generated at the given
* slot
*/
public Stream<Attestation> streamValidAttestationsForBlockAtSlot(final UnsignedLong slot) {
// Calculate bounds for valid head blocks
final UnsignedLong currentEpoch = compute_epoch_at_slot(slot);
final UnsignedLong prevEpoch =
currentEpoch.compareTo(UnsignedLong.ZERO) == 0
? currentEpoch
: currentEpoch.minus(UnsignedLong.ONE);
final UnsignedLong minBlockSlot = compute_start_slot_at_epoch(prevEpoch);
// Calculate valid assigned slots to be included in a block at the given slot
final UnsignedLong slotsPerEpoch = UnsignedLong.valueOf(SLOTS_PER_EPOCH);
final UnsignedLong minAssignedSlot =
slot.compareTo(slotsPerEpoch) <= 0 ? UnsignedLong.ZERO : slot.minus(slotsPerEpoch);
final UnsignedLong minInclusionDiff =
UnsignedLong.valueOf(Constants.MIN_ATTESTATION_INCLUSION_DELAY);
final UnsignedLong maxAssignedSlot =
slot.compareTo(minInclusionDiff) <= 0 ? slot : slot.minus(minInclusionDiff);
// Generate stream of consistent, valid attestations for inclusion
return LongStream.rangeClosed(minAssignedSlot.longValue(), maxAssignedSlot.longValue())
.mapToObj(UnsignedLong::valueOf)
.map(this::getLatestBlockAndStateAtSlot)
.filter(Objects::nonNull)
.filter(b -> b.getSlot().compareTo(minBlockSlot) >= 0)
.map(SignedBlockAndState::toUnsigned)
.flatMap(head -> attestationGenerator.streamAttestations(head, head.getSlot()));
}
private UnsignedLong minimumBroadcastTimeMillis(final UnsignedLong attestationSlot) {
final UnsignedLong lastAllowedTime =
recentChainData
.getGenesisTime()
.plus(attestationSlot.times(UnsignedLong.valueOf(SECONDS_PER_SLOT)));
final UnsignedLong lastAllowedTimeMillis = secondsToMillis(lastAllowedTime);
return lastAllowedTimeMillis.compareTo(MAXIMUM_GOSSIP_CLOCK_DISPARITY) >= 0
? lastAllowedTimeMillis.minus(MAXIMUM_GOSSIP_CLOCK_DISPARITY)
: ZERO;
}
private void onStoreInitialized() {
UnsignedLong genesisTime = recentChainData.getGenesisTime();
UnsignedLong currentTime = UnsignedLong.valueOf(System.currentTimeMillis() / 1000);
UnsignedLong currentSlot = ZERO;
if (currentTime.compareTo(genesisTime) >= 0) {
UnsignedLong deltaTime = currentTime.minus(genesisTime);
currentSlot = deltaTime.dividedBy(UnsignedLong.valueOf(SECONDS_PER_SLOT));
} else {
UnsignedLong timeUntilGenesis = genesisTime.minus(currentTime);
genesisTimeTracker = currentTime;
STATUS_LOG.timeUntilGenesis(timeUntilGenesis.longValue());
}
slotProcessor.setCurrentSlot(currentSlot);
}
@Override
public void commit(final PrepareAmounts prepareAmounts, final UnsignedLong deliveredAmount) {
Objects.requireNonNull(prepareAmounts);
Objects.requireNonNull(deliveredAmount);
if (is(prepareAmounts.getMinimumAmountToAccept()).lessThan(deliveredAmount)) {
UnsignedLong overrage = deliveredAmount.minus(prepareAmounts.getMinimumAmountToAccept());
reduceAmountLeftToDeliver(overrage);
}
this.deliveredAmount.getAndUpdate(currentAmount -> currentAmount.plus(deliveredAmount));
this.sentAmount.getAndUpdate(currentAmount -> currentAmount.plus(prepareAmounts.getAmountToSend()));
}
private UnsignedLong getVotingPeriodStartTime(
final UnsignedLong slot, final UnsignedLong genesisTime) {
final UnsignedLong eth1VotingPeriodStartSlot =
slot.minus(slot.mod(UnsignedLong.valueOf(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH)));
return computeTimeAtSlot(eth1VotingPeriodStartSlot, genesisTime);
}
public BeaconBlock createUnsignedBlock(
final BeaconState previousState,
final BeaconBlock previousBlock,
final UnsignedLong newSlot,
final BLSSignature randaoReveal,
final Optional<Bytes32> optionalGraffiti)
throws EpochProcessingException, SlotProcessingException, StateTransitionException {
// Process empty slots up to the one before the new block slot
final UnsignedLong slotBeforeBlock = newSlot.minus(UnsignedLong.ONE);
BeaconState blockPreState;
if (previousState.getSlot().equals(slotBeforeBlock)) {
blockPreState = previousState;
} else {
blockPreState = stateTransition.process_slots(previousState, slotBeforeBlock);
}
// Collect attestations to include
final BeaconState blockSlotState = stateTransition.process_slots(previousState, newSlot);
SSZList<Attestation> attestations = attestationPool.getAttestationsForBlock(blockSlotState);
// Collect slashings to include
final SSZList<ProposerSlashing> proposerSlashings =
proposerSlashingPool.getItemsForBlock(blockSlotState);
final SSZList<AttesterSlashing> attesterSlashings =
attesterSlashingPool.getItemsForBlock(blockSlotState);
// Collect exits to include
final SSZList<SignedVoluntaryExit> voluntaryExits =
voluntaryExitPool.getItemsForBlock(blockSlotState);
// Collect deposits
Eth1Data eth1Data = eth1DataCache.getEth1Vote(blockPreState);
final SSZList<Deposit> deposits = depositProvider.getDeposits(blockPreState, eth1Data);
final Bytes32 parentRoot = previousBlock.hash_tree_root();
return blockCreator
.createNewUnsignedBlock(
newSlot,
get_beacon_proposer_index(blockPreState, newSlot),
randaoReveal,
blockPreState,
parentRoot,
eth1Data,
optionalGraffiti.orElse(graffiti),
attestations,
proposerSlashings,
attesterSlashings,
deposits,
voluntaryExits)
.getBlock();
}
private UnsignedLong getCacheRangeLowerBound(UnsignedLong currentTime) {
return currentTime.compareTo(cacheDuration) > 0 ? currentTime.minus(cacheDuration) : ZERO;
}
public static UnsignedLong compute_slots_since_epoch_start(UnsignedLong slot) {
return slot.minus(compute_start_slot_at_epoch(compute_epoch_at_slot(slot)));
}
private static AttestationProcessingResult validateOnAttestation(
final MutableStore store,
final Attestation attestation,
final ForkChoiceStrategy forkChoiceStrategy) {
final Checkpoint target = attestation.getData().getTarget();
UnsignedLong current_epoch = compute_epoch_at_slot(get_current_slot(store));
// Use GENESIS_EPOCH for previous when genesis to avoid underflow
UnsignedLong previous_epoch =
current_epoch.compareTo(UnsignedLong.valueOf(GENESIS_EPOCH)) > 0
? current_epoch.minus(UnsignedLong.ONE)
: UnsignedLong.valueOf(GENESIS_EPOCH);
if (!target.getEpoch().equals(previous_epoch) && !target.getEpoch().equals(current_epoch)) {
return AttestationProcessingResult.invalid(
"Attestations must be from the current or previous epoch");
}
if (!target.getEpoch().equals(compute_epoch_at_slot(attestation.getData().getSlot()))) {
return AttestationProcessingResult.invalid("Attestation slot must be within specified epoch");
}
if (!forkChoiceStrategy.contains(target.getRoot())) {
// Attestations target must be for a known block. If a target block is unknown, delay
// consideration until the block is found
return AttestationProcessingResult.UNKNOWN_BLOCK;
}
Optional<UnsignedLong> blockSlot =
forkChoiceStrategy.blockSlot(attestation.getData().getBeacon_block_root());
if (blockSlot.isEmpty()) {
// Attestations must be for a known block. If block is unknown, delay consideration until the
// block is found
return AttestationProcessingResult.UNKNOWN_BLOCK;
}
if (blockSlot.get().compareTo(attestation.getData().getSlot()) > 0) {
return AttestationProcessingResult.invalid(
"Attestations must not be for blocks in the future. If not, the attestation should not be considered");
}
// LMD vote must be consistent with FFG vote target
final UnsignedLong target_slot = compute_start_slot_at_epoch(target.getEpoch());
if (get_ancestor(forkChoiceStrategy, attestation.getData().getBeacon_block_root(), target_slot)
.map(ancestorRoot -> !ancestorRoot.equals(target.getRoot()))
.orElse(true)) {
return AttestationProcessingResult.invalid(
"LMD vote must be consistent with FFG vote target");
}
return SUCCESSFUL;
}
/**
* Return the previous epoch of the given ``state``. Return the current epoch if it's genesis
* epoch.
*
* @param state
* @return
* @see
* <a>https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_previous_epoch</a>
*/
public static UnsignedLong get_previous_epoch(BeaconState state) {
UnsignedLong current_epoch = get_current_epoch(state);
return current_epoch.equals(UnsignedLong.valueOf(GENESIS_EPOCH))
? UnsignedLong.valueOf(GENESIS_EPOCH)
: current_epoch.minus(UnsignedLong.ONE);
}