Skip to content

Commit

Permalink
Merge pull request #192 from ltonetwork/mapped-anchor-sender
Browse files Browse the repository at this point in the history
Specify sender when verifying anchors
  • Loading branch information
jasny authored May 24, 2023
2 parents 4986e34 + 82e89c2 commit ed9f954
Show file tree
Hide file tree
Showing 15 changed files with 353 additions and 155 deletions.
9 changes: 7 additions & 2 deletions src/anchor/mapped-anchor.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('MappedAnchorService', () => {
const transaction = {
id: 'fake_transaction',
type: 22,
sender: '3NCEKjExpsxzyJpLutF8U9uVDiKu8oStn68',
anchors: {
GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn: '3zLWTHPNkmDsCRi2kZqFXFSBnTYykz13gHLezU4p6zmu',
},
Expand All @@ -60,9 +61,13 @@ describe('MappedAnchorService', () => {
expect(spies.storage.saveMappedAnchor.mock.calls[0][0]).toBe(
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
);
expect(spies.storage.saveMappedAnchor.mock.calls[0][1]).toMatchObject({
anchor: '2c67899b31a40620b0760035720a9cabd7f414c6da3db561461b1e48fe26cb08',
expect(spies.storage.saveMappedAnchor.mock.calls[0][1]).toBe(
'2c67899b31a40620b0760035720a9cabd7f414c6da3db561461b1e48fe26cb08',
);
expect(spies.storage.saveMappedAnchor.mock.calls[0][2]).toMatchObject({
hash: '2c67899b31a40620b0760035720a9cabd7f414c6da3db561461b1e48fe26cb08',
id: 'fake_transaction',
sender: '3NCEKjExpsxzyJpLutF8U9uVDiKu8oStn68',
blockHeight: 1,
position: 0,
});
Expand Down
5 changes: 3 additions & 2 deletions src/anchor/mapped-anchor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ export class MappedAnchorService {

this.logger.debug(`mapped-anchor: save ${hexKey}:${hexValue} with transaction ${transaction.id}`);

await this.storage.saveMappedAnchor(hexKey, {
anchor: hexValue,
await this.storage.saveMappedAnchor(hexKey, hexValue, {
hash: hexValue,
id: transaction.id,
sender: transaction.sender,
blockHeight,
position,
});
Expand Down
2 changes: 1 addition & 1 deletion src/config/data/development.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"url": "https://testnet.lto.network"
},
"log": {
"level": "debug"
"level": "info"
},
"starting_block": -1
}
14 changes: 7 additions & 7 deletions src/hash/hash.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('HashController', () => {

function spy() {
const hash = {
anchor: jest.spyOn(hashService, 'anchor').mockImplementation(async () => chainpoint),
hash: jest.spyOn(hashService, 'anchor').mockImplementation(async () => chainpoint),
};

const node = {
Expand Down Expand Up @@ -65,9 +65,9 @@ describe('HashController', () => {
expect(res.header['content-type']).toBe('application/json; charset=utf-8');
expect(res.body).toEqual({ chainpoint });

expect(spies.hash.anchor.mock.calls.length).toBe(1);
expect(spies.hash.anchor.mock.calls[0][0]).toBe(hash);
expect(spies.hash.anchor.mock.calls[0][1]).toBe('hex');
expect(spies.hash.hash.mock.calls.length).toBe(1);
expect(spies.hash.hash.mock.calls[0][0]).toBe(hash);
expect(spies.hash.hash.mock.calls[0][1]).toBe('hex');
});

test('should anchor hash to the blockchain when auth is enabled and given', async () => {
Expand All @@ -85,9 +85,9 @@ describe('HashController', () => {
expect(res.header['content-type']).toBe('application/json; charset=utf-8');
expect(res.body).toEqual({ chainpoint });

expect(spies.hash.anchor.mock.calls.length).toBe(1);
expect(spies.hash.anchor.mock.calls[0][0]).toBe(hash);
expect(spies.hash.anchor.mock.calls[0][1]).toBe('hex');
expect(spies.hash.hash.mock.calls.length).toBe(1);
expect(spies.hash.hash.mock.calls[0][0]).toBe(hash);
expect(spies.hash.hash.mock.calls[0][1]).toBe('hex');
});

test('should return an unauthorized when auth is enabled and not given', async () => {
Expand Down
5 changes: 2 additions & 3 deletions src/hash/hash.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,10 @@ export class HashController {
try {
const chainpoint = await this.hash.anchor(hash, encoding);

if (!chainpoint) {
if (!chainpoint)
res.status(202).end();
} else {
else
res.status(200).json({chainpoint});
}
} catch (e) {
this.logger.error(`hash-controller: failed to anchor '${e}'`, { stack: e.stack });

Expand Down
207 changes: 147 additions & 60 deletions src/hash/hash.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ describe('HashService', () => {
expect(getAnchor.mock.calls[2][0]).toBe('4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce');

expect(result.anchors).toEqual({
'8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG': true,
'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg': true,
'6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf': true,
'8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG': 1,
'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg': 2,
'6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf': 3,
});
expect(result.verified).toBe(true);
});
Expand Down Expand Up @@ -82,102 +82,189 @@ describe('HashService', () => {
expect(getAnchor.mock.calls[2][0]).toBe('4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce');

expect(result.anchors).toEqual({
'8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG': true,
'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg': false,
'6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf': true,
'8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG': 1,
'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg': null,
'6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf': 3,
});
expect(result.verified).toBe(false);
});
});

describe('verifyMappedAnchors()', () => {
test('return verified is true if all anchors match', async () => {
let getMappedAnchorsByKey;

const stored = {
'146da586036684deee1acba1ae0520a79e7502da8b302dc4b683bd4f88f7c8e1': [
{
id: 1,
hash: '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b',
sender: '3NCEKjExpsxzyJpLutF8U9uVDiKu8oStn68',
},
{
id: 2,
hash: '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae',
sender: '3NBYfy8LvDgnsr9qEiWHKD6qP7RMQdb2Uf8',
},
],
'34313fc9e1050a02c7d4931f8312cca75b9f4edef653b34794606526b9ec5a7b': [
{
id: 3,
hash: 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35',
sender: '3NBYfy8LvDgnsr9qEiWHKD6qP7RMQdb2Uf8',
},
],
'10d331592917e8ee791c5a01f2cf4bd54de81bf648fd7fd1340aa55b73ce7bda': [
{
id: 4,
hash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
sender: '3NCEKjExpsxzyJpLutF8U9uVDiKu8oStn68',
},
],
};

const expectedAnchors = {
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': 1,
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 3,
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': 4,
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': null,
};

const expectedMap = {
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG',
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': 'GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn',
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': null,
};

beforeEach(() => {
getMappedAnchorsByKey = jest.spyOn(storageService, 'getMappedAnchorsByKey')
.mockImplementation(async hash => stored[hash] || []);
});

function assertGetMappedAnchorsByKeyCalls() {
expect(getMappedAnchorsByKey.mock.calls.length).toBe(4);
expect(getMappedAnchorsByKey.mock.calls[0][0]).toBe('146da586036684deee1acba1ae0520a79e7502da8b302dc4b683bd4f88f7c8e1');
expect(getMappedAnchorsByKey.mock.calls[1][0]).toBe('34313fc9e1050a02c7d4931f8312cca75b9f4edef653b34794606526b9ec5a7b');
expect(getMappedAnchorsByKey.mock.calls[2][0]).toBe('10d331592917e8ee791c5a01f2cf4bd54de81bf648fd7fd1340aa55b73ce7bda');
expect(getMappedAnchorsByKey.mock.calls[3][0]).toBe('d5ce2b19fbda14a25deac948154722f33efd37b369a32be8f03ec2be8ef7d3a5');
}

test('return verified is true if all anchors match as first entry', async () => {
const pairs = {
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG',
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': '6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf',
};

const stored = {
'146da586036684deee1acba1ae0520a79e7502da8b302dc4b683bd4f88f7c8e1': { anchor: '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' },
'34313fc9e1050a02c7d4931f8312cca75b9f4edef653b34794606526b9ec5a7b': { anchor: 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35' },
'10d331592917e8ee791c5a01f2cf4bd54de81bf648fd7fd1340aa55b73ce7bda': { anchor: '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' },
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': 'GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn',
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': null,
};

const getMappedAnchor = jest.spyOn(storageService, 'getMappedAnchor')
.mockImplementation(async hash => stored[hash] || {});

const result = await hashService.verifyMappedAnchors(pairs, 'base58');
const {verified, anchors, map} = await hashService.verifyMappedAnchors(pairs, 'base58');
assertGetMappedAnchorsByKeyCalls();

expect(getMappedAnchor.mock.calls.length).toBe(3);
expect(getMappedAnchor.mock.calls[0][0]).toBe('146da586036684deee1acba1ae0520a79e7502da8b302dc4b683bd4f88f7c8e1');
expect(getMappedAnchor.mock.calls[1][0]).toBe('34313fc9e1050a02c7d4931f8312cca75b9f4edef653b34794606526b9ec5a7b');
expect(getMappedAnchor.mock.calls[2][0]).toBe('10d331592917e8ee791c5a01f2cf4bd54de81bf648fd7fd1340aa55b73ce7bda');

expect(result.anchors).toEqual(pairs);
expect(result.verified).toBe(true);
expect(anchors).toEqual(expectedAnchors);
expect(map).toEqual(expectedMap);
expect(verified).toBe(true);
});

test('return verified is false if one anchors is not found', async () => {
const pairs = {
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG',
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': '6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': 'GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn',
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': '81u',
};

const stored = {
'146da586036684deee1acba1ae0520a79e7502da8b302dc4b683bd4f88f7c8e1': { anchor: '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' },
'34313fc9e1050a02c7d4931f8312cca75b9f4edef653b34794606526b9ec5a7b': { },
'10d331592917e8ee791c5a01f2cf4bd54de81bf648fd7fd1340aa55b73ce7bda': { anchor: '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' },
};
const {verified, anchors, map} = await hashService.verifyMappedAnchors(pairs, 'base58');
assertGetMappedAnchorsByKeyCalls();

const getMappedAnchor = jest.spyOn(storageService, 'getMappedAnchor')
.mockImplementation(async hash => stored[hash] || {});
expect(anchors).toEqual(expectedAnchors);
expect(map).toEqual(expectedMap);
expect(verified).toBe(false);
});

const result = await hashService.verifyMappedAnchors(pairs, 'base58');
test('return verified is false if one anchors is not the first', async () => {
const pairs = {
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '3yMApqCuCjXDWPrbjfR5mjCPTHqFG8Pux1TxQrEM35jj',
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': 'GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn',
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': null,
};

expect(getMappedAnchor.mock.calls.length).toBe(3);
expect(getMappedAnchor.mock.calls[0][0]).toBe('146da586036684deee1acba1ae0520a79e7502da8b302dc4b683bd4f88f7c8e1');
expect(getMappedAnchor.mock.calls[1][0]).toBe('34313fc9e1050a02c7d4931f8312cca75b9f4edef653b34794606526b9ec5a7b');
expect(getMappedAnchor.mock.calls[2][0]).toBe('10d331592917e8ee791c5a01f2cf4bd54de81bf648fd7fd1340aa55b73ce7bda');
const {verified, anchors, map} = await hashService.verifyMappedAnchors(pairs, 'base58');
assertGetMappedAnchorsByKeyCalls();

expect(result.anchors).toEqual({
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG',
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': null,
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': '6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf',
});
expect(result.verified).toBe(false);
expect(anchors).toEqual(expectedAnchors);
expect(map).toEqual(expectedMap);
expect(verified).toBe(false);
});

test('return verified is false if one anchors does not match', async () => {
const pairs = {
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG',
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': '6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': '81u',
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': null,
};

const stored = {
'146da586036684deee1acba1ae0520a79e7502da8b302dc4b683bd4f88f7c8e1': { anchor: '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' },
'34313fc9e1050a02c7d4931f8312cca75b9f4edef653b34794606526b9ec5a7b': { anchor: 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35' },
'10d331592917e8ee791c5a01f2cf4bd54de81bf648fd7fd1340aa55b73ce7bda': { anchor: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' },
const {verified, anchors, map} = await hashService.verifyMappedAnchors(pairs, 'base58');
assertGetMappedAnchorsByKeyCalls();

expect(anchors).toEqual(expectedAnchors);
expect(map).toEqual(expectedMap);
expect(verified).toBe(false);
});

test('return verified is false if an anchor exists which is expected to be null', async () => {
const pairs = {
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG',
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': null,
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': null,
};

const getMappedAnchor = jest.spyOn(storageService, 'getMappedAnchor')
.mockImplementation(async hash => stored[hash] || {});
const {verified, anchors, map} = await hashService.verifyMappedAnchors(pairs, 'base58');
assertGetMappedAnchorsByKeyCalls();

const result = await hashService.verifyMappedAnchors(pairs, 'base58');
expect(anchors).toEqual(expectedAnchors);
expect(map).toEqual(expectedMap);
expect(verified).toBe(false);
});

expect(getMappedAnchor.mock.calls.length).toBe(3);
expect(getMappedAnchor.mock.calls[0][0]).toBe('146da586036684deee1acba1ae0520a79e7502da8b302dc4b683bd4f88f7c8e1');
expect(getMappedAnchor.mock.calls[1][0]).toBe('34313fc9e1050a02c7d4931f8312cca75b9f4edef653b34794606526b9ec5a7b');
expect(getMappedAnchor.mock.calls[2][0]).toBe('10d331592917e8ee791c5a01f2cf4bd54de81bf648fd7fd1340aa55b73ce7bda');
test('return verified is true when filtering on sender', async () => {
const pairs = {
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': {
hash: '3yMApqCuCjXDWPrbjfR5mjCPTHqFG8Pux1TxQrEM35jj',
sender: '3NBYfy8LvDgnsr9qEiWHKD6qP7RMQdb2Uf8',
},
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': {
hash: 'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg',
sender: '3NBYfy8LvDgnsr9qEiWHKD6qP7RMQdb2Uf8',
},
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': {
hash: null,
sender: '3NBYfy8LvDgnsr9qEiWHKD6qP7RMQdb2Uf8',
},
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': {
hash: null,
sender: '3NBYfy8LvDgnsr9qEiWHKD6qP7RMQdb2Uf8',
},
};

expect(result.anchors).toEqual({
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '8EjkXVSTxMFjCvNNsTo8RBMDEVQmk7gYkW4SCDuvdsBG',
const {verified, anchors, map} = await hashService.verifyMappedAnchors(pairs, 'base58');
assertGetMappedAnchorsByKeyCalls();

expect(anchors).toEqual({
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': 2,
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 3,
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': null,
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': null,
});
expect(map).toEqual({
'2Nk8JfzQ47wX7XEdkemRJbNTLxC529YwJ92U9g6FyeAc': '3yMApqCuCjXDWPrbjfR5mjCPTHqFG8Pux1TxQrEM35jj',
'4WjkssnwoTRrTo4xKX8rac1b3zwrGvpy4kgRCsHJ49yc': 'FJKTv1un7qsnyKdwKez7B67JJp3oCU5ntCVXcRsWEjtg',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': 'GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn',
'28gJaguAnsUEUMcfzXU6tpCLjhTH2xfg2G3NEHzetmUd': null,
'FPcBCxxV4teUiKecPnnzqqunAKEhwNJLckWTWAoaD5oz': null,
});
expect(result.verified).toBe(false);
expect(verified).toBe(true);
});
});
});
Loading

0 comments on commit ed9f954

Please sign in to comment.