public AcceptReply apply()

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);
        }
    }