Проблема экспорта токенов с контрактом

При прикручивании и тестировании нового сервиса от юниверсы который позволяет заранее рассчитать стоимость операции и гарантировано провести ее с этой стоимостью возникла серьезная проблема, связанная с со спецификой биржи в версии 1.

Сервис юниверсы рассчитан на клиентов, которые используют токены (гипертокены) юниверсы, он принимает на входт токен, который пользователь хочет экспортировать, и формирует для него счет-контракт, который клиент может подписать, добавить туда определенную контрактом сумму оплаты операции, и отправить в юниверсу на исполнение.

У этой схем очень много плюсов, и с биржей в2 оно бы работало на ура, но с биржей версии 1 этот подход вызывает очень большую проблему:

Проблема: предварительное резервирование гипертокена

На бирже имеется общий кошелек с гипертокенами, который используют при экспорте и импорте все счета клиентов. Это позволяет не переводить собственно токены между ключами клиентов (которых в в1 просто нет) и не тратить деньги и время на такие операции. В рещультате операции над счетами крайне быстры.

Однако, при экспорте возникает необходимость предварительного резервирования токена для формирования счет-контракта. Счет-контракт принимает на вход экспортируемый токен. Так как в обменнике юниверсы счет-контракт включает токен, который будет жкспортироваться. Поскольку кошелек системы состоит из электронных монет разного достоинства, это означает, в общем случае все расходные операции по кошельку экспорта и кошельку оплаты экспорта необходимо остановить пока поользователь не подпишет счет-контракт, и можно будет провести операцию. Типичная операция платежа с кошелька с электронными монетами имеет видд In1 + In2 +...+Inx = Out1 + Out2, где In - активные монеты обзем достоинством больше суммы платежа, Out1 - платеж и Out2 - остаток, если есть. Таким образом, когда мы создаем счет-контракт, мы должны заблокировать монеты In1..Inx пока пользователь не подпишет контракт или не откажется от него, либо не пройдет какой то таймаут.

Если же эти монеты будут использованы в какой то другой операции, то данная операция вылетит с ошибкой, так как монеты будут уже истрачены.

Блокировать только использованные в экспорте монеты не момогает - несоклько одновременных запросов на начало экспорта все равно заблокируют весь расходный кошелек. Просто 10 человек нажмут на кнопку экспорта - и все встанет пока не пройдет таймаут. Получается уязвимость - несколько намеренных или случайных незавершенных операций жкспорта, когда контракт создан, но подвтреждения нет, парализует все исходящие операции.

Другой вариант еще хуже - можо выделить две монеты на экспорт и оплату, зарегистировать их в юниверсе, и тогда можно будет блокиротаь только эти две монеты.

То есть, перед тем как строить счет-контракт, можно выполнить траназкцию In... => Out1, Out2 и зарегистировать ее в юниверсе. Тогда получается что мы блокируем только монету Out1, а Out2 остается свободной для исходящих операций.

Но тогда получаетсях что операция подготовки контракта сама по себе стоит 1 или 2 цента, независимо, согласится пользователь или нет, и точно так же можно назапускать много экспортов и заблокировать существенную часть кошелька. От этого можно пытаться защищаться отслеживая операции для каждой учетки пользователя, но все равно платная и долгая операция подготовки контракт-счета никуда не денется.

Собственно именно эта неразбериха, которая возникает, когда часть монет предполагается в одну расходную операцию, а часть в другую, и вызвала такой большой лаг по разработке; к сожалению, пока я болел, я не мог понять что происходит - прошлый механизм, который работал "по текушей цене", резервировал монеты в процессе операции и оработал как часы. Его полная неприменимость с новыми интерфейсами была неочевидна.

Пути решения

Мы в Юниверса только что начали разработку альтернативного счет-контракта, который позволяет добавлять токен после того как пользователь одобрит операцию. Эта доделка позволит использовать существующие механизмы юниверса изменив только структуру контракт-счета, поэтому сделаем это быстро,закончим не позднее 22 апреля. После этого сервисы типа нашей биржи, которые не могут резервировать средства на время согласия пользоватлея, смогут вполне эффективно работать со счет-контрактами. API биржи не изменится, изменится немного логика резервирования монет на разходные операции.

Альтернативно может быть только откат к модели когда стоимость операции заранее неизвестна и может быть любой. Но, переписывание кода на такую модель практически займет столько же времени, как и модификация счет-контракта (часов на 4-5 меньше). Так что этот вариант я не стал делать.