@ -67,27 +67,99 @@ TEST(CheckBlock, BlockSproutRejectsBadVersion) {
}
TEST ( ContextualCheckBlock , BadCoinbaseHeight ) {
SelectParams ( CBaseChainParams : : MAIN ) ;
class ContextualCheckBlockTest : public : : testing : : Test {
protected :
virtual void SetUp ( ) {
SelectParams ( CBaseChainParams : : MAIN ) ;
}
virtual void TearDown ( ) {
// Revert to test default. No-op on mainnet params.
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_SAPLING , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
}
// Returns a valid but empty mutable transaction at block height 1.
CMutableTransaction GetFirstBlockTransaction ( ) {
CMutableTransaction mtx ;
// No inputs.
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
// Set height to 1.
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
// Give it a single zero-valued, always-valid output.
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
// Give it a Founder's Reward vout for height 1.
mtx . vout . push_back ( CTxOut (
GetBlockSubsidy ( 1 , Params ( ) . GetConsensus ( ) ) / 5 ,
Params ( ) . GetFoundersRewardScriptAtHeight ( 1 ) ) ) ;
return mtx ;
}
// Expects a height-1 block containing a given transaction to pass
// ContextualCheckBlock. This is used in accepting (Sprout-Sprout,
// Overwinter-Overwinter, ...) tests. You should not call it without
// calling a SCOPED_TRACE macro first to usefully label any failures.
void ExpectValidBlockFromTx ( const CTransaction & tx ) {
// Create a block and add the transaction to it.
CBlock block ;
block . vtx . push_back ( tx ) ;
// Set the previous block index to the genesis block.
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
// We now expect this to be a valid block.
MockCValidationState state ;
EXPECT_TRUE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
}
// Expects a height-1 block containing a given transaction to fail
// ContextualCheckBlock. This is used in rejecting (Sprout-Overwinter,
// Overwinter-Sprout, ...) tests. You should not call it without
// calling a SCOPED_TRACE macro first to usefully label any failures.
void ExpectInvalidBlockFromTx ( const CTransaction & tx , int level , std : : string reason ) {
// Create a block and add the transaction to it.
CBlock block ;
block . vtx . push_back ( tx ) ;
// Set the previous block index to the genesis block.
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
// We now expect this to be an invalid block, for the given reason.
MockCValidationState state ;
EXPECT_CALL ( state , DoS ( level , false , REJECT_INVALID , reason , false ) ) . Times ( 1 ) ;
EXPECT_FALSE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
}
} ;
TEST_F ( ContextualCheckBlockTest , BadCoinbaseHeight ) {
// Put a zero-height transaction in a block
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 0 < < OP_0 ;
mtx . vout . pop_back ( ) ; // remove the FR output
// Create a block with no height in scriptSig
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
block . vtx . push_back ( mtx ) ;
// Treating block as genesis should pass
MockCValidationState state ;
EXPECT_TRUE ( ContextualCheckBlock ( block , state , NULL ) ) ;
// Give the transaction a Founder's Reward vout
mtx . vout . push_back ( CTxOut (
GetBlockSubsidy ( 1 , Params ( ) . GetConsensus ( ) ) / 5 ,
Params ( ) . GetFoundersRewardScriptAtHeight ( 1 ) ) ) ;
// Treating block as non-genesis should fail
mtx . vout . push_back ( CTxOut ( GetBlockSubsidy ( 1 , Params ( ) . GetConsensus ( ) ) / 5 , Params ( ) . GetFoundersRewardScriptAtHeight ( 1 ) ) ) ;
CTransaction tx2 { mtx } ;
block . vtx [ 0 ] = tx2 ;
CBlock prev ;
@ -110,292 +182,156 @@ TEST(ContextualCheckBlock, BadCoinbaseHeight) {
EXPECT_TRUE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
}
// TEST PLAN: first, check that each ruleset accepts its own transaction type.
// Currently (May 2018) this means we'll test Sprout-Sprout,
// Overwinter-Overwinter, and Sapling-Sapling.
// Test that a block evaluated under Sprout rules cannot contain Sapling transactions.
// Test block evaluated under Sprout rules will accept Sprout transactions.
// This test assumes that mainnet Overwinter activation is at least height 2.
TEST ( ContextualCheckBlock , BlockSproutRulesRejectSapling Tx ) {
SelectParams ( CBaseChainParams : : MAIN ) ;
TEST_F ( ContextualCheckBlockTest , BlockSproutRulesAcceptSprout Tx ) {
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
mtx . fOverwintered = true ;
mtx . nVersion = SAPLING_TX_VERSION ;
mtx . nVersionGroupId = SAPLING_VERSION_GROUP_ID ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
// Make it a Sprout transaction w/o JoinSplits
mtx . fOverwintered = false ;
mtx . nVersion = 1 ;
EXPECT_CALL ( state , DoS ( 0 , false , REJECT_INVALID , " tx-overwinter-not-active " , false ) ) . Times ( 1 ) ;
EXPECT_FALSE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
SCOPED_TRACE ( " BlockSproutRulesAcceptSproutTx " ) ;
ExpectValidBlockFromTx ( CTransaction ( mtx ) ) ;
}
// Test that a block evaluated under Sprout rules cannot contain Overwinter transactions.
// This test assumes that mainnet Overwinter activation is at least height 2.
TEST ( ContextualCheckBlock , BlockSproutRulesRejectOverwinterTx ) {
SelectParams ( CBaseChainParams : : MAIN ) ;
// Test block evaluated under Overwinter rules will accept Overwinter transactions.
TEST_F ( ContextualCheckBlockTest , BlockOverwinterRulesAcceptOverwinterTx ) {
SelectParams ( CBaseChainParams : : REGTEST ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , 1 ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
// Make it an Overwinter transaction
mtx . fOverwintered = true ;
mtx . nVersion = OVERWINTER_TX_VERSION ;
mtx . nVersionGroupId = OVERWINTER_VERSION_GROUP_ID ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
EXPECT_CALL ( state , DoS ( 0 , false , REJECT_INVALID , " tx-overwinter-not-active " , false ) ) . Times ( 1 ) ;
EXPECT_FALSE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
SCOPED_TRACE ( " BlockOverwinterRulesAcceptOverwinterTx " ) ;
ExpectValidBlockFromTx ( CTransaction ( mtx ) ) ;
}
// Test block evaluated under Sprout rules will accept Sprout transactions
TEST ( ContextualCheckBlock , BlockSproutRulesAcceptSproutTx ) {
SelectParams ( CBaseChainParams : : REGTEST ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
mtx . vout . push_back ( CTxOut (
GetBlockSubsidy ( 1 , Params ( ) . GetConsensus ( ) ) / 5 ,
Params ( ) . GetFoundersRewardScriptAtHeight ( 1 ) ) ) ;
mtx . fOverwintered = false ;
mtx . nVersion = 1 ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
EXPECT_TRUE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
// Revert to default
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
}
// Test that a block evaluated under Overwinter rules cannot contain Sapling transactions.
TEST ( ContextualCheckBlock , BlockOverwinterRulesRejectSaplingTx ) {
// Test that a block evaluated under Sapling rules can contain Sapling transactions.
TEST_F ( ContextualCheckBlockTest , BlockSaplingRulesAcceptSaplingTx ) {
SelectParams ( CBaseChainParams : : REGTEST ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , 1 ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_SAPLING , 1 ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
mtx . vout . push_back ( CTxOut (
GetBlockSubsidy ( 1 , Params ( ) . GetConsensus ( ) ) / 5 ,
Params ( ) . GetFoundersRewardScriptAtHeight ( 1 ) ) ) ;
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
// Make it a Sapling transaction
mtx . fOverwintered = true ;
mtx . nVersion = SAPLING_TX_VERSION ;
mtx . nVersionGroupId = SAPLING_VERSION_GROUP_ID ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
EXPECT_CALL ( state , DoS ( 100 , false , REJECT_INVALID , " bad-overwinter-tx-version-group-id " , false ) ) . Times ( 1 ) ;
EXPECT_FALSE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
// Revert to default
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
SCOPED_TRACE ( " BlockSaplingRulesAcceptSaplingTx " ) ;
ExpectValidBlockFromTx ( CTransaction ( mtx ) ) ;
}
// TEST PLAN: next, check that each ruleset will not accept other transaction types.
// Currently (May 2018) this means we'll test Sprout-Overwinter,
// Sprout-Sapling, Overwinter-Sprout, Overwinter-Sapling, Sapling-Sprout, and
// Sapling-Overwinter.
// Test block evaluated under Overwinter rules will accept Overwinter transactions
TEST ( ContextualCheckBlock , BlockOverwinterRulesAcceptOverwinterTx ) {
SelectParams ( CBaseChainParams : : REGTEST ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , 1 ) ;
// Test that a block evaluated under Sprout rules cannot contain Overwinter
// transactions. This test assumes that mainnet Overwinter activation is at
// least height 2.
TEST_F ( ContextualCheckBlockTest , BlockSproutRulesRejectOverwinterTx ) {
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
mtx . vout . push_back ( CTxOut (
GetBlockSubsidy ( 1 , Params ( ) . GetConsensus ( ) ) / 5 ,
Params ( ) . GetFoundersRewardScriptAtHeight ( 1 ) ) ) ;
// Make it an Overwinter transaction
mtx . fOverwintered = true ;
mtx . nVersion = OVERWINTER_TX_VERSION ;
mtx . nVersionGroupId = OVERWINTER_VERSION_GROUP_ID ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
SCOPED_TRACE ( " BlockSproutRulesRejectOverwinterTx " ) ;
ExpectInvalidBlockFromTx ( CTransaction ( mtx ) , 0 , " tx-overwinter-not-active " ) ;
} ;
EXPECT_TRUE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
// Revert to default
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
// Test that a block evaluated under Sprout rules cannot contain Sapling
// transactions. This test assumes that mainnet Overwinter activation is at
// least height 2.
TEST_F ( ContextualCheckBlockTest , BlockSproutRulesRejectSaplingTx ) {
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
// Make it a Sapling transaction
mtx . fOverwintered = true ;
mtx . nVersion = SAPLING_TX_VERSION ;
mtx . nVersionGroupId = SAPLING_VERSION_GROUP_ID ;
SCOPED_TRACE ( " BlockSproutRulesRejectSaplingTx " ) ;
ExpectInvalidBlockFromTx ( CTransaction ( mtx ) , 0 , " tx-overwinter-not-active " ) ;
}
// Test block evaluated under Overwinter rules will reject Sprout transactions
TEST ( ContextualCheckBlock , BlockOverwinterRulesRejectSproutTx ) {
TEST_F ( ContextualCheckBlockTest , BlockOverwinterRulesRejectSproutTx ) {
SelectParams ( CBaseChainParams : : REGTEST ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , 1 ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
// Set the version to Sprout+JoinSplit (but nJoinSplit will be 0).
mtx . nVersion = 2 ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
EXPECT_CALL ( state , DoS ( 100 , false , REJECT_INVALID , " tx-overwinter-active " , false ) ) . Times ( 1 ) ;
EXPECT_FALSE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
// Revert to default
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
SCOPED_TRACE ( " BlockOverwinterRulesRejectSproutTx " ) ;
ExpectInvalidBlockFromTx ( CTransaction ( mtx ) , 100 , " tx-overwinter-active " ) ;
}
// Test that a block evaluated under Sapling rules can contain Sapling transactions.
TEST ( ContextualCheckBlock , BlockSaplingRulesAccep tSaplingTx ) {
// Test that a block evaluated under Overwinter rules cannot contain Sapling transactions.
TEST_F ( ContextualCheckBlockTest , BlockOverwinterRulesRejectSaplingTx ) {
SelectParams ( CBaseChainParams : : REGTEST ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , 1 ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_SAPLING , 1 ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
mtx . vout . push_back ( CTxOut (
GetBlockSubsidy ( 1 , Params ( ) . GetConsensus ( ) ) / 5 ,
Params ( ) . GetFoundersRewardScriptAtHeight ( 1 ) ) ) ;
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
// Make it a Sapling transaction
mtx . fOverwintered = true ;
mtx . nVersion = SAPLING_TX_VERSION ;
mtx . nVersionGroupId = SAPLING_VERSION_GROUP_ID ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
EXPECT_TRUE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
// Revert to default
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_SAPLING , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
SCOPED_TRACE ( " BlockOverwinterRulesRejectSaplingTx " ) ;
ExpectInvalidBlockFromTx ( CTransaction ( mtx ) , 100 , " bad-overwinter-tx-version-group-id " ) ;
}
// Test block evaluated under Sapling rules cannot contain Overwinter transactions
TEST ( ContextualCheckBlock , BlockSaplingRulesRejectOverwinter Tx ) {
// Test block evaluated under Sapling rules cannot contain Sprout transactions
TEST_F ( ContextualCheckBlockTest , BlockSaplingRulesRejectSproutTx ) {
SelectParams ( CBaseChainParams : : REGTEST ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , 1 ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_SAPLING , 1 ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
mtx . vout . push_back ( CTxOut (
GetBlockSubsidy ( 1 , Params ( ) . GetConsensus ( ) ) / 5 ,
Params ( ) . GetFoundersRewardScriptAtHeight ( 1 ) ) ) ;
mtx . fOverwintered = true ;
mtx . nVersion = OVERWINTER_TX_VERSION ;
mtx . nVersionGroupId = OVERWINTER_VERSION_GROUP_ID ;
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
EXPECT_CALL ( state , DoS ( 100 , false , REJECT_INVALID , " bad-sapling-tx-version-group-id " , false ) ) . Times ( 1 ) ;
EXPECT_FALSE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
// Set the version to Sprout+JoinSplit (but nJoinSplit will be 0).
mtx . nVersion = 2 ;
// Revert to default
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_SAPLING , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
SCOPED_TRACE ( " BlockSaplingRulesRejectSproutTx " ) ;
ExpectInvalidBlockFromTx ( CTransaction ( mtx ) , 100 , " tx-overwinter-active " ) ;
}
// Test block evaluated under Sapling rules cannot contain Sprout transactions
TEST ( ContextualCheckBlock , BlockSaplingRulesRejectSproutTx ) {
// Test block evaluated under Sapling rules cannot contain Overwinter transactions
TEST_F ( ContextualCheckBlockTest , BlockSaplingRulesRejectOverwinterTx ) {
SelectParams ( CBaseChainParams : : REGTEST ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , 1 ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_SAPLING , 1 ) ;
CMutableTransaction mtx ;
mtx . vin . resize ( 1 ) ;
mtx . vin [ 0 ] . prevout . SetNull ( ) ;
mtx . vin [ 0 ] . scriptSig = CScript ( ) < < 1 < < OP_0 ;
mtx . vout . resize ( 1 ) ;
mtx . vout [ 0 ] . scriptPubKey = CScript ( ) < < OP_TRUE ;
mtx . vout [ 0 ] . nValue = 0 ;
mtx . nVersion = 2 ;
CMutableTransaction mtx = GetFirstBlockTransaction ( ) ;
CTransaction tx { mtx } ;
CBlock block ;
block . vtx . push_back ( tx ) ;
MockCValidationState state ;
CBlockIndex indexPrev { Params ( ) . GenesisBlock ( ) } ;
EXPECT_CALL ( state , DoS ( 100 , false , REJECT_INVALID , " tx-overwinter-active " , false ) ) . Times ( 1 ) ;
EXPECT_FALSE ( ContextualCheckBlock ( block , state , & indexPrev ) ) ;
// Make it an Overwinter transaction
mtx . fOverwintered = true ;
mtx . nVersion = OVERWINTER_TX_VERSION ;
mtx . nVersionGroupId = OVERWINTER_VERSION_GROUP_ID ;
// Revert to default
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_OVERWINTER , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
UpdateNetworkUpgradeParameters ( Consensus : : UPGRADE_SAPLING , Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) ;
SCOPED_TRACE ( " BlockSaplingRulesRejectOverwinterTx " ) ;
ExpectInvalidBlockFromTx ( CTransaction ( mtx ) , 100 , " bad-sapling-tx-version-group-id " ) ;
}