diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 22f8a7e551..72e84eaa00 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -134,6 +134,7 @@ public: g_signed_blocks = false; g_con_elementsmode = false; g_con_blockheightinheader = false; + consensus.total_valid_epochs = 0; /** * The message start string is designed to be unlikely to occur in normal data. @@ -263,6 +264,7 @@ public: g_signed_blocks = false; g_con_elementsmode = false; g_con_blockheightinheader = false; + consensus.total_valid_epochs = 0; pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; @@ -366,6 +368,7 @@ public: g_signed_blocks = false; g_con_elementsmode = false; g_con_blockheightinheader = false; + consensus.total_valid_epochs = 0; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; @@ -582,6 +585,8 @@ class CCustomParams : public CRegTestParams { uint256 entropy; GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash); + consensus.total_valid_epochs = args.GetArg("-total_valid_epochs", 2); + // Elements serialization uses derivation, bitcoin serialization uses 0x00 if (g_con_elementsmode) { CalculateAsset(consensus.pegged_asset, entropy); diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index b7c45c63fe..ac4efc9b33 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -48,6 +48,7 @@ void SetupChainParamsBaseOptions() gArgs.AddArg("-con_csv_deploy_start", "Starting height for CSV deployment. (default: -1, which means ACTIVE from genesis)", false, OptionsCategory::ELEMENTS); gArgs.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)", false, OptionsCategory::ELEMENTS); gArgs.AddArg("-dynamic_epoch_length", "Per-chain parameter that sets how many blocks dynamic federation voting and enforcement are in effect for.", false, OptionsCategory::ELEMENTS); + gArgs.AddArg("-total_valid_epochs", "Per-chain parameter that sets how long a particular fedpegscript is in effect for.", false, OptionsCategory::ELEMENTS); // END ELEMENTS // } diff --git a/src/consensus/params.h b/src/consensus/params.h index d2546c1b01..b5be5eae12 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -105,6 +105,8 @@ struct Params { uint32_t dynamic_epoch_length = std::numeric_limits::max(); // Used to seed the extension space for first dynamic blocks std::vector> first_extension_space; + // Used to allow M-epoch-old peg-in addresses as deposits + size_t total_valid_epochs; }; } // namespace Consensus diff --git a/src/pegins.cpp b/src/pegins.cpp index 5fc1dd5932..c013a970dc 100644 --- a/src/pegins.cpp +++ b/src/pegins.cpp @@ -476,27 +476,23 @@ std::vector> GetValidFedpegScripts(const CBlockIndex fedpegscripts.push_back(std::make_pair(next_param.m_fedpeg_program, next_param.m_fedpegscript)); } - // Next we walk backwards up to two epoch start blocks - const CBlockIndex* p_current_epoch_start = pblockindex->GetAncestor(epoch_start_height); - const CBlockIndex* p_prev_epoch_start = pblockindex->GetAncestor(epoch_start_height-epoch_length); + // Next we walk backwards up to M epoch starts + for (size_t i = 0; i < params.total_valid_epochs; i++) { - if (p_current_epoch_start) { - if (!p_current_epoch_start->dynafed_params.IsNull()) { - fedpegscripts.push_back(std::make_pair(p_current_epoch_start->dynafed_params.m_current.m_fedpeg_program, p_current_epoch_start->dynafed_params.m_current.m_fedpegscript)); + const CBlockIndex* p_epoch_start = pblockindex->GetAncestor(epoch_start_height-i*epoch_length); + + // We're done here, for whatever reason. + if (!p_epoch_start) { + break; + } + + if (!p_epoch_start->dynafed_params.IsNull()) { + fedpegscripts.push_back(std::make_pair(p_epoch_start->dynafed_params.m_current.m_fedpeg_program, p_epoch_start->dynafed_params.m_current.m_fedpegscript)); } else { fedpegscripts.push_back(std::make_pair(GetScriptForDestination(ScriptHash(GetScriptForDestination(WitnessV0ScriptHash(params.fedpegScript)))), params.fedpegScript)); } } - - if (p_prev_epoch_start) { - if (!p_prev_epoch_start->dynafed_params.IsNull()) { - fedpegscripts.push_back(std::make_pair(p_prev_epoch_start->dynafed_params.m_current.m_fedpeg_program, p_prev_epoch_start->dynafed_params.m_current.m_fedpegscript)); - } else { - fedpegscripts.push_back(std::make_pair(GetScriptForDestination(ScriptHash(GetScriptForDestination(WitnessV0ScriptHash(params.fedpegScript)))), params.fedpegScript)); - } - } - // Only return up to the latest two of three possible fedpegscripts, which are enforced - fedpegscripts.resize(std::min((int)fedpegscripts.size(), 2)); + fedpegscripts.resize(std::min(fedpegscripts.size(), params.total_valid_epochs)); return fedpegscripts; } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 00fb218820..e93579dfc0 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1384,6 +1384,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) " \"current_signblock_hex\" : \"xxxx\", (string) Hex of sign block challenge data enforced on the next block.\n" " \"max_block_witness\" : xx, (numeric) maximum sized block witness serialized size for the next block.\n" " \"epoch_length\" : xx, (numeric) Length of dynamic federations epoch, or signaling period\n" + " \"total_valid_epochs\" : xx, (numeric) Number of epochs a given fedpscript is valid for, defined per chain.\n" " \"epoch_age\" : xx, (numeric) number of blocks into a dynamic federation epoch chain tip is. This number is between 0 to epoch_length-1\n" " \"extension_space\" : [\"xxxx\", ...], (array) Array of extension fields in dynamic blockheader\n" " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored (only present if pruning is enabled)\n" @@ -1468,6 +1469,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) } obj.pushKV("extension_space", arr); obj.pushKV("epoch_length", (uint64_t)chainparams.GetConsensus().dynamic_epoch_length); + obj.pushKV("total_valid_epochs", (uint64_t)chainparams.GetConsensus().total_valid_epochs); obj.pushKV("epoch_age", (uint64_t)(chainActive.Tip()->nHeight % chainparams.GetConsensus().dynamic_epoch_length)); } }