-
Notifications
You must be signed in to change notification settings - Fork 9
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
[WIP] Attestation pool take 1: interop #176
Draft
mkalinin
wants to merge
64
commits into
interop
Choose a base branch
from
feature/attestation-pool
base: interop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 12 commits
Commits
Show all changes
64 commits
Select commit
Hold shift + click to select a range
69eef6f
Initial commit of the attestation pool feature
mkalinin d09e87e
Update signature verification in the pool
mkalinin 47023da
Rework reactor logic in attestation pool
mkalinin 771fe79
Instantiate attestation pool
mkalinin 4a039bb
Check isInitialized in attestation processors if needed
mkalinin da9fb0e
Add javadocs and polish attestation pool impl
mkalinin 548625c
Continue to polish and document attestation pool
mkalinin 19b7403
Get rid of redundant Input class
mkalinin 4494576
Simplify name of processors in attestaiton pool
mkalinin 817abdd
Add a javadoc to InMemoryAttestationPool class
mkalinin faf766b
Add attestation pool diagram
mkalinin e9182d0
Update pool diagram
mkalinin cb4130e
Rework attestation pool processors
mkalinin df528e5
JUNIT5: add. Add test draft
eustimenko a1219ba
Create attestation-pool at test
eustimenko d394a3b
add reactor tests
eustimenko 23f74e2
pool-test: add verify blockchain creation
eustimenko 5a47137
pool-test: add verify ReceivedAttestation creation
eustimenko 1ea3c89
pool-test: verify SlotsNumber creation
eustimenko 037ba11
pool-test: a little refactroing
eustimenko 0b1e0f1
pool-test: fix parent block chain
eustimenko 0aff0ce
pool-test: add empty checkpoint publisher
eustimenko 7138a49
test: fix NPE to create UnknownAttestationPool
eustimenko 5208599
test: correct verification
eustimenko b65b8cf
Switch to rocksDB JNI 6.2.2 since it includes compression codecs on W…
ericsson49 5339f80
Configuration of eth1_block_hash value for EmulatorContract added.
ericsson49 8bbaacd
Mocked start key pairs generation implemented.
ericsson49 5020f61
Withdrawal credentials for mocked start generation implemented.
ericsson49 11b7521
Added a command line option to specify yaml spec constants file (simp…
ericsson49 bfabbea
Modified default config to match interop settings.
ericsson49 6c2e407
For interop, MAX_EFFECTIVE_BALANCE should be used as a balance value.
ericsson49 9a87620
Use BCParameters.ORDER to initialize SimulationKeyPairGenerator#CURVE…
mkalinin b84de20
test: draft commit
eustimenko e1f2b1e
test: fix check TimeFrameFilter
eustimenko ba01970
Implement simple suboptimal attestation churn
mkalinin 2db4a97
Verify attestations against state before aggregation
mkalinin f9edbd2
test: change out to SimpleProcessor
eustimenko e669476
Update attestation pool with a bunch of fixes
mkalinin 87676b1
Merge branch 'feature/attestation-pool' of github.com:harmony-dev/bea…
mkalinin 26da60d
Use SimpleProcessor all over attestation pool
mkalinin c358638
Merge branch 'develop' into feature/attestation-pool
mkalinin 49e95b4
Merge followups
mkalinin 86813ff
Integrate attestation pool into simulator
mkalinin c00918e
pool: test valid TimeProcessor
eustimenko 11bb800
pool: test valid SanityProcessor
eustimenko 5e0d7bd
pool: correct testing valid/invalid SanityProcessor
eustimenko 6f46160
pool: test DoubleWorkProcessor
eustimenko 5ab558c
pool: test SignatureEncodingChecker
eustimenko 441dc74
Merge branch 'feature/attestation-pool' of github.com:harmony-dev/bea…
mkalinin f4ba71f
pool: test processors by one test
eustimenko 5ecceca
pool: SignatureEncodingProcessorTest
eustimenko eda3012
test: correct test attestation to be valid
eustimenko 85b5f68
test: IdentificationProcessor
eustimenko a1c2751
test: initialize tuple storage
eustimenko 01c0c7c
test: remove inmemory attestation pool test
eustimenko 33f0629
Modify update finality to comply with the fork choice spec.
ericsson49 94cd7be
Modify get_head to comply with the fork_choice spec: add tie break.
ericsson49 07d2003
attestation-pool: update eth2.0-spec-tests
eustimenko 4c6541d
Modify update finality to comply with the fork choice spec.
ericsson49 67541c0
Modify get_head to comply with the fork_choice spec: add tie break.
ericsson49 122e9af
Merge remote-tracking branch 'origin/fix/fork-choice-issues' into fix…
ericsson49 1bc6ce9
Check that BytesValue are compared the same way in Java and in python3
ericsson49 cf24e15
Replace string comparison with bytes' in get_winning_crosslink_and_at…
mkalinin 8d653af
Merge pull request #199 from harmony-dev/fix/fork-choice-issues
mkalinin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
chain/src/main/java/org/ethereum/beacon/chain/pool/AttestationPool.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package org.ethereum.beacon.chain.pool; | ||
|
||
import java.time.Duration; | ||
import org.ethereum.beacon.chain.BeaconChain; | ||
import org.ethereum.beacon.chain.pool.checker.SanityChecker; | ||
import org.ethereum.beacon.chain.pool.checker.SignatureEncodingChecker; | ||
import org.ethereum.beacon.chain.pool.checker.TimeFrameFilter; | ||
import org.ethereum.beacon.chain.pool.churn.OffChainAggregates; | ||
import org.ethereum.beacon.chain.pool.registry.ProcessedAttestations; | ||
import org.ethereum.beacon.chain.pool.registry.UnknownAttestationPool; | ||
import org.ethereum.beacon.chain.pool.verifier.AttestationVerifier; | ||
import org.ethereum.beacon.chain.pool.verifier.BatchVerifier; | ||
import org.ethereum.beacon.chain.storage.BeaconChainStorage; | ||
import org.ethereum.beacon.consensus.BeaconChainSpec; | ||
import org.ethereum.beacon.consensus.transition.EmptySlotTransition; | ||
import org.ethereum.beacon.core.BeaconBlock; | ||
import org.ethereum.beacon.core.state.Checkpoint; | ||
import org.ethereum.beacon.core.types.EpochNumber; | ||
import org.ethereum.beacon.core.types.SlotNumber; | ||
import org.ethereum.beacon.schedulers.Schedulers; | ||
import org.reactivestreams.Publisher; | ||
|
||
/** | ||
* Attestation pool API. | ||
* | ||
* <p>Along with {@link BeaconChain} attestation pool is one of the central components of the Beacon | ||
* chain client. Its main responsibilities are to verify attestation coming from the wire and | ||
* accumulate those of them which are not yet included on chain. | ||
* | ||
* <p>A list of attestation pool clients: | ||
* | ||
* <ul> | ||
* <li>Wire - valid attestations should be further propagated; peers sent attestations that are | ||
* eventually invalid must be dropped. | ||
* <li>Fork choice - LMD GHOST is driven by attestations received from the wire even if they are | ||
* not yet on chain. | ||
* <li>Validator - attestations not yet included on chain should be included into a new block | ||
* produced by proposer. | ||
* </ul> | ||
*/ | ||
public interface AttestationPool { | ||
|
||
/** A number of threads in the executor processing attestation pool. */ | ||
int MAX_THREADS = 32; | ||
|
||
/** Discard attestations with target epoch greater than current epoch plus this number. */ | ||
EpochNumber MAX_ATTESTATION_LOOKAHEAD = EpochNumber.of(1); | ||
|
||
/** | ||
* Max number of attestations kept by processed attestations registry. An entry of this registry | ||
* should be represented by a hash of registered attestation. | ||
*/ | ||
int MAX_PROCESSED_ATTESTATIONS = 1_000_000; | ||
|
||
/** Max number of attestations made to not yet known block that could be kept in memory. */ | ||
int MAX_UNKNOWN_ATTESTATIONS = 100_000; | ||
|
||
/** Max size of a buffer that collects attestations before passing them on the main verifier. */ | ||
int VERIFIER_BUFFER_SIZE = 10_000; | ||
|
||
/** A throttling interval for verifier buffer. */ | ||
Duration VERIFIER_INTERVAL = Duration.ofMillis(50); | ||
|
||
/** | ||
* Valid attestations publisher. | ||
* | ||
* @return a publisher. | ||
*/ | ||
Publisher<ReceivedAttestation> getValid(); | ||
|
||
/** | ||
* Invalid attestations publisher. | ||
* | ||
* @return a publisher. | ||
*/ | ||
Publisher<ReceivedAttestation> getInvalid(); | ||
|
||
/** | ||
* Publishes attestations which block is not yet a known block. | ||
* | ||
* <p>These attestations should be passed to a wire module in order to request a block. | ||
* | ||
* @return a publisher. | ||
*/ | ||
Publisher<ReceivedAttestation> getUnknownAttestations(); | ||
|
||
/** | ||
* Publishes aggregated attestations that are not yet included on chain. | ||
* | ||
* <p>It should be a source of attestations for block proposer. | ||
* | ||
* @return a publisher. | ||
*/ | ||
Publisher<OffChainAggregates> getAggregates(); | ||
|
||
/** Launches the pool. */ | ||
void start(); | ||
|
||
static AttestationPool create( | ||
Publisher<ReceivedAttestation> source, | ||
Publisher<SlotNumber> newSlots, | ||
Publisher<Checkpoint> finalizedCheckpoints, | ||
Publisher<BeaconBlock> importedBlocks, | ||
Publisher<BeaconBlock> chainHeads, | ||
Schedulers schedulers, | ||
BeaconChainSpec spec, | ||
BeaconChainStorage storage, | ||
EmptySlotTransition emptySlotTransition) { | ||
|
||
TimeFrameFilter timeFrameFilter = new TimeFrameFilter(spec, MAX_ATTESTATION_LOOKAHEAD); | ||
SanityChecker sanityChecker = new SanityChecker(spec); | ||
SignatureEncodingChecker encodingChecker = new SignatureEncodingChecker(); | ||
ProcessedAttestations processedFilter = | ||
new ProcessedAttestations(spec::hash_tree_root, MAX_PROCESSED_ATTESTATIONS); | ||
UnknownAttestationPool unknownAttestationPool = | ||
new UnknownAttestationPool( | ||
storage.getBlockStorage(), spec, MAX_ATTESTATION_LOOKAHEAD, MAX_UNKNOWN_ATTESTATIONS); | ||
BatchVerifier batchVerifier = | ||
new AttestationVerifier(storage.getTupleStorage(), spec, emptySlotTransition); | ||
|
||
return new InMemoryAttestationPool( | ||
source, | ||
newSlots, | ||
finalizedCheckpoints, | ||
importedBlocks, | ||
chainHeads, | ||
schedulers, | ||
timeFrameFilter, | ||
sanityChecker, | ||
encodingChecker, | ||
processedFilter, | ||
unknownAttestationPool, | ||
batchVerifier); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
chain/src/main/java/org/ethereum/beacon/chain/pool/CheckedAttestation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.ethereum.beacon.chain.pool; | ||
|
||
/** A simple DTO that carries an attestation and a result of some check run against it. */ | ||
public class CheckedAttestation { | ||
private final boolean passed; | ||
private final ReceivedAttestation attestation; | ||
|
||
public CheckedAttestation(boolean passed, ReceivedAttestation attestation) { | ||
this.passed = passed; | ||
this.attestation = attestation; | ||
} | ||
|
||
public boolean isPassed() { | ||
return passed; | ||
} | ||
|
||
public ReceivedAttestation getAttestation() { | ||
return attestation; | ||
} | ||
} |
158 changes: 158 additions & 0 deletions
158
chain/src/main/java/org/ethereum/beacon/chain/pool/InMemoryAttestationPool.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
package org.ethereum.beacon.chain.pool; | ||
|
||
import org.ethereum.beacon.chain.pool.checker.SanityChecker; | ||
import org.ethereum.beacon.chain.pool.checker.SignatureEncodingChecker; | ||
import org.ethereum.beacon.chain.pool.checker.TimeFrameFilter; | ||
import org.ethereum.beacon.chain.pool.churn.OffChainAggregates; | ||
import org.ethereum.beacon.chain.pool.reactor.ChurnProcessor; | ||
import org.ethereum.beacon.chain.pool.reactor.IdentificationProcessor; | ||
import org.ethereum.beacon.chain.pool.reactor.SanityProcessor; | ||
import org.ethereum.beacon.chain.pool.reactor.TimeProcessor; | ||
import org.ethereum.beacon.chain.pool.reactor.VerificationProcessor; | ||
import org.ethereum.beacon.chain.pool.registry.ProcessedAttestations; | ||
import org.ethereum.beacon.chain.pool.registry.UnknownAttestationPool; | ||
import org.ethereum.beacon.chain.pool.verifier.BatchVerifier; | ||
import org.ethereum.beacon.core.BeaconBlock; | ||
import org.ethereum.beacon.core.state.Checkpoint; | ||
import org.ethereum.beacon.core.types.SlotNumber; | ||
import org.ethereum.beacon.schedulers.Scheduler; | ||
import org.ethereum.beacon.schedulers.Schedulers; | ||
import org.ethereum.beacon.stream.Fluxes; | ||
import org.ethereum.beacon.stream.Fluxes.FluxSplit; | ||
import org.reactivestreams.Publisher; | ||
import reactor.core.publisher.DirectProcessor; | ||
import reactor.core.publisher.Flux; | ||
|
||
/** | ||
* An implementation of attestation pool based on <a href="https://projectreactor.io/">Reactor</a> | ||
* library, one of the implementation of reactive streams. | ||
*/ | ||
public class InMemoryAttestationPool implements AttestationPool { | ||
|
||
private final Publisher<ReceivedAttestation> source; | ||
private final Publisher<SlotNumber> newSlots; | ||
private final Publisher<Checkpoint> finalizedCheckpoints; | ||
private final Publisher<BeaconBlock> importedBlocks; | ||
private final Publisher<BeaconBlock> chainHeads; | ||
private final Schedulers schedulers; | ||
|
||
private final TimeProcessor timeProcessor; | ||
private final SanityProcessor sanityChecker; | ||
private final SignatureEncodingChecker encodingChecker; | ||
private final ProcessedAttestations processedFilter; | ||
private final IdentificationProcessor identifier; | ||
private final VerificationProcessor verifier; | ||
private final ChurnProcessor churn; | ||
|
||
private final DirectProcessor<ReceivedAttestation> invalidAttestations = DirectProcessor.create(); | ||
private final DirectProcessor<ReceivedAttestation> validAttestations = DirectProcessor.create(); | ||
|
||
public InMemoryAttestationPool( | ||
Publisher<ReceivedAttestation> source, | ||
Publisher<SlotNumber> newSlots, | ||
Publisher<Checkpoint> finalizedCheckpoints, | ||
Publisher<BeaconBlock> importedBlocks, | ||
Publisher<BeaconBlock> chainHeads, | ||
Schedulers schedulers, | ||
TimeFrameFilter timeFrameFilter, | ||
SanityChecker sanityChecker, | ||
SignatureEncodingChecker encodingChecker, | ||
ProcessedAttestations processedFilter, | ||
UnknownAttestationPool unknownAttestationPool, | ||
BatchVerifier batchVerifier) { | ||
this.source = source; | ||
this.newSlots = newSlots; | ||
this.finalizedCheckpoints = finalizedCheckpoints; | ||
this.importedBlocks = importedBlocks; | ||
this.chainHeads = chainHeads; | ||
this.schedulers = schedulers; | ||
this.timeProcessor = new TimeProcessor(timeFrameFilter); | ||
this.sanityChecker = new SanityProcessor(sanityChecker); | ||
this.encodingChecker = encodingChecker; | ||
this.processedFilter = processedFilter; | ||
this.identifier = new IdentificationProcessor(unknownAttestationPool); | ||
this.verifier = new VerificationProcessor(batchVerifier); | ||
this.churn = new ChurnProcessor(); | ||
} | ||
|
||
@Override | ||
public void start() { | ||
Scheduler executor = | ||
schedulers.newParallelDaemon("attestation-pool-%d", AttestationPool.MAX_THREADS); | ||
|
||
Flux<?> sourceFx = Flux.from(source).publishOn(executor.toReactor()); | ||
Flux<?> newSlotsFx = Flux.from(newSlots).publishOn(executor.toReactor()); | ||
Flux<?> importedBlocksFx = Flux.from(importedBlocks).publishOn(executor.toReactor()); | ||
Flux<?> finalizedCheckpointsFx = | ||
Flux.from(finalizedCheckpoints).publishOn(executor.toReactor()); | ||
Flux<?> chainHeadsFx = Flux.from(chainHeads).publishOn(executor.toReactor()); | ||
|
||
// start from time frame processor | ||
Flux.merge(sourceFx, newSlotsFx, finalizedCheckpointsFx).subscribe(timeProcessor); | ||
FluxSplit<CheckedAttestation> timeFrameOut = | ||
Fluxes.split(timeProcessor, CheckedAttestation::isPassed); | ||
|
||
// subscribe sanity checker | ||
Flux.merge( | ||
timeFrameOut.getSatisfied().map(CheckedAttestation::getAttestation), | ||
finalizedCheckpointsFx) | ||
.subscribe(sanityChecker); | ||
FluxSplit<CheckedAttestation> sanityOut = | ||
Fluxes.split(sanityChecker, CheckedAttestation::isPassed); | ||
|
||
// filter already processed attestations | ||
Flux<ReceivedAttestation> newAttestations = | ||
sanityOut | ||
.getSatisfied() | ||
.map(CheckedAttestation::getAttestation) | ||
.filter(processedFilter::add); | ||
|
||
// check signature encoding | ||
FluxSplit<ReceivedAttestation> encodingCheckOut = | ||
Fluxes.split(newAttestations, encodingChecker::check); | ||
|
||
// identify attestation target | ||
Flux.merge(encodingCheckOut.getSatisfied(), newSlotsFx, importedBlocksFx).subscribe(identifier); | ||
|
||
// verify attestations | ||
identifier.bufferTimeout(VERIFIER_BUFFER_SIZE, VERIFIER_INTERVAL).subscribe(verifier); | ||
FluxSplit<CheckedAttestation> verifierOut = | ||
Fluxes.split(verifier, CheckedAttestation::isPassed); | ||
|
||
// feed churn | ||
Flux.merge( | ||
verifierOut.getSatisfied().map(CheckedAttestation::getAttestation), | ||
newSlotsFx, | ||
chainHeadsFx); | ||
|
||
// expose invalid attestations | ||
Flux.merge( | ||
sanityOut.getUnsatisfied().map(CheckedAttestation::getAttestation), | ||
encodingCheckOut.getUnsatisfied(), | ||
verifierOut.getUnsatisfied().map(CheckedAttestation::getAttestation)) | ||
.subscribe(invalidAttestations); | ||
|
||
// expose valid attestations | ||
verifierOut.getSatisfied().map(CheckedAttestation::getAttestation).subscribe(validAttestations); | ||
} | ||
|
||
@Override | ||
public Publisher<ReceivedAttestation> getValid() { | ||
return validAttestations; | ||
} | ||
|
||
@Override | ||
public Publisher<ReceivedAttestation> getInvalid() { | ||
return invalidAttestations; | ||
} | ||
|
||
@Override | ||
public Publisher<ReceivedAttestation> getUnknownAttestations() { | ||
return identifier.getUnknownAttestations(); | ||
} | ||
|
||
@Override | ||
public Publisher<OffChainAggregates> getAggregates() { | ||
return churn; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
chain/src/main/java/org/ethereum/beacon/chain/pool/ReceivedAttestation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package org.ethereum.beacon.chain.pool; | ||
|
||
import org.ethereum.beacon.core.operations.Attestation; | ||
import org.ethereum.beacon.types.p2p.NodeId; | ||
|
||
/** An attestation received from the wire. */ | ||
public class ReceivedAttestation { | ||
|
||
/** An id of a node sent this attestation. */ | ||
private final NodeId sender; | ||
/** An attestation message itself. */ | ||
private final Attestation message; | ||
|
||
public ReceivedAttestation(NodeId sender, Attestation message) { | ||
this.sender = sender; | ||
this.message = message; | ||
} | ||
|
||
public NodeId getSender() { | ||
return sender; | ||
} | ||
|
||
public Attestation getMessage() { | ||
return message; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
chain/src/main/java/org/ethereum/beacon/chain/pool/StatefulProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.ethereum.beacon.chain.pool; | ||
|
||
/** | ||
* Stateful processor. | ||
* | ||
* <p>A processor that requires particular inner state to be initialized before it could be safely | ||
* called by its clients. | ||
* | ||
* <p>{@link #isInitialized()} method indicates whether processor has already been initialized or | ||
* not. It's a client responsibility to check {@link #isInitialized()} result before calling to the | ||
* instance of this processor. | ||
* | ||
* <p>Implementor MAY throw an {@link AssertionError} if it's been called before inner state has | ||
* been initialised. | ||
*/ | ||
public interface StatefulProcessor { | ||
|
||
/** | ||
* Checks whether processor state is initialized or not. | ||
* | ||
* @return {@code true} if processor is ready to work, {@link false}, otherwise. | ||
*/ | ||
boolean isInitialized(); | ||
} |
21 changes: 21 additions & 0 deletions
21
chain/src/main/java/org/ethereum/beacon/chain/pool/checker/AttestationChecker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.ethereum.beacon.chain.pool.checker; | ||
|
||
import org.ethereum.beacon.chain.pool.ReceivedAttestation; | ||
|
||
/** | ||
* An interface of light weight attestation checker. | ||
* | ||
* <p>Implementations of this interface SHOULD NOT execute I/O operations or run checks that are in | ||
* high demand to CPU resources. Usually, implementation of this interface runs quick checks that | ||
* could be done with the attestation itself without involving any other data. | ||
*/ | ||
public interface AttestationChecker { | ||
|
||
/** | ||
* Given attestation runs a check. | ||
* | ||
* @param attestation an attestation to check. | ||
* @return {@code true} if checks are passed successfully, {@code false} otherwise. | ||
*/ | ||
boolean check(ReceivedAttestation attestation); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Not sure I understand the purpose of this interface.
You either
assert
that a component is inited or just skip an entry if not inited. Couldn't this be the internal logic of this component?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.
For instance, we have checkers which returns value of
boolean
type saying whether check passed or not. These checkers may have several inputs and state initialized from either one or all of those inputs. Since, check MUST returnstrue/false
there is no room for merely discarding the value fed to a checker. We might useOptional<Boolean>
for that but I am not sure that it would be a better choice.