Вы не можете решить эту проблему, не изменив серверную часть, потому что, как отмечалось во всех других ответах, проблема именно в этом. Кроме того, не будет подходящего протокола, который не включает изменение серверной части.
Вполне уместно сравнить это с человеком у банковского прилавка. Этот человек представил работнику банка некоторые учетные данные, которые подтверждают, кто она и что она действительно владеет какой-то учетной записью X. Это логин.
Теперь человек хочет заказать перевод со счета X на Y. Все, что она скажет о доступных средствах, не имеет значения. Если она представит подписанный документ президента банка, в котором говорится, что у нее достаточно средств, банку все равно придется проверить, прежде чем перевод будет сделан, потому что деньги просто должны быть там.
Это означает, что даже если вы добавите в протокол логику безопасной последовательности, которая гарантирует, что EnoughFunds был вызван перед «Transfer» и вызван только один раз, и не так давно, и с правильными параметрами, это все еще клиент говорит банку "все нормально, у меня достаточно средств". Который просто не собирается сокращать это, когда-либо.
Самое близкое, что вы могли бы получить - это эквивалент банковского клиента, наклонившегося над прилавком, указывающего на экран сотрудника и говорящего: «Посмотрите, в вашей системе , он говорит, что транзакция может быть выполнена» потому что средств достаточно ", т.е. е. клиент может достоверно воспроизводить время, ввод и вывод вызова EnoughFunds, который сервер только что сделал , что нормально, но совершенно бессмысленно.
Итак, решение состоит в том, чтобы перевести EnoughFunds на внутренний счет, период . Если клиенту необходимо знать, вы можете вернуть описательное исключение / ошибку, если средств недостаточно.
(источник: userfriendly.org )