Conversation
66f6113 to
6311754
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces helper utilities in the config package to support dynamic reconfiguration flows by deciding whether a node can apply a config update without an admin restart (and by detecting party eviction), plus a small helper to build a new Configuration from a config block.
Changes:
- Added
IsPartyEvicted/FindPartyhelpers for membership/eviction checks. - Added
IsNodeConfigChangeRestartRequiredto detect restart-required config changes (endpoint/TLS/sign cert). - Added
Configuration.BuildNewConfigurationand a new unit test file for the reconfig utilities.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
| config/reconfig.go | New exported utility functions/interfaces for eviction detection and restart-required decisions. |
| config/reconfig_test.go | New tests for the reconfig utilities. |
| config/config.go | Adds BuildNewConfiguration helper to construct a new config from a config block. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func TestIsNodeConfigChangeRestartRequired(t *testing.T) { | ||
| // Test Router | ||
| currRouterConfig := &protos.RouterNodeConfig{ |
There was a problem hiding this comment.
This test covers address/TLS/sign-cert changes, but it doesn't cover the error branches of IsNodeConfigChangeRestartRequired (nil args, type mismatch). Add test cases for these conditions to prevent regressions.
| consensusMetadata, err := ReadConsensusMetadataFromConfigBlock(block) | ||
| if err != nil { | ||
| return nil, errors.Errorf("failed applying new config, failed to read consensusMetadata from last config block, block number is %d", block.Header.Number) | ||
| } |
There was a problem hiding this comment.
BuildNewConfiguration uses block.Header.Number in the error message, but there is no nil check for block (or block.Header). Add validation up front to avoid panics if callers pass a nil/invalid block.
There was a problem hiding this comment.
True, first protect against a nil block, then,
True, protect against that, use block.GetHeader(),
| // BuildNewConfiguration builds a new configuration based on current configuration and block | ||
| func (config *Configuration) BuildNewConfiguration(block *common.Block) (*Configuration, error) { | ||
| if config == nil { | ||
| return nil, errors.New("failed applying new config, current configuration is nil") | ||
| } |
There was a problem hiding this comment.
BuildNewConfiguration is new behavior in config/config.go, but there are no tests exercising it. Please add unit tests for the success case and failure cases (e.g., invalid block / unmarshal error).
0f26370 to
0c5aaea
Compare
Signed-off-by: May.Buzaglo <May.Buzaglo@ibm.com>
Signed-off-by: May.Buzaglo <May.Buzaglo@ibm.com>
0c5aaea to
cc803de
Compare
| consensusMetadata, err := ReadConsensusMetadataFromConfigBlock(block) | ||
| if err != nil { | ||
| return nil, errors.Errorf("failed applying new config, failed to read consensusMetadata from last config block, block number is %d", block.Header.Number) | ||
| } |
There was a problem hiding this comment.
True, first protect against a nil block, then,
True, protect against that, use block.GetHeader(),
| // BuildNewConfiguration builds a new configuration based on current configuration and block | ||
| func (config *Configuration) BuildNewConfiguration(block *common.Block) (*Configuration, error) { | ||
| if config == nil { | ||
| return nil, errors.New("failed applying new config, current configuration is nil") | ||
| } |
| // FindParty returns the PartyConfig associated with the given partyID from the shared configuration. | ||
| // It returns nil if the party is not found and returns error if the provided configuration is nil or incomplete. | ||
| func FindParty(partyID types.PartyID, config *Configuration) (*config_protos.PartyConfig, error) { |
| type NodeConfig interface { | ||
| GetHost() string | ||
| GetPort() uint32 | ||
| GetTlsCert() []byte | ||
| } | ||
|
|
||
| type NodeConfigWithSign interface { | ||
| NodeConfig | ||
| GetSignCert() []byte | ||
| } |
There was a problem hiding this comment.
document how this will be used, reference the protos
There was a problem hiding this comment.
Explicitly say, router and assembler are.... consenter and batcher are... etc
| newConfig := &Configuration{ | ||
| LocalConfig: config.LocalConfig, | ||
| SharedConfig: &protos.SharedConfig{}, | ||
| } |
There was a problem hiding this comment.
move that next to where you use it, below
| SharedConfig: &protos.SharedConfig{}, | ||
| } | ||
|
|
||
| consensusMetadata, err := ReadConsensusMetadataFromConfigBlock(block) |
There was a problem hiding this comment.
There must be a utility that returns func myFunc(block) (*protos.SharedConfig, error) somewhere...
| if currOK && !bytes.Equal(extendedCurrConfig.GetSignCert(), extendedNewConfig.GetSignCert()) { | ||
| return true, nil | ||
| } |
There was a problem hiding this comment.
Leave a comment that we may need to match the public key, so that we can do dynamic instead of restart in some cases when the private key & public key do not change
| // - sign certificate (this is checked if both configs implement NodeConfigWithSign) | ||
| // | ||
| // Both arguments must represent the same node type and be non-nil. | ||
| func IsNodeConfigChangeRestartRequired(currentConfig, newConfig NodeConfig) (bool, error) { |
There was a problem hiding this comment.
add a logger to the function and log what you find with Info, super useful
| func TestIsNodeConfigChangeRestartRequired(t *testing.T) { | ||
| // Test Router | ||
| currRouterConfig := &protos.RouterNodeConfig{ |
This PR adds utility functions to determine whether an admin restart is required.
Relevant issues #442 #504 #487 #445