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

feat(blockManager): refactor and use state as single source of truth for height #847

Merged

Conversation

mtsitrin
Copy link
Contributor

@mtsitrin mtsitrin commented May 12, 2024

Main changes:

  • using m.State.NextHeight() instead of Store.Height() + 1 as the expected next height
  • UpdateStateFromResponses was renamed to NextValSetFromResponses as that what it actually does
    • ConsensusParams should be treated separately
  • consolidate the state update flow, in the happy flow and the post-commit failure scenario
  • gossip related code moved to gossip.go
  • updateState methods moved to state.go

PR Standards

Opening a pull request should be able to meet the following requirements


Close #330
Close #634

<-- Briefly describe the content of this pull request -->

For Author:

  • Targeted PR against correct branch
  • included the correct type prefix in the PR title
  • Linked to Github issue with discussion and accepted design
  • Targets only one github issue
  • Wrote unit and integration tests
  • All CI checks have passed
  • Added relevant godoc comments

For Reviewer:

  • confirmed the correct type prefix in the PR title
  • Reviewers assigned
  • confirmed all author checklist items have been addressed

After reviewer approval:

  • In case targets main branch, PR should be squashed and merged.
  • In case PR targets a release branch, PR should be rebased.

@mtsitrin mtsitrin linked an issue May 12, 2024 that may be closed by this pull request
@danwt danwt marked this pull request as ready for review May 13, 2024 11:40
@danwt danwt requested a review from a team as a code owner May 13, 2024 11:40
@danwt danwt marked this pull request as draft May 13, 2024 11:40
@danwt danwt marked this pull request as ready for review May 13, 2024 11:47
Copy link
Contributor

@danwt danwt 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 but I've a coupel questions

  1. Why move the kv interfaces to store? Generally interfaces should be on consumer side, not producer side. (Return concrete types, accept interfaces)
  2. What is the purpose of adding the from param to pruning? It seems to complicate without benefit

block/gossip.go Outdated
Comment on lines 35 to 62
func (m *Manager) attemptApplyCachedBlocks() error {
m.retrieverMutex.Lock()
defer m.retrieverMutex.Unlock()

for {
expectedHeight := m.State.NextHeight()

cachedBlock, blockExists := m.blockCache[expectedHeight]
if !blockExists {
break
}
if err := m.validateBlock(cachedBlock.Block, cachedBlock.Commit); err != nil {
delete(m.blockCache, cachedBlock.Block.Header.Height)
/// TODO: can we take an action here such as dropping the peer / reducing their reputation?
return fmt.Errorf("block not valid at height %d, dropping it: err:%w", cachedBlock.Block.Header.Height, err)
}

err := m.applyBlock(cachedBlock.Block, cachedBlock.Commit, blockMetaData{source: gossipedBlock})
if err != nil {
return fmt.Errorf("apply cached block: expected height: %d: %w", expectedHeight, err)
}
m.logger.Debug("applied cached block", "height", expectedHeight)

delete(m.blockCache, cachedBlock.Block.Header.Height)
}

return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should keep this in manager.go because it's used not only in gossip

Copy link
Contributor Author

Choose a reason for hiding this comment

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

where else it is used?

Copy link
Contributor

Choose a reason for hiding this comment

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

in syncUntilTarget
you can check usages in IDE

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved back

block/manager_test.go Outdated Show resolved Hide resolved
block/produce.go Outdated Show resolved Hide resolved
block/retriever.go Outdated Show resolved Hide resolved
block/state.go Outdated Show resolved Hide resolved
store/pruning.go Outdated Show resolved Hide resolved
@mtsitrin
Copy link
Contributor Author

What is the purpose of adding the from param to pruning? It seems to complicate without benefit

The store doesn't manage base/latest heights anymore

Copy link
Contributor

@omritoptix omritoptix left a comment

Choose a reason for hiding this comment

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

great work! minor comments.

Validators: validatorSet,
LastValidators: types.NewValidatorSet(nil),
NextValidators: types.NewValidatorSet(nil),
Validators: types.NewValidatorSet(nil),
LastHeightValidatorsChanged: genDoc.InitialHeight,
Copy link
Contributor

Choose a reason for hiding this comment

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

doesn't look like this param is being used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

all the validators related logic will be refactored
currently it's static and not changing at all

Validators: validatorSet,
LastValidators: types.NewValidatorSet(nil),
NextValidators: types.NewValidatorSet(nil),
Validators: types.NewValidatorSet(nil),
LastHeightValidatorsChanged: genDoc.InitialHeight,

ConsensusParams: *genDoc.ConsensusParams,
LastHeightConsensusParamsChanged: genDoc.InitialHeight,
Copy link
Contributor

Choose a reason for hiding this comment

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

doesn't look like this param is being used

types/state.go Outdated

// SetBase sets the base height if it is higher than the existing base height
// returns OK if the value was updated successfully or did not need to be updated
func (s *State) SetBase(height uint64) {
Copy link
Contributor

Choose a reason for hiding this comment

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

method not being used (though it can be used as we do set the BaseHeight in pruning.go)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wrapped Height as it's atomic and being used all over
the base is only for pruning. I've removed the getter

types/state.go Outdated
}

// Base returns height of the earliest block saved in the Store.
func (s *State) Base() uint64 {
Copy link
Contributor

Choose a reason for hiding this comment

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

method not being used (though it can be used as we do get the BaseHeight in pruning.go)

block/block.go Outdated
newState.BaseHeight = m.Store.Base()

_, err = m.Store.UpdateState(newState, nil)
_ = m.Executor.UpdateStateAfterCommit(m.State, responses, appHash, block.Header.Height, validators)
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we return the state here and ignore it vs not returning state at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i'll remove the state return var

block/produce.go Outdated
} else {
height := m.Store.Height()
newHeight = height + 1
if !m.State.IsGenesis() {
Copy link
Contributor

Choose a reason for hiding this comment

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

as this if will be entered basically 100% of the times thinking if it would be cleaner to have a produceGenesisBlock and have part of the produceBlock code reusable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

refactored it a bit, take a look

@mtsitrin mtsitrin requested review from omritoptix and danwt May 15, 2024 07:44
@danwt
Copy link
Contributor

danwt commented May 15, 2024

there are conflicts

Copy link
Contributor

@danwt danwt left a comment

Choose a reason for hiding this comment

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

Just requested a few small refactors, including moving attemptApplyCachedBlocks() out of gossip file

block/produce.go Outdated Show resolved Hide resolved
block/pruning.go Outdated Show resolved Hide resolved
Comment on lines +107 to +112
// NextValSetFromResponses updates state based on the ABCIResponses.
func (e *Executor) NextValSetFromResponses(state *types.State, resp *tmstate.ABCIResponses, block *types.Block) (*tmtypes.ValidatorSet, error) {
// Dymint ignores any setValidator responses from the app, as it is manages the validator set based on the settlement consensus
// TODO: this will be changed when supporting multiple sequencers from the hub
validatorUpdates := []*tmtypes.Validator{}
return state.NextValidators.Copy(), nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Please inline this at all callsite: the resp and block aren't used, and it's a one liner returning error

store/pruning.go Outdated Show resolved Hide resolved
Comment on lines +9 to 11
if from <= 0 {
return 0, fmt.Errorf("from height must be greater than 0")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

seems like a usess branch since if we try to fetch h=0 it will just continue

continue

store/storeIface.go Show resolved Hide resolved
store/storeIface.go Show resolved Hide resolved
store/storeIface.go Show resolved Hide resolved
types/state.go Show resolved Hide resolved
@mtsitrin mtsitrin requested a review from danwt May 15, 2024 14:08
@mtsitrin
Copy link
Contributor Author

@danwt I'll leave further renames to other prs

@danwt
Copy link
Contributor

danwt commented May 15, 2024

ok fine re renames
when package changes it can require a rename
Btw, will you inline NextValSetFromResponses?

@mtsitrin
Copy link
Contributor Author

ok fine re renames when package changes it can require a rename Btw, will you inline NextValSetFromResponses?

not planned, will be refactored quite soon anyway

@mtsitrin mtsitrin merged commit 73aae62 into main May 15, 2024
6 checks passed
@mtsitrin mtsitrin deleted the mtsitrin/634-refactor-use-state-as-single-source-of-truth branch May 15, 2024 18:03
omritoptix pushed a commit that referenced this pull request May 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants