in accord-core/src/main/java/accord/messages/Accept.java [100:182]
public AcceptReply apply(SafeCommandStore safeStore)
{
StoreParticipants participants = StoreParticipants.update(safeStore, scope, minEpoch, txnId, txnId.epoch(), executeAt.epoch());
SafeCommand safeCommand = safeStore.get(txnId, participants);
AcceptOutcome outcome = Commands.accept(safeStore, safeCommand, participants, txnId, kind, ballot, scope, executeAt, partialDeps);
switch (outcome)
{
default: throw new UnhandledEnum(outcome);
case Redundant:
case Truncated:
{
Command command = safeCommand.current();
boolean notOwner = participants.owns().isEmpty();
Participants<?> hasDeps = null;
Deps deps = null;
if (command.known().is(DepsKnown) && (isPartialAccept || notOwner))
{
deps = command.partialDeps().asFullUnsafe();
hasDeps = command.participants().stillTouches();
}
Ballot superseding = command.promised();
if (superseding.compareTo(ballot) <= 0)
superseding = null;
boolean calculateDeps = isPartialAccept;
if (command.saveStatus() == SaveStatus.Vestigial)
{
superseding = null;
outcome = Success;
calculateDeps = true;
}
if (calculateDeps)
{
Participants<?> calculate = participants.touches();
if (hasDeps != null)
calculate = calculate.without(hasDeps);
if (!calculate.isEmpty())
{
Deps calculatedDeps = DepsCalculator.calculateDeps(safeStore, txnId, calculate, minEpoch, executeAt, true);
if (calculatedDeps == null)
return AcceptReply.inThePast(ballot, participants, command);
deps = deps == null ? calculatedDeps : calculatedDeps.with(deps);
}
hasDeps = participants.touches();
}
Participants<?> successful = isPartialAccept ? hasDeps : null;
if (notOwner && (outcome == Redundant || (hasDeps != null && hasDeps.containsAll(participants.touches()))))
outcome = Success;
return new AcceptReply(outcome, superseding, successful, deps, command.executeAtIfKnown());
}
case RejectedBallot:
return new AcceptReply(safeCommand.current().promised());
case Retired:
// if we're Retired, participants.owns() is empty, so we're just fetching deps
// TODO (desired): optimise deps calculation; for some keys we only need to return the last RX
case Success:
ExecuteFlags flags;
Deps deps;
try (DepsCalculator calculator = new DepsCalculator())
{
deps = calculator.calculate(safeStore, txnId, participants, minEpoch, executeAt, true);
if (deps == null)
return AcceptReply.inThePast(ballot, participants, safeCommand.current());
flags = calculator.executeFlags(txnId);
}
Invariants.require(deps.maxTxnId(txnId).epoch() <= executeAt.epoch());
if (filterDuplicateDependenciesFromAcceptReply())
deps = deps.without(this.partialDeps);
Participants<?> successful = isPartialAccept ? participants.touches() : null;
return new AcceptReply(successful, deps, flags);
}
}