Skip to content

Instantly share code, notes, and snippets.

@cryptozeny
Last active December 25, 2018 09:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cryptozeny/f7cdae98ed6ed1bf46600615493ba480 to your computer and use it in GitHub Desktop.
Save cryptozeny/f7cdae98ed6ed1bf46600615493ba480 to your computer and use it in GitHub Desktop.
testing LWMA-1 suite from BTG and SUSU
// Copyright (c) 2015-2017 The Bitcoin Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chain.h>
#include <chainparams.h>
#include <pow.h>
#include <random.h>
#include <util.h>
#include <test/test_bitcoin.h>
#include <boost/test/unit_test.hpp>
BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(Lwma3CalculateNextWorkRequired_test)
{
// Copyright (c) 2017-2018 h4x3rotab of the Bitcoin Gold
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
std::vector<CBlockIndex> blocks(805); // (N * 4) + 5 = (200 * 4) + 5 = 805
for (int i = 0; i < 805; i++) {
blocks[i].pprev = i ? &blocks[i - 1] : nullptr;
blocks[i].nHeight = i;
blocks[i].nTime = 1541009400 + i * chainParams->GetConsensus().nPowTargetSpacing; // block:0
blocks[i].nBits = 0x1f07ffff; // block:0 // 0x1f07ffff = 520617983
blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0);
}
int bits = Lwma3CalculateNextWorkRequired(&blocks.back(), chainParams->GetConsensus());
BOOST_CHECK_EQUAL(bits, 0x1f07fffe); // 0x1f07fffe = 520617983(0x1f07ffff) - 1 = 520617982
}
static CBlockIndex GetBlockIndex(CBlockIndex *pindexPrev, int64_t nTimeInterval,
uint32_t nBits) {
CBlockIndex block;
block.pprev = pindexPrev;
block.nHeight = pindexPrev->nHeight + 1;
block.nTime = pindexPrev->nTime + nTimeInterval;
block.nBits = nBits;
block.nChainWork = pindexPrev->nChainWork + GetBlockProof(block);
return block;
}
BOOST_AUTO_TEST_CASE(lwma_difficulty_test) {
// Copyright (c) 2018 ishikawa-pss9 of the Susucoin Core developers
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
std::vector<CBlockIndex> blocks(3000);
const arith_uint256 powLimit = UintToArith256(chainParams->GetConsensus().powLimit);
// uint32_t powLimitBits = powLimit.GetCompact();
arith_uint256 currentPow = powLimit >> 4;
uint32_t initialBits = currentPow.GetCompact();
// Genesis block.
blocks[0] = CBlockIndex();
blocks[0].nHeight = 0;
blocks[0].nTime = 1541009400;
blocks[0].nBits = initialBits;
blocks[0].nChainWork = GetBlockProof(blocks[0]);
// Block counter.
size_t i;
// Create the first window for lwma, with blocks every 10 minutes.
// consensus.lwmaAveragingWindow = 200;
// N=200 for T=15: Lwma3CalculateNextWorkRequired
for (i = 1; i < 202; i++) {
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, initialBits); // 0x1f07ffff
}
uint32_t nBits =
Lwma3CalculateNextWorkRequired(&blocks[201], chainParams->GetConsensus());
// For the first window, with 10 minutes between blocks, the difficulty should be low.
BOOST_CHECK_EQUAL( nBits, 0x1f02ffff ); // 520421370
// Add one block far in the future.
blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits);
// The difficulty is now a somewhat lower.
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus());
BOOST_CHECK_EQUAL( nBits, 0x1f031333 ); // 520295219
// Add another block with a normal timestamp.
blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 600 - 6000, nBits);
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus());
// The difficulty is now just a little bit lower, again.
BOOST_CHECK_EQUAL( nBits, 0x1f031f09 ); // 520298249
// And another block with a regular timestamp.
blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits);
// The difficulty has lowered yet again, by a fraction.
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus());
BOOST_CHECK_EQUAL( nBits, 0x1f032ade ); // 520301278
// Simulate a hash attack, add a window with very low increase.
for ( int j = 0; j < 10; j++ ) {
// first, add one block with 0.125 second interval
blocks[i] = GetBlockIndex(&blocks[i - 1], 0.125, nBits);
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus());
// then add 20 more with zero second interval
for ( int k = 0; k < 20; k++ ) {
blocks[i] = GetBlockIndex(&blocks[i - 1], 0, nBits);
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus());
}
// and do that ten times. That gives us 200 block window with very high frequency
// of blocks.
}
// The difficulty is now significantly higher.
BOOST_CHECK_EQUAL( nBits, 0x1e2eaf51 ); // 506376017
// Add one more block with a significant delay.
blocks[i] = GetBlockIndex(&blocks[i - 1], 4 * 3600, nBits);
// The difficulty has lowered significantly.
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus());
BOOST_CHECK_EQUAL( nBits, 0x1e577959 ); // 509049177
// One more block with little less delay.
blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 3600, nBits);
// The difficulty has lowered again.
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus());
BOOST_CHECK_EQUAL( nBits, 0x1e7f90f4 ); // 511676660
}
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
{
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
std::vector<CBlockIndex> blocks(10000);
for (int i = 0; i < 10000; i++) {
blocks[i].pprev = i ? &blocks[i - 1] : nullptr;
blocks[i].nHeight = i;
blocks[i].nTime = 1269211443 + i * chainParams->GetConsensus().nPowTargetSpacing;
blocks[i].nBits = 0x207fffff; /* target 0x7fffff000... */
blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0);
}
for (int j = 0; j < 1000; j++) {
CBlockIndex *p1 = &blocks[InsecureRandRange(10000)];
CBlockIndex *p2 = &blocks[InsecureRandRange(10000)];
CBlockIndex *p3 = &blocks[InsecureRandRange(10000)];
int64_t tdiff = GetBlockProofEquivalentTime(*p1, *p2, *p3, chainParams->GetConsensus());
BOOST_CHECK_EQUAL(tdiff, p1->GetBlockTime() - p2->GetBlockTime());
}
}
BOOST_AUTO_TEST_SUITE_END()
$ ./src/test/test_sugarchain test_bitcoin --log_level=test_suite --run_test=pow_tests
Running 3 test cases...
Entering test suite "Sugarchain Test Suite"
Entering test suite "pow_tests"
Entering test case "Lwma3CalculateNextWorkRequired_test"
Leaving test case "Lwma3CalculateNextWorkRequired_test"; testing time: 18564mks
Entering test case "lwma_difficulty_test"
Leaving test case "lwma_difficulty_test"; testing time: 559563mks
Entering test case "GetBlockProofEquivalentTime_test"
Leaving test case "GetBlockProofEquivalentTime_test"; testing time: 7405mks
Leaving test suite "pow_tests"
Leaving test suite "Sugarchain Test Suite"
*** No errors detected
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment