in accord-core/src/main/java/accord/local/Commands.java [714:775]
private static boolean updateWaitingOn(SafeCommandStore safeStore, ICommand waiting, Timestamp waitingExecuteAt, Update waitingOn, SafeCommand dependencySafeCommand)
{
TxnId waitingId = waiting.txnId();
Command dependency = dependencySafeCommand.current();
Invariants.require(dependency.hasBeen(PreCommitted));
TxnId dependencyId = dependency.txnId();
if (waitingId.awaitsOnlyDeps() && dependency.known().isExecuteAtKnown() && dependency.executeAt().compareTo(waitingId) > 0)
waitingOn.updateExecuteAtLeast(waitingId, dependency.executeAt());
if (dependency.hasBeen(Truncated))
{
switch (dependency.saveStatus())
{
default: throw new AssertionError("Unhandled saveStatus: " + dependency.saveStatus());
case TruncatedApplyWithOutcome:
case TruncatedApply:
case TruncatedUnapplied:
Invariants.require(dependency.executeAt().compareTo(waitingExecuteAt) < 0
|| !dependencyId.witnesses(waitingId)
|| waitingId.awaitsOnlyDeps()
|| waiting.participants().stillWaitsOn().isEmpty()
|| !markStaleIfCannotExecute(dependencyId)
|| safeStore.redundantBefore().status(dependencyId, null,
waiting.partialDeps().participants(dependencyId)).all(LOCALLY_DEFUNCT)
);
case Vestigial:
case Erased:
logger.trace("{}: {} is truncated. Stop listening and removing from waiting on commit set.", waitingId, dependencyId);
break;
case Invalidated:
logger.trace("{}: {} is invalidated. Stop listening and removing from waiting on commit set.", waitingId, dependencyId);
}
return waitingOn.setAppliedOrInvalidated(dependencyId);
}
else if (dependency.executeAt().compareTo(waitingExecuteAt) > 0 && !waitingId.awaitsOnlyDeps())
{
// dependency cannot be a predecessor if it executes later
logger.trace("{}: {} executes after us. Removing from waiting on apply set.", waitingId, dependencyId);
return waitingOn.removeWaitingOn(dependencyId);
}
else if (dependency.hasBeen(Applied))
{
logger.trace("{}: {} has been applied. Removing from waiting on apply set.", waitingId, dependencyId);
return waitingOn.setAppliedAndPropagate(dependencyId, dependency.asCommitted().waitingOn());
}
else if (waitingOn.isWaitingOn(dependencyId))
{
safeStore.registerListener(dependencySafeCommand, SaveStatus.Applied, waitingId);
return false;
}
else
{
Participants<?> participants = waiting.partialDeps().participants(dependency.txnId());
Participants<?> waitsOn = participants.intersecting(waiting.participants().stillWaitsOn(), Minimal);
RedundantStatus status = safeStore.redundantBefore().status(dependencyId, waitingExecuteAt, waitsOn);
if (status.all(LOCALLY_DEFUNCT))
return false;
throw illegalState("We have a dependency (" + dependency + ") to wait on, but have already finished waiting (" + waiting + ")");
}
}