mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-03 12:43:12 +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 <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
@ -169,17 +170,21 @@ NewPositionRuntime::NewPositionRuntime(WalletProvider* wallet,
|
|||||||
|
|
||||||
void NewPositionRuntime::clearWalletAccounts()
|
void NewPositionRuntime::clearWalletAccounts()
|
||||||
{
|
{
|
||||||
|
++m_walletGeneration;
|
||||||
m_walletPublicAccountIds.clear();
|
m_walletPublicAccountIds.clear();
|
||||||
m_wallet->clearSnapshot();
|
m_wallet->clearSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewPositionRuntime::setWalletAccounts(const QVector<WalletAccount>& accounts)
|
void NewPositionRuntime::setWalletAccounts(const QVector<WalletAccount>& accounts)
|
||||||
{
|
{
|
||||||
m_walletPublicAccountIds.clear();
|
QStringList publicAccountIds;
|
||||||
for (const WalletAccount& account : accounts) {
|
for (const WalletAccount& account : accounts) {
|
||||||
if (account.isPublic)
|
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
|
QJsonArray NewPositionRuntime::walletAccountReads(bool walletOpen, bool refresh) const
|
||||||
@ -501,13 +506,18 @@ void NewPositionRuntime::submitAsync(const QVariantMap& request,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_submitInFlight = true;
|
m_submitInFlight = true;
|
||||||
|
const quint64 walletGeneration = m_walletGeneration;
|
||||||
auto finish = [this, callback = std::move(callback)](QVariantMap result) mutable {
|
auto finish = [this, callback = std::move(callback)](QVariantMap result) mutable {
|
||||||
m_submitInFlight = false;
|
m_submitInFlight = false;
|
||||||
callback(std::move(result));
|
callback(std::move(result));
|
||||||
};
|
};
|
||||||
buildQuoteInputAsync(request, network, true, true,
|
buildQuoteInputAsync(request, network, true, true,
|
||||||
[this, quoteHash, finish = std::move(finish)](
|
[this, quoteHash, walletGeneration, finish = std::move(finish)](
|
||||||
QJsonObject input, QJsonObject error) mutable {
|
QJsonObject input, QJsonObject error) mutable {
|
||||||
|
if (walletGeneration != m_walletGeneration) {
|
||||||
|
finish(publicError(QStringLiteral("wallet_unavailable")).toVariantMap());
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!error.isEmpty()) {
|
if (!error.isEmpty()) {
|
||||||
finish(error.toVariantMap());
|
finish(error.toVariantMap());
|
||||||
return;
|
return;
|
||||||
@ -533,6 +543,10 @@ void NewPositionRuntime::submitAsync(const QVariantMap& request,
|
|||||||
|
|
||||||
QJsonValue freshLp;
|
QJsonValue freshLp;
|
||||||
if (quote.value(QStringLiteral("requiresFreshLp")).toBool(false)) {
|
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);
|
const WalletAccountCreation creation = m_wallet->createAccount(true);
|
||||||
if (!creation.ok() || !creation.publicAccount.ok()) {
|
if (!creation.ok() || !creation.publicAccount.ok()) {
|
||||||
finish(publicError(QStringLiteral("wallet_submission_failed")).toVariantMap());
|
finish(publicError(QStringLiteral("wallet_submission_failed")).toVariantMap());
|
||||||
@ -576,6 +590,10 @@ void NewPositionRuntime::submitAsync(const QVariantMap& request,
|
|||||||
finish(publicError(QStringLiteral("transaction_deadline_expired")).toVariantMap());
|
finish(publicError(QStringLiteral("transaction_deadline_expired")).toVariantMap());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (walletGeneration != m_walletGeneration) {
|
||||||
|
finish(publicError(QStringLiteral("wallet_unavailable")).toVariantMap());
|
||||||
|
return;
|
||||||
|
}
|
||||||
const WalletSubmission submission = m_wallet->submitPublicTransaction({
|
const WalletSubmission submission = m_wallet->submitPublicTransaction({
|
||||||
plan.value(QStringLiteral("programId")).toString(),
|
plan.value(QStringLiteral("programId")).toString(),
|
||||||
accountIds,
|
accountIds,
|
||||||
|
|||||||
@ -72,4 +72,5 @@ private:
|
|||||||
SequencerClient* m_sequencer;
|
SequencerClient* m_sequencer;
|
||||||
QStringList m_walletPublicAccountIds;
|
QStringList m_walletPublicAccountIds;
|
||||||
bool m_submitInFlight = false;
|
bool m_submitInFlight = false;
|
||||||
|
quint64 m_walletGeneration = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -581,5 +581,49 @@ int main(int argc, char** argv)
|
|||||||
"forced follow-up read should complete"))
|
"forced follow-up read should complete"))
|
||||||
return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user