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

[EFM] EpochCommit is backward compatible #6795

Merged

Conversation

durkmurder
Copy link
Member

#6785

Context

This PR fixes code paths that are relying on changes to the EpochCommit which were introduced in EFM workstream. In order to support protocol upgrade without spork we need to ensure that our new software version supports both data models (v0 and v1).

This PR modifies existing logic to use v0 behavior for v0 data models. Majority of logic still relies on new representation of flow.EpochCommit with the flow.DKGIndexMap field. However if flow.DKGIndexMap = nil we will use pre-upgrade logic to follow the protocol, otherwise we use new rules.

I have created multiple TODOs in next format: TODO(EFM, #6794) that needs to be removed after performing the upgrade, when we decide that we don't want to support v0 anymore.

@codecov-commenter
Copy link

codecov-commenter commented Dec 10, 2024

Codecov Report

Attention: Patch coverage is 67.96117% with 99 lines in your changes missing coverage. Please review.

Project coverage is 41.72%. Comparing base (c7c7e5a) to head (92ec89a).

Files with missing lines Patch % Lines
model/convert/service_event.go 44.82% 35 Missing and 13 partials ⚠️
utils/unittest/service_events_fixtures.go 71.42% 34 Missing and 2 partials ⚠️
state/protocol/validity.go 59.09% 6 Missing and 3 partials ⚠️
state/protocol/inmem/dkg.go 90.90% 1 Missing and 2 partials ⚠️
storage/badger/operation/epoch.go 0.00% 2 Missing ⚠️
state/protocol/inmem/epoch.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                   Coverage Diff                    @@
##           feature/efm-recovery    #6795      +/-   ##
========================================================
+ Coverage                 41.68%   41.72%   +0.03%     
========================================================
  Files                      2033     2033              
  Lines                    180749   181036     +287     
========================================================
+ Hits                      75341    75529     +188     
- Misses                    99204    99283      +79     
- Partials                   6204     6224      +20     
Flag Coverage Δ
unittests 41.72% <67.96%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@jordanschalm jordanschalm 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!


Additional comments largely unrelated to this PR 👇

While reviewing this PR, I noticed another area where we are not currently backward-compatible. The submission of the final result now includes the DKG index map, but this depends on the FlowDKG smart contract being updated.

We can add backward-compatibility logic to the result submission step, based on the protocol version. However, doing this means that we must coordinate the protocol upgrade and the smart contract upgrade within the same epoch phase. Previously we discussed how implementing backward-compatibility would allow us to decouple the protocol upgrade and the smart contract upgrade; because of the result submission, I think they will need to be coupled.

state/protocol/inmem/dkg.go Outdated Show resolved Hide resolved
storage/badger/epoch_commits_test.go Outdated Show resolved Hide resolved
}
}

func (commit *epochCommitV0) MarshalMsgpack() ([]byte, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, so we added the DKGIndexMap to Mainnet26 (current network) so that we would not have a data model change at the Protocol HCU (just nil vs non-nil values). But the encodableFromCommit wrapper made it so that the DKGIndexMap field was excluded when persisting data to storage anyway. 😬

I guess that's why you added this test with the EpochCommit type without a DKGIndexMap field.

In the end, adding the nil DKGIndexMap field wouldn't have made a difference anyway (even if it was included in the encoding). Reading an encoded value with a nil field X is equivalent to reading a value without any field X: in either case the decoded struct has a nil X field.

Copy link
Member

@AlexHentschel AlexHentschel left a comment

Choose a reason for hiding this comment

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

Very nice, clean code. Thank you for the very thorough tests

Comment on lines +155 to +162
v1 := unittest.EpochCommitFixture()
v0 := &epochCommitV0{
Counter: v1.Counter,
ClusterQCs: v1.ClusterQCs,
DKGGroupKey: v1.DKGGroupKey,
DKGParticipantKeys: v1.DKGParticipantKeys,
}
require.Equal(t, v0.ID(), v1.ID())
Copy link
Member

Choose a reason for hiding this comment

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

for a second, I was confused why these two would have the same ID ... until I realized that unittest.EpochCommitFixture() returns a v1 data structure, but sill leaves DKGIndexMap as nil.

I think it would be good to eventually have EpochCommitFixture() return a properly instantiated Epoch Commit. But we don't have to do it in this PR

Copy link
Member Author

Choose a reason for hiding this comment

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

The problem is we can create only an non-empty DKGIndexMap but not a valid one since EpochCommitFixture doesn't know anything about participants unless we require that caller needs to be pass participants for each call.

model/convert/service_event.go Outdated Show resolved Hide resolved
model/convert/service_event.go Outdated Show resolved Hide resolved
state/protocol/inmem/dkg.go Outdated Show resolved Hide resolved
state/protocol/inmem/dkg_test.go Outdated Show resolved Hide resolved
state/protocol/validity.go Outdated Show resolved Hide resolved
state/protocol/validity_test.go Outdated Show resolved Hide resolved
durkmurder and others added 3 commits December 16, 2024 13:37
Co-authored-by: Alexander Hentschel <alex.hentschel@flowfoundation.org>
Co-authored-by: Jordan Schalm <jordan.schalm@flowfoundation.org>
@durkmurder durkmurder merged commit b1b6523 into feature/efm-recovery Dec 16, 2024
55 checks passed
@durkmurder durkmurder deleted the yurii/6785-dkg-index-map-backward-compatible branch December 16, 2024 12:35
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.

4 participants