From 5fbb839f53afd16557dd5e5530befe211f538d4f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 6 Sep 2016 23:01:58 +1200 Subject: [PATCH] Add test of difficulty averaging --- src/Makefile.gtest.include | 1 + src/gtest/test_pow.cpp | 62 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/gtest/test_pow.cpp diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index c93e04332..bd6bae83d 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -13,6 +13,7 @@ zcash_gtest_SOURCES = \ gtest/test_keystore.cpp \ gtest/test_noteencryption.cpp \ gtest/test_merkletree.cpp \ + gtest/test_pow.cpp \ gtest/test_rpc.cpp \ gtest/test_circuit.cpp \ gtest/test_txid.cpp \ diff --git a/src/gtest/test_pow.cpp b/src/gtest/test_pow.cpp new file mode 100644 index 000000000..062d2dbd7 --- /dev/null +++ b/src/gtest/test_pow.cpp @@ -0,0 +1,62 @@ +#include + +#include "chain.h" +#include "chainparams.h" +#include "pow.h" +#include "random.h" + +TEST(PoW, DifficultyAveraging) { + SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); + size_t lastBlk = 2*params.nPowAveragingWindow; + size_t firstBlk = lastBlk - params.nPowAveragingWindow; + + // Start with blocks evenly-spaced and equal difficulty + std::vector blocks(lastBlk+1); + for (int i = 0; i <= lastBlk; i++) { + blocks[i].pprev = i ? &blocks[i - 1] : nullptr; + blocks[i].nHeight = i; + blocks[i].nTime = 1269211443 + i * params.nPowTargetSpacing; + blocks[i].nBits = 0x1e7fffff; /* target 0x007fffff000... */ + blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0); + } + + // Result should be the same as if last difficulty was used + EXPECT_EQ(CalculateNextWorkRequired(&blocks[lastBlk], + blocks[firstBlk].GetMedianTimePast(), + params), + GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); + // Result should be unchanged + // TODO: This should be 0x1e7fffff, and just before GetNextWorkRequired() + // returns, it is. Somehow it ends up off by one.... + EXPECT_EQ(0x1e7ffffe, GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); + + // Randomise the final block time + blocks[lastBlk].nTime += GetRand(params.nPowTargetSpacing) + - GetRand(params.nPowTargetSpacing/2); + + // Result should be the same as if last difficulty was used + EXPECT_EQ(CalculateNextWorkRequired(&blocks[lastBlk], + blocks[firstBlk].GetMedianTimePast(), + params), + GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); + // Result should not be unchanged + EXPECT_NE(0x1e7fffff, GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); + + // Change the final block difficulty + blocks[lastBlk].nBits = 0x1e0fffff; + + // Result should not be the same as if last difficulty was used + EXPECT_NE(CalculateNextWorkRequired(&blocks[lastBlk], + blocks[firstBlk].GetMedianTimePast(), + params), + GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); + + // Result should be the same as if the average difficulty was used + arith_uint256 average = UintToArith256(uint256S("0000796968696969696969696969696969696969696969696969696969696969")); + EXPECT_EQ(CalculateNextWorkRequired(average, + blocks[lastBlk].GetMedianTimePast(), + blocks[firstBlk].GetMedianTimePast(), + params), + GetNextWorkRequired(&blocks[lastBlk], nullptr, params)); +}