-
Notifications
You must be signed in to change notification settings - Fork 22
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
Pre consensus fix #240
base: main
Are you sure you want to change the base?
Pre consensus fix #240
Conversation
alonmuroch
commented
May 16, 2023
•
edited by GalRogozinski
Loading
edited by GalRogozinski
- fixes round change (not prev prepared) pre-consensus justification
- fixing pre-consensus justification now calls baseRunner.decide
- not prepared round change will return instance start value - fix message create spec test
- some comments/ code fixes - add pre-consensus to randao test fixtures
- each duty version to const -
# Conflicts: # qbft/spectest/tests/create_message_spectest.go # ssv/spectest/all_tests.go # ssv/spectest/tests/runner/consensus/post_decided.go # ssv/spectest/tests/runner/consensus/post_finish.go # ssv/spectest/tests/runner/consensus/valid_decided.go # ssv/spectest/tests/runner/consensus/valid_decided_7_operators.go # ssv/spectest/tests/runner/full_happy_flow.go # ssv/spectest/tests/runner/full_happy_flow_sc.go # ssv/spectest/tests/runner/postconsensus/duplicate_msg.go # ssv/spectest/tests/runner/postconsensus/duplicate_msg_different_roots.go # ssv/spectest/tests/runner/postconsensus/inconsistent_beacon_signer.go # ssv/spectest/tests/runner/postconsensus/post_quorum.go # ssv/spectest/tests/runner/postconsensus/quorum.go # ssv/spectest/tests/runner/postconsensus/quorum_7_operators.go # ssv/spectest/tests/runner/postconsensus/unknown_signer.go # ssv/spectest/tests/runner/preconsensus/post_decided.go # types/testingutils/beacon_node.go # types/testingutils/runner_versioned.go # types/testingutils/ssv_msgs.go
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.
Looks good to me
approved |
ssv/partial_sig_container.go
Outdated
func (ps *PartialSigContainer) HasQuorum(root [32]byte) bool { | ||
return uint64(len(ps.Signatures[rootHex(root)])) >= ps.Quorum | ||
// SignatureForRoot returns a map of signer and signature for a specific root | ||
func (ps PartialSignatureContainer) SignatureForRoot(root [32]byte) map[types.OperatorID][]byte { |
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 trying to nit pick but I think this function should be named
func (ps PartialSignatureContainer) SignatureForRoot(root [32]byte) map[types.OperatorID][]byte { | |
func (ps PartialSignatureContainer) SignaturesForRoot(root [32]byte) map[types.OperatorID][]byte { |
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.
done
ssv/partial_sig_container.go
Outdated
if len(ps) > 0 { | ||
ret := make([][32]byte, 0) | ||
for _, sigMsg := range ps { | ||
for _, msg := range sigMsg.Message.Messages { | ||
ret = append(ret, msg.SigningRoot) | ||
} | ||
break // only need to iterate first msg | ||
} | ||
return ret | ||
} |
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.
we could do
if len(ps) =< 0 {
return nil // or [][32]byte{}
}
to reduce nesting and add readability
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.
done
@@ -39,8 +27,8 @@ func (b *BaseRunner) validatePreConsensusJustifications(data *types.ConsensusDat | |||
return errors.New("wrong beacon role") | |||
} | |||
|
|||
if data.Duty.Slot <= highestDecidedDutySlot { | |||
return errors.New("duty.slot <= highest decided slot") | |||
if qbft.Height(data.Duty.Slot) <= b.QBFTController.Height && b.QBFTController.Height != qbft.FirstHeight { |
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.
if we are on first height (which will never happen I guess) then its ok that the duty height is smaller than the controller height? I understand why its ok that its equal but not lower.
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.
If it is small or equal it returns an error.
On first height it can only be equal.
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.
you mean if firstHeight would be a number different than 0?
If it will be 1 then we won't need this special condition in all those places in the code
anyQuorum = true | ||
} | ||
|
||
if b.Share.HasQuorum(len(container)) { |
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.
it seems like HasQuorum
just checks the number of sigs we have, don't we want to also check validity before we say we have quorum ?
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 a message to enter the container it should pass validity checks
"Messages": [ | ||
{ | ||
"PartialSignature": "qFQDMkcUT9KZK3wO4GHZKlEZnJKWbhULlEMkiYC0igtS+snZxJ5tfnZ5oxKvIPRcBVMI0gP/rhHuEgGzpwBuVfuFYclsirb3DZVgPJcdVBjSkhkAt4polkJ/BKEHBdC5", | ||
"SigningRoot": [ |
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.
can we make this hex encoded like other roots/signatures/pubkeys?
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 for this PR
MsgsToAdd: []*types.SignedPartialSignatureMessage{ | ||
testingutils.PostConsensusSyncCommitteeContributionMsg(ks.Shares[1], 1, ks), | ||
testingutils.PostConsensusSyncCommitteeContributionMsg(ks.Shares[2], 2, ks), | ||
testingutils.PostConsensusSyncCommitteeContributionMsg(ks.Shares[3], 3, ks), |
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.
should we test with messages other than synccommitteecontrib?
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.
maybe...
when I look at this now not sure why this test is part of the PR (it is something Alon added)...
The PR should concentrate on preconsensus...
nevertheless I am adding you point in #264
if len(test.PostReconstructedSignature) > 0 { | ||
for i, m := range msg.Message.Messages { | ||
sig, lastErr = c.ReconstructSignature(m.SigningRoot, testingutils.TestingValidatorPubKey[:]) | ||
require.EqualValues(t, test.PostReconstructedSignature[i], hex.EncodeToString(sig)) | ||
} | ||
if len(test.ExpectedErr) == 0 { | ||
require.NoError(t, lastErr) | ||
} else { | ||
require.EqualError(t, lastErr, test.ExpectedErr) | ||
} | ||
} |
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.
what about checking ExpectedErr even if postreconstructedsignature is empty? or there's no such test?
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.
Currently there is a trick in tests that Alon did to have a non empty PostReconstructedSignature
filled with empty strings.
In another test he kept the PostReconstructedSignature
empty to not have an error...
So I'd rather not change his design at this point
Messages: testingutils.SSVDecidingMsgsV(testingutils.TestSyncCommitteeContributionConsensusData, ks, types.BNRoleSyncCommitteeContribution), | ||
PostDutyRunnerStateRoot: "a991b6470a8c7a55f4ce89aea91925c2d80a9a8c4258545cc2fb17cabc388719", | ||
Messages: testingutils.SSVDecidingMsgsV(testingutils.TestSyncCommitteeContributionConsensusData(ks), ks, types.BNRoleSyncCommitteeContribution), | ||
PostDutyRunnerStateRoot: "ec47a2194bab81891bd581eaf427af211b53e13d1f77a6703eeb56a693caa878", |
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.
this is changed because preconsensus now affects the duty runner state?
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.
the runner contains all msg containers that includes messages with preconsensus justifications, yes...
But I don't see in the logic where we add prec justification for this test... will look into it...
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.
testingutils.SSVDecidingMsgsV(testingutils.TestAggregatorConsensusData(ks), ks, types.BNRoleAggregator), // consensus | ||
[]*types.SSVMessage{ // post consensus | ||
testingutils.SSVMsgAggregator(nil, testingutils.PostConsensusAggregatorMsg(ks.Shares[1], 1)), | ||
testingutils.SSVMsgAggregator(nil, testingutils.PostConsensusAggregatorMsg(ks.Shares[2], 2)), | ||
testingutils.SSVMsgAggregator(nil, testingutils.PostConsensusAggregatorMsg(ks.Shares[3], 3)), | ||
}..., |
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.
this duty now doesn't have pre consensus msgs?
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.
testingutils.SSVDecidingMsgsV(testingutils.TestSyncCommitteeConsensusData, ks, types.BNRoleSyncCommittee), // consensus
this line adds precon messages
see pre_consensus_full_happy_flow
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 from this pr but typo in file name
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.
on one hand the fix for this doesn't belong in this PR...
on the other hand getting 3 busy people to approve a typo fix on a dedicated PR will take ages...
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.
but it will add more conflicts so I won't fix
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.
Big PR. see my comments, mostly clarifications.
ssv/partial_sig_container.go
Outdated
return hex.EncodeToString(r[:]) | ||
// AllSorted returns ordered by signer array of signed messages | ||
func (ps PartialSignatureContainer) AllSorted() []*types.SignedPartialSignatureMessage { | ||
ret := make([]*types.SignedPartialSignatureMessage, 0) |
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.
allocate with capacity of len(ps)
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.
will do because you copy it to impl even though ideally spec shouldn't care
for _, m := range ps { | ||
ret = append(ret, m) | ||
} | ||
sort.Slice(ret, func(i, j int) bool { |
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 relevant for spec, but same code length with less memory allocations:
sort.Slice(ret, func(i, j int) bool { | |
ret := make([]*types.SignedPartialSignatureMessage, len(ps)) | |
for i, m := range ps { | |
ret[i] = m | |
} |
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.
why delete sort?
ssv/aggregator.go
Outdated
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.
rename quorum
to shouldProcess
or the other way around to keep consistency?
personally i like quorum
bc its self-explanatory
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.
the problem is that sometimes you have a quorum but you don't process