mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-07-21 06:19:32 +00:00
fix(amm): cancel submits after wallet changes
This commit is contained in:
parent
c5e4231890
commit
02a65aaf09
@ -3,6 +3,7 @@
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
@ -169,17 +170,21 @@ NewPositionRuntime::NewPositionRuntime(WalletProvider* wallet,
|
||||
|
||||
void NewPositionRuntime::clearWalletAccounts()
|
||||
{
|
||||
++m_walletGeneration;
|
||||
m_walletPublicAccountIds.clear();
|
||||
m_wallet->clearSnapshot();
|
||||
}
|
||||
|
||||
void NewPositionRuntime::setWalletAccounts(const QVector<WalletAccount>& accounts)
|
||||
{
|
||||
m_walletPublicAccountIds.clear();
|
||||
QStringList publicAccountIds;
|
||||
for (const WalletAccount& account : accounts) {
|
||||
if (account.isPublic)
|
||||
m_walletPublicAccountIds.append(account.address);
|
||||
publicAccountIds.append(account.address);
|
||||
}
|
||||
if (publicAccountIds != m_walletPublicAccountIds)
|
||||
++m_walletGeneration;
|
||||
m_walletPublicAccountIds = std::move(publicAccountIds);
|
||||
}
|
||||
|
||||
QJsonArray NewPositionRuntime::walletAccountReads(bool walletOpen, bool refresh) const
|
||||
@ -501,13 +506,18 @@ void NewPositionRuntime::submitAsync(const QVariantMap& request,
|
||||
return;
|
||||
}
|
||||
m_submitInFlight = true;
|
||||
const quint64 walletGeneration = m_walletGeneration;
|
||||
auto finish = [this, callback = std::move(callback)](QVariantMap result) mutable {
|
||||
m_submitInFlight = false;
|
||||
callback(std::move(result));
|
||||
};
|
||||
buildQuoteInputAsync(request, network, true, true,
|
||||
[this, quoteHash, finish = std::move(finish)](
|
||||
[this, quoteHash, walletGeneration, finish = std::move(finish)](
|
||||
QJsonObject input, QJsonObject error) mutable {
|
||||
if (walletGeneration != m_walletGeneration) {
|
||||
finish(publicError(QStringLiteral("wallet_unavailable")).toVariantMap());
|
||||
return;
|
||||
}
|
||||
if (!error.isEmpty()) {
|
||||
finish(error.toVariantMap());
|
||||
return;
|
||||
@ -533,6 +543,10 @@ void NewPositionRuntime::submitAsync(const QVariantMap& request,
|
||||
|
||||
QJsonValue freshLp;
|
||||
if (quote.value(QStringLiteral("requiresFreshLp")).toBool(false)) {
|
||||
if (walletGeneration != m_walletGeneration) {
|
||||
finish(publicError(QStringLiteral("wallet_unavailable")).toVariantMap());
|
||||
return;
|
||||
}
|
||||
const WalletAccountCreation creation = m_wallet->createAccount(true);
|
||||
if (!creation.ok() || !creation.publicAccount.ok()) {
|
||||
finish(publicError(QStringLiteral("wallet_submission_failed")).toVariantMap());
|
||||
@ -576,6 +590,10 @@ void NewPositionRuntime::submitAsync(const QVariantMap& request,
|
||||
finish(publicError(QStringLiteral("transaction_deadline_expired")).toVariantMap());
|
||||
return;
|
||||
}
|
||||
if (walletGeneration != m_walletGeneration) {
|
||||
finish(publicError(QStringLiteral("wallet_unavailable")).toVariantMap());
|
||||
return;
|
||||
}
|
||||
const WalletSubmission submission = m_wallet->submitPublicTransaction({
|
||||
plan.value(QStringLiteral("programId")).toString(),
|
||||
accountIds,
|
||||
|
||||
@ -72,4 +72,5 @@ private:
|
||||
SequencerClient* m_sequencer;
|
||||
QStringList m_walletPublicAccountIds;
|
||||
bool m_submitInFlight = false;
|
||||
quint64 m_walletGeneration = 0;
|
||||
};
|
||||
|
||||
@ -581,5 +581,49 @@ int main(int argc, char** argv)
|
||||
"forced follow-up read should complete"))
|
||||
return 1;
|
||||
|
||||
LocalRpcServer cancelledSubmitServer;
|
||||
if (!expect(cancelledSubmitServer.listen(),
|
||||
"cancelled-submit sequencer should listen"))
|
||||
return 1;
|
||||
cancelledSubmitServer.holdResponses();
|
||||
if (!expect(sequencerConfig.resize(0) && sequencerConfig.seek(0),
|
||||
"cancelled-submit config should rewind"))
|
||||
return 1;
|
||||
sequencerConfig.write(QJsonDocument(QJsonObject {
|
||||
{ QStringLiteral("sequencer_addr"), cancelledSubmitServer.endpoint() },
|
||||
}).toJson(QJsonDocument::Compact));
|
||||
sequencerConfig.flush();
|
||||
if (!expect(sequencer.configure(sequencerConfig.fileName()),
|
||||
"cancelled-submit sequencer should configure"))
|
||||
return 1;
|
||||
|
||||
FakeWallet cancelledWallet;
|
||||
FakeAmmClient cancelledClient;
|
||||
NewPositionRuntime cancelledRuntime(
|
||||
&cancelledWallet, &cancelledClient, &sequencer);
|
||||
bool cancelledCompleted = false;
|
||||
QVariantMap cancelledResult;
|
||||
cancelledRuntime.submitAsync(
|
||||
request, QStringLiteral("sha256:expected"), readyNetwork(), true,
|
||||
[&](QVariantMap result) {
|
||||
cancelledResult = std::move(result);
|
||||
cancelledCompleted = true;
|
||||
});
|
||||
if (!expect(waitForRequestCount(cancelledSubmitServer, 1),
|
||||
"submit should begin account reads"))
|
||||
return 1;
|
||||
cancelledRuntime.clearWalletAccounts();
|
||||
cancelledRuntime.setWalletAccounts({});
|
||||
cancelledSubmitServer.releaseNextResponse();
|
||||
if (!expect(waitForCallbacks(cancelledCompleted, cancelledCompleted),
|
||||
"cancelled submit should complete"))
|
||||
return 1;
|
||||
if (!expect(cancelledResult.value(QStringLiteral("code")).toString()
|
||||
== QStringLiteral("wallet_unavailable")
|
||||
&& cancelledWallet.createdAccounts == 0
|
||||
&& cancelledWallet.submissions == 0,
|
||||
"wallet change should cancel submit before side effects"))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user