2015-12-13 17:58:29 +01:00
// Copyright (c) 2011-2015 The Bitcoin Core developers
2014-12-13 05:09:33 +01:00
// Distributed under the MIT software license, see the accompanying
2014-03-18 10:11:00 +01:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2013-04-13 07:13:08 +02:00
2015-07-05 14:17:46 +02:00
# include "chainparams.h"
# include "coins.h"
2015-11-03 18:14:09 +01:00
# include "consensus/consensus.h"
2015-11-17 17:35:44 +01:00
# include "consensus/merkle.h"
2015-01-24 15:57:12 +01:00
# include "consensus/validation.h"
2012-05-22 23:55:15 +02:00
# include "main.h"
2013-04-13 07:13:08 +02:00
# include "miner.h"
2014-10-28 22:47:18 +01:00
# include "pubkey.h"
2015-07-05 14:17:46 +02:00
# include "script/standard.h"
# include "txmempool.h"
2011-10-12 01:50:06 +02:00
# include "uint256.h"
2012-04-17 20:37:47 +02:00
# include "util.h"
2015-07-05 14:17:46 +02:00
# include "utilstrencodings.h"
2011-09-27 20:16:07 +02:00
2015-03-03 16:49:12 +01:00
# include "test/test_bitcoin.h"
2016-06-19 19:26:20 +02:00
# include <cstdio>
2013-04-13 07:13:08 +02:00
# include <boost/test/unit_test.hpp>
2015-03-03 16:49:12 +01:00
BOOST_FIXTURE_TEST_SUITE ( miner_tests , TestingSetup )
2011-09-27 20:16:07 +02:00
2015-01-05 17:43:07 +01:00
/*static
2012-05-22 23:55:15 +02:00
struct {
unsigned char extranonce ;
unsigned int nonce ;
} blockinfo [ ] = {
{ 4 , 0xa4a3e223 } , { 2 , 0x15c32f9e } , { 1 , 0x0375b547 } , { 1 , 0x7004a8a5 } ,
{ 2 , 0xce440296 } , { 2 , 0x52cfe198 } , { 1 , 0x77a72cd0 } , { 2 , 0xbb5d6f84 } ,
{ 2 , 0x83f30c2c } , { 1 , 0x48a73d5b } , { 1 , 0xef7dcd01 } , { 2 , 0x6809c6c4 } ,
{ 2 , 0x0883ab3c } , { 1 , 0x087bbbe2 } , { 2 , 0x2104a814 } , { 2 , 0xdffb6daa } ,
{ 1 , 0xee8a0a08 } , { 2 , 0xba4237c1 } , { 1 , 0xa70349dc } , { 1 , 0x344722bb } ,
{ 3 , 0xd6294733 } , { 2 , 0xec9f5c94 } , { 2 , 0xca2fbc28 } , { 1 , 0x6ba4f406 } ,
{ 2 , 0x015d4532 } , { 1 , 0x6e119b7c } , { 2 , 0x43e8f314 } , { 2 , 0x27962f38 } ,
{ 2 , 0xb571b51b } , { 2 , 0xb36bee23 } , { 2 , 0xd17924a8 } , { 2 , 0x6bc212d9 } ,
{ 1 , 0x630d4948 } , { 2 , 0x9a4c4ebb } , { 2 , 0x554be537 } , { 1 , 0xd63ddfc7 } ,
{ 2 , 0xa10acc11 } , { 1 , 0x759a8363 } , { 2 , 0xfb73090d } , { 1 , 0xe82c6a34 } ,
{ 1 , 0xe33e92d7 } , { 3 , 0x658ef5cb } , { 2 , 0xba32ff22 } , { 5 , 0x0227a10c } ,
{ 1 , 0xa9a70155 } , { 5 , 0xd096d809 } , { 1 , 0x37176174 } , { 1 , 0x830b8d0f } ,
{ 1 , 0xc6e3910e } , { 2 , 0x823f3ca8 } , { 1 , 0x99850849 } , { 1 , 0x7521fb81 } ,
{ 1 , 0xaacaabab } , { 1 , 0xd645a2eb } , { 5 , 0x7aea1781 } , { 5 , 0x9d6e4b78 } ,
{ 1 , 0x4ce90fd8 } , { 1 , 0xabdc832d } , { 6 , 0x4a34f32a } , { 2 , 0xf2524c1c } ,
{ 2 , 0x1bbeb08a } , { 1 , 0xad47f480 } , { 1 , 0x9f026aeb } , { 1 , 0x15a95049 } ,
{ 2 , 0xd1cb95b2 } , { 2 , 0xf84bbda5 } , { 1 , 0x0fa62cd1 } , { 1 , 0xe05f9169 } ,
{ 1 , 0x78d194a9 } , { 5 , 0x3e38147b } , { 5 , 0x737ba0d4 } , { 1 , 0x63378e10 } ,
{ 1 , 0x6d5f91cf } , { 2 , 0x88612eb8 } , { 2 , 0xe9639484 } , { 1 , 0xb7fabc9d } ,
{ 2 , 0x19b01592 } , { 1 , 0x5a90dd31 } , { 2 , 0x5bd7e028 } , { 2 , 0x94d00323 } ,
{ 1 , 0xa9b9c01a } , { 1 , 0x3a40de61 } , { 1 , 0x56e7eec7 } , { 5 , 0x859f7ef6 } ,
{ 1 , 0xfd8e5630 } , { 1 , 0x2b0c9f7f } , { 1 , 0xba700e26 } , { 1 , 0x7170a408 } ,
{ 1 , 0x70de86a8 } , { 1 , 0x74d64cd5 } , { 1 , 0x49e738a1 } , { 2 , 0x6910b602 } ,
{ 0 , 0x643c565f } , { 1 , 0x54264b3f } , { 2 , 0x97ea6396 } , { 2 , 0x55174459 } ,
{ 2 , 0x03e8779a } , { 1 , 0x98f34d8f } , { 1 , 0xc07b2b07 } , { 1 , 0xdfe29668 } ,
{ 1 , 0x3141c7c1 } , { 1 , 0xb3b595f4 } , { 1 , 0x735abf08 } , { 5 , 0x623bfbce } ,
{ 2 , 0xd351e722 } , { 1 , 0xf4ca48c9 } , { 1 , 0x5b19c670 } , { 1 , 0xa164bf0e } ,
{ 2 , 0xbbbeb305 } , { 2 , 0xfe1c810a } ,
2015-01-05 17:43:07 +01:00
} ; */
2015-04-09 05:28:04 +02:00
/*static
2015-01-05 17:43:07 +01:00
struct {
unsigned char extranonce ;
unsigned int nonce ;
} blockinfo [ ] = {
2015-02-05 20:24:09 +01:00
{ 4 , 0x00000000 } , { 2 , 0x00000001 } , { 1 , 0x00000002 } , { 1 , 0x00000000 } , //0
{ 2 , 0x00000001 } , { 2 , 0x00000001 } , { 1 , 0x00000001 } , { 2 , 0x00000000 } , //4
{ 2 , 0x00000001 } , { 1 , 0x00000000 } , { 1 , 0x00000001 } , { 2 , 0x00000001 } , //8
{ 2 , 0x00000003 } , { 1 , 0x00000001 } , { 2 , 0x00000001 } , { 2 , 0x00000001 } , //12
{ 1 , 0x00000001 } , { 2 , 0x00000000 } , { 1 , 0x00000005 } , { 1 , 0x00000001 } , //16
{ 3 , 0x00000000 } , { 2 , 0x00000000 } , { 2 , 0x00000000 } , { 1 , 0x00000004 } , //20
{ 2 , 0x00000000 } , { 1 , 0x00000000 } , { 2 , 0x00000002 } , { 2 , 0x00000003 } , //24
{ 2 , 0x00000001 } , { 2 , 0x00000001 } , { 2 , 0x00000000 } , { 2 , 0x00000000 } , //28
{ 1 , 0x00000001 } , { 2 , 0x00000000 } , { 2 , 0x00000001 } , { 1 , 0x00000000 } , //32
{ 2 , 0x00000000 } , { 1 , 0x00000001 } , { 2 , 0x00000000 } , { 1 , 0x00000000 } , //36
{ 1 , 0x00000000 } , { 3 , 0x00000000 } , { 2 , 0x00000005 } , { 5 , 0x00000000 } , //40
{ 1 , 0x00000002 } , { 5 , 0x00000001 } , { 1 , 0x00000001 } , { 1 , 0x00000001 } , //44
{ 1 , 0x00000001 } , { 2 , 0x00000002 } , { 1 , 0x00000002 } , { 1 , 0x00000001 } , //48
{ 1 , 0x00000000 } , { 1 , 0x00000000 } , { 5 , 0x00000002 } , { 5 , 0x00000000 } , //52
{ 1 , 0x00000000 } , { 1 , 0x00000000 } , { 6 , 0x00000001 } , { 2 , 0x00000000 } , //56
{ 2 , 0x00000003 } , { 1 , 0x00000000 } , { 1 , 0x00000000 } , { 1 , 0x00000000 } , //60
{ 2 , 0x00000000 } , { 2 , 0x00000001 } , { 1 , 0x00000000 } , { 1 , 0x00000001 } , //64
{ 1 , 0x00000003 } , { 5 , 0x00000000 } , { 5 , 0x00000000 } , { 1 , 0x00000002 } , //68
{ 1 , 0x00000000 } , { 2 , 0x00000001 } , { 2 , 0x00000004 } , { 1 , 0x00000000 } , //72
{ 2 , 0x00000001 } , { 1 , 0x00000002 } , { 2 , 0x00000004 } , { 2 , 0x00000000 } , //76
{ 1 , 0x00000000 } , { 1 , 0x00000002 } , { 1 , 0x00000000 } , { 5 , 0x00000002 } , //80
{ 1 , 0x00000001 } , { 1 , 0x00000003 } , { 1 , 0x00000000 } , { 1 , 0x00000002 } , //84
{ 1 , 0x00000000 } , { 1 , 0x00000000 } , { 1 , 0x00000002 } , { 2 , 0x00000000 } , //88
{ 0 , 0x00000000 } , { 1 , 0x00000000 } , { 2 , 0x00000001 } , { 2 , 0x00000001 } , //92
{ 2 , 0x00000000 } , { 1 , 0x00000000 } , { 1 , 0x00000000 } , { 1 , 0x00000000 } , //96
{ 1 , 0x00000000 } , { 1 , 0x00000000 } , { 1 , 0x00000000 } , { 5 , 0x00000000 } , //100
{ 2 , 0x00000000 } , { 1 , 0x00000002 } , { 1 , 0x00000000 } , { 1 , 0x00000001 } , //104
{ 2 , 0x00000003 } , { 2 , 0x00000000 } , //108
2015-04-09 05:28:04 +02:00
} ; */
const unsigned int nonces [ ] = {
2016-07-01 04:27:51 +02:00
9875 , 95807 , 31359 , 234335 , 145717 , 80791 , 112145 , 24413 , 180722 , 9910 ,
43622 , 8531 , 6247 , 21164 , 31399 , 115014 , 6240 , 11855 , 15380 , 16059 ,
151773 , 42247 , 258112 , 33467 , 66678 , 118631 , 31485 , 53636 , 74882 , 4123 ,
86392 , 11386 , 58121 , 27870 , 76602 , 17616 , 80966 , 37064 , 84547 , 58182 ,
169550 , 11965 , 63424 , 245620 , 4710 , 6134 , 77310 , 100050 , 134882 , 44029 ,
3970 , 175316 , 56994 , 23523 , 12055 , 15866 , 25422 , 71227 , 105999 , 107878 ,
75188 , 17820 , 54863 , 74022 , 81834 , 121376 , 67397 , 10857 , 22081 , 33061 ,
65027 , 46272 , 56681 , 1209 , 151028 , 82788 , 7817 , 92273 , 55392 , 15714 ,
94174 , 21541 , 33833 , 30596 , 93204 , 53265 , 51495 , 59980 , 91955 , 57202 ,
40559 , 23761 , 75982 , 4582 , 3207 , 109694 , 12944 , 93689 , 47593 , 20997 ,
194095 , 112324 , 146676 , 66180 , 33360 , 140817 , 731 , 19918 , 31681 , 19541 ,
2012-05-22 23:55:15 +02:00
} ;
2015-12-07 21:44:16 +01:00
CBlockIndex CreateBlockIndex ( int nHeight )
{
CBlockIndex index ;
index . nHeight = nHeight ;
index . pprev = chainActive . Tip ( ) ;
return index ;
}
bool TestSequenceLocks ( const CTransaction & tx , int flags )
{
LOCK ( mempool . cs ) ;
return CheckSequenceLocks ( tx , flags ) ;
}
2012-05-22 23:55:15 +02:00
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
BOOST_AUTO_TEST_CASE ( CreateNewBlock_validity )
{
2015-04-20 00:17:11 +02:00
const CChainParams & chainparams = Params ( CBaseChainParams : : MAIN ) ;
2013-12-09 09:22:15 +01:00
CScript scriptPubKey = CScript ( ) < < ParseHex ( " 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f " ) < < OP_CHECKSIG ;
2012-12-19 21:21:21 +01:00
CBlockTemplate * pblocktemplate ;
2014-06-07 13:53:27 +02:00
CMutableTransaction tx , tx2 ;
2012-05-22 23:55:15 +02:00
CScript script ;
uint256 hash ;
2015-11-14 23:04:15 +01:00
TestMemPoolEntryHelper entry ;
entry . nFee = 11 ;
entry . dPriority = 111.0 ;
entry . nHeight = 11 ;
2012-05-22 23:55:15 +02:00
2013-12-02 04:11:21 +01:00
LOCK ( cs_main ) ;
2015-04-23 05:22:36 +02:00
fCheckpointsEnabled = false ;
2013-12-02 04:11:21 +01:00
2012-05-22 23:55:15 +02:00
// Simple block creation, nothing special yet:
2015-04-17 14:19:52 +02:00
BOOST_CHECK ( pblocktemplate = CreateNewBlock ( chainparams , scriptPubKey ) ) ;
2012-05-22 23:55:15 +02:00
// We can't make transactions until we have inputs
// Therefore, load 100 blocks :)
2015-12-07 21:44:16 +01:00
int baseheight = 0 ;
2012-05-22 23:55:15 +02:00
std : : vector < CTransaction * > txFirst ;
2015-04-09 05:28:04 +02:00
for ( unsigned int i = 0 ; i < 110 ; + + i )
2012-05-22 23:55:15 +02:00
{
2016-05-16 04:16:56 +02:00
BOOST_CHECK ( pblocktemplate = CreateNewBlock ( chainparams , scriptPubKey ) ) ;
2012-12-19 21:21:21 +01:00
CBlock * pblock = & pblocktemplate - > block ; // pointer for convenience
2016-04-16 08:16:32 +02:00
pblock - > hashPrevBlock = chainActive . Tip ( ) - > GetBlockHash ( ) ;
2012-08-20 16:36:43 +02:00
pblock - > nVersion = 1 ;
2016-07-01 04:27:51 +02:00
pblock - > nTime = chainActive . Tip ( ) - > GetBlockTime ( ) + chainparams . GetConsensus ( ) . nPowTargetSpacing ;
2014-06-07 13:53:27 +02:00
CMutableTransaction txCoinbase ( pblock - > vtx [ 0 ] ) ;
2015-06-03 01:25:34 +02:00
txCoinbase . nVersion = 1 ;
2014-06-07 13:53:27 +02:00
txCoinbase . vin [ 0 ] . scriptSig = CScript ( ) ;
2015-04-09 05:28:04 +02:00
txCoinbase . vin [ 0 ] . scriptSig . push_back ( 0 ) ;
2014-06-07 13:53:27 +02:00
txCoinbase . vin [ 0 ] . scriptSig . push_back ( chainActive . Height ( ) ) ;
txCoinbase . vout [ 0 ] . scriptPubKey = CScript ( ) ;
2015-10-29 04:05:30 +01:00
txCoinbase . vout [ 0 ] . nValue = GetBlockSubsidy ( chainActive . Height ( ) + 1 , Params ( ) . GetConsensus ( ) ) ;
2014-06-07 13:53:27 +02:00
pblock - > vtx [ 0 ] = CTransaction ( txCoinbase ) ;
2015-12-07 21:44:16 +01:00
if ( txFirst . size ( ) = = 0 )
baseheight = chainActive . Height ( ) ;
if ( txFirst . size ( ) < 4 )
2012-05-22 23:55:15 +02:00
txFirst . push_back ( new CTransaction ( pblock - > vtx [ 0 ] ) ) ;
2015-11-17 17:35:44 +01:00
pblock - > hashMerkleRoot = BlockMerkleRoot ( * pblock ) ;
2015-04-09 05:28:04 +02:00
pblock - > nNonce = nonces [ i ] ;
2016-06-19 19:26:20 +02:00
2016-07-01 04:27:51 +02:00
//#define NEED_NEW_NONCES_MINER_TEST
2016-06-19 19:26:20 +02:00
//Use below code to find nonces, in case we change hashing or difficulty retargeting algo
2016-07-01 04:27:51 +02:00
# ifdef NEED_NEW_NONCES_MINER_TEST
2016-06-19 19:26:20 +02:00
bool fFound = false ;
2016-06-22 16:04:22 +02:00
2015-01-05 17:43:07 +01:00
for ( int j = 0 ; ! fFound ; j + + )
{
pblock - > nNonce = j ;
2016-04-02 03:37:44 +02:00
if ( CheckProofOfWork ( pblock - > GetPoWHash ( ) , pblock - > nBits , Params ( ) . GetConsensus ( ) ) )
2015-01-05 17:43:07 +01:00
{
fFound = true ;
2015-04-09 05:28:04 +02:00
std : : cout < < pblock - > nNonce < < " , " ;
if ( ( i + 1 ) % 10 = = 0 )
2015-02-05 20:24:09 +01:00
std : : cout < < std : : endl ;
2015-04-09 05:28:04 +02:00
else
std : : cout < < " " ;
2015-01-05 17:43:07 +01:00
}
2016-07-01 04:27:51 +02:00
}
# endif
2016-06-19 19:26:20 +02:00
2013-01-27 00:14:11 +01:00
CValidationState state ;
2015-04-20 00:17:11 +02:00
BOOST_CHECK ( ProcessNewBlock ( state , chainparams , NULL , pblock , true , NULL ) ) ;
2013-01-27 00:14:11 +01:00
BOOST_CHECK ( state . IsValid ( ) ) ;
2016-04-16 08:16:32 +02:00
delete pblocktemplate ;
2012-05-22 23:55:15 +02:00
}
// Just to make sure we can still make simple blocks
2015-04-17 14:19:52 +02:00
BOOST_CHECK ( pblocktemplate = CreateNewBlock ( chainparams , scriptPubKey ) ) ;
2013-09-19 00:01:36 +02:00
delete pblocktemplate ;
2012-05-22 23:55:15 +02:00
// block sigops > limit: 1000 CHECKMULTISIG + 1
tx . vin . resize ( 1 ) ;
// NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_0 < < OP_0 < < OP_0 < < OP_NOP < < OP_CHECKMULTISIG < < OP_1 ;
tx . vin [ 0 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ;
tx . vin [ 0 ] . prevout . n = 0 ;
tx . vout . resize ( 1 ) ;
2016-04-17 00:42:11 +02:00
tx . vout [ 0 ] . nValue = 50000000LL ;
2012-05-22 23:55:15 +02:00
for ( unsigned int i = 0 ; i < 1001 ; + + i )
{
2016-05-16 04:16:56 +02:00
tx . vout [ 0 ] . nValue - = 100 ;
2012-05-22 23:55:15 +02:00
hash = tx . GetHash ( ) ;
2015-10-29 19:06:13 +01:00
bool spendsCoinbase = ( i = = 0 ) ? true : false ; // only first tx spends coinbase
2015-11-03 16:35:39 +01:00
// If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails
2016-05-16 04:16:56 +02:00
mempool . addUnchecked ( hash , entry . Fee ( 100000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( spendsCoinbase ) . FromTx ( tx ) ) ;
2012-05-22 23:55:15 +02:00
tx . vin [ 0 ] . prevout . hash = hash ;
}
2015-11-03 16:35:39 +01:00
BOOST_CHECK_THROW ( CreateNewBlock ( chainparams , scriptPubKey ) , std : : runtime_error ) ;
mempool . clear ( ) ;
tx . vin [ 0 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ;
2016-05-16 04:16:56 +02:00
tx . vout [ 0 ] . nValue = 50000000LL ;
2015-11-03 16:35:39 +01:00
for ( unsigned int i = 0 ; i < 1001 ; + + i )
{
2016-05-16 04:16:56 +02:00
tx . vout [ 0 ] . nValue - = 100 ;
2015-11-03 16:35:39 +01:00
hash = tx . GetHash ( ) ;
bool spendsCoinbase = ( i = = 0 ) ? true : false ; // only first tx spends coinbase
// If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes
2016-05-16 04:16:56 +02:00
mempool . addUnchecked ( hash , entry . Fee ( 50000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( spendsCoinbase ) . SigOps ( 20 ) . FromTx ( tx ) ) ;
2012-05-22 23:55:15 +02:00
tx . vin [ 0 ] . prevout . hash = hash ;
}
2015-04-17 14:19:52 +02:00
BOOST_CHECK ( pblocktemplate = CreateNewBlock ( chainparams , scriptPubKey ) ) ;
2012-12-19 21:21:21 +01:00
delete pblocktemplate ;
2012-05-22 23:55:15 +02:00
mempool . clear ( ) ;
// block size > limit
tx . vin [ 0 ] . scriptSig = CScript ( ) ;
// 18 * (520char + DROP) + OP_1 = 9433 bytes
std : : vector < unsigned char > vchData ( 520 ) ;
for ( unsigned int i = 0 ; i < 18 ; + + i )
tx . vin [ 0 ] . scriptSig < < vchData < < OP_DROP ;
tx . vin [ 0 ] . scriptSig < < OP_1 ;
tx . vin [ 0 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ;
2016-05-16 04:16:56 +02:00
tx . vout [ 0 ] . nValue = 500000LL ;
2012-05-22 23:55:15 +02:00
for ( unsigned int i = 0 ; i < 128 ; + + i )
{
2016-05-16 04:16:56 +02:00
tx . vout [ 0 ] . nValue - = 100 ;
2012-05-22 23:55:15 +02:00
hash = tx . GetHash ( ) ;
2015-10-29 19:06:13 +01:00
bool spendsCoinbase = ( i = = 0 ) ? true : false ; // only first tx spends coinbase
2016-05-16 04:16:56 +02:00
mempool . addUnchecked ( hash , entry . Fee ( 100000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( spendsCoinbase ) . FromTx ( tx ) ) ;
2012-05-22 23:55:15 +02:00
tx . vin [ 0 ] . prevout . hash = hash ;
}
2015-04-17 14:19:52 +02:00
BOOST_CHECK ( pblocktemplate = CreateNewBlock ( chainparams , scriptPubKey ) ) ;
2012-12-19 21:21:21 +01:00
delete pblocktemplate ;
2012-05-22 23:55:15 +02:00
mempool . clear ( ) ;
2015-11-03 16:35:39 +01:00
// orphan in mempool, template creation fails
2012-05-22 23:55:15 +02:00
hash = tx . GetHash ( ) ;
2015-11-03 16:35:39 +01:00
mempool . addUnchecked ( hash , entry . Fee ( 1000000 ) . Time ( GetTime ( ) ) . FromTx ( tx ) ) ;
BOOST_CHECK_THROW ( CreateNewBlock ( chainparams , scriptPubKey ) , std : : runtime_error ) ;
2012-05-22 23:55:15 +02:00
mempool . clear ( ) ;
// child with higher priority than parent
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_1 ;
tx . vin [ 0 ] . prevout . hash = txFirst [ 1 ] - > GetHash ( ) ;
2016-04-17 00:42:11 +02:00
tx . vout [ 0 ] . nValue = 49000000LL ;
2012-05-22 23:55:15 +02:00
hash = tx . GetHash ( ) ;
2016-05-16 04:16:56 +02:00
mempool . addUnchecked ( hash , entry . Fee ( 1000000LL ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2012-05-22 23:55:15 +02:00
tx . vin [ 0 ] . prevout . hash = hash ;
tx . vin . resize ( 2 ) ;
tx . vin [ 1 ] . scriptSig = CScript ( ) < < OP_1 ;
tx . vin [ 1 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ;
tx . vin [ 1 ] . prevout . n = 0 ;
2016-04-17 00:42:11 +02:00
tx . vout [ 0 ] . nValue = 59000000LL ;
2012-05-22 23:55:15 +02:00
hash = tx . GetHash ( ) ;
2016-05-16 04:16:56 +02:00
mempool . addUnchecked ( hash , entry . Fee ( 4000000LL ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2015-04-17 14:19:52 +02:00
BOOST_CHECK ( pblocktemplate = CreateNewBlock ( chainparams , scriptPubKey ) ) ;
2012-12-19 21:21:21 +01:00
delete pblocktemplate ;
2012-05-22 23:55:15 +02:00
mempool . clear ( ) ;
2015-11-03 16:35:39 +01:00
// coinbase in mempool, template creation fails
2012-05-22 23:55:15 +02:00
tx . vin . resize ( 1 ) ;
tx . vin [ 0 ] . prevout . SetNull ( ) ;
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_0 < < OP_1 ;
tx . vout [ 0 ] . nValue = 0 ;
hash = tx . GetHash ( ) ;
2015-11-03 16:35:39 +01:00
// give it a fee so it'll get mined
mempool . addUnchecked ( hash , entry . Fee ( 100000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( false ) . FromTx ( tx ) ) ;
BOOST_CHECK_THROW ( CreateNewBlock ( chainparams , scriptPubKey ) , std : : runtime_error ) ;
2012-05-22 23:55:15 +02:00
mempool . clear ( ) ;
2015-11-03 16:35:39 +01:00
// invalid (pre-p2sh) txn in mempool, template creation fails
2012-05-22 23:55:15 +02:00
tx . vin [ 0 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ;
tx . vin [ 0 ] . prevout . n = 0 ;
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_1 ;
2016-04-17 00:42:11 +02:00
tx . vout [ 0 ] . nValue = 49000000LL ;
2012-05-22 23:55:15 +02:00
script = CScript ( ) < < OP_0 ;
2014-09-25 04:24:46 +02:00
tx . vout [ 0 ] . scriptPubKey = GetScriptForDestination ( CScriptID ( script ) ) ;
2012-05-22 23:55:15 +02:00
hash = tx . GetHash ( ) ;
2015-11-03 16:35:39 +01:00
mempool . addUnchecked ( hash , entry . Fee ( 10000000L ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2012-05-22 23:55:15 +02:00
tx . vin [ 0 ] . prevout . hash = hash ;
2015-10-29 07:11:24 +01:00
tx . vin [ 0 ] . scriptSig = CScript ( ) < < std : : vector < unsigned char > ( script . begin ( ) , script . end ( ) ) ;
2016-04-17 00:42:11 +02:00
tx . vout [ 0 ] . nValue - = 10000 ;
2012-05-22 23:55:15 +02:00
hash = tx . GetHash ( ) ;
2015-11-03 16:35:39 +01:00
mempool . addUnchecked ( hash , entry . Fee ( 1000000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( false ) . FromTx ( tx ) ) ;
BOOST_CHECK_THROW ( CreateNewBlock ( chainparams , scriptPubKey ) , std : : runtime_error ) ;
2012-05-22 23:55:15 +02:00
mempool . clear ( ) ;
2015-11-03 16:35:39 +01:00
// double spend txn pair in mempool, template creation fails
2012-05-22 23:55:15 +02:00
tx . vin [ 0 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ;
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_1 ;
2016-04-17 00:42:11 +02:00
tx . vout [ 0 ] . nValue = 49000000LL ;
2012-05-22 23:55:15 +02:00
tx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_1 ;
hash = tx . GetHash ( ) ;
2015-11-03 16:35:39 +01:00
mempool . addUnchecked ( hash , entry . Fee ( 100000000L ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2012-05-22 23:55:15 +02:00
tx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_2 ;
hash = tx . GetHash ( ) ;
2015-11-03 16:35:39 +01:00
mempool . addUnchecked ( hash , entry . Fee ( 100000000L ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
BOOST_CHECK_THROW ( CreateNewBlock ( chainparams , scriptPubKey ) , std : : runtime_error ) ;
2012-05-22 23:55:15 +02:00
mempool . clear ( ) ;
2014-01-27 03:50:15 +01:00
// non-final txs in mempool
SetMockTime ( chainActive . Tip ( ) - > GetMedianTimePast ( ) + 1 ) ;
2015-12-07 21:44:16 +01:00
int flags = LOCKTIME_VERIFY_SEQUENCE | LOCKTIME_MEDIAN_TIME_PAST ;
// height map
std : : vector < int > prevheights ;
2014-01-27 03:50:15 +01:00
2015-12-07 21:44:16 +01:00
// relative height locked
tx . nVersion = 2 ;
tx . vin . resize ( 1 ) ;
prevheights . resize ( 1 ) ;
tx . vin [ 0 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ; // only 1 transaction
tx . vin [ 0 ] . prevout . n = 0 ;
2014-01-27 03:50:15 +01:00
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_1 ;
2015-12-07 21:44:16 +01:00
tx . vin [ 0 ] . nSequence = chainActive . Tip ( ) - > nHeight + 1 ; // txFirst[0] is the 2nd block
prevheights [ 0 ] = baseheight + 1 ;
tx . vout . resize ( 1 ) ;
2016-04-17 00:42:11 +02:00
tx . vout [ 0 ] . nValue = 49000000LL ;
2014-01-27 03:50:15 +01:00
tx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_1 ;
2015-12-07 21:44:16 +01:00
tx . nLockTime = 0 ;
2014-01-27 03:50:15 +01:00
hash = tx . GetHash ( ) ;
2016-05-16 04:16:56 +02:00
mempool . addUnchecked ( hash , entry . Fee ( 1000000L ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2015-12-07 21:44:16 +01:00
BOOST_CHECK ( CheckFinalTx ( tx , flags ) ) ; // Locktime passes
BOOST_CHECK ( ! TestSequenceLocks ( tx , flags ) ) ; // Sequence locks fail
BOOST_CHECK ( SequenceLocks ( tx , flags , & prevheights , CreateBlockIndex ( chainActive . Tip ( ) - > nHeight + 2 ) ) ) ; // Sequence locks pass on 2nd block
2014-01-27 03:50:15 +01:00
2015-12-07 21:44:16 +01:00
// relative time locked
tx . vin [ 0 ] . prevout . hash = txFirst [ 1 ] - > GetHash ( ) ;
tx . vin [ 0 ] . nSequence = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG | ( ( ( chainActive . Tip ( ) - > GetMedianTimePast ( ) + 1 - chainActive [ 1 ] - > GetMedianTimePast ( ) ) > > CTxIn : : SEQUENCE_LOCKTIME_GRANULARITY ) + 1 ) ; // txFirst[1] is the 3rd block
prevheights [ 0 ] = baseheight + 2 ;
hash = tx . GetHash ( ) ;
mempool . addUnchecked ( hash , entry . Time ( GetTime ( ) ) . FromTx ( tx ) ) ;
BOOST_CHECK ( CheckFinalTx ( tx , flags ) ) ; // Locktime passes
BOOST_CHECK ( ! TestSequenceLocks ( tx , flags ) ) ; // Sequence locks fail
for ( int i = 0 ; i < CBlockIndex : : nMedianTimeSpan ; i + + )
chainActive . Tip ( ) - > GetAncestor ( chainActive . Tip ( ) - > nHeight - i ) - > nTime + = 512 ; //Trick the MedianTimePast
BOOST_CHECK ( SequenceLocks ( tx , flags , & prevheights , CreateBlockIndex ( chainActive . Tip ( ) - > nHeight + 1 ) ) ) ; // Sequence locks pass 512 seconds later
for ( int i = 0 ; i < CBlockIndex : : nMedianTimeSpan ; i + + )
chainActive . Tip ( ) - > GetAncestor ( chainActive . Tip ( ) - > nHeight - i ) - > nTime - = 512 ; //undo tricked MTP
2014-01-27 03:50:15 +01:00
2015-12-07 21:44:16 +01:00
// absolute height locked
tx . vin [ 0 ] . prevout . hash = txFirst [ 2 ] - > GetHash ( ) ;
tx . vin [ 0 ] . nSequence = CTxIn : : SEQUENCE_FINAL - 1 ;
prevheights [ 0 ] = baseheight + 3 ;
tx . nLockTime = chainActive . Tip ( ) - > nHeight + 1 ;
hash = tx . GetHash ( ) ;
mempool . addUnchecked ( hash , entry . Time ( GetTime ( ) ) . FromTx ( tx ) ) ;
BOOST_CHECK ( ! CheckFinalTx ( tx , flags ) ) ; // Locktime fails
BOOST_CHECK ( TestSequenceLocks ( tx , flags ) ) ; // Sequence locks pass
BOOST_CHECK ( IsFinalTx ( tx , chainActive . Tip ( ) - > nHeight + 2 , chainActive . Tip ( ) - > GetMedianTimePast ( ) ) ) ; // Locktime passes on 2nd block
// absolute time locked
tx . vin [ 0 ] . prevout . hash = txFirst [ 3 ] - > GetHash ( ) ;
tx . nLockTime = chainActive . Tip ( ) - > GetMedianTimePast ( ) ;
prevheights . resize ( 1 ) ;
prevheights [ 0 ] = baseheight + 4 ;
hash = tx . GetHash ( ) ;
mempool . addUnchecked ( hash , entry . Time ( GetTime ( ) ) . FromTx ( tx ) ) ;
BOOST_CHECK ( ! CheckFinalTx ( tx , flags ) ) ; // Locktime fails
BOOST_CHECK ( TestSequenceLocks ( tx , flags ) ) ; // Sequence locks pass
BOOST_CHECK ( IsFinalTx ( tx , chainActive . Tip ( ) - > nHeight + 2 , chainActive . Tip ( ) - > GetMedianTimePast ( ) + 1 ) ) ; // Locktime passes 1 second later
// mempool-dependent transactions (not added)
tx . vin [ 0 ] . prevout . hash = hash ;
prevheights [ 0 ] = chainActive . Tip ( ) - > nHeight + 1 ;
tx . nLockTime = 0 ;
tx . vin [ 0 ] . nSequence = 0 ;
BOOST_CHECK ( CheckFinalTx ( tx , flags ) ) ; // Locktime passes
BOOST_CHECK ( TestSequenceLocks ( tx , flags ) ) ; // Sequence locks pass
tx . vin [ 0 ] . nSequence = 1 ;
BOOST_CHECK ( ! TestSequenceLocks ( tx , flags ) ) ; // Sequence locks fail
tx . vin [ 0 ] . nSequence = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG ;
BOOST_CHECK ( TestSequenceLocks ( tx , flags ) ) ; // Sequence locks pass
tx . vin [ 0 ] . nSequence = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG | 1 ;
BOOST_CHECK ( ! TestSequenceLocks ( tx , flags ) ) ; // Sequence locks fail
2014-01-27 03:50:15 +01:00
2015-04-17 14:19:52 +02:00
BOOST_CHECK ( pblocktemplate = CreateNewBlock ( chainparams , scriptPubKey ) ) ;
2014-01-27 03:50:15 +01:00
2015-12-07 21:44:16 +01:00
// None of the of the absolute height/time locked tx should have made
// it into the template because we still check IsFinalTx in CreateNewBlock,
// but relative locked txs will if inconsistently added to mempool.
// For now these will still generate a valid template until BIP68 soft fork
2014-01-27 03:50:15 +01:00
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 3 ) ;
delete pblocktemplate ;
2015-12-07 21:44:16 +01:00
// However if we advance height by 1 and time by 512, all of them should be mined
for ( int i = 0 ; i < CBlockIndex : : nMedianTimeSpan ; i + + )
chainActive . Tip ( ) - > GetAncestor ( chainActive . Tip ( ) - > nHeight - i ) - > nTime + = 512 ; //Trick the MedianTimePast
2014-01-27 03:50:15 +01:00
chainActive . Tip ( ) - > nHeight + + ;
2015-12-07 21:44:16 +01:00
SetMockTime ( chainActive . Tip ( ) - > GetMedianTimePast ( ) + 1 ) ;
2014-01-27 03:50:15 +01:00
2015-04-17 14:19:52 +02:00
BOOST_CHECK ( pblocktemplate = CreateNewBlock ( chainparams , scriptPubKey ) ) ;
2015-12-07 21:44:16 +01:00
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 5 ) ;
2014-01-27 03:50:15 +01:00
delete pblocktemplate ;
chainActive . Tip ( ) - > nHeight - - ;
SetMockTime ( 0 ) ;
2014-09-04 21:23:42 +02:00
mempool . clear ( ) ;
2014-01-27 03:50:15 +01:00
2013-09-19 00:01:36 +02:00
BOOST_FOREACH ( CTransaction * tx , txFirst )
delete tx ;
2014-01-27 03:50:15 +01:00
2015-04-23 05:22:36 +02:00
fCheckpointsEnabled = true ;
2012-05-22 23:55:15 +02:00
}
2011-09-27 20:16:07 +02:00
BOOST_AUTO_TEST_SUITE_END ( )