Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
teku
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
teku
Commits
fbccbf30
Commit
fbccbf30
authored
Jul 19, 2025
by
luxq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add new inject point
parent
c49b35d6
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
356 additions
and
192 deletions
+356
-192
build.gradle
attacker/client/build.gradle
+1
-4
AttackService.java
...c/main/java/tech/pegasys/teku/attacker/AttackService.java
+112
-84
JsonRpcClientUtil.java
...in/java/tech/pegasys/teku/attacker/JsonRpcClientUtil.java
+43
-31
AttackServiceTest.java
...st/java/tech/pegasys/teku/attacker/AttackServiceTest.java
+72
-59
build.gradle
beacon/validator/build.gradle
+1
-0
ValidatorApiHandler.java
...gasys/teku/validator/coordinator/ValidatorApiHandler.java
+58
-1
build.gradle
ethereum/statetransition/build.gradle
+1
-0
BlockManager.java
...tech/pegasys/teku/statetransition/block/BlockManager.java
+55
-0
BlockProductionDuty.java
...sys/teku/validator/client/duties/BlockProductionDuty.java
+2
-2
BlockContainerSignerDeneb.java
...ku/validator/client/signer/BlockContainerSignerDeneb.java
+11
-11
No files found.
attacker/client/build.gradle
View file @
fbccbf30
repositories
{
jar
{
enabled
=
false
}
mavenCentral
()
// Ensure Maven Central is included
}
dependencies
{
dependencies
{
implementation
project
(
':infrastructure:async'
)
implementation
project
(
':infrastructure:async'
)
implementation
'com.github.briandilley.jsonrpc4j:jsonrpc4j:1.7'
implementation
'com.github.briandilley.jsonrpc4j:jsonrpc4j:1.7'
...
...
attacker/client/src/main/java/tech/pegasys/teku/attacker/AttackService.java
View file @
fbccbf30
/*
* 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
;
package
tech
.
pegasys
.
teku
.
attacker
;
import
com.googlecode.jsonrpc4j.JsonRpcHttpClient
;
import
com.googlecode.jsonrpc4j.JsonRpcHttpClient
;
...
@@ -33,59 +46,74 @@ public class AttackService {
...
@@ -33,59 +46,74 @@ public class AttackService {
}
}
}
}
public
SafeFuture
<
AttackerResponse
>
blockGetNewParentRoot
(
final
long
slot
,
final
String
pubkey
,
final
String
parentRoot
)
{
public
SafeFuture
<
AttackerResponse
>
blockGetNewParentRoot
(
return
invokeRpc
(
BLOCK_MODULE
+
"_getNewParentRoot"
,
new
Object
[]{
slot
,
pubkey
,
parentRoot
});
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
)
{
public
SafeFuture
<
AttackerResponse
>
delayForReceiveBlock
(
final
long
slot
)
{
return
invokeRpc
(
BLOCK_MODULE
+
"_delayForReceiveBlock"
,
new
Object
[]
{
slot
});
return
invokeRpc
(
BLOCK_MODULE
+
"_delayForReceiveBlock"
,
new
Object
[]
{
slot
});
}
}
public
SafeFuture
<
AttackerResponse
>
blockBeforeBroadcast
(
final
long
slot
)
{
public
SafeFuture
<
AttackerResponse
>
blockBeforeBroadcast
(
final
long
slot
)
{
return
invokeRpc
(
BLOCK_MODULE
+
"_beforeBroadCast"
,
new
Object
[]
{
slot
});
return
invokeRpc
(
BLOCK_MODULE
+
"_beforeBroadCast"
,
new
Object
[]
{
slot
});
}
}
public
SafeFuture
<
AttackerResponse
>
blockAfterBroadcast
(
final
long
slot
)
{
public
SafeFuture
<
AttackerResponse
>
blockAfterBroadcast
(
final
long
slot
)
{
return
invokeRpc
(
BLOCK_MODULE
+
"_afterBroadCast"
,
new
Object
[]
{
slot
});
return
invokeRpc
(
BLOCK_MODULE
+
"_afterBroadCast"
,
new
Object
[]
{
slot
});
}
}
public
SafeFuture
<
AttackerResponse
>
blockBeforeSign
(
final
long
slot
,
final
String
pubkey
,
final
String
blockDataBase64
)
{
public
SafeFuture
<
AttackerResponse
>
blockBeforeSign
(
return
invokeRpc
(
BLOCK_MODULE
+
"_beforeSign"
,
new
Object
[]{
slot
,
pubkey
,
blockDataBase64
});
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
)
{
public
SafeFuture
<
AttackerResponse
>
blockAfterSign
(
return
invokeRpc
(
BLOCK_MODULE
+
"_afterSign"
,
new
Object
[]{
slot
,
pubkey
,
signedBlockDataBase64
});
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
)
{
public
SafeFuture
<
AttackerResponse
>
blockBeforePropose
(
return
invokeRpc
(
BLOCK_MODULE
+
"_beforePropose"
,
new
Object
[]{
slot
,
pubkey
,
signedBlockDataBase64
});
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
)
{
public
SafeFuture
<
AttackerResponse
>
blockAfterPropose
(
return
invokeRpc
(
BLOCK_MODULE
+
"_afterPropose"
,
new
Object
[]{
slot
,
pubkey
,
signedBlockDataBase64
});
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
)
{
public
SafeFuture
<
AttackerResponse
>
attestBeforeBroadcast
(
final
long
slot
)
{
return
invokeRpc
(
ATTEST_MODULE
+
"_beforeBroadCast"
,
new
Object
[]
{
slot
});
return
invokeRpc
(
ATTEST_MODULE
+
"_beforeBroadCast"
,
new
Object
[]
{
slot
});
}
}
public
SafeFuture
<
AttackerResponse
>
attestAfterBroadcast
(
final
long
slot
)
{
public
SafeFuture
<
AttackerResponse
>
attestAfterBroadcast
(
final
long
slot
)
{
return
invokeRpc
(
ATTEST_MODULE
+
"_afterBroadCast"
,
new
Object
[]
{
slot
});
return
invokeRpc
(
ATTEST_MODULE
+
"_afterBroadCast"
,
new
Object
[]
{
slot
});
}
}
public
SafeFuture
<
AttackerResponse
>
attestBeforeSign
(
final
long
slot
,
final
String
pubkey
,
final
String
attestDataBase64
)
{
public
SafeFuture
<
AttackerResponse
>
attestBeforeSign
(
return
invokeRpc
(
ATTEST_MODULE
+
"_beforeSign"
,
new
Object
[]{
slot
,
pubkey
,
attestDataBase64
});
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
)
{
public
SafeFuture
<
AttackerResponse
>
attestAfterSign
(
return
invokeRpc
(
ATTEST_MODULE
+
"_afterSign"
,
new
Object
[]{
slot
,
pubkey
,
signedAttestDataBase64
});
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
)
{
public
SafeFuture
<
AttackerResponse
>
attestBeforePropose
(
return
invokeRpc
(
ATTEST_MODULE
+
"_beforePropose"
,
new
Object
[]{
slot
,
pubkey
,
signedAttestDataBase64
});
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
)
{
public
SafeFuture
<
AttackerResponse
>
attestAfterPropose
(
return
invokeRpc
(
ATTEST_MODULE
+
"_afterPropose"
,
new
Object
[]{
slot
,
pubkey
,
signedAttestDataBase64
});
final
long
slot
,
final
String
pubkey
,
final
String
signedAttestDataBase64
)
{
return
invokeRpc
(
ATTEST_MODULE
+
"_afterPropose"
,
new
Object
[]
{
slot
,
pubkey
,
signedAttestDataBase64
});
}
}
}
}
attacker/client/src/main/java/tech/pegasys/teku/attacker/JsonRpcClientUtil.java
View file @
fbccbf30
/*
* 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
;
package
tech
.
pegasys
.
teku
.
attacker
;
import
com.googlecode.jsonrpc4j.JsonRpcHttpClient
;
import
com.googlecode.jsonrpc4j.JsonRpcHttpClient
;
import
java.net.MalformedURLException
;
import
java.net.MalformedURLException
;
import
java.net.URI
;
import
java.net.URI
;
...
...
attacker/client/src/test/java/tech/pegasys/teku/attacker/AttackServiceTest.java
View file @
fbccbf30
/*
* 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
;
package
tech
.
pegasys
.
teku
.
attacker
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
org.checkerframework.checker.units.qual.A
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
import
tech.pegasys.teku.infrastructure.async.SafeFuture
;
import
java.util.concurrent.ExecutionException
;
public
class
AttackServiceTest
{
public
class
AttackServiceTest
{
...
@@ -16,53 +25,57 @@ public class AttackServiceTest {
...
@@ -16,53 +25,57 @@ public class AttackServiceTest {
assertThat
(
s
.
enabled
()).
isEqualTo
(
false
);
assertThat
(
s
.
enabled
()).
isEqualTo
(
false
);
}
}
@Test
// @Test
public
void
attackIsEnabled
()
{
// public void attackIsEnabled() {
AttackService
s
=
new
AttackService
(
"http://127.0.0.1:12000"
);
// AttackService s = new AttackService("http://127.0.0.1:12000");
assertThat
(
s
.
enabled
()).
isEqualTo
(
true
);
// assertThat(s.enabled()).isEqualTo(true);
}
// }
//
@Test
// @Test
public
void
blockGetNewParentRoot
()
throws
ExecutionException
,
InterruptedException
{
// public void blockGetNewParentRoot() throws ExecutionException, InterruptedException {
AttackService
s
=
new
AttackService
(
"http://127.0.0.1:12000"
);
// AttackService s = new AttackService("http://127.0.0.1:12000");
long
slot
=
1L
;
// long slot = 1L;
String
pub
=
""
;
// String pub = "";
String
parentRoot
=
""
;
// String parentRoot = "";
SafeFuture
<
AttackerResponse
>
attackerResponse
=
s
.
blockGetNewParentRoot
(
slot
,
pub
,
parentRoot
);
// SafeFuture<AttackerResponse> attackerResponse = s.blockGetNewParentRoot(slot, pub,
assertThat
(
attackerResponse
.
get
().
getCmd
().
getValue
())
// parentRoot);
.
isEqualTo
(
AttackerCommand
.
CMD_NULL
.
getValue
());
// assertThat(attackerResponse.get().getCmd().getValue())
}
// .isEqualTo(AttackerCommand.CMD_NULL.getValue());
public
void
blockBeforeBroadcast
()
{
// }
AttackService
s
=
new
AttackService
(
"http://127.0.0.1:12000"
);
// public void blockBeforeBroadcast() {
long
slot
=
1L
;
// AttackService s = new AttackService("http://127.0.0.1:12000");
boolean
skipBroadCast
=
false
;
// long slot = 1L;
// boolean skipBroadCast = false;
try
{
//
AttackerResponse
attackerResponse
=
s
.
blockBeforeBroadcast
(
slot
).
get
();
// Blocking call to get the result
// try {
switch
(
attackerResponse
.
getCmd
())
{
// AttackerResponse attackerResponse = s.blockBeforeBroadcast(slot).get(); // Blocking
case
CMD_EXIT:
// call to get the result
case
CMD_ABORT:
// switch (attackerResponse.getCmd()) {
System
.
exit
(-
1
);
// Terminate the process
// case CMD_EXIT:
break
;
// case CMD_ABORT:
case
CMD_SKIP:
// System.exit(-1); // Terminate the process
skipBroadCast
=
true
;
// Skip broadcast
// break;
break
;
// case CMD_SKIP:
case
CMD_RETURN:
// skipBroadCast = true; // Skip broadcast
// Simulate returning a response (adjust as per actual method requirements)
// break;
return
;
// Exit the method
// case CMD_RETURN:
case
CMD_NULL:
// // Simulate returning a response (adjust as per actual method requirements)
case
CMD_CONTINUE:
// return; // Exit the method
// Do nothing
// case CMD_NULL:
break
;
// case CMD_CONTINUE:
default
:
// // Do nothing
throw
new
IllegalStateException
(
"Unexpected command received: "
+
attackerResponse
.
getCmd
());
// break;
}
// default:
}
catch
(
Exception
e
)
{
// throw new IllegalStateException("Unexpected command received: " +
e
.
printStackTrace
();
// attackerResponse.getCmd());
throw
new
RuntimeException
(
"Failed to process attacker response"
,
e
);
// }
}
// } catch (Exception e) {
// e.printStackTrace();
System
.
out
.
println
(
"Block before broadcast completed for slot: "
+
slot
);
// throw new RuntimeException("Failed to process attacker response", e);
// then sleep 10s
// }
}
//
// System.out.println("Block before broadcast completed for slot: " + slot + ", skip:" +
// skipBroadCast);
// // then sleep 10s
// }
}
}
beacon/validator/build.gradle
View file @
fbccbf30
...
@@ -5,6 +5,7 @@ idea {
...
@@ -5,6 +5,7 @@ idea {
}
}
dependencies
{
dependencies
{
implementation
project
(
':attacker:client'
)
implementation
project
(
':infrastructure:async'
)
implementation
project
(
':infrastructure:async'
)
implementation
project
(
':infrastructure:bls'
)
implementation
project
(
':infrastructure:bls'
)
implementation
project
(
':validator:api'
)
implementation
project
(
':validator:api'
)
...
...
beacon/validator/src/main/java/tech/pegasys/teku/validator/coordinator/ValidatorApiHandler.java
View file @
fbccbf30
...
@@ -45,6 +45,8 @@ import tech.pegasys.teku.api.NetworkDataProvider;
...
@@ -45,6 +45,8 @@ import tech.pegasys.teku.api.NetworkDataProvider;
import
tech.pegasys.teku.api.NodeDataProvider
;
import
tech.pegasys.teku.api.NodeDataProvider
;
import
tech.pegasys.teku.api.migrated.ValidatorLivenessAtEpoch
;
import
tech.pegasys.teku.api.migrated.ValidatorLivenessAtEpoch
;
import
tech.pegasys.teku.api.response.v1.beacon.ValidatorStatus
;
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.beacon.sync.events.SyncStateProvider
;
import
tech.pegasys.teku.bls.BLSPublicKey
;
import
tech.pegasys.teku.bls.BLSPublicKey
;
import
tech.pegasys.teku.bls.BLSSignature
;
import
tech.pegasys.teku.bls.BLSSignature
;
...
@@ -384,7 +386,33 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
...
@@ -384,7 +386,33 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
return
SafeFuture
.
completedFuture
(
Optional
.
empty
());
return
SafeFuture
.
completedFuture
(
Optional
.
empty
());
}
}
final
BeaconState
blockSlotState
=
maybeBlockSlotState
.
get
();
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
);
LOG
.
debug
(
"parent block {}:({})"
,
parentRoot
,
slot
);
if
(
combinedChainDataClient
.
isOptimisticBlock
(
parentRoot
))
{
if
(
combinedChainDataClient
.
isOptimisticBlock
(
parentRoot
))
{
LOG
.
warn
(
LOG
.
warn
(
...
@@ -662,6 +690,35 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
...
@@ -662,6 +690,35 @@ public class ValidatorApiHandler implements ValidatorApiChannel {
public
SafeFuture
<
SendSignedBlockResult
>
sendSignedBlock
(
public
SafeFuture
<
SendSignedBlockResult
>
sendSignedBlock
(
final
SignedBlockContainer
maybeBlindedBlockContainer
,
final
SignedBlockContainer
maybeBlindedBlockContainer
,
final
BroadcastValidationLevel
broadcastValidationLevel
)
{
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
=
final
BlockPublishingPerformance
blockPublishingPerformance
=
blockProductionAndPublishingPerformanceFactory
.
createForPublishing
(
blockProductionAndPublishingPerformanceFactory
.
createForPublishing
(
maybeBlindedBlockContainer
.
getSlot
());
maybeBlindedBlockContainer
.
getSlot
());
...
...
ethereum/statetransition/build.gradle
View file @
fbccbf30
...
@@ -7,6 +7,7 @@ idea {
...
@@ -7,6 +7,7 @@ idea {
dependencies
{
dependencies
{
api
project
(
':ethereum:events'
)
api
project
(
':ethereum:events'
)
implementation
project
(
':attacker:client'
)
implementation
project
(
':ethereum:performance-trackers'
)
implementation
project
(
':ethereum:performance-trackers'
)
implementation
project
(
':ethereum:execution-types'
)
implementation
project
(
':ethereum:execution-types'
)
implementation
project
(
':ethereum:dataproviders'
)
implementation
project
(
':ethereum:dataproviders'
)
...
...
ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/block/BlockManager.java
View file @
fbccbf30
...
@@ -13,12 +13,16 @@
...
@@ -13,12 +13,16 @@
package
tech
.
pegasys
.
teku
.
statetransition
.
block
;
package
tech
.
pegasys
.
teku
.
statetransition
.
block
;
import
static
tech
.
pegasys
.
teku
.
spec
.
datastructures
.
validator
.
BroadcastValidationLevel
.
EQUIVOCATION
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.Optional
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.apache.logging.log4j.Logger
;
import
org.apache.tuweni.bytes.Bytes32
;
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.ethereum.events.SlotEventsChannel
;
import
tech.pegasys.teku.infrastructure.async.SafeFuture
;
import
tech.pegasys.teku.infrastructure.async.SafeFuture
;
import
tech.pegasys.teku.infrastructure.logging.EventLogger
;
import
tech.pegasys.teku.infrastructure.logging.EventLogger
;
...
@@ -105,9 +109,60 @@ public class BlockManager extends Service
...
@@ -105,9 +109,60 @@ public class BlockManager extends Service
final
BlockBroadcastValidator
blockBroadcastValidator
=
final
BlockBroadcastValidator
blockBroadcastValidator
=
blockValidator
.
initiateBroadcastValidation
(
block
,
broadcastValidationLevel
);
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
=
final
SafeFuture
<
BlockImportResult
>
importResult
=
doImportBlock
(
block
,
Optional
.
empty
(),
blockBroadcastValidator
,
origin
);
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
// we want to intercept any early import exceptions happening before the consensus validation is
// completed
// completed
blockBroadcastValidator
.
attachToBlockImport
(
importResult
);
blockBroadcastValidator
.
attachToBlockImport
(
importResult
);
...
...
validator/client/src/main/java/tech/pegasys/teku/validator/client/duties/BlockProductionDuty.java
View file @
fbccbf30
...
@@ -38,7 +38,6 @@ import tech.pegasys.teku.spec.datastructures.execution.ExecutionPayloadSummary;
...
@@ -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.metadata.BlockContainerAndMetaData
;
import
tech.pegasys.teku.spec.datastructures.state.ForkInfo
;
import
tech.pegasys.teku.spec.datastructures.state.ForkInfo
;
import
tech.pegasys.teku.spec.datastructures.validator.BroadcastValidationLevel
;
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.api.ValidatorApiChannel
;
import
tech.pegasys.teku.validator.client.ForkProvider
;
import
tech.pegasys.teku.validator.client.ForkProvider
;
import
tech.pegasys.teku.validator.client.Validator
;
import
tech.pegasys.teku.validator.client.Validator
;
...
@@ -145,7 +144,8 @@ public class BlockProductionDuty implements Duty {
...
@@ -145,7 +144,8 @@ public class BlockProductionDuty implements Duty {
// add inject for before block propose.
// add inject for before block propose.
AttackService
s
=
new
AttackService
();
AttackService
s
=
new
AttackService
();
if
(
s
.
enabled
())
{
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
();
final
UInt64
slot
=
signedBlockContainer
.
getSlot
();
try
{
try
{
AttackerResponse
res
=
s
.
blockBeforePropose
(
slot
.
longValue
(),
""
,
""
).
get
();
AttackerResponse
res
=
s
.
blockBeforePropose
(
slot
.
longValue
(),
""
,
""
).
get
();
...
...
validator/client/src/main/java/tech/pegasys/teku/validator/client/signer/BlockContainerSignerDeneb.java
View file @
fbccbf30
...
@@ -13,8 +13,8 @@
...
@@ -13,8 +13,8 @@
package
tech
.
pegasys
.
teku
.
validator
.
client
.
signer
;
package
tech
.
pegasys
.
teku
.
validator
.
client
.
signer
;
import
org.apache.tuweni.bytes.Bytes32
;
import
tech.pegasys.teku.attacker.AttackService
;
import
tech.pegasys.teku.attacker.AttackService
;
import
tech.pegasys.teku.attacker.AttackerResponse
;
import
tech.pegasys.teku.infrastructure.async.SafeFuture
;
import
tech.pegasys.teku.infrastructure.async.SafeFuture
;
import
tech.pegasys.teku.infrastructure.ssz.SszList
;
import
tech.pegasys.teku.infrastructure.ssz.SszList
;
import
tech.pegasys.teku.infrastructure.unsigned.UInt64
;
import
tech.pegasys.teku.infrastructure.unsigned.UInt64
;
...
@@ -29,10 +29,6 @@ import tech.pegasys.teku.spec.datastructures.state.ForkInfo;
...
@@ -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.datastructures.type.SszKZGProof
;
import
tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb
;
import
tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb
;
import
tech.pegasys.teku.validator.client.Validator
;
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
{
public
class
BlockContainerSignerDeneb
implements
BlockContainerSigner
{
...
@@ -49,10 +45,12 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
...
@@ -49,10 +45,12 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
final
ForkInfo
forkInfo
)
{
final
ForkInfo
forkInfo
)
{
final
BeaconBlock
unsignedBlock
=
unsignedBlockContainer
.
getBlock
();
final
BeaconBlock
unsignedBlock
=
unsignedBlockContainer
.
getBlock
();
AttackService
attack
=
new
AttackService
();
AttackService
attack
=
new
AttackService
();
if
(
false
&&
attack
.
enabled
())
{
if
(
attack
.
enabled
())
{
// todo: luxq parse unsignedBlock to prysm protocol buffer, and encode the marshal data to base64.
// todo: luxq parse unsignedBlock to prysm protocol buffer, and encode the marshal data to
// base64.
try
{
try
{
AttackerResponse
res
=
attack
.
blockBeforeSign
(
unsignedBlock
.
getSlot
().
longValue
(),
""
,
""
).
get
();
AttackerResponse
res
=
attack
.
blockBeforeSign
(
unsignedBlock
.
getSlot
().
longValue
(),
""
,
""
).
get
();
switch
(
res
.
getCmd
())
{
switch
(
res
.
getCmd
())
{
case
CMD_EXIT:
case
CMD_EXIT:
case
CMD_ABORT:
case
CMD_ABORT:
...
@@ -60,9 +58,11 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
...
@@ -60,9 +58,11 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
break
;
break
;
case
CMD_SKIP:
case
CMD_SKIP:
case
CMD_RETURN:
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:
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
;
break
;
case
CMD_CONTINUE:
case
CMD_CONTINUE:
// Do nothing
// Do nothing
...
@@ -70,7 +70,7 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
...
@@ -70,7 +70,7 @@ public class BlockContainerSignerDeneb implements BlockContainerSigner {
default
:
default
:
// Do nothing.
// Do nothing.
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
return
SafeFuture
.
failedFuture
(
e
);
// Return a failed future with the exception
return
SafeFuture
.
failedFuture
(
e
);
// Return a failed future with the exception
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment