Skip to content
This repository has been archived by the owner on Dec 16, 2021. It is now read-only.

feat: waitForStateTransitionResult endpoint #331

Merged
merged 40 commits into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
deaf239
feat: waitForStateTransitionResult endpoint
Jan 13, 2021
74a6d3f
bugfix
Jan 13, 2021
3aaa596
test: add unit tests
Jan 14, 2021
8071597
bugfix
Jan 14, 2021
3fd9b7e
Bugfix
Jan 15, 2021
edca7eb
remove rewiremock
Jan 15, 2021
70cdd37
fix test name
antouhou Jan 19, 2021
f227a71
add waitForTransactionHash to the WS client
antouhou Jan 19, 2021
80d5650
Merge branch 'v0.18-dev' into wait-for-st
shumkov Jan 20, 2021
296d18b
add TransactionsClient.js to subscribe to tendermint transactions mor…
antouhou Jan 20, 2021
ca734b8
Merge remote-tracking branch 'origin/wait-for-st' into wait-for-st
antouhou Jan 20, 2021
c4f3ed1
move init logic from constructor to `start` method in TransactionsCli…
antouhou Jan 20, 2021
735d184
marked private methods as private in jsdoc
antouhou Jan 20, 2021
fbd27ce
add jsdoc for TransactionsClient.js start method
antouhou Jan 20, 2021
44044e1
shortened start method
antouhou Jan 20, 2021
ac42552
remove unused method from WsClient.js
antouhou Jan 20, 2021
ff04df5
add handling of the st timeout in waitForStateTransitionResultHandler…
antouhou Jan 20, 2021
2638966
fixed old waitForStateTransitionResultHandlerFactory tests
antouhou Jan 20, 2021
08f8373
fix TransactionsClient.spec.js
antouhou Jan 20, 2021
0199bf1
remove unnecessary condition
antouhou Jan 20, 2021
a3bcd59
Update scripts/api.js
antouhou Jan 20, 2021
6879af7
Update scripts/api.js
antouhou Jan 20, 2021
08a59ee
Update scripts/api.js
antouhou Jan 20, 2021
9544a49
Update test/integration/grpcServer/handlers/platform/waitForStateTran…
antouhou Jan 20, 2021
6d8f0bc
Update test/integration/grpcServer/handlers/platform/waitForStateTran…
antouhou Jan 20, 2021
2ded36a
Update test/integration/grpcServer/handlers/platform/waitForStateTran…
antouhou Jan 20, 2021
32e0ae9
Update test/integration/grpcServer/handlers/platform/waitForStateTran…
antouhou Jan 20, 2021
907548f
remove duplicated test
antouhou Jan 20, 2021
45ea796
Merge remote-tracking branch 'origin/wait-for-st' into wait-for-st
antouhou Jan 20, 2021
f89c546
add dpp/DriveStateRepository.js and renamed old class with this name …
antouhou Jan 22, 2021
ad45925
add test for waiting for blocks
antouhou Jan 22, 2021
9f9e39c
fix waitForStateTransitionResultHandlerFactory.js tests
antouhou Jan 22, 2021
a3cdb3c
add handling of checTx errors in broadcastStateTransition
antouhou Jan 28, 2021
7269007
rename TransactionsClient to BlockchainListener.js
antouhou Jan 29, 2021
9399de0
add dpp to DriveStateRepository and added a test
antouhou Jan 29, 2021
36074e2
remove unused imports from state repository
antouhou Jan 29, 2021
fb59e20
Update test/integration/externalApis/tenderdash/BlockchainListener.sp…
shumkov Jan 29, 2021
498360b
Merge branch 'v0.18-dev' into wait-for-st
antouhou Feb 1, 2021
2f4a527
update lock
antouhou Feb 1, 2021
d729dc2
feat: update dapi-grpc to 0.18.0-dev.3
Feb 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions lib/dpp/DriveStateRepository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @implements StateRepository
*/
class DriveStateRepository {
/**
* @param {DriveClient} driveClient
* @param {DashPlatformProtocol} dpp
*/
constructor(driveClient, dpp) {
this.driveClient = driveClient;
this.dpp = dpp;
}

/**
* Fetches data contract from Drive
* @param {Identifier} contractIdentifier
* @return {Promise<DataContract>}
*/
async fetchDataContract(contractIdentifier) {
const driveResponse = await this.driveClient.fetchDataContract(
contractIdentifier, false,
);

return this.dpp.dataContract.createFromBuffer(driveResponse.data);
}
}

module.exports = DriveStateRepository;
25 changes: 25 additions & 0 deletions lib/errors/TransactionWaitPeriodExceededError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class TransactionWaitPeriodExceededError extends Error {
/**
* @param {string} transactionHash
* @param originalStack
*/
constructor(transactionHash, originalStack) {
const message = `Transaction waiting period for ${transactionHash} exceeded`;
super(message);
if (originalStack) {
this.stack = originalStack;
}

this.transactionHash = transactionHash;
}

/**
* Returns transaction hash
* @return {string}
*/
getTransactionHash() {
return this.transactionHash;
}
}

module.exports = TransactionWaitPeriodExceededError;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const cbor = require('cbor');
const RPCError = require('../../rpcServer/RPCError');
const AbciResponseError = require('../../errors/AbciResponseError');

class DriveStateRepository {
class DriveClient {
/**
* @param options
* @param {string} options.host
Expand Down Expand Up @@ -160,6 +160,25 @@ class DriveStateRepository {
prove,
);
}

/**
* Fetch proofs by ids
*
* @param {Buffer[]} [documentIds]
* @param {Buffer[]} [identityIds]
* @param {Buffer[]} [dataContractIds]
* @return {Promise<{data: Buffer}>}
*/
async fetchProofs({ documentIds, identityIds, dataContractIds }) {
return this.request(
'/proofs',
{
documentIds,
identityIds,
dataContractIds,
},
);
}
}

module.exports = DriveStateRepository;
module.exports = DriveClient;
116 changes: 116 additions & 0 deletions lib/externalApis/tenderdash/BlockchainListener.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
const EventEmitter = require('events');
const TransactionWaitPeriodExceededError = require('../../errors/TransactionWaitPeriodExceededError');

const TX_QUERY = 'tm.event = \'Tx\'';
const NEW_BLOCK_QUERY = 'tm.event = \'NewBlock\'';
const events = {
NEW_BLOCK: 'block',
};

class BlockchainListener extends EventEmitter {
/**
* @param {WsClient} tenderdashWsClient
*/
constructor(tenderdashWsClient) {
super();
this.wsClient = tenderdashWsClient;
}

/**
* Returns an event name for a specific hash
* @private
* @param {string} transactionHashString
* @return {string}
*/
static getTransactionEventName(transactionHashString) {
return `transaction:${transactionHashString}`;
}

/**
* Subscribe to transactions and attach transaction event handler
*/
start() {
this.wsClient.subscribe(TX_QUERY);
this.wsClient.on(TX_QUERY, this.emitTransaction.bind(this));

this.wsClient.subscribe(NEW_BLOCK_QUERY);
this.wsClient.on(NEW_BLOCK_QUERY, (message) => {
this.emit(events.NEW_BLOCK, message);
});
}

/**
* Creates promisified event handler
* @private
* @param {string} eventName
* @param {function} resolve
* @return {function}
*/
createPromiseHandler(eventName, resolve) {
const handler = (data) => {
this.off(eventName, handler);
resolve(data);
};

return handler;
}

/**
* Emits transaction:%tx_hash% if there's a transaction in the message
* @private
* @param {Object} message
*/
emitTransaction(message) {
const hashArray = message && message.events ? message.events['tx.hash'] : null;
const hashString = Array.isArray(hashArray) && hashArray[0];
if (!hashString) {
return;
}

this.emit(BlockchainListener.getTransactionEventName(hashString), message);
}

/**
* Returns data for a transaction or rejects after a timeout
* @param {string} hashString - transaction hash to resolve data for
* @param {number} [timeout] - timeout to reject after
* @return {Promise<Object>}
*/
waitForTransaction(hashString, timeout = 60000) {
const topic = BlockchainListener.getTransactionEventName(hashString);
let handler;

return Promise.race([
new Promise((resolve) => {
handler = this.createPromiseHandler(topic, resolve);
this.on(topic, handler);
}),
new Promise((resolve, reject) => {
setTimeout(() => {
this.off(topic, handler);
reject(new TransactionWaitPeriodExceededError(hashString));
}, timeout);
}),
]);
}

waitForNextBlock() {
return new Promise((resolve) => {
this.once(events.NEW_BLOCK, resolve);
});
}

async waitForBlocks(countToWait = 1) {
let blocksSeen = 0;
while (blocksSeen !== countToWait) {
await this.waitForNextBlock();
blocksSeen += 1;
}
}
}

BlockchainListener.TX_QUERY = TX_QUERY;
BlockchainListener.NEW_BLOCK_QUERY = NEW_BLOCK_QUERY;
BlockchainListener.events = events;

module.exports = BlockchainListener;
Loading