Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 340: Content hash is out of spec in announcements #343

Merged
merged 10 commits into from
Aug 7, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ export class DsnpAnnouncementProcessor {
attachment: attachments,
});
const noteString = JSON.stringify(note);
const [cid, hash] = await this.pinBufferToIPFS(Buffer.from(noteString));
const toUint8Array = new TextEncoder();
const encoded = toUint8Array.encode(noteString);

const [cid, hash] = await this.pinBufferToIPFS(Buffer.from(encoded));
const ipfsUrl = this.formIpfsUrl(cid);
return [cid, ipfsUrl, hash];
}
Expand Down Expand Up @@ -397,8 +400,11 @@ export class DsnpAnnouncementProcessor {
icon: attachments,
tag: this.prepareTags(content.profile.tag),
};
const toUint8Array = new TextEncoder();
const profileString = JSON.stringify(profileActivity);
const [cid, hash] = await this.pinBufferToIPFS(Buffer.from(profileString));
const profileEncoded = toUint8Array.encode(profileString);

const [cid, hash] = await this.pinBufferToIPFS(Buffer.from(profileEncoded));
saraswatpuneet marked this conversation as resolved.
Show resolved Hide resolved
return createProfile(dsnpUserId, this.formIpfsUrl(cid), hash);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Test, TestingModule } from '@nestjs/testing';
import { IpfsService } from './ipfs.client';
import { ConfigService } from '#libs/config';
import { Logger } from '@nestjs/common';

jest.mock('axios');

describe('IpfsService Tests', () => {
let service: IpfsService;
let configService: ConfigService;
let logger: Logger;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
IpfsService,
{
provide: ConfigService,
useValue: {
ipfsEndpoint: 'http://localhost:5001',
ipfsBasicAuthUser: '',
ipfsBasicAuthSecret: '',
ipfsGatewayUrl: 'http://localhost:8080/ipfs/[CID]',
},
},
],
}).compile();

service = module.get<IpfsService>(IpfsService);
configService = module.get<ConfigService>(ConfigService);
logger = new Logger(IpfsService.name);
});


it('should be defined', () => {
expect(service).toBeDefined();
});

it("hashes blake2b correctly ABC", async () => {
const mb = await service.ipfsHashBuffer(Buffer.from("abc"));
expect(mb).toMatch("z2DrjgbH33g3bTa7dPaMq1XbVmKH11m2SwxAF6aNzSd5F3j63p4");
});
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

23 changes: 6 additions & 17 deletions services/content-publishing/libs/common/src/utils/ipfs.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import FormData from 'form-data';
import { extension as getExtension } from 'mime-types';
import { CID } from 'multiformats/cid';
import { blake2b256 as hasher } from '@multiformats/blake2/blake2b';
import { create } from 'multiformats/hashes/digest';
import { randomUUID } from 'crypto';
import { base58btc } from 'multiformats/bases/base58';
import { ConfigService } from '#libs/config';
Expand Down Expand Up @@ -37,10 +36,7 @@ export class IpfsService {

const ipfsAuthUser = this.configService.ipfsBasicAuthUser;
const ipfsAuthSecret = this.configService.ipfsBasicAuthSecret;
const ipfsAuth =
ipfsAuthUser && ipfsAuthSecret
? `Basic ${Buffer.from(`${ipfsAuthUser}:${ipfsAuthSecret}`).toString('base64')}`
: '';
const ipfsAuth = ipfsAuthUser && ipfsAuthSecret ? `Basic ${Buffer.from(`${ipfsAuthUser}:${ipfsAuthSecret}`).toString('base64')}` : '';

const headers = {
'Content-Type': `multipart/form-data; boundary=${form.getBoundary()}`,
Expand Down Expand Up @@ -93,10 +89,7 @@ export class IpfsService {
const ipfsGet = `${this.configService.ipfsEndpoint}/api/v0/cat?arg=${cid}`;
const ipfsAuthUser = this.configService.ipfsBasicAuthUser;
const ipfsAuthSecret = this.configService.ipfsBasicAuthSecret;
const ipfsAuth =
ipfsAuthUser && ipfsAuthSecret
? `Basic ${Buffer.from(`${ipfsAuthUser}:${ipfsAuthSecret}`).toString('base64')}`
: '';
const ipfsAuth = ipfsAuthUser && ipfsAuthSecret ? `Basic ${Buffer.from(`${ipfsAuthUser}:${ipfsAuthSecret}`).toString('base64')}` : '';

const headers = {
Accept: '*/*',
Expand All @@ -116,10 +109,7 @@ export class IpfsService {
const ipfsGet = `${this.configService.ipfsEndpoint}/api/v0/pin/ls?type=all&quiet=true&arg=${v0Cid}`;
const ipfsAuthUser = this.configService.ipfsBasicAuthUser;
const ipfsAuthSecret = this.configService.ipfsBasicAuthSecret;
const ipfsAuth =
ipfsAuthUser && ipfsAuthSecret
? `Basic ${Buffer.from(`${ipfsAuthUser}:${ipfsAuthSecret}`).toString('base64')}`
: '';
const ipfsAuth = ipfsAuthUser && ipfsAuthSecret ? `Basic ${Buffer.from(`${ipfsAuthUser}:${ipfsAuthSecret}`).toString('base64')}` : '';

const headers = {
Accept: '*/*',
Expand All @@ -136,11 +126,10 @@ export class IpfsService {
return response && response.data && JSON.stringify(response.data).indexOf(v0Cid) >= 0;
}

private async ipfsHashBuffer(fileBuffer: Buffer): Promise<string> {
public async ipfsHashBuffer(fileBuffer: Buffer): Promise<string> {
this.logger.debug(`Hashing file buffer with length: ${fileBuffer.length}`);
const hashed = await hasher.digest(fileBuffer);
const hash = create(hasher.code, hashed.bytes);
saraswatpuneet marked this conversation as resolved.
Show resolved Hide resolved
return base58btc.encode(hash.bytes);
const hash = hasher.digest(fileBuffer);
return base58btc.encode((await hash).bytes);
saraswatpuneet marked this conversation as resolved.
Show resolved Hide resolved
saraswatpuneet marked this conversation as resolved.
Show resolved Hide resolved
}

public ipfsUrl(cid: string): string {
Expand Down
4 changes: 2 additions & 2 deletions services/content-watcher/libs/common/src/ipfs/ipfs.dsnp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class IPFSContentProcessor extends BaseConsumer {
if (isBroadcast(mapRecord)) {
announcementResponse.announcement = {
fromId: mapRecord.fromId,
contentHash: bases.base16.encode(mapRecord.contentHash as never),
saraswatpuneet marked this conversation as resolved.
Show resolved Hide resolved
contentHash: mapRecord.contentHash,
url: mapRecord.url,
announcementType: mapRecord.announcementType,
};
Expand All @@ -108,7 +108,7 @@ export class IPFSContentProcessor extends BaseConsumer {
announcementResponse.announcement = {
fromId: mapRecord.fromId,
targetAnnouncementType: mapRecord.targetAnnouncementType,
targetContentHash: bases.base58btc.encode(mapRecord.targetContentHash as any),
targetContentHash: mapRecord.targetContentHash,
announcementType: mapRecord.announcementType,
};
queue = this.tombstoneQueue;
Expand Down
6 changes: 3 additions & 3 deletions services/content-watcher/libs/common/src/utils/ipfs.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ export class IpfsService {

private async ipfsHashBuffer(fileBuffer: Buffer): Promise<string> {
this.logger.debug(`Hashing file buffer with length: ${fileBuffer.length}`);
const hashed = await hasher.digest(fileBuffer);
const hash = create(hasher.code, hashed.bytes);
return base58btc.encode(hash.bytes);
const hash = hasher.digest(fileBuffer);
return base58btc.encode((await hash).bytes);
}


public ipfsUrl(cid: string): string {
if (this.configService.ipfsGatewayUrl.includes('[CID]')) {
return this.configService.ipfsGatewayUrl.replace('[CID]', cid);
Expand Down
Loading