2017-11-09 19:34:51 +01:00
/*
* This file is part of the Flowee project
* Copyright (C) 2011-2015 The Bitcoin Core developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2013-04-13 00:13:08 -05:00
2015-07-05 14:17:46 +02:00
# include "chainparams.h"
2015-11-03 17:14:09 +00:00
# include "consensus/consensus.h"
2020-04-01 22:51:47 +02:00
# include <merkle.h>
2015-01-24 15:57:12 +01:00
# include "consensus/validation.h"
2012-05-22 21:55:15 +00:00
# include "main.h"
2013-04-13 00:13:08 -05:00
# include "miner.h"
2023-11-24 18:01:36 +01:00
# include "primitives/PublicKey.h"
2015-07-05 14:17:46 +02:00
# include "script/standard.h"
# include "txmempool.h"
2011-10-11 19:50:06 -04:00
# include "uint256.h"
2012-04-17 20:37:47 +02:00
# include "util.h"
2026-05-14 13:13:40 +02:00
# include "utiltime.h"
2015-07-05 14:17:46 +02:00
# include "utilstrencodings.h"
2021-11-02 10:23:33 +01:00
# include <primitives/Block.h>
2018-07-23 18:05:43 +02:00
# include <utxo/UnspentOutputDatabase.h>
2018-01-15 15:26:12 +00:00
# include "BlocksDB_p.h" // to access the blockMap directly and use erase
2011-09-27 20:16:07 +02:00
2015-03-03 07:49:12 -08:00
# include "test/test_bitcoin.h"
2013-04-13 00:13:08 -05:00
# include <boost/test/unit_test.hpp>
2018-12-30 15:33:11 +01:00
# include <boost/foreach.hpp>
2013-04-13 00:13:08 -05:00
2018-01-15 15:26:12 +00:00
BOOST_FIXTURE_TEST_SUITE ( miner_tests , MainnetTestingSetup )
2011-09-27 20:16:07 +02:00
2018-01-15 15:26:12 +00:00
CBlockIndex CreateBlockIndex ( CBlockIndex * parent , int offset )
2015-12-07 15:44:16 -05:00
{
CBlockIndex index ;
2018-01-15 15:26:12 +00:00
index . nHeight = parent - > nHeight + offset ;
index . pprev = parent ;
2015-12-07 15:44:16 -05:00
return index ;
}
2018-01-15 15:26:12 +00:00
bool TestSequenceLocks ( CTxMemPool & mempool , const CTransaction & tx , int flags )
2015-12-07 15:44:16 -05:00
{
LOCK ( mempool . cs ) ;
2018-01-15 15:26:12 +00:00
return CheckSequenceLocks ( mempool , tx , flags ) ;
2015-12-07 15:44:16 -05:00
}
2012-05-22 21:55:15 +00:00
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
BOOST_AUTO_TEST_CASE ( CreateNewBlock_validity )
{
2013-12-09 09:22:15 +01:00
CScript scriptPubKey = CScript ( ) < < ParseHex ( " 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f " ) < < OP_CHECKSIG ;
2012-12-19 15:21:21 -05:00
CBlockTemplate * pblocktemplate ;
2012-05-22 21:55:15 +00:00
CScript script ;
uint256 hash ;
2015-11-14 17:04:15 -05:00
TestMemPoolEntryHelper entry ;
entry . nFee = 11 ;
entry . dPriority = 111.0 ;
entry . nHeight = 11 ;
2012-05-22 21:55:15 +00:00
2015-04-22 23:22:36 -04:00
fCheckpointsEnabled = false ;
2013-12-02 13:11:21 +10:00
2018-01-15 15:26:12 +00:00
BOOST_CHECK_EQUAL ( bv . blockchain ( ) - > Height ( ) , 0 ) ;
2012-05-22 21:55:15 +00:00
// Simple block creation, nothing special yet:
2016-05-05 14:36:07 +01:00
Mining miner ;
miner . SetCoinbase ( scriptPubKey ) ;
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
BOOST_CHECK_EQUAL ( bv . blockchain ( ) - > Height ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 1 ) ;
2018-07-23 18:05:43 +02:00
delete pblocktemplate ;
2012-05-22 21:55:15 +00:00
// We can't make transactions until we have inputs
2020-04-12 23:48:32 +02:00
// Therefore, load 110 blocks :)
2018-01-15 15:26:12 +00:00
int baseheight = bv . blockchain ( ) - > Height ( ) ;
auto chain = bv . appendChain ( 110 , MockBlockValidation : : EmptyOutScript ) ;
2012-05-22 21:55:15 +00:00
std : : vector < CTransaction * > txFirst ;
2018-01-15 15:26:12 +00:00
for ( int i = 0 ; i < 4 ; + + i ) {
2021-11-02 09:36:09 +01:00
MutableBlock block = chain [ i ] . createOldBlock ( ) ;
2018-01-15 15:26:12 +00:00
txFirst . push_back ( new CTransaction ( block . vtx [ 0 ] ) ) ;
2012-05-22 21:55:15 +00:00
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK_EQUAL ( bv . blockchain ( ) - > Height ( ) , 110 ) ;
2012-05-22 21:55:15 +00:00
// Just to make sure we can still make simple blocks
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2013-09-19 00:01:36 +02:00
delete pblocktemplate ;
2012-05-22 21:55:15 +00:00
// block sigops > limit: 1000 CHECKMULTISIG + 1
2020-04-12 23:48:32 +02:00
CMutableTransaction tx ;
2012-05-22 21:55:15 +00:00
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 ) ;
tx . vout [ 0 ] . nValue = 5000000000LL ;
2018-01-15 15:26:12 +00:00
for ( unsigned int i = 0 ; i < 1 ; + + i ) {
2015-11-03 10:35:39 -05:00
tx . vout [ 0 ] . nValue - = 1000000 ;
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
const bool spendsCoinbase = i = = 0 ; // only first tx spends coinbase
2015-11-03 10:35:39 -05:00
// If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes
2020-04-12 23:48:32 +02:00
bv . mp . addUnchecked ( hash , entry . Fee ( 1000000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( spendsCoinbase ) . FromTx ( tx ) ) ;
2012-05-22 21:55:15 +00:00
tx . vin [ 0 ] . prevout . hash = hash ;
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2016-03-01 12:45:43 -05:00
BOOST_CHECK ( pblocktemplate - > block . vtx . size ( ) > 1 ) ;
2012-12-19 15:21:21 -05:00
delete pblocktemplate ;
2018-01-15 15:26:12 +00:00
bv . mp . clear ( ) ;
2012-05-22 21:55:15 +00:00
// 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 ( ) ;
tx . vout [ 0 ] . nValue = 5000000000LL ;
for ( unsigned int i = 0 ; i < 128 ; + + i )
{
tx . vout [ 0 ] . nValue - = 10000000 ;
hash = tx . GetHash ( ) ;
2015-10-29 14:06:13 -04:00
bool spendsCoinbase = ( i = = 0 ) ? true : false ; // only first tx spends coinbase
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 1000000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( spendsCoinbase ) . FromTx ( tx ) ) ;
2012-05-22 21:55:15 +00:00
tx . vin [ 0 ] . prevout . hash = hash ;
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2012-12-19 15:21:21 -05:00
delete pblocktemplate ;
2018-01-15 15:26:12 +00:00
bv . mp . clear ( ) ;
2012-05-22 21:55:15 +00:00
2016-03-01 12:45:43 -05:00
// orphan in mempool not mined
2012-05-22 21:55:15 +00:00
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 1000000 ) . Time ( GetTime ( ) ) . FromTx ( tx ) ) ;
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2016-03-01 12:45:43 -05:00
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 1 ) ;
delete pblocktemplate ;
2018-01-15 15:26:12 +00:00
bv . mp . clear ( ) ;
2012-05-22 21:55:15 +00:00
// child with higher priority than parent
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_1 ;
tx . vin [ 0 ] . prevout . hash = txFirst [ 1 ] - > GetHash ( ) ;
tx . vout [ 0 ] . nValue = 4900000000LL ;
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 100000000LL ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2012-05-22 21:55:15 +00: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 ;
tx . vout [ 0 ] . nValue = 5900000000LL ;
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 400000000LL ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2012-12-19 15:21:21 -05:00
delete pblocktemplate ;
2018-01-15 15:26:12 +00:00
bv . mp . clear ( ) ;
2012-05-22 21:55:15 +00:00
2015-11-03 10:35:39 -05:00
// coinbase in mempool, template creation fails
2012-05-22 21:55:15 +00: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 10:35:39 -05:00
// give it a fee so it'll get mined
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 100000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( false ) . FromTx ( tx ) ) ;
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2016-03-01 12:45:43 -05:00
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 1 ) ;
delete pblocktemplate ;
2018-01-15 15:26:12 +00:00
bv . mp . clear ( ) ;
2012-05-22 21:55:15 +00:00
2016-03-01 12:45:43 -05:00
// invalid (pre-p2sh) txn in mempool, don't mine
2012-05-22 21:55:15 +00:00
tx . vin [ 0 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ;
tx . vin [ 0 ] . prevout . n = 0 ;
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_1 ;
tx . vout [ 0 ] . nValue = 4900000000LL ;
script = CScript ( ) < < OP_0 ;
2014-09-24 22:24:46 -04:00
tx . vout [ 0 ] . scriptPubKey = GetScriptForDestination ( CScriptID ( script ) ) ;
2012-05-22 21:55:15 +00:00
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 10000000L ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2012-05-22 21:55:15 +00: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 ( ) ) ;
2012-05-22 21:55:15 +00:00
tx . vout [ 0 ] . nValue - = 1000000 ;
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 1000000 ) . Time ( GetTime ( ) ) . SpendsCoinbase ( false ) . FromTx ( tx ) ) ;
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2016-03-01 12:45:43 -05:00
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 1 ) ; // Just coinbase
2018-07-23 18:05:43 +02:00
delete pblocktemplate ;
2018-01-15 15:26:12 +00:00
bv . mp . clear ( ) ;
2012-05-22 21:55:15 +00:00
2016-03-01 12:45:43 -05:00
// double spend txn pair in mempool, don't mine
2012-05-22 21:55:15 +00:00
tx . vin [ 0 ] . prevout . hash = txFirst [ 0 ] - > GetHash ( ) ;
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_1 ;
tx . vout [ 0 ] . nValue = 4900000000LL ;
tx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_1 ;
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 100000000L ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2012-05-22 21:55:15 +00:00
tx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_2 ;
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 100000000L ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2016-03-01 12:45:43 -05:00
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 1 ) ; // Just coinbase
delete pblocktemplate ;
2018-01-15 15:26:12 +00:00
bv . mp . clear ( ) ;
2012-05-22 21:55:15 +00:00
// subsidy changing
2018-01-15 15:26:12 +00:00
int nHeight = bv . blockchain ( ) - > Height ( ) ;
2016-02-15 05:13:27 +01:00
// Create an actual 209999-long block chain (without valid blocks).
2018-01-15 15:26:12 +00:00
while ( bv . blockchain ( ) - > Tip ( ) - > nHeight < 209999 ) {
CBlockIndex * prev = bv . blockchain ( ) - > Tip ( ) ;
2016-02-15 05:13:27 +01:00
CBlockIndex * next = new CBlockIndex ( ) ;
2018-01-15 15:26:12 +00:00
2016-02-15 05:13:27 +01:00
next - > pprev = prev ;
next - > nHeight = prev - > nHeight + 1 ;
2018-01-15 15:26:12 +00:00
next - > phashBlock = Blocks : : Index : : insert ( GetRandHash ( ) , next ) ;
next - > RaiseValidity ( BLOCK_VALID_TRANSACTIONS ) ;
2016-02-15 05:13:27 +01:00
next - > BuildSkip ( ) ;
2018-01-15 15:26:12 +00:00
bv . blockchain ( ) - > SetTip ( next ) ;
2018-07-23 18:05:43 +02:00
g_utxo - > blockFinished ( next - > nHeight , next - > GetBlockHash ( ) ) ;
2018-01-15 15:26:12 +00:00
Blocks : : DB : : instance ( ) - > appendHeader ( next ) ;
2016-02-15 05:13:27 +01:00
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2012-12-19 15:21:21 -05:00
delete pblocktemplate ;
2016-02-15 05:13:27 +01:00
// Extend to a 210000-long block chain.
2018-01-15 15:26:12 +00:00
while ( bv . blockchain ( ) - > Tip ( ) - > nHeight < 210000 ) {
CBlockIndex * prev = bv . blockchain ( ) - > Tip ( ) ;
2016-02-15 05:13:27 +01:00
CBlockIndex * next = new CBlockIndex ( ) ;
2018-01-15 15:26:12 +00:00
2016-02-15 05:13:27 +01:00
next - > pprev = prev ;
next - > nHeight = prev - > nHeight + 1 ;
2018-01-15 15:26:12 +00:00
next - > phashBlock = Blocks : : Index : : insert ( GetRandHash ( ) , next ) ;
next - > RaiseValidity ( BLOCK_VALID_TRANSACTIONS ) ;
2016-02-15 05:13:27 +01:00
next - > BuildSkip ( ) ;
2018-01-15 15:26:12 +00:00
bv . blockchain ( ) - > SetTip ( next ) ;
2018-07-23 18:05:43 +02:00
g_utxo - > blockFinished ( next - > nHeight , next - > GetBlockHash ( ) ) ;
2018-01-15 15:26:12 +00:00
Blocks : : DB : : instance ( ) - > appendHeader ( next ) ;
2016-02-15 05:13:27 +01:00
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2012-12-19 15:21:21 -05:00
delete pblocktemplate ;
2016-02-15 05:13:27 +01:00
// Delete the dummy blocks again.
2018-01-15 15:26:12 +00:00
while ( bv . blockchain ( ) - > Tip ( ) - > nHeight > nHeight ) {
CBlockIndex * del = bv . blockchain ( ) - > Tip ( ) ;
del - > nStatus | = BLOCK_FAILED_VALID ;
Blocks : : DB : : instance ( ) - > appendHeader ( del ) ;
bv . blockchain ( ) - > SetTip ( del - > pprev ) ;
2018-07-23 18:05:43 +02:00
g_utxo - > blockFinished ( del - > pprev - > nHeight , del - > pprev - > GetBlockHash ( ) ) ;
2018-01-15 15:26:12 +00:00
Blocks : : DB : : instance ( ) - > priv ( ) - > indexMap . erase ( del - > GetBlockHash ( ) ) ;
2016-02-15 05:13:27 +01:00
delete del ;
}
2013-09-19 00:01:36 +02:00
2014-01-26 21:50:15 -05:00
// non-final txs in mempool
2018-01-15 15:26:12 +00:00
SetMockTime ( bv . blockchain ( ) - > Tip ( ) - > GetMedianTimePast ( ) + 1 ) ;
2015-12-07 15:44:16 -05:00
int flags = LOCKTIME_VERIFY_SEQUENCE | LOCKTIME_MEDIAN_TIME_PAST ;
// height map
std : : vector < int > prevheights ;
2014-01-26 21:50:15 -05:00
2015-12-07 15:44:16 -05: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-26 21:50:15 -05:00
tx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_1 ;
2018-01-15 15:26:12 +00:00
tx . vin [ 0 ] . nSequence = bv . blockchain ( ) - > Tip ( ) - > nHeight + 1 ; // txFirst[0] is the 2nd block
2015-12-07 15:44:16 -05:00
prevheights [ 0 ] = baseheight + 1 ;
tx . vout . resize ( 1 ) ;
2014-01-26 21:50:15 -05:00
tx . vout [ 0 ] . nValue = 4900000000LL ;
tx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_1 ;
2015-12-07 15:44:16 -05:00
tx . nLockTime = 0 ;
2014-01-26 21:50:15 -05:00
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Fee ( 100000000L ) . Time ( GetTime ( ) ) . SpendsCoinbase ( true ) . FromTx ( tx ) ) ;
2026-04-15 21:35:08 +02:00
Tx newTx = Tx : : fromOldTransaction ( tx ) ;
BOOST_CHECK ( CheckFinalTx ( newTx , flags ) ) ; // Locktime passes
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( ! TestSequenceLocks ( bv . mp , tx , flags ) ) ; // Sequence locks fail
BOOST_CHECK ( SequenceLocks ( tx , flags , & prevheights , CreateBlockIndex ( bv . blockchain ( ) - > Tip ( ) , 2 ) ) ) ; // Sequence locks pass on 2nd block
2014-01-26 21:50:15 -05:00
2015-12-07 15:44:16 -05:00
// relative time locked
tx . vin [ 0 ] . prevout . hash = txFirst [ 1 ] - > GetHash ( ) ;
2018-01-15 15:26:12 +00:00
tx . vin [ 0 ] . nSequence = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG | ( ( ( bv . blockchain ( ) - > Tip ( ) - > GetMedianTimePast ( ) + 1 - ( * bv . blockchain ( ) ) [ 1 ] - > GetMedianTimePast ( ) ) > > CTxIn : : SEQUENCE_LOCKTIME_GRANULARITY ) + 1 ) ; // txFirst[1] is the 3rd block
2015-12-07 15:44:16 -05:00
prevheights [ 0 ] = baseheight + 2 ;
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Time ( GetTime ( ) ) . FromTx ( tx ) ) ;
2026-04-15 21:35:08 +02:00
newTx = Tx : : fromOldTransaction ( tx ) ;
BOOST_CHECK ( CheckFinalTx ( newTx , flags ) ) ; // Locktime passes
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( ! TestSequenceLocks ( bv . mp , tx , flags ) ) ; // Sequence locks fail
2015-12-07 15:44:16 -05:00
for ( int i = 0 ; i < CBlockIndex : : nMedianTimeSpan ; i + + )
2018-01-15 15:26:12 +00:00
bv . blockchain ( ) - > Tip ( ) - > GetAncestor ( bv . blockchain ( ) - > Tip ( ) - > nHeight - i ) - > nTime + = 512 ; //Trick the MedianTimePast
BOOST_CHECK ( SequenceLocks ( tx , flags , & prevheights , CreateBlockIndex ( bv . blockchain ( ) - > Tip ( ) , 1 ) ) ) ; // Sequence locks pass 512 seconds later
2015-12-07 15:44:16 -05:00
for ( int i = 0 ; i < CBlockIndex : : nMedianTimeSpan ; i + + )
2018-01-15 15:26:12 +00:00
bv . blockchain ( ) - > Tip ( ) - > GetAncestor ( bv . blockchain ( ) - > Tip ( ) - > nHeight - i ) - > nTime - = 512 ; //undo tricked MTP
2015-12-07 15:44:16 -05:00
// absolute height locked
tx . vin [ 0 ] . prevout . hash = txFirst [ 2 ] - > GetHash ( ) ;
tx . vin [ 0 ] . nSequence = CTxIn : : SEQUENCE_FINAL - 1 ;
prevheights [ 0 ] = baseheight + 3 ;
2018-01-15 15:26:12 +00:00
tx . nLockTime = bv . blockchain ( ) - > Tip ( ) - > nHeight + 1 ;
2015-12-07 15:44:16 -05:00
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Time ( GetTime ( ) ) . FromTx ( tx ) ) ;
2026-04-15 21:35:08 +02:00
newTx = Tx : : fromOldTransaction ( tx ) ;
BOOST_CHECK ( ! CheckFinalTx ( newTx , flags ) ) ; // Locktime fails
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( TestSequenceLocks ( bv . mp , tx , flags ) ) ; // Sequence locks pass
2026-04-15 21:35:08 +02:00
BOOST_CHECK ( IsFinalTx ( newTx , bv . blockchain ( ) - > Tip ( ) - > nHeight + 2 , bv . blockchain ( ) - > Tip ( ) - > GetMedianTimePast ( ) ) ) ; // Locktime passes on 2nd block
2015-12-07 15:44:16 -05:00
// absolute time locked
tx . vin [ 0 ] . prevout . hash = txFirst [ 3 ] - > GetHash ( ) ;
2018-01-15 15:26:12 +00:00
tx . nLockTime = bv . blockchain ( ) - > Tip ( ) - > GetMedianTimePast ( ) ;
2015-12-07 15:44:16 -05:00
prevheights . resize ( 1 ) ;
prevheights [ 0 ] = baseheight + 4 ;
hash = tx . GetHash ( ) ;
2018-01-15 15:26:12 +00:00
bv . mp . addUnchecked ( hash , entry . Time ( GetTime ( ) ) . FromTx ( tx ) ) ;
2026-04-15 21:35:08 +02:00
newTx = Tx : : fromOldTransaction ( tx ) ;
BOOST_CHECK ( ! CheckFinalTx ( newTx , flags ) ) ; // Locktime fails
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( TestSequenceLocks ( bv . mp , tx , flags ) ) ; // Sequence locks pass
2026-04-15 21:35:08 +02:00
BOOST_CHECK ( IsFinalTx ( newTx , bv . blockchain ( ) - > Tip ( ) - > nHeight + 2 , bv . blockchain ( ) - > Tip ( ) - > GetMedianTimePast ( ) + 1 ) ) ; // Locktime passes 1 second later
2015-12-07 15:44:16 -05:00
// mempool-dependent transactions (not added)
tx . vin [ 0 ] . prevout . hash = hash ;
2018-01-15 15:26:12 +00:00
prevheights [ 0 ] = bv . blockchain ( ) - > Tip ( ) - > nHeight + 1 ;
2015-12-07 15:44:16 -05:00
tx . nLockTime = 0 ;
tx . vin [ 0 ] . nSequence = 0 ;
2026-04-15 21:35:08 +02:00
newTx = Tx : : fromOldTransaction ( tx ) ;
BOOST_CHECK ( CheckFinalTx ( newTx , flags ) ) ; // Locktime passes
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( TestSequenceLocks ( bv . mp , tx , flags ) ) ; // Sequence locks pass
2015-12-07 15:44:16 -05:00
tx . vin [ 0 ] . nSequence = 1 ;
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( ! TestSequenceLocks ( bv . mp , tx , flags ) ) ; // Sequence locks fail
2015-12-07 15:44:16 -05:00
tx . vin [ 0 ] . nSequence = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG ;
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( TestSequenceLocks ( bv . mp , tx , flags ) ) ; // Sequence locks pass
2015-12-07 15:44:16 -05:00
tx . vin [ 0 ] . nSequence = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG | 1 ;
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( ! TestSequenceLocks ( bv . mp , tx , flags ) ) ; // Sequence locks fail
2014-01-26 21:50:15 -05:00
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2014-01-26 21:50:15 -05:00
2015-12-07 15:44:16 -05: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
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 3 ) ;
2014-01-26 21:50:15 -05:00
delete pblocktemplate ;
2015-12-07 15:44:16 -05:00
// However if we advance height by 1 and time by 512, all of them should be mined
2018-01-15 15:26:12 +00:00
bv . appendChain ( 1 ) ;
2015-12-07 15:44:16 -05:00
for ( int i = 0 ; i < CBlockIndex : : nMedianTimeSpan ; i + + )
2018-01-15 15:26:12 +00:00
bv . blockchain ( ) - > Tip ( ) - > GetAncestor ( bv . blockchain ( ) - > Tip ( ) - > nHeight - i ) - > nTime + = 512 ; //Trick the MedianTimePast
SetMockTime ( bv . blockchain ( ) - > Tip ( ) - > GetMedianTimePast ( ) + 1 ) ;
2014-01-26 21:50:15 -05:00
2018-01-15 15:26:12 +00:00
BOOST_CHECK ( pblocktemplate = miner . CreateNewBlock ( bv ) ) ;
2015-12-07 15:44:16 -05:00
BOOST_CHECK_EQUAL ( pblocktemplate - > block . vtx . size ( ) , 5 ) ;
2014-01-26 21:50:15 -05:00
delete pblocktemplate ;
2018-01-15 15:26:12 +00:00
bv . blockchain ( ) - > Tip ( ) - > nHeight - - ;
2014-01-26 21:50:15 -05:00
SetMockTime ( 0 ) ;
2018-01-15 15:26:12 +00:00
bv . mp . clear ( ) ;
2014-01-26 21:50:15 -05:00
2013-09-19 00:01:36 +02:00
BOOST_FOREACH ( CTransaction * tx , txFirst )
delete tx ;
2014-01-26 21:50:15 -05:00
2015-04-22 23:22:36 -04:00
fCheckpointsEnabled = true ;
2012-05-22 21:55:15 +00:00
}
2011-09-27 20:16:07 +02:00
BOOST_AUTO_TEST_SUITE_END ( )