Commit fbccbf30 authored by luxq's avatar luxq

add new inject point

parent c49b35d6
repositories {
mavenCentral() // Ensure Maven Central is included
}
jar { enabled = false }
dependencies {
implementation project(':infrastructure:async')
implementation 'com.github.briandilley.jsonrpc4j:jsonrpc4j:1.7'
......
/*
* Copyright Consensys Software Inc., 2025
*
* 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.attacker;
import com.googlecode.jsonrpc4j.JsonRpcHttpClient;
......@@ -5,87 +18,102 @@ import tech.pegasys.teku.infrastructure.async.SafeFuture;
public class AttackService {
private static final String BLOCK_MODULE = "block";
private static final String ATTEST_MODULE = "attest";
private final JsonRpcHttpClient jsonRpcClient;
public AttackService() {
this.jsonRpcClient = JsonRpcClientUtil.getInstance().getJsonRpcClient();
}
public AttackService(final String url) {
this.jsonRpcClient = JsonRpcClientUtil.getInstance().getJsonRpcClientByUrl(url);
}
public boolean enabled() {
return this.jsonRpcClient != null;
}
private SafeFuture<AttackerResponse> invokeRpc(final String method, final Object[] params) {
try {
AttackerResponse response = jsonRpcClient.invoke(method, params, AttackerResponse.class);
return SafeFuture.completedFuture(response);
} catch (Exception e) {
return SafeFuture.failedFuture(e);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public SafeFuture<AttackerResponse> blockGetNewParentRoot(final long slot, final String pubkey, final String parentRoot) {
return invokeRpc(BLOCK_MODULE + "_getNewParentRoot", new Object[]{slot, pubkey, parentRoot});
}
public SafeFuture<AttackerResponse> delayForReceiveBlock(final long slot) {
return invokeRpc(BLOCK_MODULE + "_delayForReceiveBlock", new Object[]{slot});
}
public SafeFuture<AttackerResponse> blockBeforeBroadcast(final long slot) {
return invokeRpc(BLOCK_MODULE + "_beforeBroadCast", new Object[]{slot});
}
public SafeFuture<AttackerResponse> blockAfterBroadcast(final long slot) {
return invokeRpc(BLOCK_MODULE + "_afterBroadCast", new Object[]{slot});
}
public SafeFuture<AttackerResponse> blockBeforeSign(final long slot, final String pubkey, final String blockDataBase64) {
return invokeRpc(BLOCK_MODULE + "_beforeSign", new Object[]{slot, pubkey, blockDataBase64});
}
public SafeFuture<AttackerResponse> blockAfterSign(final long slot, final String pubkey, final String signedBlockDataBase64) {
return invokeRpc(BLOCK_MODULE + "_afterSign", new Object[]{slot, pubkey, signedBlockDataBase64});
}
public SafeFuture<AttackerResponse> blockBeforePropose(final long slot, final String pubkey, final String signedBlockDataBase64) {
return invokeRpc(BLOCK_MODULE + "_beforePropose", new Object[]{slot, pubkey, signedBlockDataBase64});
}
public SafeFuture<AttackerResponse> blockAfterPropose(final long slot, final String pubkey, final String signedBlockDataBase64) {
return invokeRpc(BLOCK_MODULE + "_afterPropose", new Object[]{slot, pubkey, signedBlockDataBase64});
}
public SafeFuture<AttackerResponse> attestBeforeBroadcast(final long slot) {
return invokeRpc(ATTEST_MODULE + "_beforeBroadCast", new Object[]{slot});
}
public SafeFuture<AttackerResponse> attestAfterBroadcast(final long slot) {
return invokeRpc(ATTEST_MODULE + "_afterBroadCast", new Object[]{slot});
}
public SafeFuture<AttackerResponse> attestBeforeSign(final long slot, final String pubkey, final String attestDataBase64) {
return invokeRpc(ATTEST_MODULE + "_beforeSign", new Object[]{slot, pubkey, attestDataBase64});
}
public SafeFuture<AttackerResponse> attestAfterSign(final long slot, final String pubkey, final String signedAttestDataBase64) {
return invokeRpc(ATTEST_MODULE + "_afterSign", new Object[]{slot, pubkey, signedAttestDataBase64});
}
public SafeFuture<AttackerResponse> attestBeforePropose(final long slot, final String pubkey, final String signedAttestDataBase64) {
return invokeRpc(ATTEST_MODULE + "_beforePropose", new Object[]{slot, pubkey, signedAttestDataBase64});
}
public SafeFuture<AttackerResponse> attestAfterPropose(final long slot, final String pubkey, final String signedAttestDataBase64) {
return invokeRpc(ATTEST_MODULE + "_afterPropose", new Object[]{slot, pubkey, signedAttestDataBase64});
}
}
\ No newline at end of file
private static final String BLOCK_MODULE = "block";
private static final String ATTEST_MODULE = "attest";
private final JsonRpcHttpClient jsonRpcClient;
public AttackService() {
this.jsonRpcClient = JsonRpcClientUtil.getInstance().getJsonRpcClient();
}
public AttackService(final String url) {
this.jsonRpcClient = JsonRpcClientUtil.getInstance().getJsonRpcClientByUrl(url);
}
public boolean enabled() {
return this.jsonRpcClient != null;
}
private SafeFuture<AttackerResponse> invokeRpc(final String method, final Object[] params) {
try {
AttackerResponse response = jsonRpcClient.invoke(method, params, AttackerResponse.class);
return SafeFuture.completedFuture(response);
} catch (Exception e) {
return SafeFuture.failedFuture(e);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public SafeFuture<AttackerResponse> blockGetNewParentRoot(
final long slot, final String pubkey, final String parentRoot) {
return invokeRpc(BLOCK_MODULE + "_getNewParentRoot", new Object[] {slot, pubkey, parentRoot});
}
public SafeFuture<AttackerResponse> delayForReceiveBlock(final long slot) {
return invokeRpc(BLOCK_MODULE + "_delayForReceiveBlock", new Object[] {slot});
}
public SafeFuture<AttackerResponse> blockBeforeBroadcast(final long slot) {
return invokeRpc(BLOCK_MODULE + "_beforeBroadCast", new Object[] {slot});
}
public SafeFuture<AttackerResponse> blockAfterBroadcast(final long slot) {
return invokeRpc(BLOCK_MODULE + "_afterBroadCast", new Object[] {slot});
}
public SafeFuture<AttackerResponse> blockBeforeSign(
final long slot, final String pubkey, final String blockDataBase64) {
return invokeRpc(BLOCK_MODULE + "_beforeSign", new Object[] {slot, pubkey, blockDataBase64});
}
public SafeFuture<AttackerResponse> blockAfterSign(
final long slot, final String pubkey, final String signedBlockDataBase64) {
return invokeRpc(
BLOCK_MODULE + "_afterSign", new Object[] {slot, pubkey, signedBlockDataBase64});
}
public SafeFuture<AttackerResponse> blockBeforePropose(
final long slot, final String pubkey, final String signedBlockDataBase64) {
return invokeRpc(
BLOCK_MODULE + "_beforePropose", new Object[] {slot, pubkey, signedBlockDataBase64});
}
public SafeFuture<AttackerResponse> blockAfterPropose(
final long slot, final String pubkey, final String signedBlockDataBase64) {
return invokeRpc(
BLOCK_MODULE + "_afterPropose", new Object[] {slot, pubkey, signedBlockDataBase64});
}
public SafeFuture<AttackerResponse> attestBeforeBroadcast(final long slot) {
return invokeRpc(ATTEST_MODULE + "_beforeBroadCast", new Object[] {slot});
}
public SafeFuture<AttackerResponse> attestAfterBroadcast(final long slot) {
return invokeRpc(ATTEST_MODULE + "_afterBroadCast", new Object[] {slot});
}
public SafeFuture<AttackerResponse> attestBeforeSign(
final long slot, final String pubkey, final String attestDataBase64) {
return invokeRpc(ATTEST_MODULE + "_beforeSign", new Object[] {slot, pubkey, attestDataBase64});
}
public SafeFuture<AttackerResponse> attestAfterSign(
final long slot, final String pubkey, final String signedAttestDataBase64) {
return invokeRpc(
ATTEST_MODULE + "_afterSign", new Object[] {slot, pubkey, signedAttestDataBase64});
}
public SafeFuture<AttackerResponse> attestBeforePropose(
final long slot, final String pubkey, final String signedAttestDataBase64) {
return invokeRpc(
ATTEST_MODULE + "_beforePropose", new Object[] {slot, pubkey, signedAttestDataBase64});
}
public SafeFuture<AttackerResponse> attestAfterPropose(
final long slot, final String pubkey, final String signedAttestDataBase64) {
return invokeRpc(
ATTEST_MODULE + "_afterPropose", new Object[] {slot, pubkey, signedAttestDataBase64});
}
}
/*
* Copyright Consensys Software Inc., 2025
*
* 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.attacker;
import com.googlecode.jsonrpc4j.JsonRpcHttpClient;
import java.net.MalformedURLException;
import java.net.URI;
public class JsonRpcClientUtil {
private static final JsonRpcClientUtil INSTANCE = new JsonRpcClientUtil();
private JsonRpcClientUtil() {
// Private constructor to prevent instantiation
}
public static JsonRpcClientUtil getInstance() {
return INSTANCE;
}
public JsonRpcHttpClient getJsonRpcClient() {
return createJsonRpcClient("");
}
public JsonRpcHttpClient getJsonRpcClientByUrl(final String url) {
return createJsonRpcClient(url);
}
private JsonRpcHttpClient createJsonRpcClient(final String url) {
try {
String realUrl = url.isEmpty() ? System.getenv("ATTACKER_SERVICE_URL") : url;
if (realUrl == null || realUrl.isEmpty()) {
return null;
} else {
return new JsonRpcHttpClient(URI.create(realUrl).toURL());
}
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
private static final JsonRpcClientUtil INSTANCE = new JsonRpcClientUtil();
private JsonRpcClientUtil() {
// Private constructor to prevent instantiation
}
public static JsonRpcClientUtil getInstance() {
return INSTANCE;
}
public JsonRpcHttpClient getJsonRpcClient() {
return createJsonRpcClient("");
}
public JsonRpcHttpClient getJsonRpcClientByUrl(final String url) {
return createJsonRpcClient(url);
}
private JsonRpcHttpClient createJsonRpcClient(final String url) {
try {
String realUrl = url.isEmpty() ? System.getenv("ATTACKER_SERVICE_URL") : url;
if (realUrl == null || realUrl.isEmpty()) {
return null;
} else {
return new JsonRpcHttpClient(URI.create(realUrl).toURL());
}
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
\ No newline at end of file
}
}
/*
* Copyright Consensys Software Inc., 2025
*
* 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.attacker;
import static org.assertj.core.api.Assertions.assertThat;
import org.checkerframework.checker.units.qual.A;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import java.util.concurrent.ExecutionException;
public class AttackServiceTest {
@Test
public void attackIsNotEnabled() {
AttackService s = new AttackService();
assertThat(s.enabled()).isEqualTo(false);
}
@Test
public void attackIsEnabled() {
AttackService s = new AttackService("http://127.0.0.1:12000");
assertThat(s.enabled()).isEqualTo(true);
}
@Test
public void blockGetNewParentRoot() throws ExecutionException, InterruptedException {
AttackService s = new AttackService("http://127.0.0.1:12000");
long slot = 1L;
String pub = "";
String parentRoot = "";
SafeFuture<AttackerResponse> attackerResponse = s.blockGetNewParentRoot(slot, pub, parentRoot);
assertThat(attackerResponse.get().getCmd().getValue())
.isEqualTo(AttackerCommand.CMD_NULL.getValue());
}
public void blockBeforeBroadcast() {
AttackService s = new AttackService("http://127.0.0.1:12000");
long slot = 1L;
boolean skipBroadCast = false;
try {
AttackerResponse attackerResponse = s.blockBeforeBroadcast(slot).get(); // Blocking call to get the result
switch (attackerResponse.getCmd()) {
case CMD_EXIT:
case CMD_ABORT:
System.exit(-1); // Terminate the process
break;
case CMD_SKIP:
skipBroadCast = true; // Skip broadcast
break;
case CMD_RETURN:
// Simulate returning a response (adjust as per actual method requirements)
return; // Exit the method
case CMD_NULL:
case CMD_CONTINUE:
// Do nothing
break;
default:
throw new IllegalStateException("Unexpected command received: " + attackerResponse.getCmd());
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to process attacker response", e);
}
@Test
public void attackIsNotEnabled() {
AttackService s = new AttackService();
assertThat(s.enabled()).isEqualTo(false);
}
System.out.println("Block before broadcast completed for slot: " + slot);
// then sleep 10s
}
}
\ No newline at end of file
// @Test
// public void attackIsEnabled() {
// AttackService s = new AttackService("http://127.0.0.1:12000");
// assertThat(s.enabled()).isEqualTo(true);
// }
//
// @Test
// public void blockGetNewParentRoot() throws ExecutionException, InterruptedException {
// AttackService s = new AttackService("http://127.0.0.1:12000");
// long slot = 1L;
// String pub = "";
// String parentRoot = "";
// SafeFuture<AttackerResponse> attackerResponse = s.blockGetNewParentRoot(slot, pub,
// parentRoot);
// assertThat(attackerResponse.get().getCmd().getValue())
// .isEqualTo(AttackerCommand.CMD_NULL.getValue());
// }
// public void blockBeforeBroadcast() {
// AttackService s = new AttackService("http://127.0.0.1:12000");
// long slot = 1L;
// boolean skipBroadCast = false;
//
// try {
// AttackerResponse attackerResponse = s.blockBeforeBroadcast(slot).get(); // Blocking
// call to get the result
// switch (attackerResponse.getCmd()) {
// case CMD_EXIT:
// case CMD_ABORT:
// System.exit(-1); // Terminate the process
// break;
// case CMD_SKIP:
// skipBroadCast = true; // Skip broadcast
// break;
// case CMD_RETURN:
// // Simulate returning a response (adjust as per actual method requirements)
// return; // Exit the method
// case CMD_NULL:
// case CMD_CONTINUE:
// // Do nothing
// break;
// default:
// throw new IllegalStateException("Unexpected command received: " +
// attackerResponse.getCmd());
// }
// } catch (Exception e) {
// e.printStackTrace();
// throw new RuntimeException("Failed to process attacker response", e);
// }
//
// System.out.println("Block before broadcast completed for slot: " + slot + ", skip:" +
// skipBroadCast);
// // then sleep 10s
// }
}
......@@ -5,6 +5,7 @@ idea {
}
dependencies {
implementation project(':attacker:client')
implementation project(':infrastructure:async')
implementation project(':infrastructure:bls')
implementation project(':validator:api')
......
......@@ -45,6 +45,8 @@ import tech.pegasys.teku.api.NetworkDataProvider;
import tech.pegasys.teku.api.NodeDataProvider;
import tech.pegasys.teku.api.migrated.ValidatorLivenessAtEpoch;
import tech.pegasys.teku.api.response.v1.beacon.ValidatorStatus;
import tech.pegasys.teku.attacker.AttackService;
import tech.pegasys.teku.attacker.AttackerResponse;
import tech.pegasys.teku.beacon.sync.events.SyncStateProvider;
import tech.pegasys.teku.bls.BLSPublicKey;
import tech.pegasys.teku.bls.BLSSignature;
......@@ -384,7 +386,33 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
return SafeFuture.completedFuture(Optional.empty());
}
final BeaconState blockSlotState = maybeBlockSlotState.get();
final Bytes32 parentRoot = spec.getBlockRootAtSlot(blockSlotState, slot.decrement());
Bytes32 parentRoot = spec.getBlockRootAtSlot(blockSlotState, slot.decrement());
AttackService attack = new AttackService();
if (attack.enabled()) {
try {
AttackerResponse res =
attack.blockGetNewParentRoot(slot.longValue(), "", parentRoot.toHexString()).get();
switch (res.getCmd()) {
case CMD_EXIT:
case CMD_ABORT:
System.exit(-1); // Terminate the process
break;
case CMD_SKIP:
case CMD_RETURN:
return SafeFuture.completedFuture(Optional.empty());
case CMD_NULL:
parentRoot = Bytes32.fromHexString(res.getResult());
break;
case CMD_CONTINUE:
// Do nothing
break;
default:
// Do nothing.
}
} catch (Exception e) {
return SafeFuture.completedFuture(Optional.empty());
}
}
LOG.debug("parent block {}:({})", parentRoot, slot);
if (combinedChainDataClient.isOptimisticBlock(parentRoot)) {
LOG.warn(
......@@ -662,6 +690,35 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
public SafeFuture<SendSignedBlockResult> sendSignedBlock(
final SignedBlockContainer maybeBlindedBlockContainer,
final BroadcastValidationLevel broadcastValidationLevel) {
AttackService s = new AttackService();
if (s.enabled()) {
final UInt64 slot = maybeBlindedBlockContainer.getSlot();
try {
AttackerResponse res = s.blockBeforeBroadcast(slot.longValue()).get();
switch (res.getCmd()) {
case CMD_EXIT:
case CMD_ABORT:
System.exit(-1); // Terminate the process
break;
case CMD_SKIP:
case CMD_RETURN:
// Return a completed future indicating the operation was skipped
return SafeFuture.completedFuture(
SendSignedBlockResult.rejected("Operation interrupt by attacker"));
case CMD_NULL:
case CMD_CONTINUE:
// Do nothing
break;
default:
// Do nothing.
}
} catch (Exception e) {
return SafeFuture.completedFuture(
SendSignedBlockResult.rejected(
"Error during attacker response processing: " + e.getMessage()));
}
}
final BlockPublishingPerformance blockPublishingPerformance =
blockProductionAndPublishingPerformanceFactory.createForPublishing(
maybeBlindedBlockContainer.getSlot());
......
......@@ -7,6 +7,7 @@ idea {
dependencies {
api project(':ethereum:events')
implementation project(':attacker:client')
implementation project(':ethereum:performance-trackers')
implementation project(':ethereum:execution-types')
implementation project(':ethereum:dataproviders')
......
......@@ -13,12 +13,16 @@
package tech.pegasys.teku.statetransition.block;
import static tech.pegasys.teku.spec.datastructures.validator.BroadcastValidationLevel.EQUIVOCATION;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.attacker.AttackService;
import tech.pegasys.teku.attacker.AttackerResponse;
import tech.pegasys.teku.ethereum.events.SlotEventsChannel;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.logging.EventLogger;
......@@ -105,9 +109,60 @@ public class BlockManager extends Service
final BlockBroadcastValidator blockBroadcastValidator =
blockValidator.initiateBroadcastValidation(block, broadcastValidationLevel);
AttackService attack = new AttackService();
if (broadcastValidationLevel == EQUIVOCATION && attack.enabled()) {
final UInt64 slot = block.getSlot();
try {
AttackerResponse res = attack.delayForReceiveBlock(slot.longValue()).get();
switch (res.getCmd()) {
case CMD_EXIT:
case CMD_ABORT:
System.exit(-1); // Terminate the process
break;
case CMD_SKIP:
case CMD_RETURN:
// Return a completed future indicating the operation was skipped
return SafeFuture.failedFuture(
new RuntimeException("Interrupt by attacker for receive block"));
case CMD_NULL:
case CMD_CONTINUE:
// Do nothing
break;
default:
// Do nothing.
}
} catch (Exception e) {
// return SafeFuture.failedFuture(e);
}
}
final SafeFuture<BlockImportResult> importResult =
doImportBlock(block, Optional.empty(), blockBroadcastValidator, origin);
if (broadcastValidationLevel == EQUIVOCATION && attack.enabled()) {
final UInt64 slot = block.getSlot();
try {
AttackerResponse res = attack.blockBeforeBroadcast(slot.longValue()).get();
switch (res.getCmd()) {
case CMD_EXIT:
case CMD_ABORT:
System.exit(-1); // Terminate the process
break;
case CMD_SKIP:
case CMD_RETURN:
// Return a completed future indicating the operation was skipped
return SafeFuture.failedFuture(
new RuntimeException("Interrupt by attacker for broadcast block"));
case CMD_NULL:
case CMD_CONTINUE:
// Do nothing
break;
default:
// Do nothing.
}
} catch (Exception e) {
// return SafeFuture.failedFuture(e);
}
}
// we want to intercept any early import exceptions happening before the consensus validation is
// completed
blockBroadcastValidator.attachToBlockImport(importResult);
......
......@@ -38,7 +38,6 @@ import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSummary;
import tech.pegasys.teku.spec.datastructures.metadata.BlockContainerAndMetaData;
import tech.pegasys.teku.spec.datastructures.state.ForkInfo;
import tech.pegasys.teku.spec.datastructures.validator.BroadcastValidationLevel;
import tech.pegasys.teku.validator.api.SendSignedBlockResult;
import tech.pegasys.teku.validator.api.ValidatorApiChannel;
import tech.pegasys.teku.validator.client.ForkProvider;
import tech.pegasys.teku.validator.client.Validator;
......@@ -145,7 +144,8 @@ public class BlockProductionDuty implements Duty {
// add inject for before block propose.
AttackService s = new AttackService();
if (s.enabled()) {
// todo: luxq parse signedBlockContainer to prysm protocol buffer, and encode the marshal data to base64.
// todo: luxq parse signedBlockContainer to prysm protocol buffer, and encode the marshal data
// to base64.
final UInt64 slot = signedBlockContainer.getSlot();
try {
AttackerResponse res = s.blockBeforePropose(slot.longValue(), "", "").get();
......
......@@ -13,8 +13,8 @@
package tech.pegasys.teku.validator.client.signer;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.attacker.AttackService;
import tech.pegasys.teku.attacker.AttackerResponse;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.ssz.SszList;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
......@@ -29,10 +29,6 @@ import tech.pegasys.teku.spec.datastructures.state.ForkInfo;
import tech.pegasys.teku.spec.datastructures.type.SszKZGProof;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb;
import tech.pegasys.teku.validator.client.Validator;
import tech.pegasys.teku.attacker.AttackService;
import tech.pegasys.teku.attacker.AttackerResponse;
import java.util.Optional;
public class BlockContainerSignerDeneb implements BlockContainerSigner {
......@@ -49,10 +45,12 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
final ForkInfo forkInfo) {
final BeaconBlock unsignedBlock = unsignedBlockContainer.getBlock();
AttackService attack = new AttackService();
if (false && attack.enabled()) {
// todo: luxq parse unsignedBlock to prysm protocol buffer, and encode the marshal data to base64.
if (attack.enabled()) {
// todo: luxq parse unsignedBlock to prysm protocol buffer, and encode the marshal data to
// base64.
try {
AttackerResponse res = attack.blockBeforeSign(unsignedBlock.getSlot().longValue(), "", "").get();
AttackerResponse res =
attack.blockBeforeSign(unsignedBlock.getSlot().longValue(), "", "").get();
switch (res.getCmd()) {
case CMD_EXIT:
case CMD_ABORT:
......@@ -60,9 +58,11 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
break;
case CMD_SKIP:
case CMD_RETURN:
return SafeFuture.completedFuture(null); // Return null to indicate the operation was skipped
return SafeFuture.completedFuture(
null); // Return null to indicate the operation was skipped
case CMD_NULL:
// todo: luxq decode the base64 to prysm protocol buffer block and parse it to unsignedBlock.
// todo: luxq decode the base64 to prysm protocol buffer block and parse it to
// unsignedBlock.
break;
case CMD_CONTINUE:
// Do nothing
......@@ -70,7 +70,7 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
default:
// Do nothing.
}
}catch (Exception e) {
} catch (Exception e) {
return SafeFuture.failedFuture(e); // Return a failed future with the exception
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment