use of tech.pegasys.teku.spec.executionengine.PayloadAttributes in project teku by ConsenSys.
the class ForkChoiceNotifierTest method getPayloadId_shouldObtainAPayloadIdWhenProposingTheMergeBlock.
@Test
void getPayloadId_shouldObtainAPayloadIdWhenProposingTheMergeBlock() {
reInitializePreMerge();
Bytes32 terminalBlockHash = dataStructureUtil.randomBytes32();
final Bytes8 payloadId = dataStructureUtil.randomBytes8();
final BeaconState headState = getHeadState();
final UInt64 blockSlot = headState.getSlot().plus(1);
final Bytes32 blockRoot = recentChainData.getBestBlockRoot().orElseThrow();
// we expect head block root and slot to be ZERO since in the test we do not send an
// onForkChoiceUpdated before calling onTerminalBlock, so it will initialize ZEROED
final ForkChoiceState forkChoiceState = new ForkChoiceState(Bytes32.ZERO, UInt64.ZERO, terminalBlockHash, terminalBlockHash, Bytes32.ZERO, false);
final PayloadAttributes payloadAttributes = withProposerForSlot(headState, blockSlot);
notifier.onTerminalBlockReached(terminalBlockHash);
validateGetPayloadIdOnTheFlyRetrieval(blockSlot, blockRoot, forkChoiceState, payloadId, payloadAttributes, false);
}
use of tech.pegasys.teku.spec.executionengine.PayloadAttributes in project teku by ConsenSys.
the class ForkChoiceNotifierTest method onAttestationsDue_shouldSendUpdateEvenWithAMissedBlockIfWeAreDueToProposeNextTwo.
@Test
void onAttestationsDue_shouldSendUpdateEvenWithAMissedBlockIfWeAreDueToProposeNextTwo() {
final BeaconState headState = getHeadState();
// slot 2
final UInt64 blockSlot1 = headState.getSlot().plus(1);
// slot 3
final UInt64 blockSlot2 = headState.getSlot().plus(2);
final List<PayloadAttributes> payloadAttributes = withProposerForTwoSlots(headState, blockSlot1, blockSlot2);
// context:
// current slot is 1
// proposer index 1 proposes on slot 2
// proposer index 0 proposes on slot 3
// slot is 1 and is not empty -> sending forkChoiceUpdated
final ForkChoiceState forkChoiceState = getCurrentForkChoiceState();
assertThat(notifier.onForkChoiceUpdated(forkChoiceState)).isCompleted();
// We are proposing block on slot 2
verify(executionEngineChannel).forkChoiceUpdated(forkChoiceState, Optional.of(payloadAttributes.get(0)));
// onAttestationsDue for slot 1 (attributes for slot2)
notifier.onAttestationsDue(headState.getSlot());
verifyNoMoreInteractions(executionEngineChannel);
// simulating we missed trying to produce a block: we are now in slot 2
storageSystem.chainUpdater().setCurrentSlot(recentChainData.getCurrentSlot().orElseThrow().plus(1));
// Slot 2 is now assumed empty so prepare to propose in slot 3
notifier.onAttestationsDue(recentChainData.getCurrentSlot().orElseThrow());
verify(executionEngineChannel).forkChoiceUpdated(forkChoiceState, Optional.of(payloadAttributes.get(1)));
// Shouldn't resend with added payload attributes
verifyNoMoreInteractions(executionEngineChannel);
}
use of tech.pegasys.teku.spec.executionengine.PayloadAttributes in project teku by ConsenSys.
the class ForkChoiceNotifierTest method getPayloadId_shouldReturnExceptionallyLatestPayloadIdOnWrongRoot.
@Test
void getPayloadId_shouldReturnExceptionallyLatestPayloadIdOnWrongRoot() {
final Bytes8 payloadId = dataStructureUtil.randomBytes8();
final ForkChoiceState forkChoiceState = getCurrentForkChoiceState();
final BeaconState headState = getHeadState();
final UInt64 blockSlot = headState.getSlot().plus(1);
final Bytes32 wrongBlockRoot = dataStructureUtil.randomBytes32();
final PayloadAttributes payloadAttributes = withProposerForSlot(headState, blockSlot);
final SafeFuture<ForkChoiceUpdatedResult> responseFuture = new SafeFuture<>();
when(executionEngineChannel.forkChoiceUpdated(forkChoiceState, Optional.of(payloadAttributes))).thenReturn(responseFuture);
assertThat(notifier.onForkChoiceUpdated(forkChoiceState)).isCompleted();
responseFuture.complete(createForkChoiceUpdatedResult(ExecutionPayloadStatus.VALID, Optional.of(payloadId)));
assertThatSafeFuture(notifier.getPayloadId(wrongBlockRoot, blockSlot)).isCompletedExceptionally();
}
use of tech.pegasys.teku.spec.executionengine.PayloadAttributes in project teku by ConsenSys.
the class ForkChoiceNotifierTest method getPayloadId_shouldObtainAPayloadIdOnPostMergeBlockFinalizedEvenIfProposerNotPrepared.
@Test
void getPayloadId_shouldObtainAPayloadIdOnPostMergeBlockFinalizedEvenIfProposerNotPrepared() {
final Bytes8 payloadId = dataStructureUtil.randomBytes8();
// current slot: 1
// send post-merge onForkChoiceUpdated (with finalized block state)
ForkChoiceState finalizedForkChoiceState = getCurrentForkChoiceState();
assertThat(finalizedForkChoiceState.getFinalizedExecutionBlockHash()).isNotEqualTo(Bytes32.ZERO);
assertThat(notifier.onForkChoiceUpdated(finalizedForkChoiceState)).isCompleted();
verify(executionEngineChannel).forkChoiceUpdated(finalizedForkChoiceState, Optional.empty());
final BeaconState headState = getHeadState();
// proposing slot 3
final UInt64 blockSlot = headState.getSlot().plus(2);
final Bytes32 blockRoot = recentChainData.getBestBlockRoot().orElseThrow();
final PayloadAttributes payloadAttributes = withProposerForSlotButDoNotPrepare(headState, blockSlot, defaultFeeRecipient);
validateGetPayloadIdOnTheFlyRetrieval(blockSlot, blockRoot, finalizedForkChoiceState, payloadId, payloadAttributes, false);
}
use of tech.pegasys.teku.spec.executionengine.PayloadAttributes in project teku by ConsenSys.
the class ForkChoiceNotifierTest method onForkChoiceUpdated_shouldNotSendNotificationOfOutOfOrderPayloadAttributes.
@Test
@SuppressWarnings("unchecked")
void onForkChoiceUpdated_shouldNotSendNotificationOfOutOfOrderPayloadAttributes() {
final ForkChoiceState forkChoiceState = getCurrentForkChoiceState();
final BeaconState headState = getHeadState();
// slot 2
final UInt64 blockSlot = headState.getSlot().plus(1);
// proposer index 1 and 0 will propose slot 2 and 3
final List<PayloadAttributes> payloadAttributes = withProposerForTwoSlots(headState, blockSlot, blockSlot.plus(1));
// current slot is 1
// store real payload attributes and return an incomplete future
AtomicReference<SafeFuture<Optional<PayloadAttributes>>> actualResponseA = new AtomicReference<>();
SafeFuture<Optional<PayloadAttributes>> deferredResponseA = new SafeFuture<>();
doAnswer(invocation -> {
actualResponseA.set((SafeFuture<Optional<PayloadAttributes>>) invocation.callRealMethod());
return deferredResponseA;
}).when(payloadAttributesCalculator).calculatePayloadAttributes(any(), anyBoolean(), any(), anyBoolean());
assertThat(notifier.onForkChoiceUpdated(forkChoiceState)).isCompleted();
// it is called once with no attributes. the one with attributes is pending
verify(executionEngineChannel).forkChoiceUpdated(forkChoiceState, Optional.empty());
// forward to real method call
doAnswer(InvocationOnMock::callRealMethod).when(payloadAttributesCalculator).calculatePayloadAttributes(any(), anyBoolean(), any(), anyBoolean());
storageSystem.chainUpdater().setCurrentSlot(// set current slot to 2
headState.getSlot().plus(1));
assertThat(notifier.onForkChoiceUpdated(forkChoiceState)).isCompleted();
// expect a call with second attributes
verify(executionEngineChannel).forkChoiceUpdated(forkChoiceState, Optional.of(payloadAttributes.get(1)));
// let the payload attributes for slot 2 return
actualResponseA.get().propagateTo(deferredResponseA);
// it should get ignored
verifyNoMoreInteractions(executionEngineChannel);
}
Aggregations