Skip to content
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

Open
wants to merge 127 commits into
base: main
Choose a base branch
from
Open

Conversation

alonmuroch
Copy link
Contributor

@alonmuroch alonmuroch commented May 16, 2023

  • fixes round change (not prev prepared) pre-consensus justification
  • fixing pre-consensus justification now calls baseRunner.decide

alonmuroch and others added 30 commits May 16, 2023 17:47
- 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
# 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
Copy link
Contributor

@MatheusFranco99 MatheusFranco99 left a 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

@alonmuroch
Copy link
Contributor Author

approved

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 {
Copy link
Contributor

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

Suggested change
func (ps PartialSignatureContainer) SignatureForRoot(root [32]byte) map[types.OperatorID][]byte {
func (ps PartialSignatureContainer) SignaturesForRoot(root [32]byte) map[types.OperatorID][]byte {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 47 to 56
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
}
Copy link
Contributor

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

Copy link
Contributor

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 {
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor

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)) {
Copy link
Contributor

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 ?

Copy link
Contributor

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": [
Copy link
Contributor

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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not for this PR

Comment on lines +15 to +18
MsgsToAdd: []*types.SignedPartialSignatureMessage{
testingutils.PostConsensusSyncCommitteeContributionMsg(ks.Shares[1], 1, ks),
testingutils.PostConsensusSyncCommitteeContributionMsg(ks.Shares[2], 2, ks),
testingutils.PostConsensusSyncCommitteeContributionMsg(ks.Shares[3], 3, ks),
Copy link
Contributor

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?

Copy link
Contributor

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

Comment on lines +45 to +55
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)
}
}
Copy link
Contributor

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?

Copy link
Contributor

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",
Copy link
Contributor

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?

Copy link
Contributor

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...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the commit 66c1585 has this change

This should be overridden by deneb imo and the root may need to change again...
I will resolve conflicts and then regenrate jsons and see what's going on

Comment on lines +72 to +77
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)),
}...,
Copy link
Contributor

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?

Copy link
Contributor

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

Copy link
Contributor

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

Copy link
Contributor

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...

Copy link
Contributor

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

Copy link
Contributor

@y0sher y0sher left a 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.

@GalRogozinski GalRogozinski mentioned this pull request Feb 5, 2024
5 tasks
return hex.EncodeToString(r[:])
// AllSorted returns ordered by signer array of signed messages
func (ps PartialSignatureContainer) AllSorted() []*types.SignedPartialSignatureMessage {
ret := make([]*types.SignedPartialSignatureMessage, 0)
Copy link
Contributor

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)

Copy link
Contributor

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 {
Copy link
Contributor

@moshe-blox moshe-blox Feb 13, 2024

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:

Suggested change
sort.Slice(ret, func(i, j int) bool {
ret := make([]*types.SignedPartialSignatureMessage, len(ps))
for i, m := range ps {
ret[i] = m
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why delete sort?

Copy link
Contributor

@moshe-blox moshe-blox Feb 13, 2024

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

Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants