-
Notifications
You must be signed in to change notification settings - Fork 355
[Stateless Proto] Introducing execution proofs subnet and gossip validation #9869
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
Changes from 119 commits
022d9fb
580af8a
b6230a8
a0f6f62
468fa81
e8c52bb
3006324
cd8f5ae
2f42260
8d4a101
7f4e13e
6011bc7
6d24453
00f8fdf
f37f4be
3323b18
934330f
84cf649
fe3c4ff
e9aa75f
25a6203
06d8835
7e3fffc
58fc879
5be132d
651d50d
3b4376b
cbf2371
2ee1eb0
a81ebc7
11217cc
53abb23
a2f0768
7373d63
ff06fda
dfbeaca
b052c91
2a0e93c
62f53aa
fa420a8
ca71c8f
a1318b9
35f9188
efa29cf
84dd8b7
a2989d6
3b256d8
06e2fdf
934de8c
4320861
7647417
dbc906d
058ce7e
5008d04
d260a0d
f282971
73b6b57
25c6dfd
99c52dc
1c75e48
c958a32
326e487
18c4cee
f876a73
4b521f5
2b55a08
d444c68
f67b45d
7183bb7
4d078f8
8663868
17cab73
2fbcc2d
8c52ef5
3794d36
452bda9
119a957
833f803
d039fcf
dd715aa
cd0d231
9bb5afc
a27e8e7
b294185
ff7f802
43ee8a2
659f373
780a2da
45bb603
9501477
1327a13
b981eee
0379250
0ae1e8a
16c520a
9284650
2b06395
de2a545
bb6ec28
db19aa7
72a6d58
caee242
2d65f59
eabcd2a
818ad31
e389e0f
3b92c10
196f27f
464a820
36e31c5
5d73f96
59fcf8d
4ff2231
244ba6d
ed5eab9
19bb1ce
71a5d7b
142c8f3
bdd3dae
738994c
2c9ec99
837da57
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,53 @@ | ||
| /* | ||
| * 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.statetransition.executionproofs; | ||
|
|
||
| import java.util.Optional; | ||
| import tech.pegasys.teku.infrastructure.async.SafeFuture; | ||
| import tech.pegasys.teku.infrastructure.unsigned.UInt64; | ||
| import tech.pegasys.teku.spec.datastructures.execution.ExecutionProof; | ||
| import tech.pegasys.teku.statetransition.blobs.RemoteOrigin; | ||
| import tech.pegasys.teku.statetransition.validation.InternalValidationResult; | ||
|
|
||
| public interface ExecutionProofManager { | ||
|
|
||
| ExecutionProofManager NOOP = | ||
| new ExecutionProofManager() { | ||
| @Override | ||
| public SafeFuture<InternalValidationResult> onExecutionProofGossip( | ||
| ExecutionProof executionProof, Optional<UInt64> arrivalTimestamp) { | ||
| return SafeFuture.completedFuture(InternalValidationResult.ACCEPT); | ||
| } | ||
|
|
||
| @Override | ||
| public void onExecutionProofPublish( | ||
| final ExecutionProof executionProof, final RemoteOrigin remoteOrigin) {} | ||
|
|
||
| @Override | ||
| public void subscribeToValidExecutionProofs( | ||
| final ValidExecutionProofListener sidecarsListener) {} | ||
| }; | ||
|
|
||
| void onExecutionProofPublish(ExecutionProof executionProof, RemoteOrigin remoteOrigin); | ||
|
||
|
|
||
| SafeFuture<InternalValidationResult> onExecutionProofGossip( | ||
| ExecutionProof executionProof, Optional<UInt64> arrivalTimestamp); | ||
|
|
||
| void subscribeToValidExecutionProofs( | ||
| ExecutionProofManager.ValidExecutionProofListener executionProofListener); | ||
|
||
|
|
||
| interface ValidExecutionProofListener { | ||
| void onNewValidExecutionProof(ExecutionProof executionProof, RemoteOrigin remoteOrigin); | ||
Check noticeCode scanning / CodeQL Useless parameter Note
The parameter 'remoteOrigin' is never used.
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| /* | ||
| * 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.statetransition.executionproofs; | ||
|
|
||
| import java.util.Optional; | ||
| import org.apache.logging.log4j.LogManager; | ||
| import org.apache.logging.log4j.Logger; | ||
| import tech.pegasys.teku.infrastructure.async.SafeFuture; | ||
| import tech.pegasys.teku.infrastructure.subscribers.Subscribers; | ||
| import tech.pegasys.teku.infrastructure.unsigned.UInt64; | ||
| import tech.pegasys.teku.spec.datastructures.execution.ExecutionProof; | ||
| import tech.pegasys.teku.statetransition.blobs.RemoteOrigin; | ||
| import tech.pegasys.teku.statetransition.validation.ExecutionProofGossipValidator; | ||
| import tech.pegasys.teku.statetransition.validation.InternalValidationResult; | ||
|
|
||
| public class ExecutionProofManagerImpl implements ExecutionProofManager { | ||
|
|
||
| final ExecutionProofGossipValidator executionProofGossipValidator; | ||
| private final Subscribers<ValidExecutionProofListener> receivedExecutionProofSubscribers = | ||
| Subscribers.create(true); | ||
|
|
||
| private static final Logger LOG = LogManager.getLogger(); | ||
|
|
||
| public ExecutionProofManagerImpl( | ||
| final ExecutionProofGossipValidator executionProofGossipValidator) { | ||
| this.executionProofGossipValidator = executionProofGossipValidator; | ||
| } | ||
|
|
||
| @Override | ||
| public void onExecutionProofPublish( | ||
| final ExecutionProof executionProof, final RemoteOrigin remoteOrigin) { | ||
| LOG.trace("Published execution proof {}", executionProof); | ||
| } | ||
|
|
||
| @Override | ||
| public SafeFuture<InternalValidationResult> onExecutionProofGossip( | ||
| final ExecutionProof executionProof, final Optional<UInt64> arrivalTimestamp) { | ||
| LOG.debug("Received execution proof for block {}", executionProof); | ||
| // TODO fix this as this needs to obtain subnetId from the topic we received the proof from? | ||
| // this is probably a validation that only makes sense for the stub we're doing | ||
| return executionProofGossipValidator.validate( | ||
| executionProof, executionProof.getSubnetId().get()); | ||
lucassaldanha marked this conversation as resolved.
Show resolved
Hide resolved
gfukushima marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| @Override | ||
| public void subscribeToValidExecutionProofs( | ||
| final ValidExecutionProofListener executionProofListener) { | ||
| receivedExecutionProofSubscribers.subscribe(executionProofListener); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| /* | ||
| * 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.statetransition.validation; | ||
|
|
||
| import static tech.pegasys.teku.spec.config.Constants.MAX_EXECUTION_PROOF_SUBNETS; | ||
|
|
||
| import java.util.Set; | ||
| import org.apache.logging.log4j.LogManager; | ||
| import org.apache.logging.log4j.Logger; | ||
| import tech.pegasys.teku.infrastructure.async.SafeFuture; | ||
| import tech.pegasys.teku.infrastructure.collections.LimitedSet; | ||
| import tech.pegasys.teku.infrastructure.unsigned.UInt64; | ||
| import tech.pegasys.teku.spec.datastructures.execution.ExecutionProof; | ||
|
|
||
| public class ExecutionProofGossipValidator { | ||
gfukushima marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| private static final Logger LOG = LogManager.getLogger(); | ||
|
|
||
| private final Set<ExecutionProof> receivedValidExecutionProofSet; | ||
|
|
||
| public static ExecutionProofGossipValidator create() { | ||
| return new ExecutionProofGossipValidator( | ||
lucassaldanha marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // max subnets * 2 epochs * slots per epoch 32 based on mainnet for now | ||
| LimitedSet.createSynchronized(MAX_EXECUTION_PROOF_SUBNETS.intValue() * 64)); | ||
|
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. |
||
| } | ||
|
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. Bug: Code-Comment Mismatch in
|
||
|
|
||
| public ExecutionProofGossipValidator(final Set<ExecutionProof> receivedValidExecutionProofSet) { | ||
|
|
||
| this.receivedValidExecutionProofSet = receivedValidExecutionProofSet; | ||
| } | ||
|
|
||
| public SafeFuture<InternalValidationResult> validate( | ||
| final ExecutionProof executionProof, final UInt64 subnetId) { | ||
|
|
||
| // TODO need to check for other validations done in the prototype and spec | ||
| if (!executionProof.getSubnetId().get().equals(subnetId)) { | ||
| LOG.trace( | ||
| "ExecutionProof for block root {} / block hash {} does not match the gossip subnetId", | ||
| executionProof.getBlockRoot(), | ||
| executionProof.getBlockHash()); | ||
| return SafeFuture.completedFuture(InternalValidationResult.reject("SubnetId mismatch")); | ||
| } | ||
gfukushima marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Already seen and valid | ||
| if (receivedValidExecutionProofSet.contains(executionProof)) { | ||
| LOG.trace("Received duplicate execution proof {}", executionProof); | ||
| return SafeFuture.completedFuture(InternalValidationResult.IGNORE); | ||
gfukushima marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // Validated the execution proof | ||
| LOG.trace( | ||
| "Received and validated execution proof for block root {}, block hash {}", | ||
| executionProof.getBlockRoot(), | ||
| executionProof.getBlockHash()); | ||
| receivedValidExecutionProofSet.add(executionProof); | ||
| return SafeFuture.completedFuture(InternalValidationResult.ACCEPT); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.