Skip to content

Instantly share code, notes, and snippets.

@cryptozeny
Last active December 26, 2018 05:45
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/0967562edb1dc0d8ae949e64cf7e2214 to your computer and use it in GitHub Desktop.
Save cryptozeny/0967562edb1dc0d8ae949e64cf7e2214 to your computer and use it in GitHub Desktop.
[WIP] pow_tests.cpp: Hash Attack Simulation
// 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()
$ ./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