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

native: prevent improper Neo cache invalidation #3279

Merged
merged 2 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions pkg/consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,12 +681,12 @@ func (s *service) getValidators(txes ...block.Transaction) []crypto.PublicKey {
// block's validators, thus should return validators from the current
// epoch without recalculation.
pKeys, err = s.Chain.GetNextBlockValidators()
} else {
// getValidators with non-empty args is used by dbft to fill block's
// NextConsensus field, ComputeNextBlockValidators will return proper
// value for NextConsensus wrt dBFT epoch start/end.
pKeys = s.Chain.ComputeNextBlockValidators()
}
// getValidators with non-empty args is used by dbft to fill block's
// NextConsensus field, but NeoGo doesn't provide WithGetConsensusAddress
// callback and fills NextConsensus by itself via WithNewBlockFromContext
// callback. Thus, leave pKeys empty if txes != nil.

if err != nil {
s.log.Error("error while trying to get validators", zap.Error(err))
}
Expand Down Expand Up @@ -727,6 +727,16 @@ func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
block.PrevStateRoot = sr.Root
}

// ComputeNextBlockValidators returns proper set of validators wrt dBFT epochs
// boundary. I.e. for the last block in the dBFT epoch this method returns the
// list of validators recalculated from the latest relevant information about
// NEO votes; in this case list of validators may differ from the one returned
// by GetNextBlockValidators. For the not-last block of dBFT epoch this method
// returns the same list as GetNextBlockValidators. Note, that by this moment
// we must be sure that previous block was successfully persisted to chain
// (i.e. PostPersist was completed for native Neo contract and PostPersist
// execution cache was persisted to s.Chain's DAO), otherwise the wrong
// (outdated, relevant for the previous dBFT epoch) value will be returned.
var validators = s.Chain.ComputeNextBlockValidators()
script, err := smartcontract.CreateDefaultMultiSigRedeemScript(validators)
if err != nil {
Expand Down
1 change: 0 additions & 1 deletion pkg/core/native/native_neo.go
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,6 @@ func (n *NEO) ModifyAccountVotes(acc *state.NEOBalance, d *dao.Simple, value *bi
return nil
}
}
cache.newEpochNextValidators = nil
return putConvertibleToDAO(n.ID, d, key, cd)
}
return nil
Expand Down
Loading