98 lines
3.0 KiB
C++
98 lines
3.0 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include "chainparams.h"
|
|
#include "consensus/params.h"
|
|
#include "util/test.h"
|
|
|
|
#include <optional>
|
|
|
|
enum TestFeature : uint32_t {
|
|
TF_1,
|
|
TF_2,
|
|
TF_3,
|
|
TF_4,
|
|
TF_MAX
|
|
};
|
|
|
|
struct TestParams {
|
|
std::set<TestFeature> vRequiredFeatures;
|
|
|
|
bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const {
|
|
switch (idx) {
|
|
case Consensus::BASE_SPROUT:
|
|
return nHeight >= 0;
|
|
case Consensus::UPGRADE_OVERWINTER:
|
|
return nHeight >= 5;
|
|
case Consensus::UPGRADE_SAPLING:
|
|
return nHeight >= 10;
|
|
case Consensus::UPGRADE_BLOSSOM:
|
|
return nHeight >= 15;
|
|
case Consensus::UPGRADE_HEARTWOOD:
|
|
return nHeight >= 20;
|
|
case Consensus::UPGRADE_CANOPY:
|
|
return nHeight >= 25;
|
|
case Consensus::UPGRADE_ZFUTURE:
|
|
return nHeight >= 30;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool FeatureRequired(const TestFeature feature) const {
|
|
return vRequiredFeatures.count(feature) > 0;
|
|
}
|
|
};
|
|
|
|
TEST(FeatureFlagging, FeatureDependencies) {
|
|
TestParams params;
|
|
|
|
Consensus::FeatureSet<TestFeature, TestParams> features({
|
|
{
|
|
.dependsOn = {},
|
|
.activation = Consensus::BASE_SPROUT
|
|
},
|
|
{
|
|
.dependsOn = {TF_1},
|
|
.activation = Consensus::UPGRADE_OVERWINTER
|
|
},
|
|
{
|
|
.dependsOn = {},
|
|
.activation = Consensus::UPGRADE_BLOSSOM
|
|
},
|
|
{
|
|
.dependsOn = {TF_2, TF_3},
|
|
.activation = Consensus::UPGRADE_HEARTWOOD
|
|
}
|
|
});
|
|
|
|
EXPECT_TRUE(features.FeatureActive(params, 1, TF_1));
|
|
EXPECT_FALSE(features.FeatureActive(params, 1, TF_2));
|
|
EXPECT_FALSE(features.FeatureActive(params, 1, TF_3));
|
|
EXPECT_FALSE(features.FeatureActive(params, 1, TF_4));
|
|
|
|
EXPECT_TRUE(features.FeatureActive(params, 5, TF_1));
|
|
EXPECT_TRUE(features.FeatureActive(params, 5, TF_2));
|
|
EXPECT_FALSE(features.FeatureActive(params, 5, TF_3));
|
|
EXPECT_FALSE(features.FeatureActive(params, 5, TF_4));
|
|
|
|
EXPECT_TRUE(features.FeatureActive(params, 15, TF_1));
|
|
EXPECT_TRUE(features.FeatureActive(params, 15, TF_2));
|
|
EXPECT_TRUE(features.FeatureActive(params, 15, TF_3));
|
|
EXPECT_FALSE(features.FeatureActive(params, 15, TF_4));
|
|
|
|
EXPECT_TRUE(features.FeatureActive(params, 20, TF_1));
|
|
EXPECT_TRUE(features.FeatureActive(params, 20, TF_2));
|
|
EXPECT_TRUE(features.FeatureActive(params, 20, TF_3));
|
|
EXPECT_TRUE(features.FeatureActive(params, 20, TF_4));
|
|
|
|
// Force TF_4 to be active
|
|
params.vRequiredFeatures.insert(TF_4);
|
|
|
|
// Ensure that a feature cannot be forced to be active if
|
|
// all of its dependencies are not active
|
|
EXPECT_DEATH(features.FeatureActive(params, 5, TF_4), "");
|
|
// A feature can be activated before its activation height
|
|
// if all of its dependencies are active
|
|
EXPECT_TRUE(features.FeatureActive(params, 15, TF_4));
|
|
}
|