From f96ccb0c56da9fe0d81a65d0b9025c9b44925465 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Wed, 20 Apr 2022 16:42:07 +0300 Subject: [PATCH] Add reuseOrder method (#1421) * added reuseOrder method * wip add test to reuseOrder * update test * check also ProviderFee event --- src/tokens/Datatoken.ts | 77 ++++++++++++++++++++++++++++++ test/unit/tokens/Datatoken.test.ts | 41 ++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/src/tokens/Datatoken.ts b/src/tokens/Datatoken.ts index 701bb3023..bcebc1dfd 100644 --- a/src/tokens/Datatoken.ts +++ b/src/tokens/Datatoken.ts @@ -1009,6 +1009,83 @@ export class Datatoken { } } + /** Estimate gas cost for reuseOrder method + * @param {String} dtAddress Datatoken address + * @param {String} address User address which calls + * @param {String} orderTxId previous valid order + * @param {providerFees} providerFees provider fees + * @param {Contract} contractInstance optional contract instance + * @return {Promise} + */ + public async estGasReuseOrder( + dtAddress: string, + address: string, + orderTxId: string, + providerFees: ProviderFees, + contractInstance?: Contract + ): Promise { + const dtContract = + contractInstance || + setContractDefaults( + new this.web3.eth.Contract(this.datatokensAbi, dtAddress), + this.config + ) + + // Estimate gas for reuseOrder method + const gasLimitDefault = this.GASLIMIT_DEFAULT + let estGas + try { + estGas = await dtContract.methods + .reuseOrder(orderTxId, providerFees) + .estimateGas({ from: address }, (err, estGas) => (err ? gasLimitDefault : estGas)) + } catch (e) { + estGas = gasLimitDefault + } + return estGas + } + + /** Reuse Order: called by payer or consumer having a valid order, but with expired provider access. + * Pays the provider fee again, but it will not require a new datatoken payment + * Requires previous approval of provider fee. + * @param {String} dtAddress Datatoken address + * @param {String} address User address which calls + * @param {String} orderTxId previous valid order + * @param {providerFees} providerFees provider fees + * @return {Promise} string + */ + public async reuseOrder( + dtAddress: string, + address: string, + orderTxId: string, + providerFees: ProviderFees + ): Promise { + const dtContract = setContractDefaults( + new this.web3.eth.Contract(this.datatokensAbi, dtAddress), + this.config + ) + try { + const estGas = await this.estGasReuseOrder( + dtAddress, + address, + orderTxId, + providerFees, + dtContract + ) + + const trxReceipt = await dtContract.methods + .reuseOrder(orderTxId, providerFees) + .send({ + from: address, + gas: estGas + 1, + gasPrice: await getFairGasPrice(this.web3, this.config) + }) + return trxReceipt + } catch (e) { + LoggerInstance.error(`ERROR: Failed to call reuse order order : ${e.message}`) + throw new Error(`Failed to start order: ${e.message}`) + } + } + /** Estimate gas cost for buyFromFreAndOrder method * @param {String} dtAddress Datatoken address * @param {String} address User address which calls diff --git a/test/unit/tokens/Datatoken.test.ts b/test/unit/tokens/Datatoken.test.ts index 8c84e8b01..90080c06d 100644 --- a/test/unit/tokens/Datatoken.test.ts +++ b/test/unit/tokens/Datatoken.test.ts @@ -388,6 +388,47 @@ describe('Datatoken', () => { ) }) + it('#reuseOrder- user2 should user should succeed to call reuseOrder on a using a previous txId ', async () => { + const providerData = JSON.stringify({ timeout: 0 }) + const providerFeeToken = ZERO_ADDRESS + const providerFeeAmount = '0' + const providerValidUntil = '0' + const message = web3.utils.soliditySha3( + { t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) }, + { t: 'address', v: user3 }, + { t: 'address', v: providerFeeToken }, + { t: 'uint256', v: providerFeeAmount }, + { t: 'uint256', v: providerValidUntil } + ) + const { v, r, s } = await signHash(web3, message, user3) + const providerFees: ProviderFees = { + providerFeeAddress: user3, + providerFeeToken: providerFeeToken, + providerFeeAmount: providerFeeAmount, + v: v, + r: r, + s: s, + providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData)), + validUntil: providerValidUntil + } + const order = await datatoken.startOrder( + datatokenAddress, + user1, + user2, + 1, + providerFees + ) + assert(order.transactionHash, ' Failed to start order') + const reusedOrder = await datatoken.reuseOrder( + datatokenAddress, + user2, + order.transactionHash, + providerFees + ) + assert(reusedOrder.events.OrderReused.event === 'OrderReused') + assert(reusedOrder.events.ProviderFee.event === 'ProviderFee') + }) + it('#buyFromDispenserAndOrder- Enterprise method', async () => { const providerData = JSON.stringify({ timeout: 0 }) const providerFeeToken = ZERO_ADDRESS