diff --git a/test/integration/block-generation/coming-back-with-less-than-sigqty.ts b/test/integration/block-generation/coming-back-with-less-than-sigqty.ts new file mode 100644 index 0000000000000000000000000000000000000000..e563493ad2489552ba8fe88b0f7201962686d3af --- /dev/null +++ b/test/integration/block-generation/coming-back-with-less-than-sigqty.ts @@ -0,0 +1,98 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Äž1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {assertEqual, writeBasicTestWithConfAnd2Users} from "../tools/test-framework" +import {CommonConstants} from "../../../app/lib/common-libs/constants" + +const currentVersion = CommonConstants.BLOCK_GENESIS_VERSION + +describe('A block generated with member coming back with less than `sigQty` valid certs', () => writeBasicTestWithConfAnd2Users({ + sigQty: 2, + sigReplay: 0, + sigPeriod: 0, + sigValidity: 10, + dtDiffEval: 1, + forksize: 0, +}, (test) => { + + const now = 1500000000 + + test('(t = 0) should init with a 3 members WoT with bidirectionnal certs', async (s1, cat, tac, toc) => { + CommonConstants.BLOCK_GENESIS_VERSION = 11 + await cat.createIdentity() + await tac.createIdentity() + await toc.createIdentity() + await cat.cert(tac) + await cat.cert(toc) + await tac.cert(cat) + await tac.cert(toc) + await toc.cert(cat) + await toc.cert(tac) + await cat.join() + await tac.join() + await toc.join() + const b0 = await s1.commit({ time: now }) + assertEqual(b0.certifications.length, 6) + const b1 = await s1.commit({ time: now }) + assertEqual(b1.membersCount, 3) + }) + + test('(t = 5) cat & tac certify each other', async (s1, cat, tac, toc) => { + await s1.commit({ time: now + 5 }) + const b3 = await s1.commit({ time: now + 5 }) + await new Promise(resolve => setTimeout(resolve, 500)) + // cat and tac certify each other to stay in the WoT + await tac.cert(cat) + await toc.cert(cat) // <-- toc adds the 2nd certification + const b1 = await s1.commit({ time: now + 6 }) + assertEqual(b1.certifications.length, 2) + await cat.cert(tac) + await toc.cert(tac) // <-- toc adds the 2nd certification + const b2 = await s1.commit({ time: now + 6 }) + assertEqual(b2.certifications.length, 2) + // // /!\/!\/!\ + // // toc gets certified by cat, to a have a remaining valid certification in the blockchain: THIS WONT BE ENOUGH! + await cat.cert(toc) + // // /!\/!\/!\ + const b4 = await s1.commit({ time: now + 6 }) + assertEqual(b4.certifications.length, 1) + }) + + test('(t = 12) toc is excluded for lack of certifications', async (s1, cat, tac, toc) => { + await s1.commit({ time: now + 12 }) + await s1.commit({ time: now + 12 }) + const b = await s1.commit({ time: now + 12 }) + assertEqual(b.excluded.length, 1) + assertEqual(b.excluded[0], toc.pub) + }) + + test('(t = 13) toc is NOT coming back with 1 cert only!', async (s1, cat, tac, toc) => { + await s1.commit({ time: now + 13 }) + await s1.commit({ time: now + 13 }) + const c1 = await cat.makeCert(toc) // <-- a renewal ==> this is what we want to observe + const join = await toc.makeMembership('IN'); + + // Inject c1 & join in mempool + await cat.sendCert(c1) + await toc.sendMembership(join) + + // Generate potential next bloc, must NOT include toc join (#1402) + const b_gen = s1.generateNext({ time: now + 13 }) + assertEqual((await b_gen).joiners.length, 0); + }) + + after(() => { + CommonConstants.BLOCK_GENESIS_VERSION = currentVersion + }) +})) + diff --git a/test/integration/fork-resolution/coming-back-with-less-than-sigqty.ts b/test/integration/fork-resolution/coming-back-with-less-than-sigqty.ts index a534c57514696ae9d56f0e453aa0526d3d140d68..e89ba363726d1f0e346eaa82ccbd699c4a65db51 100644 --- a/test/integration/fork-resolution/coming-back-with-less-than-sigqty.ts +++ b/test/integration/fork-resolution/coming-back-with-less-than-sigqty.ts @@ -81,17 +81,8 @@ describe('A member coming back with less than `sigQty` valid certs total', () => await s1.commit({ time: now + 13 }) await s1.commit({ time: now + 13 }) const c1 = await cat.makeCert(toc) // <-- a renewal ==> this is what we want to observe - const join = await toc.makeMembership('IN'); - - // Inject c1 & join in mempool - await cat.sendCert(c1) - await toc.sendMembership(join) - - // Generate potential next bloc, must NOT include toc join (#1402) - const b_gen = s1.generateNext({ time: now + 13 }) - assertEqual((await b_gen).joiners.length, 0); - - // Try to force toc coming back, must be fail because toc not have enough certs (#1394) + const join = await toc.makeMembership('IN') + // toc is **NOT** coming back! not enough certs await assertThrows(s1.commit({ time: now + 13, joiners: [join], @@ -99,13 +90,13 @@ describe('A member coming back with less than `sigQty` valid certs total', () => }), 'BLOCK_WASNT_COMMITTED') // BUT is coming back with 1 more cert const c2 = await tac.makeCert(toc) - const b2 = await s1.commit({ + const b = await s1.commit({ time: now + 13, joiners: [join], certifications: [c1, c2] }) - assertEqual(b2.membersCount, 3) // <--- toc is welcome back :) - assertEqual(b2.number, 12) + assertEqual(b.membersCount, 3) // <--- toc is welcome back :) + assertEqual(b.number, 12) }) after(() => { diff --git a/test/integration/tools/TestUser.ts b/test/integration/tools/TestUser.ts index 86619853e5d7637128ea72e4e9935174c69185f8..375b7b1071c1333ac11d6ac372ce118704c829a7 100644 --- a/test/integration/tools/TestUser.ts +++ b/test/integration/tools/TestUser.ts @@ -98,7 +98,7 @@ export class TestUser { return this.createdIdentity } - public async makeCert(user:TestUser, fromServer?:TestingServer, overrideProps?:any): Promise<CertificationDTO> { + public async makeCert(user:TestUser, fromServer?:TestingServer, overrideProps?:any) { const lookup = await this.lookup(user.pub, fromServer) const current = await this.node.server.BlockchainService.current() const idty = Underscore.filter(lookup.results[0].uids, uidEntry => uidEntry.uid === user.uid)[0] diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts index 312b7f8c08eb559c22cf84743a79803d2c263c9c..be44dd60d90f3caaaba871cf9c67d9180f446aa0 100644 --- a/test/integration/tools/toolbox.ts +++ b/test/integration/tools/toolbox.ts @@ -528,7 +528,7 @@ export class TestingServer { return blocksResolved } - async generateNext(options:any) { + generateNext(options:any) { const server = this.server as any // Brings a priver to the server if (!server._utProver) {