Skip to content

Commit

Permalink
Merge pull request #1091 from input-output-hk/feat/explicit-handle-va…
Browse files Browse the repository at this point in the history
…lidation-arg

feat: add explicit handle validation arg
  • Loading branch information
mkazlauskas authored Feb 12, 2024
2 parents e0aeb99 + 01938a2 commit 3564618
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,12 @@ const serviceMapFactory = (options: ServiceMapFactoryOptions) => {
[ServiceNames.TxSubmit]: async () => {
const txSubmitProvider = args.useSubmitApi
? getSubmitApiProvider()
: await getOgmiosTxSubmitProvider(dnsResolver, logger, args, await getHandleProvider());
: await getOgmiosTxSubmitProvider(
dnsResolver,
logger,
args,
args.submitValidateHandles ? await getHandleProvider() : undefined
);
return new TxSubmitHttpService({ logger, txSubmitProvider });
}
};
Expand Down
4 changes: 3 additions & 1 deletion packages/cardano-services/src/Program/programs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ export enum ProviderServerOptionDescriptions {
UseBlockfrost = 'Enables Blockfrost cached data DB',
UseKoraLabsProvider = 'Use the KoraLabs handle provider',
UseSubmitApi = 'Use cardano-submit-api provider',
UseTypeormAssetProvider = 'Use the TypeORM Asset Provider (default is db-sync)'
UseTypeormAssetProvider = 'Use the TypeORM Asset Provider (default is db-sync)',
SubmitValidateHandles = 'Validate handle resolutions before submitting transactions. Requires handle provider options (USE_KORA_LABS or POSTGRES options with HANDLE suffix).'
}

export type ProviderServerArgs = CommonProgramOptions &
Expand All @@ -82,6 +83,7 @@ export type ProviderServerArgs = CommonProgramOptions &
paginationPageSizeLimit?: number;
serviceNames: ServiceNames[];
submitApiUrl?: URL;
submitValidateHandles?: boolean;
tokenMetadataCacheTTL?: Seconds;
tokenMetadataServerUrl?: string;
tokenMetadataRequestTimeout?: Milliseconds;
Expand Down
12 changes: 12 additions & 0 deletions packages/cardano-services/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,18 @@ addOptions(withOgmiosOptions(withHandlePolicyIdsOptions(providerServerWithCommon
stringOptionToBoolean(useKoraLabs, Programs.ProviderServer, ProviderServerOptionDescriptions.UseKoraLabsProvider),
false
),
newOption(
'--submit-validate-handles <true/false>',
ProviderServerOptionDescriptions.SubmitValidateHandles,
'SUBMIT_VALIDATE_HANDLES',
(submitValidateHandles) =>
stringOptionToBoolean(
submitValidateHandles,
Programs.ProviderServer,
ProviderServerOptionDescriptions.SubmitValidateHandles
),
false
),
newOption(
'--pagination-page-size-limit <paginationPageSizeLimit>',
ProviderServerOptionDescriptions.PaginationPageSizeLimit,
Expand Down
15 changes: 12 additions & 3 deletions packages/cardano-services/test/Program/services/ogmios.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,18 @@ describe('Service dependency abstractions', () => {
});

it('throws a provider error if the submitted transaction does not contain addresses that can be resolved from the included context', async () => {
const provider = await getOgmiosTxSubmitProvider(dnsResolver, logger, {
ogmiosSrvServiceName: process.env.OGMIOS_SRV_SERVICE_NAME
});
const provider = await getOgmiosTxSubmitProvider(
dnsResolver,
logger,
{
ogmiosSrvServiceName: process.env.OGMIOS_SRV_SERVICE_NAME
},
{
getPolicyIds: async () => [],
healthCheck: async () => ({ ok: true }),
resolveHandles: async ({ handles }) => handles.map(() => null)
}
);
await provider.initialize();
await provider.start();

Expand Down
22 changes: 21 additions & 1 deletion packages/cardano-services/test/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,27 @@ describe('CLI', () => {
await assertServiceHealthy(apiUrl, services.txSubmit, lastBlock, { withTip: false });
});

it('exposes a HTTP server with /tx-submit/health endpoint when SUBMIT_VALIDATE_HANDLES is true', async () => {
proc = withLogging(
fork(exePath, ['start-provider-server'], {
env: {
API_URL: apiUrl,
CARDANO_NODE_CONFIG_PATH: cardanoNodeConfigPath,
DB_CACHE_TTL: dbCacheTtl,
HANDLE_POLICY_IDS,
LOGGER_MIN_SEVERITY: 'error',
OGMIOS_URL: ogmiosConnection.address.webSocket,
POSTGRES_CONNECTION_STRING_HANDLE: postgresConnectionStringHandle,
SERVICE_NAMES: `${ServiceNames.TxSubmit}`,
SUBMIT_VALIDATE_HANDLES: 'true'
},
stdio: 'pipe'
})
);

await assertServiceHealthy(apiUrl, services.txSubmit, lastBlock, { withTip: false });
});

it('tx-submit uses the default Ogmios configuration if not specified when using env variables', async () => {
proc = withLogging(
fork(exePath, ['start-provider-server'], {
Expand All @@ -1494,7 +1515,6 @@ describe('CLI', () => {
HANDLE_POLICY_IDS,
HANDLE_PROVIDER_SERVER_URL,
LOGGER_MIN_SEVERITY: 'error',
POSTGRES_CONNECTION_STRING_HANDLE: postgresConnectionStringHandle,
SERVICE_NAMES: ServiceNames.TxSubmit
},
stdio: 'pipe'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,8 @@ export class OgmiosTxSubmitProvider extends RunnableModule implements TxSubmitPr
private async throwIfHandleResolutionConflict(context: SubmitTxArgs['context']): Promise<void> {
if (context?.handleResolutions && context.handleResolutions.length > 0) {
if (!this.#handleProvider) {
throw new ProviderError(
ProviderFailure.NotImplemented,
undefined,
'No HandleProvider was set during construction.'
);
this.logger.debug('No handle provider: bypassing handle validation');
return;
}

const handleInfoList = await this.#handleProvider.resolveHandles({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,25 +137,6 @@ describe('OgmiosTxSubmitProvider', () => {
);
});

it('throws an error if context has handles, and no handleProvider is passed', async () => {
mockServer = createMockOgmiosServer({
submitTx: { response: { failWith: { type: 'eraMismatch' }, success: false } }
});
await listenPromise(mockServer, connection.port);
provider = new OgmiosTxSubmitProvider(connection, { logger });
await provider.initialize();
await provider.start();

await expect(
provider.submitTx({
context: {
handleResolutions: [mockHandleResolution]
},
signedTransaction: emptyUintArrayAsHexString
})
).rejects.toThrowError(/not_implemented/i);
});

it('does not throw an error if handles resolve to same addresses as in context', async () => {
mockServer = createMockOgmiosServer({ submitTx: { response: { success: true } } });
await listenPromise(mockServer, connection.port);
Expand Down

0 comments on commit 3564618

Please sign in to comment.