Bugfix: more correct for inner->outer sanity transition
This commit is contained in:
parent
1e5d58b22d
commit
e79265228e
1 changed files with 49 additions and 10 deletions
|
@ -1164,17 +1164,15 @@ react_to_env_A29(Retries, P_latest, LatestUnanimousP, ReadExtra,
|
||||||
#projection_v1{author_server=Author_latest} = P_latest,
|
#projection_v1{author_server=Author_latest} = P_latest,
|
||||||
{Epoch_latest,_} = EpochID_latest = machi_projection:get_epoch_id(P_latest),
|
{Epoch_latest,_} = EpochID_latest = machi_projection:get_epoch_id(P_latest),
|
||||||
Trigger = if CMode == cp_mode, EpochID_latest /= EpochID_current ->
|
Trigger = if CMode == cp_mode, EpochID_latest /= EpochID_current ->
|
||||||
?REACT({a29, ?LINE,
|
|
||||||
[{epoch_id_latest,EpochID_latest},
|
|
||||||
{epoch_id_current,EpochID_current}]}),
|
|
||||||
true;
|
true;
|
||||||
true ->
|
true ->
|
||||||
?REACT({a29, ?LINE, []}),
|
|
||||||
false
|
false
|
||||||
end,
|
end,
|
||||||
if Trigger ->
|
if Trigger ->
|
||||||
?REACT({a29, ?LINE,
|
?REACT({a29, ?LINE,
|
||||||
[{old_current, machi_projection:make_summary(P_current)}]}),
|
[{epoch_id_latest,EpochID_latest},
|
||||||
|
{epoch_id_current,EpochID_current},
|
||||||
|
{old_current, machi_projection:make_summary(P_current)}]}),
|
||||||
if Epoch_latest >= Epoch_current orelse Epoch_latest == 0 orelse
|
if Epoch_latest >= Epoch_current orelse Epoch_latest == 0 orelse
|
||||||
P_current#projection_v1.upi == [] ->
|
P_current#projection_v1.upi == [] ->
|
||||||
ok; % sanity check
|
ok; % sanity check
|
||||||
|
@ -2572,14 +2570,14 @@ projection_transition_is_sane(P1, P2, RelativeToServer) ->
|
||||||
projection_transition_is_sane(P1, P2, RelativeToServer, RetrospectiveP) ->
|
projection_transition_is_sane(P1, P2, RelativeToServer, RetrospectiveP) ->
|
||||||
put(myname, RelativeToServer),
|
put(myname, RelativeToServer),
|
||||||
put(why2, []),
|
put(why2, []),
|
||||||
|
HasInner1 = inner_projection_exists(P1),
|
||||||
|
HasInner2 = inner_projection_exists(P2),
|
||||||
|
Inner1 = inner_projection_or_self(P1),
|
||||||
|
Inner2 = inner_projection_or_self(P2),
|
||||||
case projection_transition_is_sane_with_si_epoch(
|
case projection_transition_is_sane_with_si_epoch(
|
||||||
P1, P2, RelativeToServer, RetrospectiveP) of
|
P1, P2, RelativeToServer, RetrospectiveP) of
|
||||||
true ->
|
true ->
|
||||||
HasInner1 = inner_projection_exists(P1),
|
|
||||||
HasInner2 = inner_projection_exists(P2),
|
|
||||||
if HasInner1 orelse HasInner2 ->
|
if HasInner1 orelse HasInner2 ->
|
||||||
Inner1 = inner_projection_or_self(P1),
|
|
||||||
Inner2 = inner_projection_or_self(P2),
|
|
||||||
if HasInner1 orelse HasInner2 ->
|
if HasInner1 orelse HasInner2 ->
|
||||||
%% In case of transition with inner projections, we
|
%% In case of transition with inner projections, we
|
||||||
%% must allow the epoch number to remain constant.
|
%% must allow the epoch number to remain constant.
|
||||||
|
@ -2590,6 +2588,7 @@ projection_transition_is_sane(P1, P2, RelativeToServer, RetrospectiveP) ->
|
||||||
projection_transition_is_sane_except_si_epoch(
|
projection_transition_is_sane_except_si_epoch(
|
||||||
Inner1, Inner2, RelativeToServer, RetrospectiveP)));
|
Inner1, Inner2, RelativeToServer, RetrospectiveP)));
|
||||||
true ->
|
true ->
|
||||||
|
exit(delete_this_inner_clause_impossible_with_two_identical_nested_if_clauses),
|
||||||
?RETURN2(
|
?RETURN2(
|
||||||
projection_transition_is_sane_final_review(P1, P2,
|
projection_transition_is_sane_final_review(P1, P2,
|
||||||
projection_transition_is_sane_with_si_epoch(
|
projection_transition_is_sane_with_si_epoch(
|
||||||
|
@ -2600,7 +2599,32 @@ projection_transition_is_sane(P1, P2, RelativeToServer, RetrospectiveP) ->
|
||||||
?RETURN2(true))
|
?RETURN2(true))
|
||||||
end;
|
end;
|
||||||
Else ->
|
Else ->
|
||||||
|
if HasInner1 and (not HasInner2) ->
|
||||||
|
%% OK, imagine that we used to be flapping but now we've
|
||||||
|
%% stopped flapping.
|
||||||
|
%%
|
||||||
|
%% P1 = outer = upi=[a,d,e],repairing=[] epoch 870
|
||||||
|
%% inner = upi=[a,e,d],repairing=[] epoch 605
|
||||||
|
%% to
|
||||||
|
%% P2 = outer = upi=[a,e,d],repairing=[] epoch 875
|
||||||
|
%% inner = undefined
|
||||||
|
%%
|
||||||
|
%% Everyone is using the inner projection [a,e,d],[],
|
||||||
|
%% everyone thinks that that is OK. It has been in use
|
||||||
|
%% for a while now.
|
||||||
|
%%
|
||||||
|
%% Now there's a new epoch, e875 that is saying that we
|
||||||
|
%% should transition from inner e605 [a,e,d],[] -> outer
|
||||||
|
%% e875 [a,e,d],[] This is SAFE! The UPI is the *same*.
|
||||||
|
%%
|
||||||
|
%% Verify this Inner1->P2 transition, including SI epoch
|
||||||
|
?RETURN2(
|
||||||
|
projection_transition_is_sane_final_review(P1, P2,
|
||||||
|
projection_transition_is_sane_with_si_epoch(
|
||||||
|
Inner1, P2, RelativeToServer, RetrospectiveP)));
|
||||||
|
true ->
|
||||||
?RETURN2(Else)
|
?RETURN2(Else)
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
projection_transition_is_sane_final_review(
|
projection_transition_is_sane_final_review(
|
||||||
|
@ -2774,6 +2798,21 @@ projection_transition_is_sane_except_si_epoch(
|
||||||
%% We won't check the checksum of P1, but we will of P2.
|
%% We won't check the checksum of P1, but we will of P2.
|
||||||
P2 = machi_projection:update_checksum(P2),
|
P2 = machi_projection:update_checksum(P2),
|
||||||
|
|
||||||
|
%% CP mode extra sanity checks
|
||||||
|
if CMode1 == cp_mode ->
|
||||||
|
Majority = full_majority_size(All_list2),
|
||||||
|
if length(UPI_list2) == 0 ->
|
||||||
|
ok; % none projection
|
||||||
|
length(UPI_list2) >= Majority ->
|
||||||
|
%% We have at least one non-witness
|
||||||
|
true = (length(UPI_list2 -- Witness_list2) > 0);
|
||||||
|
true ->
|
||||||
|
error({majority_not_met, UPI_list2})
|
||||||
|
end;
|
||||||
|
CMode1 == ap_mode ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
|
||||||
%% Hooray, all basic properties of the projection's elements are
|
%% Hooray, all basic properties of the projection's elements are
|
||||||
%% not obviously bad. Now let's check if the UPI+Repairing->UPI
|
%% not obviously bad. Now let's check if the UPI+Repairing->UPI
|
||||||
%% transition is good.
|
%% transition is good.
|
||||||
|
|
Loading…
Reference in a new issue