2021-08-13 16:53:04 +00:00
|
|
|
package slasher
|
|
|
|
|
|
|
|
import (
|
2022-06-28 13:03:24 +00:00
|
|
|
ssz "github.com/prysmaticlabs/fastssz"
|
2024-02-15 05:46:47 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
2021-08-13 16:53:04 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Parameters for slashing detection.
|
|
|
|
//
|
|
|
|
// To properly access the element at epoch `e` for a validator index `i`, we leverage helper
|
|
|
|
// functions from these parameter values as nice abstractions. the following parameters are
|
|
|
|
// required for the helper functions defined in this file.
|
|
|
|
type Parameters struct {
|
Beacon node slasher improvement (#13549)
* Slasher: Ensure all gorouting are stopped before running `Stop` actions.
Fixes #13550.
In tests, `exitChan` are now useless since waitgroup are used to wait
for all goroutines to be stopped.
* `slasher.go`: Add comments and rename some variables. - NFC
* `detect_blocks.go`: Improve. - NFC
- Rename some variables.
- Add comments.
- Use second element of `range` when possible.
* `chunks.go`: Remove `_`receivers. - NFC
* `validateAttestationIntegrity`: Improve documentation. - NFC
* `filterAttestations`: Avoid `else`and rename variable. - NFC
* `slasher.go`: Fix and add comments.
* `SaveAttestationRecordsForValidators`: Remove unused code.
* `LastEpochWrittenForValidators`: Name variables consistently. - NFC
Avoid mixes between `indice(s)`and `index(es)`.
* `SaveLastEpochsWrittenForValidators`: Name variables consistently. - NFC
* `CheckAttesterDoubleVotes`: Rename variables and add comments. - NFC
* `schema.go`: Add comments. - NFC
* `processQueuedAttestations`: Add comments. - NFC
* `checkDoubleVotes`: Rename variable. - NFC
* `Test_processQueuedAttestations`: Ensure there is no error log.
* `shouldNotBeSlashable` => `shouldBeSlashable`
* `Test_processQueuedAttestations`: Add 2 test cases:
- Same target with different signing roots
- Same target with same signing roots
* `checkDoubleVotesOnDisk` ==> `checkDoubleVotes`.
Before this commit, `checkDoubleVotes` did two tasks:
- Checking if there are any slashable double votes in the input
list of attestations with respect to each other.
- Checking if there are any slashable double votes in the input
list of attestations with respect to our database.
However, `checkDoubleVotes` is called only in
`checkSlashableAttestations`.
And `checkSlashableAttestations` is called only in:
- `processQueuedAttestations`, and in
- `IsSlashableAttestation`
Study of case `processQueuedAttestations`:
---------------------------------------------
In `processQueuedAttestations`, `checkSlashableAttestations`
is ALWAYS called after
`Database.SaveAttestationRecordsForValidators`.
It means that, when calling `checkSlashableAttestations`,
`validAtts` are ALREADY stored in the DB.
Each attestation of `validAtts` will be checked twice:
- Against the other attestations of `validAtts` (the portion of
deleted code)
- Against the content of the database.
One of those two checks is redundent.
==> We can remove the check against other attestations in `validAtts`.
Study of case `Database.SaveAttestationRecordsForValidators`:
----------------------------------------------------------------
In `Database.SaveAttestationRecordsForValidators`,
`checkSlashableAttestations` is ALWAYS called with a list of
attestations containing only ONE attestation.
This only attestaion will be checked twice:
- Against itself, and an attestation cannot conflict with itself.
- Against the content of the database.
==> We can remove the check against other attestations in `validAtts`.
=========================
In both cases, we showed that we can remove the check of attestation
against the content of `validAtts`, and the corresponding test
`Test_checkDoubleVotes_SlashableInputAttestations`.
* `Test_processQueuedBlocks_DetectsDoubleProposals`: Wrap proposals.
So we can add new proposals later.
* Fix slasher multiple proposals false negative.
If a first batch of blocks is sent with:
- validator 1 - slot 4 - signing root 1
- validator 1 - slot 5 - signing root 1
Then, if a second batch of blocks is sent with:
- validator 1 - slot 4 - signing root 2
Because we have two blocks proposed by the same validator (1) and for
the same slot (4), but with two different signing roots (1 and 2), the
validator 1 should be slashed.
This is not the case before this commit.
A new test case has been added as well to check this.
Fixes #13551
* `params.go`: Change comments. - NFC
* `CheckSlashable`: Keep the happy path without indentation.
* `detectAllAttesterSlashings` => `checkSurrounds`.
* Update beacon-chain/db/slasherkv/slasher.go
Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
* Update beacon-chain/db/slasherkv/slasher.go
Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
* `CheckAttesterDoubleVotes`: Keep happy path without indentation.
Well, even if, in our case, "happy path" mean slashing.
* 'SaveAttestationRecordsForValidators': Save the first attestation.
In case of multiple votes, arbitrarily save the first attestation.
Saving the first one in particular has no functional impact,
since in any case all attestations will be tested against
the content of the database. So all but the first one will be
detected as slashable.
However, saving the first one and not an other one let us not
to modify the end to end tests, since they expect the first one
to be saved in the database.
* Rename `min` => `minimum`.
Not to conflict with the new `min` built-in function.
* `couldNotSaveSlashableAtt` ==> `couldNotCheckSlashableAtt`
---------
Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-01-31 09:49:14 +00:00
|
|
|
chunkSize uint64 // C - defines how many elements are in a chunk for a validator min or max span slice.
|
|
|
|
validatorChunkSize uint64 // K - defines how many validators' chunks we store in a single flat byte slice on disk.
|
|
|
|
historyLength primitives.Epoch // H - defines how many epochs we keep of min or max spans.
|
2021-08-13 16:53:04 +00:00
|
|
|
}
|
|
|
|
|
2024-03-27 16:15:39 +00:00
|
|
|
// ChunkSize returns the chunk size.
|
|
|
|
func (p *Parameters) ChunkSize() uint64 {
|
|
|
|
return p.chunkSize
|
|
|
|
}
|
|
|
|
|
|
|
|
// ValidatorChunkSize returns the validator chunk size.
|
|
|
|
func (p *Parameters) ValidatorChunkSize() uint64 {
|
|
|
|
return p.validatorChunkSize
|
|
|
|
}
|
|
|
|
|
|
|
|
// HistoryLength returns the history length.
|
|
|
|
func (p *Parameters) HistoryLength() primitives.Epoch {
|
|
|
|
return p.historyLength
|
|
|
|
}
|
|
|
|
|
2021-08-13 16:53:04 +00:00
|
|
|
// DefaultParams defines default values for slasher's important parameters, defined
|
|
|
|
// based on optimization analysis for best and worst case scenarios for
|
|
|
|
// slasher's performance.
|
|
|
|
//
|
|
|
|
// The default values for chunkSize and validatorChunkSize were
|
|
|
|
// decided after an optimization analysis performed by the Sigma Prime team.
|
|
|
|
// See: https://hackmd.io/@sproul/min-max-slasher#1D-vs-2D for more information.
|
|
|
|
// We decide to keep 4096 epochs worth of data in each validator's min max spans.
|
|
|
|
func DefaultParams() *Parameters {
|
|
|
|
return &Parameters{
|
|
|
|
chunkSize: 16,
|
|
|
|
validatorChunkSize: 256,
|
|
|
|
historyLength: 4096,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-27 16:15:39 +00:00
|
|
|
func NewParams(chunkSize, validatorChunkSize uint64, historyLength primitives.Epoch) *Parameters {
|
|
|
|
return &Parameters{
|
|
|
|
chunkSize: chunkSize,
|
|
|
|
validatorChunkSize: validatorChunkSize,
|
|
|
|
historyLength: historyLength,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ChunkIndex Validator min and max spans are split into chunks of length C = chunkSize.
|
2021-08-13 16:53:04 +00:00
|
|
|
// That is, if we are keeping N epochs worth of attesting history, finding what
|
|
|
|
// chunk a certain epoch, e, falls into can be computed as (e % N) / C. For example,
|
|
|
|
// if we are keeping 6 epochs worth of data, and we have chunks of size 2, then epoch
|
|
|
|
// 4 will fall into chunk index (4 % 6) / 2 = 2.
|
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// span = [-, -, -, -, -, -]
|
|
|
|
// chunked = [[-, -], [-, -], [-, -]]
|
|
|
|
// |-> epoch 4, chunk idx 2
|
2023-01-26 14:40:12 +00:00
|
|
|
func (p *Parameters) chunkIndex(epoch primitives.Epoch) uint64 {
|
2021-08-13 16:53:04 +00:00
|
|
|
return uint64(epoch.Mod(uint64(p.historyLength)).Div(p.chunkSize))
|
|
|
|
}
|
|
|
|
|
|
|
|
// When storing data on disk, we take K validators' chunks. To figure out
|
|
|
|
// which validator chunk index a validator index is for, we simply divide
|
|
|
|
// the validator index, i, by K.
|
2023-01-26 14:40:12 +00:00
|
|
|
func (p *Parameters) validatorChunkIndex(validatorIndex primitives.ValidatorIndex) uint64 {
|
2021-08-13 16:53:04 +00:00
|
|
|
return uint64(validatorIndex.Div(p.validatorChunkSize))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the epoch at the 0th index of a chunk at the specified chunk index.
|
|
|
|
// For example, if we have chunks of length 3 and we ask to give us the
|
|
|
|
// first epoch of chunk1, then:
|
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// chunk0 chunk1 chunk2
|
|
|
|
// | | |
|
|
|
|
// [[-, -, -], [-, -, -], [-, -, -], ...]
|
|
|
|
// |
|
|
|
|
// -> first epoch of chunk 1 equals 3
|
2023-01-26 14:40:12 +00:00
|
|
|
func (p *Parameters) firstEpoch(chunkIndex uint64) primitives.Epoch {
|
|
|
|
return primitives.Epoch(chunkIndex * p.chunkSize)
|
2021-08-13 16:53:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the epoch at the last index of a chunk at the specified chunk index.
|
|
|
|
// For example, if we have chunks of length 3 and we ask to give us the
|
|
|
|
// last epoch of chunk1, then:
|
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// chunk0 chunk1 chunk2
|
|
|
|
// | | |
|
|
|
|
// [[-, -, -], [-, -, -], [-, -, -], ...]
|
|
|
|
// |
|
|
|
|
// -> last epoch of chunk 1 equals 5
|
2023-01-26 14:40:12 +00:00
|
|
|
func (p *Parameters) lastEpoch(chunkIndex uint64) primitives.Epoch {
|
2021-08-13 16:53:04 +00:00
|
|
|
return p.firstEpoch(chunkIndex).Add(p.chunkSize - 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Given a validator index, and epoch, we compute the exact index
|
|
|
|
// into our flat slice on disk which stores K validators' chunks, each
|
|
|
|
// chunk of size C. For example, if C = 3 and K = 3, the data we store
|
|
|
|
// on disk is a flat slice as follows:
|
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// val0 val1 val2
|
|
|
|
// | | |
|
|
|
|
// { } { } { }
|
|
|
|
// [-, -, -, -, -, -, -, -, -]
|
2021-08-13 16:53:04 +00:00
|
|
|
//
|
|
|
|
// Then, figuring out the exact cell index for epoch 1 for validator 2 is computed
|
|
|
|
// with (validatorIndex % K)*C + (epoch % C), which gives us:
|
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// (2 % 3)*3 + (1 % 3) =
|
Beacon node slasher improvement (#13549)
* Slasher: Ensure all gorouting are stopped before running `Stop` actions.
Fixes #13550.
In tests, `exitChan` are now useless since waitgroup are used to wait
for all goroutines to be stopped.
* `slasher.go`: Add comments and rename some variables. - NFC
* `detect_blocks.go`: Improve. - NFC
- Rename some variables.
- Add comments.
- Use second element of `range` when possible.
* `chunks.go`: Remove `_`receivers. - NFC
* `validateAttestationIntegrity`: Improve documentation. - NFC
* `filterAttestations`: Avoid `else`and rename variable. - NFC
* `slasher.go`: Fix and add comments.
* `SaveAttestationRecordsForValidators`: Remove unused code.
* `LastEpochWrittenForValidators`: Name variables consistently. - NFC
Avoid mixes between `indice(s)`and `index(es)`.
* `SaveLastEpochsWrittenForValidators`: Name variables consistently. - NFC
* `CheckAttesterDoubleVotes`: Rename variables and add comments. - NFC
* `schema.go`: Add comments. - NFC
* `processQueuedAttestations`: Add comments. - NFC
* `checkDoubleVotes`: Rename variable. - NFC
* `Test_processQueuedAttestations`: Ensure there is no error log.
* `shouldNotBeSlashable` => `shouldBeSlashable`
* `Test_processQueuedAttestations`: Add 2 test cases:
- Same target with different signing roots
- Same target with same signing roots
* `checkDoubleVotesOnDisk` ==> `checkDoubleVotes`.
Before this commit, `checkDoubleVotes` did two tasks:
- Checking if there are any slashable double votes in the input
list of attestations with respect to each other.
- Checking if there are any slashable double votes in the input
list of attestations with respect to our database.
However, `checkDoubleVotes` is called only in
`checkSlashableAttestations`.
And `checkSlashableAttestations` is called only in:
- `processQueuedAttestations`, and in
- `IsSlashableAttestation`
Study of case `processQueuedAttestations`:
---------------------------------------------
In `processQueuedAttestations`, `checkSlashableAttestations`
is ALWAYS called after
`Database.SaveAttestationRecordsForValidators`.
It means that, when calling `checkSlashableAttestations`,
`validAtts` are ALREADY stored in the DB.
Each attestation of `validAtts` will be checked twice:
- Against the other attestations of `validAtts` (the portion of
deleted code)
- Against the content of the database.
One of those two checks is redundent.
==> We can remove the check against other attestations in `validAtts`.
Study of case `Database.SaveAttestationRecordsForValidators`:
----------------------------------------------------------------
In `Database.SaveAttestationRecordsForValidators`,
`checkSlashableAttestations` is ALWAYS called with a list of
attestations containing only ONE attestation.
This only attestaion will be checked twice:
- Against itself, and an attestation cannot conflict with itself.
- Against the content of the database.
==> We can remove the check against other attestations in `validAtts`.
=========================
In both cases, we showed that we can remove the check of attestation
against the content of `validAtts`, and the corresponding test
`Test_checkDoubleVotes_SlashableInputAttestations`.
* `Test_processQueuedBlocks_DetectsDoubleProposals`: Wrap proposals.
So we can add new proposals later.
* Fix slasher multiple proposals false negative.
If a first batch of blocks is sent with:
- validator 1 - slot 4 - signing root 1
- validator 1 - slot 5 - signing root 1
Then, if a second batch of blocks is sent with:
- validator 1 - slot 4 - signing root 2
Because we have two blocks proposed by the same validator (1) and for
the same slot (4), but with two different signing roots (1 and 2), the
validator 1 should be slashed.
This is not the case before this commit.
A new test case has been added as well to check this.
Fixes #13551
* `params.go`: Change comments. - NFC
* `CheckSlashable`: Keep the happy path without indentation.
* `detectAllAttesterSlashings` => `checkSurrounds`.
* Update beacon-chain/db/slasherkv/slasher.go
Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
* Update beacon-chain/db/slasherkv/slasher.go
Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
* `CheckAttesterDoubleVotes`: Keep happy path without indentation.
Well, even if, in our case, "happy path" mean slashing.
* 'SaveAttestationRecordsForValidators': Save the first attestation.
In case of multiple votes, arbitrarily save the first attestation.
Saving the first one in particular has no functional impact,
since in any case all attestations will be tested against
the content of the database. So all but the first one will be
detected as slashable.
However, saving the first one and not an other one let us not
to modify the end to end tests, since they expect the first one
to be saved in the database.
* Rename `min` => `minimum`.
Not to conflict with the new `min` built-in function.
* `couldNotSaveSlashableAtt` ==> `couldNotCheckSlashableAtt`
---------
Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-01-31 09:49:14 +00:00
|
|
|
// 2*3 + 1 =
|
|
|
|
// 7
|
2021-08-13 16:53:04 +00:00
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// val0 val1 val2
|
|
|
|
// | | |
|
|
|
|
// { } { } { }
|
|
|
|
// [-, -, -, -, -, -, -, -, -]
|
|
|
|
// |-> epoch 1 for val2
|
2023-01-26 14:40:12 +00:00
|
|
|
func (p *Parameters) cellIndex(validatorIndex primitives.ValidatorIndex, epoch primitives.Epoch) uint64 {
|
2021-08-13 16:53:04 +00:00
|
|
|
validatorChunkOffset := p.validatorOffset(validatorIndex)
|
|
|
|
chunkOffset := p.chunkOffset(epoch)
|
|
|
|
return validatorChunkOffset*p.chunkSize + chunkOffset
|
|
|
|
}
|
|
|
|
|
|
|
|
// Computes the start index of a chunk given an epoch.
|
2023-01-26 14:40:12 +00:00
|
|
|
func (p *Parameters) chunkOffset(epoch primitives.Epoch) uint64 {
|
2021-08-13 16:53:04 +00:00
|
|
|
return uint64(epoch.Mod(p.chunkSize))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Computes the start index of a validator chunk given a validator index.
|
2023-01-26 14:40:12 +00:00
|
|
|
func (p *Parameters) validatorOffset(validatorIndex primitives.ValidatorIndex) uint64 {
|
2021-08-13 16:53:04 +00:00
|
|
|
return uint64(validatorIndex.Mod(p.validatorChunkSize))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Construct a key for our database schema given a validator chunk index and chunk index.
|
|
|
|
// This calculation gives us a uint encoded as bytes that uniquely represents
|
|
|
|
// a 2D chunk given a validator index and epoch value.
|
|
|
|
// First, we compute the validator chunk index for the validator index,
|
|
|
|
// Then, we compute the chunk index for the epoch.
|
|
|
|
// If chunkSize C = 3 and validatorChunkSize K = 3, and historyLength H = 12,
|
|
|
|
// if we are looking for epoch 6 and validator 6, then
|
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// validatorChunkIndex = 6 / 3 = 2
|
|
|
|
// chunkIndex = (6 % historyLength) / 3 = (6 % 12) / 3 = 2
|
2021-08-13 16:53:04 +00:00
|
|
|
//
|
|
|
|
// Then we compute how many chunks there are per max span, known as the "width"
|
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// width = H / C = 12 / 3 = 4
|
2021-08-13 16:53:04 +00:00
|
|
|
//
|
|
|
|
// So every span has 4 chunks. Then, we have a disk key calculated by
|
|
|
|
//
|
2022-11-18 19:12:19 +00:00
|
|
|
// validatorChunkIndex * width + chunkIndex = 2*4 + 2 = 10
|
2021-08-13 16:53:04 +00:00
|
|
|
func (p *Parameters) flatSliceID(validatorChunkIndex, chunkIndex uint64) []byte {
|
|
|
|
width := p.historyLength.Div(p.chunkSize)
|
|
|
|
return ssz.MarshalUint64(make([]byte, 0), uint64(width.Mul(validatorChunkIndex).Add(chunkIndex)))
|
|
|
|
}
|
|
|
|
|
2024-03-27 16:15:39 +00:00
|
|
|
// ValidatorIndexesInChunk Given a validator chunk index, we determine all the validators
|
2021-08-13 16:53:04 +00:00
|
|
|
// indices that will belong in that chunk.
|
2024-03-27 16:15:39 +00:00
|
|
|
func (p *Parameters) ValidatorIndexesInChunk(validatorChunkIndex uint64) []primitives.ValidatorIndex {
|
2023-01-26 14:40:12 +00:00
|
|
|
validatorIndices := make([]primitives.ValidatorIndex, 0)
|
Slasher: Refactor and add tests (#13589)
* `helpers.go`: Improve naming consistency.
* `detect_attestations.go`: Improve readability.
* `receive.go`: Add `attsQueueSize` in log message.
* `checkSlashableAttestations`: Improve logging.
`avgBatchProcessingTime` is not displayed any more if not batch is
processed.
* `loadChunks`: Use explicit `chunkKind` and `chunkIndices`.
* `getChunk`: Use specific `chunkIndex` and `chunkKind`.
* `validatorIndicesInChunk` -> `validatorIndexesInChunk`.
* `epochUpdateForValidator`: Use explicit arguments.
* `getChunk`: Change order of arguments.
* `latestEpochWrittenForValidator`: Use `ok` parameter.
So the default value is not any more considered as the absence of
value.
* `applyAttestationForValidator`: Use explicit arguments.
* `updateSpans`: Use explicit arguments.
* `saveUpdatedChunks`: Use explicit arguments.
* `checkSurrounds`: Use explicit arguments.
We see here that, previously, in `checkSlashableAttestations`,
`checkSurrounds` was called with the default value of `slashertypes`: `MinSpan`.
Now, we set it expliciterly at `MinSpan`, which may explicit a bug.
* `epochUpdateForValidator`: Set modified by the function argument first.
* `applyAttestationForValidator`: Set mutated argument `chunksByChunkIdx`first.
* `applyAttestationForValidator`: Rename variables.
* `Test_processQueuedAttestations`: Fix test.
Two tests were actually exactly the same.
* `updateSpans`: Keep happy path in the outer scope.
Even if in this case the "happy" path means slashing.
* `checkSurrounds`: Rename variable.
* `getChunk`: Avoid side effects.
It adds a few lines for callers, but it does not modify any more
arguments and it does what it says: getting a chunk.
* `CheckSlashable`: Flatten.
* `detect_attestations_test.go`: Simplify.
* `CheckSlashable`: Add error log in case of missing attestation.
* `processQueuedAttestations`: Extract a sub function.
So testing will be easier.
* `processAttesterSlashings` and `processProposerSlashings`: Improve.
* `processAttesterSlashings`: Return processed slashings.
* `createAttestationWrapper`: Rename variables.
* `signingRoot` ==> `headerRoot` or `dataRoot`.
Before this commit, there is two typse of `signing root`s floating around.
- The first one is a real signing root, aka a hash tree root computed from an object root and
a domain. This real signing root is the object ready to be signed.
- The second one is a "false" signing root, which is actually just the hash tree root of an object. This object is either the `Data` field of an attestation, or the `Header` field of a block.
Having 2 differents objects with the same name `signing root` is quite confusing.
This commit renames wrongly named `signing root` objects.
* `createAttestationWrapper` => `createAttestationWrapperEmptySig`.
So it's clear for the user that the created attestation wrapper has an empty signature.
* Implement `createAttestationWrapper`.
* `processAttestations`: Return processed attester slashings.
* Test `processAttestations` instead of `processQueuedAttestations`.
By testing `processAttestations` instead of `processQueuedAttestations`, we get rid of a lot of tests fixtures, including the 200 ms sleep.
The whole testing duration is shorter.
* `Test_processAttestations`: Allow multiple steps.
* `Test_processAttestations`: Add double steps tests.
Some new failing tests are commented with a corresponding github issue.
* `NextChunkStartEpoch`: Fix function comment.
Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
* `chunks.go`: Avoid templating log messages.
* `checkSlashableAttestations`: Simplify duration computation.
---------
Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2024-02-09 21:02:18 +00:00
|
|
|
low := validatorChunkIndex * p.validatorChunkSize
|
|
|
|
high := (validatorChunkIndex + 1) * p.validatorChunkSize
|
|
|
|
|
2021-08-13 16:53:04 +00:00
|
|
|
for i := low; i < high; i++ {
|
2023-01-26 14:40:12 +00:00
|
|
|
validatorIndices = append(validatorIndices, primitives.ValidatorIndex(i))
|
2021-08-13 16:53:04 +00:00
|
|
|
}
|
Slasher: Refactor and add tests (#13589)
* `helpers.go`: Improve naming consistency.
* `detect_attestations.go`: Improve readability.
* `receive.go`: Add `attsQueueSize` in log message.
* `checkSlashableAttestations`: Improve logging.
`avgBatchProcessingTime` is not displayed any more if not batch is
processed.
* `loadChunks`: Use explicit `chunkKind` and `chunkIndices`.
* `getChunk`: Use specific `chunkIndex` and `chunkKind`.
* `validatorIndicesInChunk` -> `validatorIndexesInChunk`.
* `epochUpdateForValidator`: Use explicit arguments.
* `getChunk`: Change order of arguments.
* `latestEpochWrittenForValidator`: Use `ok` parameter.
So the default value is not any more considered as the absence of
value.
* `applyAttestationForValidator`: Use explicit arguments.
* `updateSpans`: Use explicit arguments.
* `saveUpdatedChunks`: Use explicit arguments.
* `checkSurrounds`: Use explicit arguments.
We see here that, previously, in `checkSlashableAttestations`,
`checkSurrounds` was called with the default value of `slashertypes`: `MinSpan`.
Now, we set it expliciterly at `MinSpan`, which may explicit a bug.
* `epochUpdateForValidator`: Set modified by the function argument first.
* `applyAttestationForValidator`: Set mutated argument `chunksByChunkIdx`first.
* `applyAttestationForValidator`: Rename variables.
* `Test_processQueuedAttestations`: Fix test.
Two tests were actually exactly the same.
* `updateSpans`: Keep happy path in the outer scope.
Even if in this case the "happy" path means slashing.
* `checkSurrounds`: Rename variable.
* `getChunk`: Avoid side effects.
It adds a few lines for callers, but it does not modify any more
arguments and it does what it says: getting a chunk.
* `CheckSlashable`: Flatten.
* `detect_attestations_test.go`: Simplify.
* `CheckSlashable`: Add error log in case of missing attestation.
* `processQueuedAttestations`: Extract a sub function.
So testing will be easier.
* `processAttesterSlashings` and `processProposerSlashings`: Improve.
* `processAttesterSlashings`: Return processed slashings.
* `createAttestationWrapper`: Rename variables.
* `signingRoot` ==> `headerRoot` or `dataRoot`.
Before this commit, there is two typse of `signing root`s floating around.
- The first one is a real signing root, aka a hash tree root computed from an object root and
a domain. This real signing root is the object ready to be signed.
- The second one is a "false" signing root, which is actually just the hash tree root of an object. This object is either the `Data` field of an attestation, or the `Header` field of a block.
Having 2 differents objects with the same name `signing root` is quite confusing.
This commit renames wrongly named `signing root` objects.
* `createAttestationWrapper` => `createAttestationWrapperEmptySig`.
So it's clear for the user that the created attestation wrapper has an empty signature.
* Implement `createAttestationWrapper`.
* `processAttestations`: Return processed attester slashings.
* Test `processAttestations` instead of `processQueuedAttestations`.
By testing `processAttestations` instead of `processQueuedAttestations`, we get rid of a lot of tests fixtures, including the 200 ms sleep.
The whole testing duration is shorter.
* `Test_processAttestations`: Allow multiple steps.
* `Test_processAttestations`: Add double steps tests.
Some new failing tests are commented with a corresponding github issue.
* `NextChunkStartEpoch`: Fix function comment.
Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
* `chunks.go`: Avoid templating log messages.
* `checkSlashableAttestations`: Simplify duration computation.
---------
Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2024-02-09 21:02:18 +00:00
|
|
|
|
2021-08-13 16:53:04 +00:00
|
|
|
return validatorIndices
|
|
|
|
}
|