mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-25 14:11:09 +00:00
fix(wallet): canonicalize root sequencer endpoints
This commit is contained in:
@@ -56,6 +56,15 @@ QByteArray rpcBody(const QString& method, const QJsonArray& params)
|
||||
}).toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
QUrl canonicalEndpoint(QUrl endpoint)
|
||||
{
|
||||
// Both forms issue requests to the HTTP root, so they must share cache
|
||||
// and credential identity.
|
||||
if (endpoint.path() == QLatin1String("/"))
|
||||
endpoint.setPath({});
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
WalletAccountRead accountRead(const QJsonObject& value, const QString& fallbackId)
|
||||
{
|
||||
WalletAccountRead read;
|
||||
@@ -90,8 +99,8 @@ bool SequencerClient::configure(const QString& configPath,
|
||||
if (configValid) {
|
||||
const QJsonDocument document = QJsonDocument::fromJson(file.readAll());
|
||||
const QJsonObject config = document.object();
|
||||
configuredEndpoint = QUrl(
|
||||
config.value(QStringLiteral("sequencer_addr")).toString());
|
||||
configuredEndpoint = canonicalEndpoint(QUrl(
|
||||
config.value(QStringLiteral("sequencer_addr")).toString()));
|
||||
const QString scheme = configuredEndpoint.scheme().toLower();
|
||||
configValid = document.isObject()
|
||||
&& configuredEndpoint.isValid()
|
||||
@@ -108,8 +117,8 @@ bool SequencerClient::configure(const QString& configPath,
|
||||
}
|
||||
}
|
||||
|
||||
QUrl endpoint = effectiveEndpoint.isEmpty()
|
||||
? configuredEndpoint : QUrl(effectiveEndpoint);
|
||||
QUrl endpoint = canonicalEndpoint(effectiveEndpoint.isEmpty()
|
||||
? configuredEndpoint : QUrl(effectiveEndpoint));
|
||||
const QString scheme = endpoint.scheme().toLower();
|
||||
const bool valid = endpoint.isValid()
|
||||
&& !endpoint.host().isEmpty()
|
||||
|
||||
@@ -748,6 +748,79 @@ int main(int argc, char** argv)
|
||||
"matching endpoint should retain configured credentials"))
|
||||
return 1;
|
||||
|
||||
LocalRpcServer rootEndpointServer;
|
||||
if (!expect(rootEndpointServer.listen(),
|
||||
"root endpoint sequencer should listen"))
|
||||
return 1;
|
||||
QTemporaryFile rootEndpointConfig;
|
||||
if (!expect(rootEndpointConfig.open(),
|
||||
"root endpoint config should open"))
|
||||
return 1;
|
||||
rootEndpointConfig.write(QJsonDocument(QJsonObject {
|
||||
{ QStringLiteral("sequencer_addr"), rootEndpointServer.endpoint() + QLatin1Char('/') },
|
||||
{ QStringLiteral("basic_auth"), QJsonObject {
|
||||
{ QStringLiteral("username"), QStringLiteral("user") },
|
||||
{ QStringLiteral("password"), QStringLiteral("pass") },
|
||||
} },
|
||||
}).toJson(QJsonDocument::Compact));
|
||||
rootEndpointConfig.flush();
|
||||
FakeAmmClient rootEndpointClient;
|
||||
SequencerClient rootEndpointSequencer(&rootEndpointClient);
|
||||
if (!expect(rootEndpointSequencer.configure(rootEndpointConfig.fileName()),
|
||||
"root endpoint config should configure"))
|
||||
return 1;
|
||||
const QString rootEndpointAccount(64, QLatin1Char('4'));
|
||||
QVector<WalletAccountRead> rootEndpointReads;
|
||||
if (!expect(waitForAccounts(rootEndpointSequencer, { rootEndpointAccount }, false,
|
||||
&rootEndpointReads),
|
||||
"root endpoint initial read should complete"))
|
||||
return 1;
|
||||
if (!expect(rootEndpointServer.requestCount() == 1
|
||||
&& rootEndpointServer.lastRequest().toLower().contains(
|
||||
"authorization: basic dxnlcjpwyxnz"),
|
||||
"configured root endpoint should use configured credentials"))
|
||||
return 1;
|
||||
|
||||
if (!expect(rootEndpointSequencer.configure(
|
||||
rootEndpointConfig.fileName(), rootEndpointServer.endpoint()),
|
||||
"slash-equivalent endpoint should configure"))
|
||||
return 1;
|
||||
rootEndpointReads.clear();
|
||||
if (!expect(waitForAccounts(rootEndpointSequencer, { rootEndpointAccount }, false,
|
||||
&rootEndpointReads),
|
||||
"slash-equivalent cached read should complete"))
|
||||
return 1;
|
||||
if (!expect(rootEndpointServer.requestCount() == 1,
|
||||
"slash-equivalent endpoint should preserve account cache"))
|
||||
return 1;
|
||||
|
||||
const QString rootEndpointFreshAccount(64, QLatin1Char('5'));
|
||||
if (!expect(waitForAccounts(rootEndpointSequencer, { rootEndpointFreshAccount }, true,
|
||||
&rootEndpointReads),
|
||||
"slash-equivalent forced read should complete"))
|
||||
return 1;
|
||||
if (!expect(rootEndpointServer.requestCount() == 2
|
||||
&& rootEndpointServer.lastRequest().toLower().contains(
|
||||
"authorization: basic dxnlcjpwyxnz"),
|
||||
"slash-equivalent endpoint should retain configured credentials"))
|
||||
return 1;
|
||||
|
||||
if (!expect(rootEndpointSequencer.configure(
|
||||
rootEndpointConfig.fileName(),
|
||||
rootEndpointServer.endpoint() + QStringLiteral("/rpc")),
|
||||
"path-changing endpoint should configure"))
|
||||
return 1;
|
||||
rootEndpointReads.clear();
|
||||
if (!expect(waitForAccounts(rootEndpointSequencer, { rootEndpointAccount }, false,
|
||||
&rootEndpointReads),
|
||||
"path-changing endpoint read should complete"))
|
||||
return 1;
|
||||
if (!expect(rootEndpointServer.requestCount() == 3
|
||||
&& !rootEndpointServer.lastRequest().toLower().contains(
|
||||
"authorization:"),
|
||||
"path-changing endpoint should clear cache and credentials"))
|
||||
return 1;
|
||||
|
||||
LocalRpcServer staleContextServer;
|
||||
if (!expect(staleContextServer.listen(),
|
||||
"stale-context sequencer should listen"))
|
||||
|
||||
Reference in New Issue
Block a user