Skip to content

Commit

Permalink
feat: provide state tree proofs (dashevo#323)
Browse files Browse the repository at this point in the history
  • Loading branch information
Konstantin Shuplenkov committed Dec 17, 2020
1 parent 197b905 commit 61dac7f
Show file tree
Hide file tree
Showing 14 changed files with 465 additions and 131 deletions.
44 changes: 30 additions & 14 deletions lib/externalApis/drive/DriveStateRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,25 @@ class DriveStateRepository {
*
* @param {string} path
* @param {Object} data
* @param {boolean} prove
*
* @return {Promise<Buffer>}
* @return {Promise<{ data: Buffer, [proof]: {rootTreeProof: Buffer, storeTreeProof: Buffer}}>}
*/
async request(path, data = {}) {
async request(path, data = {}, prove = false) {
const encodedData = cbor.encode(data);

const requestOptions = {
path,
data: encodedData.toString('hex'),
};

if (prove === true) {
requestOptions.prove = 'true';
}

const { result, error } = await this.client.request(
'abci_query', {
path,
data: encodedData.toString('hex'),
},
'abci_query',
requestOptions,
);

// Handle JSON RPC error
Expand All @@ -45,9 +53,7 @@ class DriveStateRepository {

if (response.code === undefined || response.code === 0) {
// no errors found return the serialized response value
const value = cbor.decode(Buffer.from(response.value, 'base64'));

return value.data;
return cbor.decode(Buffer.from(response.value, 'base64'));
}

const { error: abciError } = JSON.parse(response.log);
Expand All @@ -59,15 +65,17 @@ class DriveStateRepository {
* Fetch serialized data contract
*
* @param {string} contractId
* @param {boolean} prove - include proofs into the response
*
* @return {Promise<Buffer>}
*/
async fetchDataContract(contractId) {
async fetchDataContract(contractId, prove) {
return this.request(
'/dataContracts',
{
id: contractId,
},
prove,
);
}

Expand All @@ -83,65 +91,73 @@ class DriveStateRepository {
* @param {number} options.limit - how many objects to fetch
* @param {number} options.startAt - number of objects to skip
* @param {number} options.startAfter - exclusive skip
* @param {boolean} prove - include proofs into the response
*
* @return {Promise<Buffer[]>}
*/
async fetchDocuments(contractId, type, options) {
async fetchDocuments(contractId, type, options, prove) {
return this.request(
'/dataContracts/documents',
{
...options,
contractId,
type,
},
prove,
);
}

/**
* Fetch serialized identity
*
* @param {string} id
* @param {boolean} prove - include proofs into the response
*
* @return {Promise<Buffer>}
*/
async fetchIdentity(id) {
async fetchIdentity(id, prove) {
return this.request(
'/identities',
{
id,
},
prove,
);
}

/**
* Fetch serialized identities by it's public key hashes
*
* @param {Buffer[]} publicKeyHashes
* @param {boolean} prove - include proofs into the response
*
* @return {Promise<Buffer[]>}
*/
async fetchIdentitiesByPublicKeyHashes(publicKeyHashes) {
async fetchIdentitiesByPublicKeyHashes(publicKeyHashes, prove) {
return this.request(
'/identities/by-public-key-hash',
{
publicKeyHashes,
},
prove,
);
}

/**
* Fetch serialized identity ids by it's public key hashes
*
* @param {Buffer[]} publicKeyHashes
* @param {boolean} prove - include proofs into the response
*
* @return {Promise<Buffer[]>}
*/
async fetchIdentityIdsByPublicKeyHashes(publicKeyHashes) {
async fetchIdentityIdsByPublicKeyHashes(publicKeyHashes, prove) {
return this.request(
'/identities/by-public-key-hash/id',
{
publicKeyHashes,
},
prove,
);
}
}
Expand Down
16 changes: 14 additions & 2 deletions lib/grpcServer/handlers/platform/getDataContractHandlerFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
const {
v0: {
GetDataContractResponse,
Proof,
},
} = require('@dashevo/dapi-grpc');

Expand All @@ -26,19 +27,22 @@ function getDataContractHandlerFactory(driveStateRepository, handleAbciResponseE
*
* @param {Object} call
*
* @returns {Promise<GetDocumentsResponse>}
* @returns {Promise<GetDataContractResponse>}
*/
async function getDataContractHandler(call) {
const { request } = call;
const id = request.getId();
const prove = request.getProve();

if (id === null) {
throw new InvalidArgumentGrpcError('id is not specified');
}

let dataContractBuffer;
let proofObject;
try {
dataContractBuffer = await driveStateRepository.fetchDataContract(id);
({ data: dataContractBuffer, proof: proofObject } = await driveStateRepository
.fetchDataContract(id, prove));
} catch (e) {
if (e instanceof AbciResponseError) {
handleAbciResponseError(e);
Expand All @@ -50,6 +54,14 @@ function getDataContractHandlerFactory(driveStateRepository, handleAbciResponseE

response.setDataContract(dataContractBuffer);

if (prove === true) {
const proof = new Proof();
proof.setRootTreeProof(proofObject.rootTreeProof);
proof.setStoreTreeProof(proofObject.storeTreeProof);

response.setProof(proof);
}

return response;
}

Expand Down
21 changes: 17 additions & 4 deletions lib/grpcServer/handlers/platform/getDocumentsHandlerFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const {
const {
v0: {
GetDocumentsResponse,
Proof,
},
} = require('@dashevo/dapi-grpc');

Expand All @@ -35,7 +36,6 @@ function getDocumentsHandlerFactory(driveStateRepository, handleAbciResponseErro
const { request } = call;

// Data Contract ID

const dataContractId = request.getDataContractId();

if (!dataContractId) {
Expand Down Expand Up @@ -107,11 +107,16 @@ function getDocumentsHandlerFactory(driveStateRepository, handleAbciResponseErro
startAt,
};

// Prove

const prove = request.getProve();

let documentBuffers;
let proofObject;
try {
documentBuffers = await driveStateRepository.fetchDocuments(
dataContractId, documentType, options,
);
({ data: documentBuffers, proof: proofObject } = await driveStateRepository.fetchDocuments(
dataContractId, documentType, options, prove,
));
} catch (e) {
if (e instanceof AbciResponseError) {
handleAbciResponseError(e);
Expand All @@ -123,6 +128,14 @@ function getDocumentsHandlerFactory(driveStateRepository, handleAbciResponseErro

response.setDocumentsList(documentBuffers);

if (prove === true) {
const proof = new Proof();
proof.setRootTreeProof(proofObject.rootTreeProof);
proof.setStoreTreeProof(proofObject.storeTreeProof);

response.setProof(proof);
}

return response;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
const {
v0: {
GetIdentitiesByPublicKeyHashesResponse,
Proof,
},
} = require('@dashevo/dapi-grpc');

Expand Down Expand Up @@ -37,11 +38,13 @@ function getIdentitiesByPublicKeyHashesHandlerFactory(
throw new InvalidArgumentGrpcError('No public key hashes were provided');
}

const prove = request.getProve();

let identities;
let proofObject;
try {
identities = await driveStateRepository.fetchIdentitiesByPublicKeyHashes(
publicKeyHashes,
);
({ data: identities, proof: proofObject } = await driveStateRepository
.fetchIdentitiesByPublicKeyHashes(publicKeyHashes, prove));
} catch (e) {
if (e instanceof AbciResponseError) {
handleAbciResponseError(e);
Expand All @@ -55,6 +58,14 @@ function getIdentitiesByPublicKeyHashesHandlerFactory(
identities,
);

if (prove === true) {
const proof = new Proof();
proof.setRootTreeProof(proofObject.rootTreeProof);
proof.setStoreTreeProof(proofObject.storeTreeProof);

response.setProof(proof);
}

return response;
}

Expand Down
16 changes: 15 additions & 1 deletion lib/grpcServer/handlers/platform/getIdentityHandlerFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
const {
v0: {
GetIdentityResponse,
Proof,
},
} = require('@dashevo/dapi-grpc');

Expand Down Expand Up @@ -37,9 +38,14 @@ function getIdentityHandlerFactory(driveStateRepository, handleAbciResponseError
throw new InvalidArgumentGrpcError('id is not specified');
}

const prove = request.getProve();

let identityBuffer;
let proofObject;

try {
identityBuffer = await driveStateRepository.fetchIdentity(id);
({ data: identityBuffer, proof: proofObject } = await driveStateRepository
.fetchIdentity(id, prove));
} catch (e) {
if (e instanceof AbciResponseError) {
handleAbciResponseError(e);
Expand All @@ -51,6 +57,14 @@ function getIdentityHandlerFactory(driveStateRepository, handleAbciResponseError

response.setIdentity(identityBuffer);

if (prove === true) {
const proof = new Proof();
proof.setRootTreeProof(proofObject.rootTreeProof);
proof.setStoreTreeProof(proofObject.storeTreeProof);

response.setProof(proof);
}

return response;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
const {
v0: {
GetIdentityIdsByPublicKeyHashesResponse,
Proof,
},
} = require('@dashevo/dapi-grpc');

Expand Down Expand Up @@ -37,11 +38,17 @@ function getIdentityIdsByPublicKeyHashesHandlerFactory(
throw new InvalidArgumentGrpcError('No public key hashes were provided');
}

const prove = request.getProve();

let identityIds;
let proofObject;

try {
identityIds = await driveStateRepository.fetchIdentityIdsByPublicKeyHashes(
publicKeyHashes,
);
({ data: identityIds, proof: proofObject } = await driveStateRepository
.fetchIdentityIdsByPublicKeyHashes(
publicKeyHashes,
prove,
));
} catch (e) {
if (e instanceof AbciResponseError) {
handleAbciResponseError(e);
Expand All @@ -55,6 +62,14 @@ function getIdentityIdsByPublicKeyHashesHandlerFactory(
identityIds,
);

if (prove === true) {
const proof = new Proof();
proof.setRootTreeProof(proofObject.rootTreeProof);
proof.setStoreTreeProof(proofObject.storeTreeProof);

response.setProof(proof);
}

return response;
}

Expand Down
Loading

0 comments on commit 61dac7f

Please sign in to comment.