Last active
December 26, 2018 05:45
-
-
Save cryptozeny/0967562edb1dc0d8ae949e64cf7e2214 to your computer and use it in GitHub Desktop.
[WIP] pow_tests.cpp: Hash Attack Simulation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) | |
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(sugarchain_test) { | |
// Copyright (c) 2018 The Sugarchain Core developers | |
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); | |
const Consensus::Params &mainnetParams = chainParams->GetConsensus(); | |
std::vector<CBlockIndex> blocks(500); | |
// Block counter. | |
int i = 0; | |
const arith_uint256 powLimit = UintToArith256(chainParams->GetConsensus().powLimit); | |
uint32_t powLimitBits = powLimit.GetCompact(); | |
// arith_uint256 currentPow = powLimit >> 4; | |
// uint32_t initialBits = currentPow.GetCompact(); | |
printf("*** mainnetParams \n"); | |
printf("%-12s %-5ld \n", "T", mainnetParams.nPowTargetSpacing); | |
printf("%-12s %-5ld \n", "N", mainnetParams.lwmaAveragingWindow); | |
printf("*** block[0] \n"); | |
printf("%-12s %-5s %s\n", "Parameter", "Block", "Value"); | |
printf("%-12s %-5d %u / %x\n", "powLimitBits", i, (unsigned)powLimitBits, (unsigned)powLimitBits); | |
printf("%-12s %-5d %s\n", "powLimit", i, powLimit.ToString().c_str()); // 0x1f07ffff | |
/* BEGIN - SetCompact */ | |
// https://en.bitcoin.it/wiki/Difficulty | |
// https://en.bitcoin.it/wiki/Target | |
arith_uint256 powLimitFromBits; | |
bool fNegative; | |
bool fOverflow; | |
powLimitFromBits.SetCompact((unsigned)powLimitBits, &fNegative, &fOverflow); // powLimitBits == 0x1f07ffff | |
printf("%-12s %-5d %s\n", "powLimit2", i, powLimitFromBits.GetHex().c_str()); | |
/* END - SetCompact */ | |
// printf("%-12s %-5d %u\n", "powLimitA", i, (unsigned)powLimitBits.SetCompact(); | |
// printf("%-12s %-5d %s\n", "powLimit2", i, ArithToUint256(powLimitBits).ToString().c_str()); | |
// printf("%-12s %-5d %s\n", "powLimit3", i, currentPow.ToString().c_str()); | |
// printf("%-12s %-5d %s\n", "currentPow", i, currentPow.ToString().c_str()); | |
// printf("%-12s %-5d %u / %x\n", "currentBits", i, (unsigned)powLimit.GetCompact(), (unsigned)powLimit.GetCompact()); | |
// printf("******\n"); | |
// Genesis block. | |
blocks[0] = CBlockIndex(); | |
blocks[0].nHeight = 0; | |
blocks[0].nTime = 1541009400; | |
blocks[0].nBits = powLimitBits; | |
blocks[0].nChainWork = GetBlockProof(blocks[0]); | |
// Create the first window for lwma, with blocks every 10 minutes. | |
// consensus.lwmaAveragingWindow = 200; | |
// N=200 for T=15: Lwma3CalculateNextWorkRequired | |
/* Begin - First Window */ | |
for (i = 1; i < 201; i++) { | |
blocks[i] = GetBlockIndex(&blocks[i - 1], 15, powLimitBits); // 0x1f07ffff | |
} | |
uint32_t nBits = Lwma3CalculateNextWorkRequired(&blocks[201], chainParams->GetConsensus()); | |
// Last block for the first window: still same | |
blocks[i] = GetBlockIndex(&blocks[i - 1], 15+1, nBits); | |
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus()); | |
printf("*** block[201] \n"); | |
printf("%-12s %-5d %u / %x\n", "currentBits", i-1, (unsigned)nBits, (unsigned)nBits); | |
powLimitFromBits.SetCompact((unsigned)powLimitBits, &fNegative, &fOverflow); // powLimitBits == 0x1f07ffff | |
printf("%-12s %-5d %s\n", "powLimit2", i-1, powLimitFromBits.GetHex().c_str()); | |
printf("*** \n"); | |
BOOST_CHECK_EQUAL( nBits, powLimitBits ); // 0x1f07ffff | |
// BOOST_CHECK_EQUAL( powLimitBits.c_str(), powLimitFromBits.GetHex().c_str() ); // 0x1f07ffff // FIXME.SUGAR | |
/* End - First Window */ | |
printf("*** filling first window finished \n"); | |
printf("*** \n"); | |
// Add one block: still same | |
blocks[i] = GetBlockIndex(&blocks[i - 1], 15+1, nBits); | |
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus()); | |
printf("*** block[202] \n"); | |
printf("%-12s %-5d %u / %x\n", "currentBits", i-1, (unsigned)nBits, (unsigned)nBits); | |
powLimitFromBits.SetCompact((unsigned)powLimitBits, &fNegative, &fOverflow); // powLimitBits == 0x1f07ffff | |
printf("%-12s %-5d %s\n", "powLimit2", i-1, powLimitFromBits.GetHex().c_str()); | |
printf("*** \n"); | |
BOOST_CHECK_EQUAL( nBits, powLimitBits ); // 0x1f07ffff | |
// Add one block: a little bit higher | |
blocks[i] = GetBlockIndex(&blocks[i - 1], 15-1.0000000000000010, nBits); | |
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus()); | |
printf("*** block[203] \n"); | |
printf("%-12s %-5d %u / %x\n", "currentBits", i-1, (unsigned)nBits, (unsigned)nBits); | |
powLimitFromBits.SetCompact(0x1f07fff9, &fNegative, &fOverflow); | |
printf("%-12s %-5d %s\n", "powLimit2", i-1, powLimitFromBits.GetHex().c_str()); | |
printf("*** \n"); | |
BOOST_CHECK_EQUAL( nBits, 0x1f07fff9 ); | |
// Add one block: a little bit lower: back to powLimit | |
blocks[i] = GetBlockIndex(&blocks[i - 1], 15*100, nBits); | |
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus()); | |
printf("*** block[204] \n"); | |
printf("%-12s %-5d %u / %x\n", "currentBits", i-1, (unsigned)nBits, (unsigned)nBits); | |
powLimitFromBits.SetCompact((unsigned)powLimitBits, &fNegative, &fOverflow); // powLimitBits == 0x1f07ffff | |
printf("%-12s %-5d %s\n", "powLimit2", i-1, powLimitFromBits.GetHex().c_str()); | |
printf("*** \n"); | |
BOOST_CHECK_EQUAL( nBits, powLimitBits ); | |
// Add 5 blocks: small attack: with 0 interval | |
printf("*** SMALL ATTACK \n"); | |
for ( int j = 0; j < 5; j++ ) { | |
blocks[i] = GetBlockIndex(&blocks[i - 1], 0, nBits); | |
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus()); | |
// printf("*** block[%d] \n", i-1); | |
printf("%-12s %-5d %u / %x\n", "currentBits", i-1, (unsigned)nBits, (unsigned)nBits); | |
powLimitFromBits.SetCompact((unsigned)powLimitBits, &fNegative, &fOverflow); // powLimitBits == 0x1f07ffff | |
printf("%-12s %-5d %s\n", "powLimit2", i-1, powLimitFromBits.GetHex().c_str()); | |
BOOST_CHECK_EQUAL( nBits, powLimitBits ); | |
} | |
printf("*** \n"); | |
// Add one block: higher with normal interval | |
blocks[i] = GetBlockIndex(&blocks[i - 1], 15, nBits); | |
nBits = Lwma3CalculateNextWorkRequired(&blocks[i++], chainParams->GetConsensus()); | |
printf("*** block[210] \n"); | |
printf("%-12s %-5d %u / %x\n", "currentBits", i-1, (unsigned)nBits, (unsigned)nBits); | |
powLimitFromBits.SetCompact(0x1f07fe58, &fNegative, &fOverflow); // powLimitBits == 0x1f07ffff | |
printf("%-12s %-5d %s\n", "powLimit2", i-1, powLimitFromBits.GetHex().c_str()); | |
printf("*** \n"); | |
BOOST_CHECK_EQUAL( nBits, 0x1f07fe58 ); | |
/* | |
// 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_SUITE_END() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ./src/test/test_sugarchain test_bitcoin --log_level=test_suite --run_test=pow_tests | |
Running 4 test cases... | |
Entering test suite "Sugarchain Test Suite" | |
Entering test suite "pow_tests" | |
Entering test case "h4x3rotab_test" | |
Leaving test case "h4x3rotab_test"; testing time: 17276mks | |
Entering test case "ishikawa_test" | |
Leaving test case "ishikawa_test"; testing time: 539171mks | |
Entering test case "sugarchain_test" | |
*** mainnetParams | |
T 15 | |
N 200 | |
*** block[0] | |
Parameter Block Value | |
powLimitBits 0 520617983 / 1f07ffff | |
powLimit 0 0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff | |
powLimit2 0 0007ffff00000000000000000000000000000000000000000000000000000000 | |
*** block[201] | |
currentBits 201 520617983 / 1f07ffff | |
powLimit2 201 0007ffff00000000000000000000000000000000000000000000000000000000 | |
*** | |
*** filling first window finished | |
*** | |
*** block[202] | |
currentBits 202 520617983 / 1f07ffff | |
powLimit2 202 0007ffff00000000000000000000000000000000000000000000000000000000 | |
*** | |
*** block[203] | |
currentBits 203 520617977 / 1f07fff9 | |
powLimit2 203 0007fff900000000000000000000000000000000000000000000000000000000 | |
*** | |
*** block[204] | |
currentBits 204 520617983 / 1f07ffff | |
powLimit2 204 0007ffff00000000000000000000000000000000000000000000000000000000 | |
*** | |
*** SMALL ATTACK | |
currentBits 205 520617983 / 1f07ffff | |
powLimit2 205 0007ffff00000000000000000000000000000000000000000000000000000000 | |
currentBits 206 520617983 / 1f07ffff | |
powLimit2 206 0007ffff00000000000000000000000000000000000000000000000000000000 | |
currentBits 207 520617983 / 1f07ffff | |
powLimit2 207 0007ffff00000000000000000000000000000000000000000000000000000000 | |
currentBits 208 520617983 / 1f07ffff | |
powLimit2 208 0007ffff00000000000000000000000000000000000000000000000000000000 | |
currentBits 209 520617983 / 1f07ffff | |
powLimit2 209 0007ffff00000000000000000000000000000000000000000000000000000000 | |
*** | |
*** block[210] | |
currentBits 210 520617560 / 1f07fe58 | |
powLimit2 210 0007fe5800000000000000000000000000000000000000000000000000000000 | |
*** | |
Leaving test case "sugarchain_test"; testing time: 28201mks | |
Entering test case "GetBlockProofEquivalentTime_test" | |
Leaving test case "GetBlockProofEquivalentTime_test"; testing time: 9154mks | |
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