Commit 37ad8da5 authored by Cédric Moreau's avatar Cédric Moreau
Browse files

[fix] #1379 + #1380: prevent expired documents to reach the mempool

parent 26c48bd4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
export enum DataErrors {
  TRANSACTION_WINDOW_IS_PASSED,
  MEMBERSHIP_WINDOW_IS_PASSED,
  CERT_WINDOW_IS_PASSED,
  WRONG_STAT_NAME,
  DB_INDEXED_BLOCK_NOT_FOUND,
  DB_INCORRECT_INDEX,
+2 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import {hashf} from "../common"
import {Indexer, SimpleTxInput} from "../indexer"
import {DBTx} from "../db/DBTx"
import {Tristamp} from "../common/Tristamp"
import {DataErrors} from "../common-libs/errors"

const constants      = CommonConstants

@@ -231,7 +232,7 @@ export const GLOBAL_RULES_HELPERS = {
    tx.blockstampTime = basedBlock.medianTime;
    const current = await dal.getCurrentBlockOrNull();
    if (current && current.medianTime > basedBlock.medianTime + constants.TX_WINDOW) {
      throw "Transaction has expired";
      throw DataErrors[DataErrors.TRANSACTION_WINDOW_IS_PASSED];
    }
  }
}
+6 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import {GLOBAL_RULES_HELPERS} from "../lib/rules/global_rules";
import {MembershipDTO} from "../lib/dto/MembershipDTO";
import {FIFOService} from "./FIFOService";
import {DBBlock} from "../lib/db/DBBlock"
import {DataErrors} from "../lib/common-libs/errors"

const constants       = require('../lib/constants');

@@ -75,6 +76,10 @@ export class MembershipService extends FIFOService {
        }, this.conf.pair && this.conf.pair.pub))) {
        throw constants.ERRORS.SANDBOX_FOR_MEMERSHIP_IS_FULL;
      }
      const expires_on = basedBlock ? basedBlock.medianTime + this.conf.msWindow : 0
      if (current && expires_on < current.medianTime) {
        throw DataErrors[DataErrors.MEMBERSHIP_WINDOW_IS_PASSED]
      }
      // Saves entry
      await this.dal.savePendingMembership({
        issuers: [entry.pubkey],
@@ -90,7 +95,7 @@ export class MembershipService extends FIFOService {
        idtyHash: entry.getIdtyHash(),
        written: false,
        written_number: null,
        expires_on: basedBlock ? basedBlock.medianTime + this.conf.msWindow : 0,
        expires_on,
        signature: entry.signature,
        expired: false,
        block_number: entry.number
+63 −0
Original line number Diff line number Diff line
// 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 {writeBasicTestWithConfAnd2Users} from "../tools/test-framework"
import {assertThrows} from "../../unit-tools"
import {CommonConstants} from "../../../app/lib/common-libs/constants"
import {CertificationDTO} from "../../../app/lib/dto/CertificationDTO"

describe('Expired certifications', () => writeBasicTestWithConfAnd2Users({
  sigReplay: 3,
  sigPeriod: 0,
  sigValidity: 10,
  sigWindow: 2, // <--- this is the important parameter for this test!
}, (test) => {

  before(() => {
    CommonConstants.BLOCK_NEW_GENERATED_VERSION = 11
  })

  const now = 1500000000
  let certToResend: CertificationDTO

  test('should be able to init with 2 blocks', async (s1, cat, tac) => {
    await cat.createIdentity()
    await tac.createIdentity()
    await cat.cert(tac)
    await tac.cert(cat)
    await cat.join()
    await tac.join()
    await s1.commit({ time: now, version: 10 })
    await s1.commit({ time: now })
  })

  test('should accept toc, a new member at t+2', async (s1, cat, tac, toc) => {
    await s1.commit({ time: now + 2 })
    await s1.commit({ time: now + 2 })
    await toc.createIdentity()
    certToResend = await cat.makeCert(toc)
    await cat.sendCert(certToResend)
    await toc.join()
    await s1.commit({ time: now + 2 })
  })

  test('should **NOT** be able to send again a written cert, even if replay time is passed', async (s1, cat, tac) => {
    await s1.commit({ time: now + 6 })
    await s1.commit({ time: now + 6 })
    await assertThrows(cat.sendCert(certToResend), '{\n  "ucode": 1002,\n  "message": "CERT_WINDOW_IS_PASSED"\n}')
  })

  after(() => {
    CommonConstants.BLOCK_NEW_GENERATED_VERSION = 10
  })
}))
+52 −0
Original line number Diff line number Diff line
// 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 {writeBasicTestWithConfAnd2Users} from "../tools/test-framework"
import {assertThrows} from "../../unit-tools"
import {CommonConstants} from "../../../app/lib/common-libs/constants"

describe('Expired identities', () => writeBasicTestWithConfAnd2Users({
  sigReplay: 3,
  sigPeriod: 0,
  sigValidity: 10,
  idtyWindow: 2, // <--- this is the important parameter for this test!
}, (test) => {

  before(() => {
    CommonConstants.BLOCK_NEW_GENERATED_VERSION = 11
  })

  const now = 1500000000

  test('should be able to init with 2 blocks', async (s1, cat, tac) => {
    await cat.createIdentity()
    await tac.createIdentity()
    await cat.cert(tac)
    await tac.cert(cat)
    await cat.join()
    await tac.join()
    await s1.commit({ time: now, version: 10 })
    await s1.commit({ time: now })
  })

  test('should **NOT** accept an expired identity', async (s1, cat, tac, toc) => {
    const idty = await toc.makeIdentity()
    await s1.commit({ time: now + 6 })
    await s1.commit({ time: now + 6 })
    await assertThrows(toc.submitIdentity(idty), '{\n  "ucode": 1002,\n  "message": "Identity is too old and cannot be written"\n}')
  })

  after(() => {
    CommonConstants.BLOCK_NEW_GENERATED_VERSION = 10
  })
}))
Loading