Merge ElementsProject/elements#1062: Implement vbparams equivalent for elements

85c3c2b819 Deprecate con_dyna_deploy_start in favor of evbparams (Pablo Greco)
d15d08c605 Dynafed is already activated in liquidv1, remove start argument parsing (Pablo Greco)
a06aac152a Make dynafed signaling opt-out instead of opt-in (Pablo Greco)
19f54eb5e0 Make sure command line takes precedence when processing evbparams (Pablo Greco)
24cafa50cf Implement vbparams for Elements (evbparams) (Pablo Greco)

Pull request description:

  Fixes: https://github.com/ElementsProject/elements/issues/1061

ACKs for top commit:
  stevenroose:
    Looks good, utACK 85c3c2b

Tree-SHA512: 124a25d762e8c5053d388153374ac629779df5dc8af09308cb5f794c707c890fd379e81b72ecc9892e5a02e414bc6539082d95fb69dcb2512e7f91b3f8bcffdd
This commit is contained in:
Steven Roose 2021-11-26 12:27:30 +00:00
commit 586e5c7dd7
No known key found for this signature in database
GPG key ID: 2F2A88D7F8D68E87
13 changed files with 117 additions and 30 deletions

View file

@ -482,7 +482,7 @@ extra_args = [
"-con_max_block_sig_size=150",
# We also disable dynamic federations, since we are not going to do any
# dynafed transitions in this tutorial. FIXME we probably should.
"-con_dyna_deploy_start=0",
"-evbparams=dynafed:0:::",
]
print ("6b. Restart both nodes")

View file

@ -85,6 +85,96 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits
return CreateGenesisBlock(params, genesisScriptSig, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
/**
* Allows modifying the Version Bits Elements regtest parameters (and liquidv1test).
* Ideally, this would be a method in the base class, inherited everywhere, but that might complicate future merges,
* so we settle for this static function.
*/
static void UpdateElementsActivationParametersFromArgs(Consensus::Params& consensus, const ArgsManager& args)
{
if (!args.IsArgSet("-evbparams")) return;
std::map<std::string,int> map_deployments;
for (const std::string& strDeployment : args.GetArgs("-evbparams")) {
std::vector<std::string> vDeploymentParams;
boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
if (vDeploymentParams.size() != 5) {
throw std::runtime_error("ElementsVersion bits parameters malformed, expecting deployment:start:end:period:threshold");
}
int64_t nStartTime = 0, nTimeout = 0, nPeriod = 0, nThreshold = 0;
bool use_nStartTime = false, use_nTimeout = false, use_nPeriod = false, use_nThreshold = false;
if(vDeploymentParams[1].length()) {
if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
}
use_nStartTime = true;
}
if(vDeploymentParams[2].length()) {
if (!ParseInt64(vDeploymentParams[2], &nTimeout)) {
throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
}
use_nTimeout = true;
}
if(vDeploymentParams[3].length()) {
if (!ParseInt64(vDeploymentParams[3], &nPeriod)) {
throw std::runtime_error(strprintf("Invalid nPeriod (%s)", vDeploymentParams[3]));
}
use_nPeriod = true;
}
if(vDeploymentParams[4].length()) {
if (!ParseInt64(vDeploymentParams[4], &nThreshold)) {
throw std::runtime_error(strprintf("Invalid nThreshold (%s)", vDeploymentParams[4]));
}
use_nThreshold = true;
}
bool found = false;
for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
if(map_deployments[vDeploymentParams[0]]) {
found = true;
LogPrintf("Ignoring duplicated version bits activation parameters for \"%s\"\n", strDeployment.c_str());
break;
}
std::string extra_logging;
map_deployments[vDeploymentParams[0]]=1;
Consensus::DeploymentPos d=Consensus::DeploymentPos(j);
if (use_nStartTime) {
consensus.vDeployments[d].nStartTime = nStartTime;
} else {
nStartTime =consensus.vDeployments[d].nStartTime;
}
if (use_nTimeout) {
consensus.vDeployments[d].nTimeout = nTimeout;
} else {
nTimeout = consensus.vDeployments[d].nTimeout;
}
if (consensus.vDeployments[d].nPeriod) {
if(use_nPeriod) {
consensus.vDeployments[d].nPeriod = nPeriod;
} else {
nPeriod = *consensus.vDeployments[d].nPeriod;
}
extra_logging+= strprintf(", period=%ld", nPeriod);
}
if (consensus.vDeployments[d].nThreshold) {
if(use_nThreshold) {
consensus.vDeployments[d].nThreshold = nThreshold;
} else {
nThreshold = *consensus.vDeployments[d].nThreshold;
}
extra_logging+= strprintf(", threshold=%ld", nThreshold);
}
found = true;
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld%s\n", vDeploymentParams[0], nStartTime, nTimeout, extra_logging.c_str());
break;
}
}
if (!found) {
throw std::runtime_error(strprintf("Invalid deployment (%s)", vDeploymentParams[0]));
}
}
}
/**
* Main network
*/
@ -478,7 +568,7 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = 1230767999; // December 31, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = gArgs.GetArg("-con_taproot_signal_start", Consensus::BIP9Deployment::ALWAYS_ACTIVE);
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nPeriod = 128; // test ability to change from default
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nThreshold = 128;
@ -749,8 +839,10 @@ class CCustomParams : public CRegTestParams {
}
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25;
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = args.GetArg("-con_dyna_deploy_start", Consensus::BIP9Deployment::ALWAYS_ACTIVE);
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
UpdateElementsActivationParametersFromArgs(consensus, args);
// END ELEMENTS fields
}
@ -1011,7 +1103,7 @@ public:
// Activated from block 1,000,000.
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25;
// Allow blocksigners to delay activation.
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = gArgs.GetArg("-con_dyna_deploy_start", 1000000);
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = 1000000;
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
@ -1064,6 +1156,9 @@ public:
// For testing purposes, default to the same junk keys that CustomParams uses (this can be overridden.)
consensus.first_extension_space = {ParseHex("02fcba7ecf41bc7e1be4ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f02fcba7ecf41bc7e1be4ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f")};
// Don't use liquidv1's height to enable taproot
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 0;
// Use all regtest rather than mainchain magic numbers:
bech32_hrp = args.GetArg("-bech32_hrp", "ert");
blech32_hrp = args.GetArg("-blech32_hrp", "el");
@ -1101,9 +1196,6 @@ public:
// This is unlike the CCustomParams UpdateFromArgs method, which has lots of defaults in it.
void UpdateFromArgs(const ArgsManager& args)
{
// NOTE: We don't handle version bits, because I'm not sure we actually use them, and it would be messy to do so.
// UpdateVersionBitsParametersFromArgs(args);
consensus.nSubsidyHalvingInterval = args.GetArg("-con_nsubsidyhalvinginterval", consensus.nSubsidyHalvingInterval);
if (args.IsArgSet("-con_bip16exception")) {
consensus.BIP16Exception = uint256S(args.GetArg("-con_bip16exception", ""));
@ -1269,15 +1361,11 @@ public:
consensus.subsidy_asset = CAsset(uint256S(args.GetArg("-subsidyasset", "")));
}
if (args.IsArgSet("-con_dyna_deploy_start")) {
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25;
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = args.GetArg("-con_dyna_deploy_start", Consensus::BIP9Deployment::ALWAYS_ACTIVE);
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
}
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25;
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
if (args.IsArgSet("-con_taproot_signal_start")) {
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = gArgs.GetArg("-con_taproot_signal_start", 0);
}
UpdateElementsActivationParametersFromArgs(consensus, args);
// END ELEMENTS fields
}

View file

@ -56,11 +56,10 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
argsman.AddArg("-pak", "Sets the 'first extension space' field to the pak entries ala pre-dynamic federations. Only used for testing in custom chains.", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-multi_data_permitted", "Allow relay of multiple OP_RETURN outputs. (default: -enforce_pak)", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-con_csv_deploy_start", "Starting height for CSV deployment. (default: -1, which means ACTIVE from genesis)", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-con_dyna_deploy_start", "Starting height for Dynamic Federations deployment. Once active, signblockscript becomes a BIP141 WSH scriptPubKey of the original signblockscript. All other dynamic parameters stay constant.(default: -1, which means ACTIVE from genesis)", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-con_dyna_deploy_signal", "Whether to signal for the Dynamic Federations deployment (default: false).", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-con_dyna_deploy_signal", "Whether to signal for the Dynamic Federations deployment (default: true).", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-dynamic_epoch_length", "Per-chain parameter that sets how many blocks dynamic federation voting and enforcement are in effect for.", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-total_valid_epochs", "Per-chain parameter that sets how long a particular fedpegscript is in effect for.", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-con_taproot_signal_start", "Whether, and at what blockheight, to start signalling for Taproot activation (default: false) (regtest, Liquid testnet, or custom only).", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
argsman.AddArg("-evbparams=deployment:start:end:period:threshold", "Use given start/end times for specified version bits deployment (regtest or custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::ELEMENTS);
// END ELEMENTS
//
}

View file

@ -1982,7 +1982,7 @@ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Para
}
// Undo default signalling behavior for dynafed unless explicitly enabled.
if (!gArgs.GetBoolArg("-con_dyna_deploy_signal", false)) {
if (!gArgs.GetBoolArg("-con_dyna_deploy_signal", true)) {
auto dynafed = Consensus::DeploymentPos::DEPLOYMENT_DYNA_FED;
int bit = params.vDeployments[dynafed].bit;
if (bit > 0 && bit < VERSIONBITS_NUM_BITS) {

View file

@ -322,7 +322,7 @@ def initialize_datadir(dirname, n):
f.write("pubkeyprefix=111\n")
f.write("scriptprefix=196\n")
f.write("bech32_hrp=bcrt\n")
f.write("con_dyna_deploy_start="+str(2**31)+"\n") # Never starts
f.write("evbparams=dynafed:"+str(2**31)+":::\n") # Never starts
f.write("minrelaytxfee=0.00001\n")
os.makedirs(os.path.join(datadir, 'stderr'), exist_ok=True)
os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True)

View file

@ -82,7 +82,7 @@ class BlockSignTest(BitcoinTestFramework):
"-signblockscript={}".format(signblockscript),
"-con_max_block_sig_size={}".format(self.required_signers*74+self.num_nodes*33),
"-anyonecanspendaremine=1",
"-con_dyna_deploy_start=0",
"-evbparams=dynafed:0:::",
"-con_dyna_deploy_signal=1",
]] * self.num_nodes

View file

@ -67,7 +67,7 @@ class DynaFedTest(BitcoinTestFramework):
self.num_nodes = 2
# We want to test activation of dynafed
self.extra_args = [[
"-con_dyna_deploy_start=1000",
"-evbparams=dynafed:1000:::",
"-enforce_pak=1",
"-con_parent_chain_signblockscript=51",
"-peginconfirmationdepth=1",
@ -78,7 +78,7 @@ class DynaFedTest(BitcoinTestFramework):
# second node will not mine transactions
self.extra_args[1].append("-blocksonly=1")
# Make sure nothing breaks if peers have a different activation.
self.extra_args[1][0] = "-con_dyna_deploy_start=937"
self.extra_args[1][0] = "-evbparams=dynafed:937:::"
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()

View file

@ -98,7 +98,7 @@ class TaprootActivationTest(BitcoinTestFramework):
assert_equal(rpc.getblockheader(blocks[0])["versionHex"], "20000000")
def run_test(self):
# Test that regtest nodes without -con_taproot_signal_start never signal
# Test that regtest nodes never signal taproot by default
self.log.info("Testing node not configured to activate taproot")
blocks = self.nodes[0].generatetoaddress(2500, self.nodes[0].getnewaddress())
assert_equal(self.nodes[0].getblockcount(), 2500)
@ -113,7 +113,7 @@ class TaprootActivationTest(BitcoinTestFramework):
assert_equal (decode["versionHex"], "20000000")
# Test activation starting from height 1000
self.restart_node(0, ["-con_taproot_signal_start=500"])
self.restart_node(0, ["-evbparams=taproot:500:::"])
self.nodes[0].invalidateblock(self.nodes[0].getblockhash(1))
self.test_activation(self.nodes[0], 500)

View file

@ -140,7 +140,7 @@ class FedPegTest(BitcoinTestFramework):
# Immediate activation of dynafed when requested versus "never" from conf
if self.options.pre_transition or self.options.post_transition:
extra_args.extend(["-con_dyna_deploy_start=-1"])
extra_args.extend(["-evbparams=dynafed:-1:::"])
# Use rpcuser auth only for first parent.
if n==0:

View file

@ -18,7 +18,7 @@ class PAKTest (BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 3
self.setup_clean_chain = True
self.extra_args = [["-enforce_pak=1", "-con_dyna_deploy_start=-1", "-initialfreecoins=210000000000000", "-anyonecanspendaremine=1", "-parent_bech32_hrp=lol", "-pubkeyprefix=112", "-scriptprefix=197", "-con_connect_genesis_outputs=1"] for i in range(self.num_nodes)]
self.extra_args = [["-enforce_pak=1", "-evbparams=dynafed:-1:::", "-initialfreecoins=210000000000000", "-anyonecanspendaremine=1", "-parent_bech32_hrp=lol", "-pubkeyprefix=112", "-scriptprefix=197", "-con_connect_genesis_outputs=1"] for i in range(self.num_nodes)]
# First node doesn't enforce PAK, a "HF" of the other two nodes
self.extra_args[0] = ["-acceptnonstdtxn=1"] + self.extra_args[0][1:] ## FIXME -acceptnonstdtxn=1 should not be needed

View file

@ -51,7 +51,7 @@ class SighashRangeproofTest(BitcoinTestFramework):
self.num_nodes = 3
# We want to test activation of dynafed
self.extra_args = [[
"-con_dyna_deploy_start=1000",
"-evbparams=dynafed:1000:::",
"-con_dyna_deploy_signal=1",
"-blindedaddresses=1",
"-initialfreecoins=2100000000000000",

View file

@ -26,7 +26,7 @@ class TweakFedpegTest(BitcoinTestFramework):
[
"-fedpegscript="+LIQUID_SCRIPT,
"-con_dyna_deploy_signal=1",
"-con_dyna_deploy_start=0", # test dynafed derivation
"-evbparams=dynafed:0:::", # test dynafed derivation
]]
def setup_network(self):

View file

@ -381,7 +381,7 @@ def initialize_datadir(dirname, n, chain):
f.write("con_bip65height=1351\n")
f.write("con_bip66height=1251\n")
f.write("blindedaddresses=0\n") # Set to minimize broken tests in favor of custom
f.write("con_dyna_deploy_start="+str(2**31)+"\n") # Never starts unless overridden
f.write("evbparams=dynafed:"+str(2**31)+":::\n") # Never starts unless overridden
f.write("minrelaytxfee=0.00001\n")
#f.write("pubkeyprefix=111\n")
#f.write("scriptprefix=196\n")