Strict Serializability Verifier may incorrectly handle blind writes when witnessed before the writing operation ACKs

patch by Benedict; reviewed by Alex Petrov for CASSANDRA-20905
This commit is contained in:
Benedict Elliott Smith 2025-09-15 21:34:15 +01:00
parent bf2c1c124e
commit c7de33c597
8 changed files with 12 additions and 12 deletions

4
.gitmodules vendored
View File

@ -1,4 +1,4 @@
[submodule "modules/accord"]
path = modules/accord
url = https://github.com/apache/cassandra-accord.git
branch = trunk
url = https://github.com/belliottsmith/cassandra-accord.git
branch = 20905-ssverifier

@ -1 +1 @@
Subproject commit 9c7f856c3e1f10c6f985495702edb844cfee2b80
Subproject commit ff4119fa45ad9700cfa94cd50b5cd4af9dd0b7a4

View File

@ -22,7 +22,7 @@ import javax.annotation.Nullable;
public interface HistoryValidator
{
Checker witness(int start, int end);
Checker witness(Object witnessedBy, int start, int end);
void print(@Nullable Integer pk);

View File

@ -37,7 +37,7 @@ public class LinearizabilityValidator implements HistoryValidator
}
@Override
public Checker witness(int start, int end)
public Checker witness(Object witnessedBy, int start, int end)
{
return new Checker()
{

View File

@ -35,11 +35,11 @@ public class LoggingHistoryValidator implements HistoryValidator
}
@Override
public Checker witness(int start, int end)
public Checker witness(Object witnessedBy, int start, int end)
{
StringBuilder sb = new StringBuilder();
sb.append("Witness(start=").append(start).append(", end=").append(end).append(")\n");
Checker sub = delegate.witness(start, end);
Checker sub = delegate.witness(witnessedBy, start, end);
return new Checker()
{
@Override

View File

@ -203,7 +203,7 @@ public class PairOfSequencesAccordSimulation extends AbstractPairOfSequencesPaxo
IntHashSet seen = new IntHashSet();
//TODO if there isn't a value then we get empty read, which then doesn't make it into the QueryResult
// given the fact that we always run with the partitions defined this should be fine
try (HistoryValidator.Checker checker = validator.witness(outcome.start, outcome.end))
try (HistoryValidator.Checker checker = validator.witness(outcome, outcome.start, outcome.end))
{
while (result.hasNext())
{

View File

@ -43,7 +43,7 @@ public class StrictSerializabilityValidator implements HistoryValidator
}
@Override
public Checker witness(int start, int end)
public Checker witness(Object witnessedBy, int start, int end)
{
verifier.begin();
return new Checker()
@ -63,7 +63,7 @@ public class StrictSerializabilityValidator implements HistoryValidator
@Override
public void close()
{
convertHistoryViolation(() -> verifier.apply("", start, end));
convertHistoryViolation(() -> verifier.apply(witnessedBy, start, end));
}
};
}

View File

@ -326,7 +326,7 @@ public class HistoryValidatorTest
{
String type = events.length == 1 ? "single" : "multiple";
logger.info("[Validator={}, Observation=({}, {}, {})] Validating {} {}}", validator.getClass().getSimpleName(), ob.id, ob.start, ob.end, type, events);
try (HistoryValidator.Checker check = validator.witness(ob.start, ob.end))
try (HistoryValidator.Checker check = validator.witness(ob, ob.start, ob.end))
{
for (Event e : events)
e.process(ob, check);
@ -477,7 +477,7 @@ public class HistoryValidatorTest
void process(HistoryValidator validator)
{
try (HistoryValidator.Checker check = validator.witness(start, end))
try (HistoryValidator.Checker check = validator.witness("", start, end))
{
for (Operation a : actions)
a.check(check);