We currently validate configuration changes at proposal time
|
for i := range m.Entries { |
|
e := &m.Entries[i] |
|
var cc pb.ConfChangeI |
|
if e.Type == pb.EntryConfChange { |
|
var ccc pb.ConfChange |
|
if err := ccc.Unmarshal(e.Data); err != nil { |
|
panic(err) |
|
} |
|
cc = ccc |
|
} else if e.Type == pb.EntryConfChangeV2 { |
|
var ccc pb.ConfChangeV2 |
|
if err := ccc.Unmarshal(e.Data); err != nil { |
|
panic(err) |
|
} |
|
cc = ccc |
|
} |
|
if cc != nil { |
|
alreadyPending := r.pendingConfIndex > r.raftLog.applied |
|
alreadyJoint := len(r.prs.Config.Voters[1]) > 0 |
|
wantsLeaveJoint := len(cc.AsV2().Changes) == 0 |
|
|
|
var refused string |
|
if alreadyPending { |
|
refused = fmt.Sprintf("possible unapplied conf change at index %d (applied to %d)", r.pendingConfIndex, r.raftLog.applied) |
|
} else if alreadyJoint && !wantsLeaveJoint { |
|
refused = "must transition out of joint config first" |
|
} else if !alreadyJoint && wantsLeaveJoint { |
|
refused = "not in joint state; refusing empty conf change" |
|
} |
|
|
|
if refused != "" { |
|
r.logger.Infof("%x ignoring conf change %v at config %s: %s", r.id, cc, r.prs.Config, refused) |
|
m.Entries[i] = pb.Entry{Type: pb.EntryNormal} |
|
} else { |
|
r.pendingConfIndex = r.raftLog.lastIndex() + uint64(i) + 1 |
|
} |
|
} |
This is not very helpful because it has false positives (refusing a config change that is actually allowed) though at least it currently doesn't have false negatives (because the set of false positives is sufficiently large 😄)
It could be more effective to either compare against the actual most recent config change in the (including the unstable) log, or to move the verification to apply time (i.e. erroring out conf changes that are illegal).
See #81.
We currently validate configuration changes at proposal time
raft/raft.go
Lines 1224 to 1260 in 4abd9e9
This is not very helpful because it has false positives (refusing a config change that is actually allowed) though at least it currently doesn't have false negatives (because the set of false positives is sufficiently large 😄)
It could be more effective to either compare against the actual most recent config change in the (including the unstable) log, or to move the verification to apply time (i.e. erroring out conf changes that are illegal).
See #81.