diff --git a/app/lib/constants.js b/app/lib/constants.js index b556c103a565767908e7223c5fba2bc8a7a45180..a44c9a28e508b9452b2fb682fb1b5912a2ef5aa3 100644 --- a/app/lib/constants.js +++ b/app/lib/constants.js @@ -30,6 +30,7 @@ const IPV6_REGEXP = /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1, const MAXIMUM_LEN_OF_COMPACT_TX = 100; const MAXIMUM_LEN_OF_OUTPUT = 2000; +const MAXIMUM_LEN_OF_UNLOCK = MAXIMUM_LEN_OF_OUTPUT; module.exports = { @@ -90,7 +91,8 @@ module.exports = { TOO_OLD_MEMBERSHIP: { httpCode: 400, uerr: { ucode: 2029, message: "Too old membership." }}, TX_ALREADY_PROCESSED: { httpCode: 400, uerr: { ucode: 2030, message: "Transaction already processed" }}, A_MORE_RECENT_MEMBERSHIP_EXISTS: { httpCode: 400, uerr: { ucode: 2031, message: "A more recent membership already exists" }}, - MAXIMUM_LEN_OF_OUTPUT: { httpCode: 400, uerr: { ucode: 2032, message: 'A transaction output has a maximum size of ' + MAXIMUM_LEN_OF_OUTPUT + ' characters' }} + MAXIMUM_LEN_OF_OUTPUT: { httpCode: 400, uerr: { ucode: 2032, message: 'A transaction output has a maximum size of ' + MAXIMUM_LEN_OF_OUTPUT + ' characters' }}, + MAXIMUM_LEN_OF_UNLOCK: { httpCode: 400, uerr: { ucode: 2033, message: 'A transaction unlock has a maximum size of ' + MAXIMUM_LEN_OF_UNLOCK + ' characters' }} }, DEBUG: { @@ -306,7 +308,8 @@ module.exports = { SANDBOX_SIZE_MEMBERSHIPS: 200, MAXIMUM_LEN_OF_COMPACT_TX: MAXIMUM_LEN_OF_COMPACT_TX, - MAXIMUM_LEN_OF_OUTPUT: MAXIMUM_LEN_OF_OUTPUT, + MAXIMUM_LEN_OF_OUTPUT, + MAXIMUM_LEN_OF_UNLOCK, CURRENT_BLOCK_CACHE_DURATION: 10 * 1000, // 30 seconds CORES_MAXIMUM_USE_IN_PARALLEL: 8, // For more cores, we need to use a better PoW synchronization algorithm diff --git a/app/lib/rules/local_rules.js b/app/lib/rules/local_rules.js index f633a66fdf6f8e4a51c0339524dc7b9ca4ddfb3d..c0eb654a3e9b264e796ff9849adfb7712519fe62 100644 --- a/app/lib/rules/local_rules.js +++ b/app/lib/rules/local_rules.js @@ -309,6 +309,14 @@ rules.FUNCTIONS = { } } } + // Check rule against each unlock of each transaction + for (const tx of txs) { + for (const unlock of tx.unlocks) { + if (unlock.length > constants.MAXIMUM_LEN_OF_UNLOCK) { + throw constants.ERRORS.MAXIMUM_LEN_OF_UNLOCK + } + } + } return true; }), diff --git a/test/data/blocks.js b/test/data/blocks.js index af3d1a0a084b0d09dfc476e5ee67c579d90246f2..4c4c6bd7f49fb2b75ae60af68245bb3033bd42a8 100644 --- a/test/data/blocks.js +++ b/test/data/blocks.js @@ -3624,6 +3624,41 @@ module.exports = { "Nonce: 0\n" + "kNsKdC8eH0d4zdHh1djyMzRXjFrwk3Bc3M8wo4DV/7clE9J66K/U0FljyS79SI78ZZUPaVmrImKJ9SNiubCiBg==\n", + UNLOCK_TOO_LONG: + "Version: 10\n" + + "Type: Block\n" + + "Currency: test_net\n" + + "Number: 33520\n" + + "PoWMin: 77\n" + + "Time: 1472124036\n" + + "MedianTime: 1472124036\n" + + "UnitBase: 3\n" + + "Issuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\n" + + "IssuersFrame: 52\n" + + "IssuersFrameVar: -2\n" + + "DifferentIssuersCount: 9\n" + + "PreviousHash: 00001E78E26DD813024EEFBC8F5C50BBA8B30DD1DB5C4F492D9606EE12C06BB4\n" + + "PreviousIssuer: 5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of\n" + + "MembersCount: 128\n" + + "Identities:\n" + + "Joiners:\n" + + "Actives:\n" + + "Leavers:\n" + + "Revoked:\n" + + "Excluded:\n" + + "Certifications:\n" + + "Transactions:\n" + + "TX:10:1:1:1:1:0:0\n" + + "33518-00001D9E2EA1F967667528817FAF17ECBACE6150EBB875A2196B4457C0366D2A\n" + + "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\n" + + "60:3:T:2A74F44780925586EA4C01BEE9DA5042FE8BDB0FB0506B9D69990750B555AC91:15\n" + + "0:SIG(0) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789)\n" + + "60:3:SIG(EA7Dsw39ShZg4SpURsrgMaMqrweJPUFPYHwZA8e92e3D)\n" + + "ue7NjWPfPXxPNqvlGgr/K4jZjyHlUdYVl6dq+RXJ5RMuu8xBoo6bKhTKOyz/vXZz2clnwV/FqPDdDsWImxCmAg==\n" + + "InnerHash: 1C9EF3BCCBB14DA060F172855D18F7D979FBA752E55BB288E253806E4980E5AC\n" + + "Nonce: 0\n" + + "kNsKdC8eH0d4zdHh1djyMzRXjFrwk3Bc3M8wo4DV/7clE9J66K/U0FljyS79SI78ZZUPaVmrImKJ9SNiubCiBg==\n", + TRANSACTION_WRONG_TRANSFORM: "Version: 10\n" + "Type: Block\n" + diff --git a/test/fast/block/block_local.js b/test/fast/block/block_local.js index a7a6adea7b4741bb9f75f9a9d836269e381e2b7f..00dfe70d7365f366c86aa7cc3a6184a76f582fae 100644 --- a/test/fast/block/block_local.js +++ b/test/fast/block/block_local.js @@ -71,6 +71,7 @@ describe("Block local coherence", function(){ it('Block cannot contain transactions with unexisting lower base in sources', test(rules.LOCAL.checkTxAmounts, blocks.TRANSACTION_WRONG_TRANSFORM_LOW_BASE, 'Transaction output base amount does not equal previous base deltas')); it('Block cannot contain transactions with more than 100 lines', test(rules.LOCAL.checkTxLen, blocks.TRANSACTION_TOO_LONG, 'A transaction has a maximum size of 100 lines')); it('Block cannot contain transactions with a too large output', test(rules.LOCAL.checkTxLen, blocks.OUTPUT_TOO_LONG, 'A transaction output has a maximum size of 2000 characters')); + it('Block cannot contain transactions with a too large unlock', test(rules.LOCAL.checkTxLen, blocks.UNLOCK_TOO_LONG, 'A transaction unlock has a maximum size of 2000 characters')); it('Block cannot be refused with a good V3 transaction', test(rules.LOCAL.checkTxAmounts, blocks.TRANSACTION_V3_GOOD_AMOUNTS)); it('Block cannot contain transactions with wrong signatures', test(rules.LOCAL.checkTxSignature, blocks.TRANSACTION_WITH_WRONG_SIGNATURES, 'Signature from a transaction must match')); }); diff --git a/test/integration/transactions-test.js b/test/integration/transactions-test.js index e435fbd12d3fb62490103d3822a5df5274a81ba0..8c3609341e3fd5369dad1bac159c688e1798ebaa 100644 --- a/test/integration/transactions-test.js +++ b/test/integration/transactions-test.js @@ -155,7 +155,7 @@ describe("Testing transactions", function() { (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(4); // As well as tic let tx3 = yield tic.prepareUTX(tx2, ['XHX(1872767826647264) SIG(0)'], [{ qty: 1201, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); let tx4 = yield toc.prepareUTX(tx2, ['XHX(1872767826647264) SIG(0)'], [{ qty: 1201, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'ok', blockstamp: [current.number, current.hash].join('-') }); - let tx5 = yield tic.prepareMTX(tx2, toc, ['XHX(1872767826647264) SIG(1) SIG(0)'], [{ qty: 1201, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'multi OK', blockstamp: [current.number, current.hash].join('-') }); + let tx5 = yield tic.prepareMTX(tx2, toc, ['XHX(1872767826647264) SIG(1) SIG(0) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789) XHX(123456789)'], [{ qty: 1201, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'multi OK', blockstamp: [current.number, current.hash].join('-') }); let tx6 = yield toc.prepareMTX(tx2, tic, ['XHX(1872767826647264) SIG(1) SIG(0)'], [{ qty: 1201, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'multi WRONG', blockstamp: [current.number, current.hash].join('-') }); // nLocktime let tx7 = yield tic.prepareMTX(tx2, toc, ['XHX(1872767826647264) SIG(1) SIG(0)'], [{ qty: 1201, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong locktime', locktime: 100, blockstamp: [current.number, current.hash].join('-') });