Fetch_canister_logs 400 subnet_not_found bad request on mainnet

I get a 400 bad request error when I try to query fetch_canister_logs on mainnet.

POST https://icp0.io/api/v2/canister/aaaaa-aa/query 400 (Bad Request)
vendor.k4coD-xg.js:29 Uncaught (in promise) Ue: Server returned an error:
Code: 400 ()
Body: subnet_not_found

Why? Any idea?

export const canisterLogs = async ({
	canisterId,
	identity
}: {
	canisterId: Principal;
	identity: Identity;
}): Promise<canister_log_record[]> => {
	const { fetch_canister_logs } = await getICActor({ identity, verifyQuerySignatures: false });

	const { canister_log_records } = await fetch_canister_logs({
		canister_id: canisterId
	});

	return canister_log_records;
};

export const getICActor = (params: GetAgentParams): Promise<ICActor> =>
	createActor<ICActor>({
		canisterId: MANAGEMENT_CANISTER_ID,
		config: {
			callTransform: transform,
			queryTransform: transform
		},
		idlFactory: idlFactorIC,
		...params
	});

const transform = (
	_methodName: string,
	args: unknown[],
	_callConfig: CallConfig
): { effectiveCanisterId: Principal } => {
	const first = args[0] as any;
	let effectiveCanisterId = MANAGEMENT_CANISTER_ID;
	if (first && typeof first === 'object' && first.canister_id) {
		effectiveCanisterId = Principal.from(first.canister_id as unknown);
	}

	return { effectiveCanisterId };
};

export const createActor = async <T = Record<string, ActorMethod>>({
	canisterId,
	idlFactory,
	config = {},
	...rest
}: {
	canisterId: string | Principal;
	idlFactory: IDL.InterfaceFactory;
	config?: Pick<ActorConfig, 'callTransform' | 'queryTransform'>;
} & GetAgentParams): Promise<ActorSubclass<T>> => {
	const agent = await getAgent(rest);

	// Creates an actor with using the candid interface and the HttpAgent
	return Actor.createActor(idlFactory, {
		agent,
		canisterId,
		...config
	});
};

const getAgent = async ({ identity, verifyQuerySignatures = true }: GetAgentParams) => {
	const host = 'https://icp0.io';
	return new HttpAgent({ identity, host, verifyQuerySignatures });
};

Sounds like we need to add an exception for aaaaa-aa in the query certification

Looks like the effective-canister-id is being set to ‘aaaaa-aa’, the error message shows the ‘aaaaa-aa’ in the url. When calling the management-canister with an ingress-message, the effective-canister-id needs to be set to the canister being managed.

It’s what the transform function do. The issue is probably in the URL that is used.

Anything I can do or it’s stricly something to be solved within @dfinity/agent?

I’m trying to reproduce right now, and I have to reverse engineer a few functions and interfaces referenced but not included in the sample above.

Ordinarily I’d just say to use the getManagementCanister export but I need to figure out what fetch_canister_logs is

getManagementCanister unfortunatelly does not work neither, I tried it out as well.

The transform function by default sets the effectiveCanisterId to ‘aaaaa-aa’;

Maybe this condition if (first && typeof first === 'object' && first.canister_id) is not being met?

I was also doubtful about it but, double checked that effectiveCanisterId was effectivelly correctly set - i.e. I debugged it and can confirm it is set. console.log for the win :wink:.

Also same code works fine for example for canister_status. So it’s really scoped to that particular feature.

Do you mind sharing with me where fetch_canister_logs comes from? It doesn’t exist in ic/hs/spec_compliance/ic.did at master · dfinity/ic · GitHub

:+1: that’s good.

The agent however is using ‘aaaaa-aa’ as the effective-canister-id in the url as shown in the error message.

1 Like

Sure in this PR for the specification which is in review but, the feature is effectively implemented in dfx therefore I assumed it’s on mainnet as well. It also works fine locally or at least I don’t get error but, an empty array or logs.

Here also the did I used: https://github.com/junobuild/juno/blob/feat/functions-logs/candid/ic.did

Note that I assume it’s live on mainnet because I assume the feature in dfx is implemented to communicate with mainnet and not locally. Maybe that’s a misinterpretation, I did not search in the proposals neither.

Okay, I’ve made the basic fix I anticipated and am still getting errors. Based on the 400 bad request response I’m getting back, I don’t think this is available yet on mainnet. See here, and the new test in mainnet.test.ts

{ response: { ok: false, status: 400, statusText: 'Bad Request', headers: [ [ 'access-control-allow-headers', 'DNT,User-Agent,X-Requested-With,If-None-Match,If-Modified-Since,Cache-Control,Content-Type,Range,Cookie,X-Ic-Canister-Id' ], [ 'access-control-allow-methods', 'HEAD, POST' ], [ 'access-control-allow-origin', '*' ], [ 'access-control-expose-headers', 'Accept-Ranges,Content-Length,Content-Range,X-Request-Id,X-Ic-Canister-Id' ], [ 'access-control-max-age', '600' ], [ 'connection', 'keep-alive' ], [ 'content-length', '17' ], [ 'content-type', 'text/plain; charset=utf-8' ], [ 'date', 'Wed, 20 Mar 2024 18:03:30 GMT' ], [ 'server', 'nginx' ], [ 'x-ic-canister-id', 'aaaaa-aa' ], [ 'x-request-id', 'f640e12c-4218-66ac-3535-02b9b3fee56f' ] ] } }
1 Like

Weird, from dfx v0.18.0 CHANGELOG:

feat: add dfx canister logs <canister_id> for fetching canister’s logs (preview)

There is a new subcommand logs to fetch canister’s logs.
When printing the log entries it tries to guess if the content can be converted to UTF-8 text and prints an array of hex bytes if it fails.

Note

This feature is still in development. Changes may occur in following releases.

But indeed, the logs does not mention if the feature is only for local environment or for mainnet but, given that is is never mentionned, I assumed it was for mainnet as well.

I’ll still clean this up and get a local e2e test working for it, but it sounds like this isn’t a p0 around existing functionality

For sure, I don’t need it tomorrow, but it’s a nice feature to add to Juno as it can be really useful for developers. Therefore, for me, it’s also not a P9999, if you know what I mean. Thanks for tracking it; keep me posted.

1 Like

Oh definitely. I’m just glad I didn’t drop the ball on this, lagging behind mainnet

1 Like

Okay, got my proof of concept working. Some changes actually had to happen to the agent, since effective canister ID in queries hadn’t come up before.

1 Like

I can also now confirm that canister logs aren’t available on mainnet (yet)

1 Like