From d9e64e5ea574e49ca546dbde1a2952191b823bb8 Mon Sep 17 00:00:00 2001 From: Seonghwa Yun Date: Wed, 19 Jul 2023 14:05:45 +0900 Subject: [PATCH 1/3] return gas_amount_charged for dryrun even if balance < gasCost --- db/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/index.js b/db/index.js index 29983cb65..95755c0c4 100644 --- a/db/index.js +++ b/db/index.js @@ -1725,7 +1725,7 @@ class DB { } let balance = this.getBalance(billedTo); const gasCost = CommonUtil.getTotalGasCost(gasPrice, gasAmountChargedByTransfer, gasPriceUnit); - if (balance < gasCost) { + if (!isDryrun && balance < gasCost) { Object.assign(executionResult, { code: TxResultCode.FEE_BALANCE_TOO_LOW, message: `Failed to collect gas fee: balance too low (${balance} / ${gasCost})` From d2c5c62c79f66e25d853f96d1da27903ee421d26 Mon Sep 17 00:00:00 2001 From: Dongil Seo Date: Wed, 19 Jul 2023 17:49:49 +0900 Subject: [PATCH 2/3] Add tests for transfer txs lacking gas fee --- test/integration/node.test.js | 142 ++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/test/integration/node.test.js b/test/integration/node.test.js index 8c324c975..65205480e 100644 --- a/test/integration/node.test.js +++ b/test/integration/node.test.js @@ -3798,6 +3798,77 @@ describe('Blockchain Node', () => { }); }) + it('accepts a transfer transaction lacking gas fee', () => { + // NOTE: transfer all amount of the balance + const fromBalance = parseOrLog(syncRequest('GET', + server1 + `/get_value?ref=/accounts/${account09.address}/balance`).body.toString('utf-8')).result; + const client = jayson.client.http(server1 + '/json-rpc'); + const txBody = { + operation: { + type: 'SET_VALUE', + ref: `/transfer/${account09.address}/${account3.address}/${Date.now()}/value`, + value: fromBalance, // all amount of the balance + }, + gas_price: 500, // non-zero gas price + timestamp: Date.now(), + nonce: -1, // unordered nonce + }; + const signature = + ainUtil.ecSignTransaction(txBody, Buffer.from(account09.private_key, 'hex')); + return client.request(JSON_RPC_METHODS.AIN_SEND_SIGNED_TRANSACTION_DRYRUN, { + tx_body: txBody, + signature, + protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION + }) + .then((res) => { + const result = _.get(res, 'result.result', null); + expect(result).to.not.equal(null); + assert.deepEqual(res.result, { + protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, + result: { + result: { + "bandwidth_gas_amount": 1, + "code": 0, + "func_results": { + "_transfer": { + "bandwidth_gas_amount": 2000, + "code": 0, + "op_results": { + "0": { + "path": "/accounts/0x09A0d53FDf1c36A131938eb379b98910e55EEfe1/balance", + "result": { + "bandwidth_gas_amount": 1, + "code": 0 + } + }, + "1": { + "path": "/accounts/0x758fd59D3f8157Ae4458f8E29E2A8317be3d5974/balance", + "result": { + "bandwidth_gas_amount": 1, + "code": 0 + } + } + } + } + }, + "gas_amount_charged": 3281, + "gas_amount_total": { + "bandwidth": { + "service": 2003 + }, + "state": { + "service": 1278 + } + }, + "gas_cost_total": 1.6405, + "is_dryrun": true + }, + tx_hash: CommonUtil.hashSignature(signature), + } + }); + }); + }) + it('rejects a transaction with an invalid signature.', () => { const client = jayson.client.http(server1 + '/json-rpc'); const txBody = { @@ -4597,6 +4668,77 @@ describe('Blockchain Node', () => { }); }) + it('accepts a transfer transaction lacking gas fee', () => { + // NOTE: transfer all amount of the balance + const fromBalance = parseOrLog(syncRequest('GET', + server1 + `/get_value?ref=/accounts/${account09.address}/balance`).body.toString('utf-8')).result; + const client = jayson.client.http(server1 + '/json-rpc'); + const txBody = { + operation: { + type: 'SET_VALUE', + ref: `/transfer/${account09.address}/${account3.address}/${Date.now()}/value`, + value: fromBalance, // all amount of the balance + }, + gas_price: 500, // non-zero gas price + timestamp: Date.now(), + nonce: -1, // unordered nonce + }; + const signature = + ainUtil.ecSignTransaction(txBody, Buffer.from(account09.private_key, 'hex')); + return client.request(JSON_RPC_METHODS.AIN_SEND_SIGNED_TRANSACTION, { + tx_body: txBody, + signature, + protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION + }) + .then((res) => { + const result = _.get(res, 'result.result', null); + expect(result).to.not.equal(null); + assert.deepEqual(res.result, { + protoVer: BlockchainConsts.CURRENT_PROTOCOL_VERSION, + result: { + result: { + "bandwidth_gas_amount": 1, + "code": 11001, + "func_results": { + "_transfer": { + "bandwidth_gas_amount": 0, + "code": 0, + "op_results": { + "0": { + "path": "/accounts/0x09A0d53FDf1c36A131938eb379b98910e55EEfe1/balance", + "result": { + "bandwidth_gas_amount": 1, + "code": 0 + } + }, + "1": { + "path": "/accounts/0x758fd59D3f8157Ae4458f8E29E2A8317be3d5974/balance", + "result": { + "bandwidth_gas_amount": 1, + "code": 0 + } + } + } + } + }, + "gas_amount_charged": 3, + "gas_amount_total": { + "bandwidth": { + "service": 3 + }, + "state": { + "service": 364 + } + }, + "gas_cost_total": 0.0015, + "message": "Failed to collect gas fee: balance too low (0 / 0.1835)" + }, + tx_hash: CommonUtil.hashSignature(signature), + } + }); + }); + }) + it('accepts a multi-set transaction with account registration gas amount from nonce', () => { // NOTE: account4 does not have balance nor nonce/timestamp. const client = jayson.client.http(server1 + '/json-rpc'); From f545e6a6074c18d6296344cbe3b7683079a90695 Mon Sep 17 00:00:00 2001 From: Dongil Seo Date: Fri, 28 Jul 2023 09:57:56 +0900 Subject: [PATCH 3/3] Upgrade package version to v1.1.1 --- client/protocol_versions.json | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/client/protocol_versions.json b/client/protocol_versions.json index 6560b37d6..e2be4646c 100644 --- a/client/protocol_versions.json +++ b/client/protocol_versions.json @@ -125,5 +125,8 @@ }, "1.1.0": { "min": "1.0.0" + }, + "1.1.1": { + "min": "1.0.0" } } \ No newline at end of file diff --git a/package.json b/package.json index f8a6eec72..67a820297 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ain-blockchain", "description": "AI Network Blockchain", - "version": "1.1.0", + "version": "1.1.1", "private": true, "license": "MIT", "author": "dev@ainetwork.ai",