From 79cdb1b866b2edf593b3d8d547fd7ab02b490d95 Mon Sep 17 00:00:00 2001 From: Evan Chou Date: Fri, 2 Oct 2020 21:42:37 +0000 Subject: [PATCH 1/2] allow hive engine owner to create and update pool for utility token --- contracts/mining.js | 10 +++++---- test/mining.js | 55 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/contracts/mining.js b/contracts/mining.js index 88bbdbe0..2d2ac5dc 100644 --- a/contracts/mining.js +++ b/contracts/mining.js @@ -223,7 +223,7 @@ actions.updatePool = async (payload) => { // eslint-disable-next-line no-template-curly-in-string const utilityTokenBalance = await api.db.findOneInTable('tokens', 'balances', { account: api.sender, symbol: "'${CONSTANTS.UTILITY_TOKEN_SYMBOL}$'" }); - const authorized = api.BigNumber(poolUpdateFee).lte(0) + const authorized = api.BigNumber(poolUpdateFee).lte(0) || api.sender === api.owner ? true : utilityTokenBalance && api.BigNumber(utilityTokenBalance.balance).gte(poolUpdateFee); @@ -236,7 +236,8 @@ actions.updatePool = async (payload) => { const pool = await api.db.findOne('pools', { id }); if (api.assert(pool, 'pool id not found')) { const minedTokenObject = await api.db.findOneInTable('tokens', 'tokens', { symbol: pool.minedToken }); - if (api.assert(minedTokenObject && minedTokenObject.issuer === api.sender, 'must be issuer of minedToken') + // eslint-disable-next-line no-template-curly-in-string + if (api.assert(minedTokenObject && (minedTokenObject.issuer === api.sender || (minedTokenObject.symbol === "'${CONSTANTS.UTILITY_TOKEN_SYMBOL}$'" && api.sender === api.owner)), 'must be issuer of minedToken') && api.assert(api.BigNumber(lotteryAmount).dp() <= minedTokenObject.precision, 'minedToken precision mismatch for lotteryAmount')) { const validMinersChange = validateTokenMinersChange(pool.tokenMiners, tokenMiners); if (validMinersChange) { @@ -291,7 +292,7 @@ actions.createPool = async (payload) => { // eslint-disable-next-line no-template-curly-in-string const utilityTokenBalance = await api.db.findOneInTable('tokens', 'balances', { account: api.sender, symbol: "'${CONSTANTS.UTILITY_TOKEN_SYMBOL}$'" }); - const authorizedCreation = api.BigNumber(poolCreationFee).lte(0) + const authorizedCreation = api.BigNumber(poolCreationFee).lte(0) || api.sender === api.owner ? true : utilityTokenBalance && api.BigNumber(utilityTokenBalance.balance).gte(poolCreationFee); @@ -306,7 +307,8 @@ actions.createPool = async (payload) => { const minedTokenObject = await api.db.findOneInTable('tokens', 'tokens', { symbol: minedToken }); if (api.assert(minedTokenObject, 'minedToken does not exist') - && api.assert(minedTokenObject.issuer === api.sender, 'must be issuer of minedToken') + // eslint-disable-next-line no-template-curly-in-string + && api.assert(minedTokenObject.issuer === api.sender || (minedTokenObject.symbol === "'${CONSTANTS.UTILITY_TOKEN_SYMBOL}$'" && api.sender === api.owner), 'must be issuer of minedToken') && api.assert(api.BigNumber(lotteryAmount).dp() <= minedTokenObject.precision, 'minedToken precision mismatch for lotteryAmount') && await validateTokenMiners(tokenMiners)) { const blockDate = new Date(`${api.hiveBlockTimestamp}.000Z`); diff --git a/test/mining.js b/test/mining.js index 6c0d2f9d..ace0b2f2 100644 --- a/test/mining.js +++ b/test/mining.js @@ -850,6 +850,61 @@ describe('mining', function () { }); }); + it.only('should update mining pool for utility token as api owner', (done) => { + new Promise(async (resolve) => { + await loadPlugin(blockchain); + database1 = new Database(); + + await database1.init(conf.databaseURL, conf.databaseName); + + let transactions = []; + transactions.push(new Transaction(12345678901, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'contract', 'update', JSON.stringify(tokensContractPayload))); + transactions.push(new Transaction(12345678901, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'contract', 'deploy', JSON.stringify(contractPayload))); + transactions.push(new Transaction(12345678901, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'tokens', 'transfer', `{ "symbol": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "to": "harpagon", "quantity": "7300", "isSignedWithActiveKey": true }`)); + transactions.push(new Transaction(12345678901, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'mining', 'createPool', `{ "lotteryWinners": 1, "lotteryIntervalHours": 720, "lotteryAmount": "1", "minedToken": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "tokenMiners": [{"symbol": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "multiplier": 1}], "isSignedWithActiveKey": true }`)); + + let block = { + refHiveBlockNumber: 12345678901, + refHiveBlockId: 'ABCD1', + prevRefHiveBlockId: 'ABCD2', + timestamp: '2018-06-01T00:00:00', + transactions, + }; + + await send(blockchain.PLUGIN_NAME, 'MASTER', { action: blockchain.PLUGIN_ACTIONS.PRODUCE_NEW_BLOCK_SYNC, payload: block }); + + await assertNoErrorInLastBlock(); + + await assertPool({id: `${CONSTANTS.UTILITY_TOKEN_SYMBOL}:${CONSTANTS.UTILITY_TOKEN_SYMBOL}`, totalPower: '0', lotteryWinners: 1, lotteryIntervalHours: 720, lotteryAmount: "1", nextLotteryTimestamp: new Date('2018-07-01T00:00:00.000Z').getTime()}, { inProgress: false, lastAccountId: 0, tokenIndex: 0 }); + + transactions = []; + transactions.push(new Transaction(12345678903, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'mining', 'updatePool', `{ "id": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}:${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "lotteryWinners": 2, "lotteryIntervalHours": 3, "lotteryAmount": "15.7", "minedToken": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "tokenMiners": [{"symbol": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "multiplier": 1}], "isSignedWithActiveKey": true }`)); + + block = { + refHiveBlockNumber: 12345678903, + refHiveBlockId: 'ABCD1', + prevRefHiveBlockId: 'ABCD2', + timestamp: '2018-06-01T00:00:00', + transactions, + }; + + await send(blockchain.PLUGIN_NAME, 'MASTER', { action: blockchain.PLUGIN_ACTIONS.PRODUCE_NEW_BLOCK_SYNC, payload: block }); + + await assertNoErrorInLastBlock(); + + await assertTokenPool(CONSTANTS.UTILITY_TOKEN_SYMBOL, `${CONSTANTS.UTILITY_TOKEN_SYMBOL}:${CONSTANTS.UTILITY_TOKEN_SYMBOL}`); + + await assertPool({id: `${CONSTANTS.UTILITY_TOKEN_SYMBOL}:${CONSTANTS.UTILITY_TOKEN_SYMBOL}`, totalPower: '0', lotteryWinners: 2, lotteryIntervalHours: 3, lotteryAmount: "15.7", nextLotteryTimestamp: new Date('2018-06-01T03:00:00.000Z').getTime()}, { inProgress: false, lastAccountId: 0, tokenIndex: 0 }); + + resolve(); + }) + .then(() => { + unloadPlugin(blockchain); + database1.close(); + done(); + }); + }); + it('should not run basic lottery when inactive', (done) => { new Promise(async (resolve) => { await loadPlugin(blockchain); From 79ce4b7b37e75b9590ab3d00e0fccc4c501a0156 Mon Sep 17 00:00:00 2001 From: Evan Chou Date: Sat, 3 Oct 2020 10:23:54 +0000 Subject: [PATCH 2/2] do not deduct fee from api owner --- contracts/mining.js | 4 ++-- test/mining.js | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/contracts/mining.js b/contracts/mining.js index 2d2ac5dc..85e5da7f 100644 --- a/contracts/mining.js +++ b/contracts/mining.js @@ -260,7 +260,7 @@ actions.updatePool = async (payload) => { await api.db.update('pools', pool); // burn the token creation fees - if (api.BigNumber(poolUpdateFee).gt(0)) { + if (api.sender !== api.owner && api.BigNumber(poolUpdateFee).gt(0)) { await api.executeSmartContract('tokens', 'transfer', { // eslint-disable-next-line no-template-curly-in-string to: 'null', symbol: "'${CONSTANTS.UTILITY_TOKEN_SYMBOL}$'", quantity: poolUpdateFee, isSignedWithActiveKey, @@ -339,7 +339,7 @@ actions.createPool = async (payload) => { await api.db.insert('pools', newPool); // burn the token creation fees - if (api.BigNumber(poolCreationFee).gt(0)) { + if (api.sender !== api.owner && api.BigNumber(poolCreationFee).gt(0)) { await api.executeSmartContract('tokens', 'transfer', { // eslint-disable-next-line no-template-curly-in-string to: 'null', symbol: "'${CONSTANTS.UTILITY_TOKEN_SYMBOL}$'", quantity: poolCreationFee, isSignedWithActiveKey, diff --git a/test/mining.js b/test/mining.js index ace0b2f2..187a622c 100644 --- a/test/mining.js +++ b/test/mining.js @@ -850,7 +850,7 @@ describe('mining', function () { }); }); - it.only('should update mining pool for utility token as api owner', (done) => { + it('should update mining pool for utility token as api owner', (done) => { new Promise(async (resolve) => { await loadPlugin(blockchain); database1 = new Database(); @@ -860,7 +860,6 @@ describe('mining', function () { let transactions = []; transactions.push(new Transaction(12345678901, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'contract', 'update', JSON.stringify(tokensContractPayload))); transactions.push(new Transaction(12345678901, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'contract', 'deploy', JSON.stringify(contractPayload))); - transactions.push(new Transaction(12345678901, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'tokens', 'transfer', `{ "symbol": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "to": "harpagon", "quantity": "7300", "isSignedWithActiveKey": true }`)); transactions.push(new Transaction(12345678901, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'mining', 'createPool', `{ "lotteryWinners": 1, "lotteryIntervalHours": 720, "lotteryAmount": "1", "minedToken": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "tokenMiners": [{"symbol": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "multiplier": 1}], "isSignedWithActiveKey": true }`)); let block = { @@ -875,7 +874,9 @@ describe('mining', function () { await assertNoErrorInLastBlock(); + await assertTokenPool(CONSTANTS.UTILITY_TOKEN_SYMBOL, `${CONSTANTS.UTILITY_TOKEN_SYMBOL}:${CONSTANTS.UTILITY_TOKEN_SYMBOL}`); await assertPool({id: `${CONSTANTS.UTILITY_TOKEN_SYMBOL}:${CONSTANTS.UTILITY_TOKEN_SYMBOL}`, totalPower: '0', lotteryWinners: 1, lotteryIntervalHours: 720, lotteryAmount: "1", nextLotteryTimestamp: new Date('2018-07-01T00:00:00.000Z').getTime()}, { inProgress: false, lastAccountId: 0, tokenIndex: 0 }); + await assertUserBalances(CONSTANTS.HIVE_ENGINE_ACCOUNT, CONSTANTS.UTILITY_TOKEN, '1500011.41552511', 0); transactions = []; transactions.push(new Transaction(12345678903, getNextTxId(), CONSTANTS.HIVE_ENGINE_ACCOUNT, 'mining', 'updatePool', `{ "id": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}:${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "lotteryWinners": 2, "lotteryIntervalHours": 3, "lotteryAmount": "15.7", "minedToken": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "tokenMiners": [{"symbol": "${CONSTANTS.UTILITY_TOKEN_SYMBOL}", "multiplier": 1}], "isSignedWithActiveKey": true }`)); @@ -896,6 +897,8 @@ describe('mining', function () { await assertPool({id: `${CONSTANTS.UTILITY_TOKEN_SYMBOL}:${CONSTANTS.UTILITY_TOKEN_SYMBOL}`, totalPower: '0', lotteryWinners: 2, lotteryIntervalHours: 3, lotteryAmount: "15.7", nextLotteryTimestamp: new Date('2018-06-01T03:00:00.000Z').getTime()}, { inProgress: false, lastAccountId: 0, tokenIndex: 0 }); + await assertUserBalances(CONSTANTS.HIVE_ENGINE_ACCOUNT, CONSTANTS.UTILITY_TOKEN, '1500011.41552511', 0); + resolve(); }) .then(() => {