-
Notifications
You must be signed in to change notification settings - Fork 283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add BlindBlockUtil for EIP-4844 #6532
Changes from 1 commit
34b1f57
f1d371b
90f197f
81b0a88
600696a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright ConsenSys Software Inc., 2022 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
*/ | ||
|
||
package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip4844; | ||
|
||
import static com.google.common.base.Preconditions.checkState; | ||
|
||
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; | ||
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock; | ||
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.common.AbstractSignedBeaconBlockBlinder; | ||
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsEip4844; | ||
|
||
public class SignedBeaconBlockBlinderEip4844 extends AbstractSignedBeaconBlockBlinder { | ||
|
||
public SignedBeaconBlockBlinderEip4844(final SchemaDefinitionsEip4844 schemaDefinitions) { | ||
super(schemaDefinitions); | ||
} | ||
|
||
@Override | ||
public SignedBeaconBlock blind(final SignedBeaconBlock signedUnblindedBock) { | ||
final BeaconBlockBodyEip4844Impl unblindedBlockBody = | ||
BeaconBlockBodyEip4844Impl.required(signedUnblindedBock.getMessage().getBody()); | ||
|
||
final BlindedBeaconBlockBodySchemaEip4844Impl schema = | ||
(BlindedBeaconBlockBodySchemaEip4844Impl) | ||
schemaDefinitions.getBlindedBeaconBlockBodySchema(); | ||
|
||
final BlindedBeaconBlockBodyEip4844Impl blindedBody = | ||
new BlindedBeaconBlockBodyEip4844Impl( | ||
schema, | ||
unblindedBlockBody.getRandaoRevealSsz(), | ||
unblindedBlockBody.getEth1Data(), | ||
unblindedBlockBody.getGraffitiSsz(), | ||
unblindedBlockBody.getProposerSlashings(), | ||
unblindedBlockBody.getAttesterSlashings(), | ||
unblindedBlockBody.getAttestations(), | ||
unblindedBlockBody.getDeposits(), | ||
unblindedBlockBody.getVoluntaryExits(), | ||
unblindedBlockBody.getSyncAggregate(), | ||
schema | ||
.getExecutionPayloadHeaderSchema() | ||
.createFromExecutionPayload(unblindedBlockBody.getExecutionPayload()), | ||
unblindedBlockBody.getBlsToExecutionChanges(), | ||
unblindedBlockBody.getBlobKzgCommitments()); | ||
|
||
final BeaconBlock blindedBeaconBlock = | ||
schemaDefinitions | ||
.getBlindedBeaconBlockSchema() | ||
.create( | ||
signedUnblindedBock.getSlot(), | ||
signedUnblindedBock.getProposerIndex(), | ||
signedUnblindedBock.getParentRoot(), | ||
signedUnblindedBock.getStateRoot(), | ||
blindedBody); | ||
|
||
checkState( | ||
blindedBeaconBlock.hashTreeRoot().equals(signedUnblindedBock.getMessage().hashTreeRoot()), | ||
"blinded block root do not match original unblinded block root"); | ||
|
||
return schemaDefinitions | ||
.getSignedBlindedBeaconBlockSchema() | ||
.create(blindedBeaconBlock, signedUnblindedBock.getSignature()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright ConsenSys Software Inc., 2022 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
*/ | ||
|
||
package tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip4844; | ||
|
||
import static com.google.common.base.Preconditions.checkNotNull; | ||
import static com.google.common.base.Preconditions.checkState; | ||
|
||
import java.util.function.Supplier; | ||
import tech.pegasys.teku.infrastructure.async.SafeFuture; | ||
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; | ||
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock; | ||
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.common.AbstractSignedBeaconBlockUnblinder; | ||
import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayload; | ||
import tech.pegasys.teku.spec.datastructures.execution.versions.eip4844.ExecutionPayloadEip4844; | ||
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix; | ||
|
||
public class SignedBeaconBlockUnblinderEip4844 extends AbstractSignedBeaconBlockUnblinder { | ||
protected SafeFuture<ExecutionPayload> executionPayloadFuture; | ||
|
||
public SignedBeaconBlockUnblinderEip4844( | ||
final SchemaDefinitionsBellatrix schemaDefinitions, | ||
final SignedBeaconBlock signedBlindedBeaconBlock) { | ||
super(schemaDefinitions, signedBlindedBeaconBlock); | ||
} | ||
|
||
@Override | ||
public void setExecutionPayloadSupplier( | ||
final Supplier<SafeFuture<ExecutionPayload>> executionPayloadSupplier) { | ||
this.executionPayloadFuture = executionPayloadSupplier.get(); | ||
} | ||
|
||
@Override | ||
public SafeFuture<SignedBeaconBlock> unblind() { | ||
BeaconBlock blindedBeaconBlock = signedBlindedBeaconBlock.getMessage(); | ||
if (!blindedBeaconBlock.getBody().isBlinded()) { | ||
return SafeFuture.completedFuture(signedBlindedBeaconBlock); | ||
} | ||
|
||
checkNotNull(executionPayloadFuture, "executionPayload must be set"); | ||
|
||
return executionPayloadFuture.thenApply( | ||
executionPayload -> { | ||
ExecutionPayloadEip4844.required(executionPayload); | ||
final BlindedBeaconBlockBodyEip4844 blindedBody = | ||
BlindedBeaconBlockBodyEip4844.required(blindedBeaconBlock.getBody()); | ||
checkState( | ||
executionPayload | ||
.hashTreeRoot() | ||
.equals(blindedBody.getExecutionPayloadHeader().hashTreeRoot()), | ||
"executionPayloadHeader root in blinded block do not match provided executionPayload root"); | ||
return signedBlindedBeaconBlock.unblind(schemaDefinitions, executionPayload); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright ConsenSys Software Inc., 2022 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
*/ | ||
|
||
package tech.pegasys.teku.spec.logic.versions.eip4844.util; | ||
|
||
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock; | ||
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockBlinder; | ||
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlockUnblinder; | ||
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip4844.SignedBeaconBlockBlinderEip4844; | ||
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.eip4844.SignedBeaconBlockUnblinderEip4844; | ||
import tech.pegasys.teku.spec.logic.common.util.BlindBlockUtil; | ||
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsEip4844; | ||
|
||
public class BlindBlockUtilEip4844 extends BlindBlockUtil { | ||
private final SchemaDefinitionsEip4844 schemaDefinitions; | ||
private final SignedBeaconBlockBlinder signedBeaconBlockBlinder; | ||
|
||
public BlindBlockUtilEip4844(final SchemaDefinitionsEip4844 schemaDefinitions) { | ||
this.schemaDefinitions = schemaDefinitions; | ||
this.signedBeaconBlockBlinder = new SignedBeaconBlockBlinderEip4844(schemaDefinitions); | ||
} | ||
|
||
@Override | ||
protected SignedBeaconBlockUnblinder createSignedBeaconBlockUnblinder( | ||
final SignedBeaconBlock signedBeaconBlock) { | ||
return new SignedBeaconBlockUnblinderEip4844(schemaDefinitions, signedBeaconBlock); | ||
} | ||
|
||
@Override | ||
protected SignedBeaconBlockBlinder getSignedBeaconBlockBlinder() { | ||
return signedBeaconBlockBlinder; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* Copyright ConsenSys Software Inc., 2022 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
*/ | ||
|
||
package tech.pegasys.teku.spec.logic.common.util; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.TestTemplate; | ||
import tech.pegasys.teku.infrastructure.async.SafeFuture; | ||
import tech.pegasys.teku.spec.Spec; | ||
import tech.pegasys.teku.spec.SpecMilestone; | ||
import tech.pegasys.teku.spec.SpecVersion; | ||
import tech.pegasys.teku.spec.TestSpecContext; | ||
import tech.pegasys.teku.spec.TestSpecInvocationContextProvider.SpecContext; | ||
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; | ||
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock; | ||
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix; | ||
import tech.pegasys.teku.spec.util.DataStructureUtil; | ||
|
||
@TestSpecContext(milestone = {SpecMilestone.BELLATRIX, SpecMilestone.EIP4844}) | ||
class BlindBlockUtilTest { | ||
|
||
private Spec spec; | ||
private DataStructureUtil dataStructureUtil; | ||
private BlindBlockUtil blindBlockUtil; | ||
|
||
@BeforeEach | ||
void setUp(final SpecContext specContext) { | ||
spec = specContext.getSpec(); | ||
dataStructureUtil = specContext.getDataStructureUtil(); | ||
final SpecVersion specVersion = spec.forMilestone(specContext.getSpecMilestone()); | ||
blindBlockUtil = specVersion.getBlindBlockUtil().orElseThrow(); | ||
} | ||
|
||
@TestTemplate | ||
void shouldBlindAndUnblindBlock(final SpecContext specContext) { | ||
|
||
final SignedBeaconBlock signedBeaconBlock = dataStructureUtil.randomSignedBeaconBlock(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CodeQL is actually right :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
assertThat(signedBeaconBlock.isBlinded()).isFalse(); | ||
final SignedBeaconBlock blindSignedBeaconBlock = | ||
blindBlockUtil.blindSignedBeaconBlock(signedBeaconBlock); | ||
assertThat(blindSignedBeaconBlock.isBlinded()).isTrue(); | ||
assertThat(blindSignedBeaconBlock.getBodyRoot()).isEqualTo(signedBeaconBlock.getBodyRoot()); | ||
assertThat(blindSignedBeaconBlock.getMessage().getBody().getOptionalExecutionPayload()) | ||
.isEmpty(); | ||
assertThat(blindSignedBeaconBlock.getMessage().getBody().getOptionalExecutionPayloadHeader()) | ||
.isNotEmpty(); | ||
|
||
final SafeFuture<SignedBeaconBlock> signedBeaconBlockSafeFuture = | ||
blindBlockUtil.unblindSignedBeaconBlock( | ||
blindSignedBeaconBlock, | ||
unblinder -> { | ||
final BeaconBlock block = unblinder.getSignedBlindedBeaconBlock().getMessage(); | ||
|
||
if (block | ||
.getBody() | ||
.getOptionalExecutionPayloadHeader() | ||
.orElseThrow() | ||
.isHeaderOfDefaultPayload()) { | ||
// Terminal block not reached, provide default payload | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. youre providing a random block, so you'll never fall in this code path so you can leave only the code in the |
||
unblinder.setExecutionPayloadSupplier( | ||
() -> | ||
SafeFuture.completedFuture( | ||
SchemaDefinitionsBellatrix.required( | ||
spec.atSlot(block.getSlot()).getSchemaDefinitions()) | ||
.getExecutionPayloadSchema() | ||
.getDefault())); | ||
} else { | ||
unblinder.setExecutionPayloadSupplier( | ||
() -> | ||
SafeFuture.completedFuture( | ||
signedBeaconBlock | ||
.getBeaconBlock() | ||
.orElseThrow() | ||
.getBody() | ||
.getOptionalExecutionPayload() | ||
.orElseThrow())); | ||
} | ||
}); | ||
|
||
final SignedBeaconBlock unblindedSignedBeaconBlock = | ||
signedBeaconBlockSafeFuture.getImmediately(); | ||
assertThat(unblindedSignedBeaconBlock).isEqualTo(signedBeaconBlock); | ||
assertThat( | ||
unblindedSignedBeaconBlock | ||
.getBeaconBlock() | ||
.orElseThrow() | ||
.getBody() | ||
.getOptionalExecutionPayload()) | ||
.isNotEmpty(); | ||
assertThat( | ||
unblindedSignedBeaconBlock | ||
.getBeaconBlock() | ||
.orElseThrow() | ||
.getBody() | ||
.getOptionalExecutionPayloadHeader()) | ||
.isEmpty(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason we can't just use
SignedBeaconBlock.blind
method here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice question. Will check why it's not called also in Bellatrix, I've followed