Refactor ContextualCheckBlock tests (#3187)
Initial cleanup. Reduces duplication of code, especially around constructing transactions, resetting the activation heights, and setting up the EXPECT calls for accepting and rejecting tests. Also adds a bunch of comments explaining the test plan and what particular parts of the test are doing.
This commit is contained in:
parent
ad97158836
commit
ec7466b62f
|
@ -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, BlockSproutRulesRejectSaplingTx) {
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
TEST_F(ContextualCheckBlockTest, BlockSproutRulesAcceptSproutTx) {
|
||||
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()};
|
||||
|
||||
EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "tx-overwinter-not-active", false)).Times(1);
|
||||
EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev));
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
|
||||
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 = 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));
|
||||
}
|
||||
|
||||
|
||||
// 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)));
|
||||
// Make it a Sprout transaction w/o JoinSplits
|
||||
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);
|
||||
SCOPED_TRACE("BlockSproutRulesAcceptSproutTx");
|
||||
ExpectValidBlockFromTx(CTransaction(mtx));
|
||||
}
|
||||
|
||||
|
||||
// Test that a block evaluated under Overwinter rules cannot contain Sapling transactions.
|
||||
TEST(ContextualCheckBlock, BlockOverwinterRulesRejectSaplingTx) {
|
||||
// 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;
|
||||
mtx.vout.push_back(CTxOut(
|
||||
GetBlockSubsidy(1, Params().GetConsensus())/5,
|
||||
Params().GetFoundersRewardScriptAtHeight(1)));
|
||||
CMutableTransaction mtx = GetFirstBlockTransaction();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// Test block evaluated under Overwinter rules will accept Overwinter transactions
|
||||
TEST(ContextualCheckBlock, 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;
|
||||
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()};
|
||||
|
||||
EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev));
|
||||
|
||||
// Revert to default
|
||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
|
||||
}
|
||||
|
||||
|
||||
// Test block evaluated under Overwinter rules will reject Sprout transactions
|
||||
TEST(ContextualCheckBlock, 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;
|
||||
|
||||
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("BlockOverwinterRulesAcceptOverwinterTx");
|
||||
ExpectValidBlockFromTx(CTransaction(mtx));
|
||||
}
|
||||
|
||||
|
||||
// Test that a block evaluated under Sapling rules can contain Sapling transactions.
|
||||
TEST(ContextualCheckBlock, BlockSaplingRulesAcceptSaplingTx) {
|
||||
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_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("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 Sapling rules cannot contain Overwinter transactions
|
||||
TEST(ContextualCheckBlock, BlockSaplingRulesRejectOverwinterTx) {
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, 1);
|
||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, 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_CALL(state, DoS(100, false, REJECT_INVALID, "bad-sapling-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);
|
||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, 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_F(ContextualCheckBlockTest, BlockOverwinterRulesRejectSproutTx) {
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, 1);
|
||||
|
||||
CMutableTransaction mtx = GetFirstBlockTransaction();
|
||||
|
||||
// Set the version to Sprout+JoinSplit (but nJoinSplit will be 0).
|
||||
mtx.nVersion = 2;
|
||||
|
||||
SCOPED_TRACE("BlockOverwinterRulesRejectSproutTx");
|
||||
ExpectInvalidBlockFromTx(CTransaction(mtx), 100, "tx-overwinter-active");
|
||||
}
|
||||
|
||||
|
||||
// Test that a block evaluated under Overwinter rules cannot contain Sapling transactions.
|
||||
TEST_F(ContextualCheckBlockTest, BlockOverwinterRulesRejectSaplingTx) {
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, 1);
|
||||
|
||||
CMutableTransaction mtx = GetFirstBlockTransaction();
|
||||
|
||||
// Make it a Sapling transaction
|
||||
mtx.fOverwintered = true;
|
||||
mtx.nVersion = SAPLING_TX_VERSION;
|
||||
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
|
||||
|
||||
SCOPED_TRACE("BlockOverwinterRulesRejectSaplingTx");
|
||||
ExpectInvalidBlockFromTx(CTransaction(mtx), 100, "bad-overwinter-tx-version-group-id");
|
||||
}
|
||||
|
||||
|
||||
// Test block evaluated under Sapling rules cannot contain Sprout transactions
|
||||
TEST(ContextualCheckBlock, BlockSaplingRulesRejectSproutTx) {
|
||||
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;
|
||||
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);
|
||||
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 Overwinter transactions
|
||||
TEST_F(ContextualCheckBlockTest, BlockSaplingRulesRejectOverwinterTx) {
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, 1);
|
||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, 1);
|
||||
|
||||
CMutableTransaction mtx = GetFirstBlockTransaction();
|
||||
|
||||
// Make it an Overwinter transaction
|
||||
mtx.fOverwintered = true;
|
||||
mtx.nVersion = OVERWINTER_TX_VERSION;
|
||||
mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
|
||||
|
||||
SCOPED_TRACE("BlockSaplingRulesRejectOverwinterTx");
|
||||
ExpectInvalidBlockFromTx(CTransaction(mtx), 100, "bad-sapling-tx-version-group-id");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue