Skip to content

Commit 3564618

Browse files
authored
Merge pull request #1091 from input-output-hk/feat/explicit-handle-validation-arg
feat: add explicit handle validation arg
2 parents e0aeb99 + 01938a2 commit 3564618

File tree

7 files changed

+56
-30
lines changed

7 files changed

+56
-30
lines changed

packages/cardano-services/src/Program/programs/providerServer.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,12 @@ const serviceMapFactory = (options: ServiceMapFactoryOptions) => {
315315
[ServiceNames.TxSubmit]: async () => {
316316
const txSubmitProvider = args.useSubmitApi
317317
? getSubmitApiProvider()
318-
: await getOgmiosTxSubmitProvider(dnsResolver, logger, args, await getHandleProvider());
318+
: await getOgmiosTxSubmitProvider(
319+
dnsResolver,
320+
logger,
321+
args,
322+
args.submitValidateHandles ? await getHandleProvider() : undefined
323+
);
319324
return new TxSubmitHttpService({ logger, txSubmitProvider });
320325
}
321326
};

packages/cardano-services/src/Program/programs/types.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ export enum ProviderServerOptionDescriptions {
5959
UseBlockfrost = 'Enables Blockfrost cached data DB',
6060
UseKoraLabsProvider = 'Use the KoraLabs handle provider',
6161
UseSubmitApi = 'Use cardano-submit-api provider',
62-
UseTypeormAssetProvider = 'Use the TypeORM Asset Provider (default is db-sync)'
62+
UseTypeormAssetProvider = 'Use the TypeORM Asset Provider (default is db-sync)',
63+
SubmitValidateHandles = 'Validate handle resolutions before submitting transactions. Requires handle provider options (USE_KORA_LABS or POSTGRES options with HANDLE suffix).'
6364
}
6465

6566
export type ProviderServerArgs = CommonProgramOptions &
@@ -82,6 +83,7 @@ export type ProviderServerArgs = CommonProgramOptions &
8283
paginationPageSizeLimit?: number;
8384
serviceNames: ServiceNames[];
8485
submitApiUrl?: URL;
86+
submitValidateHandles?: boolean;
8587
tokenMetadataCacheTTL?: Seconds;
8688
tokenMetadataServerUrl?: string;
8789
tokenMetadataRequestTimeout?: Milliseconds;

packages/cardano-services/src/cli.ts

+12
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,18 @@ addOptions(withOgmiosOptions(withHandlePolicyIdsOptions(providerServerWithCommon
310310
stringOptionToBoolean(useKoraLabs, Programs.ProviderServer, ProviderServerOptionDescriptions.UseKoraLabsProvider),
311311
false
312312
),
313+
newOption(
314+
'--submit-validate-handles <true/false>',
315+
ProviderServerOptionDescriptions.SubmitValidateHandles,
316+
'SUBMIT_VALIDATE_HANDLES',
317+
(submitValidateHandles) =>
318+
stringOptionToBoolean(
319+
submitValidateHandles,
320+
Programs.ProviderServer,
321+
ProviderServerOptionDescriptions.SubmitValidateHandles
322+
),
323+
false
324+
),
313325
newOption(
314326
'--pagination-page-size-limit <paginationPageSizeLimit>',
315327
ProviderServerOptionDescriptions.PaginationPageSizeLimit,

packages/cardano-services/test/Program/services/ogmios.test.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,18 @@ describe('Service dependency abstractions', () => {
308308
});
309309

310310
it('throws a provider error if the submitted transaction does not contain addresses that can be resolved from the included context', async () => {
311-
const provider = await getOgmiosTxSubmitProvider(dnsResolver, logger, {
312-
ogmiosSrvServiceName: process.env.OGMIOS_SRV_SERVICE_NAME
313-
});
311+
const provider = await getOgmiosTxSubmitProvider(
312+
dnsResolver,
313+
logger,
314+
{
315+
ogmiosSrvServiceName: process.env.OGMIOS_SRV_SERVICE_NAME
316+
},
317+
{
318+
getPolicyIds: async () => [],
319+
healthCheck: async () => ({ ok: true }),
320+
resolveHandles: async ({ handles }) => handles.map(() => null)
321+
}
322+
);
314323
await provider.initialize();
315324
await provider.start();
316325

packages/cardano-services/test/cli.test.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,27 @@ describe('CLI', () => {
14861486
await assertServiceHealthy(apiUrl, services.txSubmit, lastBlock, { withTip: false });
14871487
});
14881488

1489+
it('exposes a HTTP server with /tx-submit/health endpoint when SUBMIT_VALIDATE_HANDLES is true', async () => {
1490+
proc = withLogging(
1491+
fork(exePath, ['start-provider-server'], {
1492+
env: {
1493+
API_URL: apiUrl,
1494+
CARDANO_NODE_CONFIG_PATH: cardanoNodeConfigPath,
1495+
DB_CACHE_TTL: dbCacheTtl,
1496+
HANDLE_POLICY_IDS,
1497+
LOGGER_MIN_SEVERITY: 'error',
1498+
OGMIOS_URL: ogmiosConnection.address.webSocket,
1499+
POSTGRES_CONNECTION_STRING_HANDLE: postgresConnectionStringHandle,
1500+
SERVICE_NAMES: `${ServiceNames.TxSubmit}`,
1501+
SUBMIT_VALIDATE_HANDLES: 'true'
1502+
},
1503+
stdio: 'pipe'
1504+
})
1505+
);
1506+
1507+
await assertServiceHealthy(apiUrl, services.txSubmit, lastBlock, { withTip: false });
1508+
});
1509+
14891510
it('tx-submit uses the default Ogmios configuration if not specified when using env variables', async () => {
14901511
proc = withLogging(
14911512
fork(exePath, ['start-provider-server'], {
@@ -1494,7 +1515,6 @@ describe('CLI', () => {
14941515
HANDLE_POLICY_IDS,
14951516
HANDLE_PROVIDER_SERVER_URL,
14961517
LOGGER_MIN_SEVERITY: 'error',
1497-
POSTGRES_CONNECTION_STRING_HANDLE: postgresConnectionStringHandle,
14981518
SERVICE_NAMES: ServiceNames.TxSubmit
14991519
},
15001520
stdio: 'pipe'

packages/ogmios/src/Provider/TxSubmitProvider/OgmiosTxSubmitProvider.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,8 @@ export class OgmiosTxSubmitProvider extends RunnableModule implements TxSubmitPr
9999
private async throwIfHandleResolutionConflict(context: SubmitTxArgs['context']): Promise<void> {
100100
if (context?.handleResolutions && context.handleResolutions.length > 0) {
101101
if (!this.#handleProvider) {
102-
throw new ProviderError(
103-
ProviderFailure.NotImplemented,
104-
undefined,
105-
'No HandleProvider was set during construction.'
106-
);
102+
this.logger.debug('No handle provider: bypassing handle validation');
103+
return;
107104
}
108105

109106
const handleInfoList = await this.#handleProvider.resolveHandles({

packages/ogmios/test/Provider/TxSubmitProvider/OgmiosTxSubmitProvider.test.ts

-19
Original file line numberDiff line numberDiff line change
@@ -137,25 +137,6 @@ describe('OgmiosTxSubmitProvider', () => {
137137
);
138138
});
139139

140-
it('throws an error if context has handles, and no handleProvider is passed', async () => {
141-
mockServer = createMockOgmiosServer({
142-
submitTx: { response: { failWith: { type: 'eraMismatch' }, success: false } }
143-
});
144-
await listenPromise(mockServer, connection.port);
145-
provider = new OgmiosTxSubmitProvider(connection, { logger });
146-
await provider.initialize();
147-
await provider.start();
148-
149-
await expect(
150-
provider.submitTx({
151-
context: {
152-
handleResolutions: [mockHandleResolution]
153-
},
154-
signedTransaction: emptyUintArrayAsHexString
155-
})
156-
).rejects.toThrowError(/not_implemented/i);
157-
});
158-
159140
it('does not throw an error if handles resolve to same addresses as in context', async () => {
160141
mockServer = createMockOgmiosServer({ submitTx: { response: { success: true } } });
161142
await listenPromise(mockServer, connection.port);

0 commit comments

Comments
 (0)