mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Add fedpeg_program field in dynafed header
This commit is contained in:
parent
4ad2b8018d
commit
bd11097cec
14 changed files with 75 additions and 46 deletions
|
|
@ -243,7 +243,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Consensus {
|
namespace Consensus {
|
||||||
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks, const std::vector<CScript>& fedpegscripts)
|
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks, const std::vector<std::pair<CScript, CScript>>& fedpegscripts)
|
||||||
{
|
{
|
||||||
// are the actual inputs available?
|
// are the actual inputs available?
|
||||||
if (!inputs.HaveInputs(tx)) {
|
if (!inputs.HaveInputs(tx)) {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace Consensus {
|
||||||
* @param[out] fee_map Set to the transaction fee if successful.
|
* @param[out] fee_map Set to the transaction fee if successful.
|
||||||
* Preconditions: tx.IsCoinBase() is false.
|
* Preconditions: tx.IsCoinBase() is false.
|
||||||
*/
|
*/
|
||||||
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks, const std::vector<CScript>& fedpegscripts);
|
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks, const std::vector<std::pair<CScript, CScript>>& fedpegscripts);
|
||||||
} // namespace Consensus
|
} // namespace Consensus
|
||||||
|
|
||||||
/** Auxiliary functions for transaction validation (ideally should not be exposed) */
|
/** Auxiliary functions for transaction validation (ideally should not be exposed) */
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,10 @@ DynaFedParamEntry ComputeNextBlockFullCurrentParameters(const CBlockIndex* pinde
|
||||||
// We need to construct the "full" current parameters of pre-dynafed
|
// We need to construct the "full" current parameters of pre-dynafed
|
||||||
// consensus
|
// consensus
|
||||||
|
|
||||||
// Convert signblockscript to P2WSH
|
// Convert signblockscript to P2WSH and fedpeg_program to P2SH-P2WSH
|
||||||
CScript p2wsh_signblock_script = GetScriptForDestination(WitnessV0ScriptHash(p_epoch_start->proof.challenge));
|
CScript p2wsh_signblock_script = GetScriptForDestination(WitnessV0ScriptHash(p_epoch_start->proof.challenge));
|
||||||
winning_proposal = DynaFedParamEntry(p2wsh_signblock_script, consensus.max_block_signature_size+consensus.signblockscript.size(), consensus.fedpegScript, consensus.first_extension_space);
|
CScript sh_wsh_fedpeg_program = GetScriptForDestination(ScriptHash(GetScriptForDestination(WitnessV0ScriptHash(consensus.fedpegScript))));
|
||||||
|
winning_proposal = DynaFedParamEntry(p2wsh_signblock_script, consensus.max_block_signature_size+consensus.signblockscript.size(), sh_wsh_fedpeg_program, consensus.fedpegScript, consensus.first_extension_space);
|
||||||
} else {
|
} else {
|
||||||
winning_proposal = p_epoch_start->dynafed_params.m_current;
|
winning_proposal = p_epoch_start->dynafed_params.m_current;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ CScript calculate_contract(const CScript& federation_script, const CScript& scri
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool CheckPeginTx(const std::vector<unsigned char>& tx_data, T& pegtx, const COutPoint& prevout, const CAmount claim_amount, const CScript& claim_script, const std::vector<CScript>& fedpegscripts)
|
static bool CheckPeginTx(const std::vector<unsigned char>& tx_data, T& pegtx, const COutPoint& prevout, const CAmount claim_amount, const CScript& claim_script, const std::vector<std::pair<CScript, CScript>>& fedpegscripts)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
CDataStream pegtx_stream(tx_data, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream pegtx_stream(tx_data, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
|
@ -171,12 +171,15 @@ static bool CheckPeginTx(const std::vector<unsigned char>& tx_data, T& pegtx, co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the witness program matches the p2ch on the p2sh-p2wsh transaction output
|
// Check that the witness program matches the p2ch on the (p2sh-)p2wsh
|
||||||
// We support multiple scripts as a grace period for peg-in users
|
// transaction output. We support multiple scripts as a grace period for peg-in users
|
||||||
for (const auto& fedpegscript : fedpegscripts) {
|
for (const auto& scripts : fedpegscripts) {
|
||||||
CScript tweaked_fedpegscript = calculate_contract(fedpegscript, claim_script);
|
CScript tweaked_fedpegscript = calculate_contract(scripts.second, claim_script);
|
||||||
CScript witness_output(GetScriptForWitness(tweaked_fedpegscript));
|
// TODO: Remove script/standard.h dep for GetScriptFor*
|
||||||
CScript expected_script(CScript() << OP_HASH160 << ToByteVector(ScriptHash(CScriptID(witness_output))) << OP_EQUAL);
|
CScript expected_script(GetScriptForWitness(tweaked_fedpegscript));
|
||||||
|
if (scripts.first.IsPayToScriptHash()) {
|
||||||
|
expected_script = GetScriptForDestination(ScriptHash(expected_script));
|
||||||
|
}
|
||||||
if (pegtx->vout[prevout.n].scriptPubKey == expected_script) {
|
if (pegtx->vout[prevout.n].scriptPubKey == expected_script) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +231,7 @@ bool CheckParentProofOfWork(uint256 hash, unsigned int nBits, const Consensus::P
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const std::vector<CScript>& fedpegscripts, const COutPoint& prevout, std::string& err_msg, bool check_depth) {
|
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const std::vector<std::pair<CScript, CScript>>& fedpegscripts, const COutPoint& prevout, std::string& err_msg, bool check_depth) {
|
||||||
// 0) Return false if !consensus.has_parent_chain
|
// 0) Return false if !consensus.has_parent_chain
|
||||||
if (!Params().GetConsensus().has_parent_chain) {
|
if (!Params().GetConsensus().has_parent_chain) {
|
||||||
err_msg = "Parent chain is not enabled on this network.";
|
err_msg = "Parent chain is not enabled on this network.";
|
||||||
|
|
@ -447,11 +450,11 @@ bool MatchLiquidWatchman(const CScript& script)
|
||||||
return (it == script.end());
|
return (it == script.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CScript> GetValidFedpegScripts(const CBlockIndex* pblockindex, const Consensus::Params& params, bool nextblock_validation)
|
std::vector<std::pair<CScript, CScript>> GetValidFedpegScripts(const CBlockIndex* pblockindex, const Consensus::Params& params, bool nextblock_validation)
|
||||||
{
|
{
|
||||||
assert(pblockindex);
|
assert(pblockindex);
|
||||||
|
|
||||||
std::vector<CScript> fedpegscripts;
|
std::vector<std::pair<CScript, CScript>> fedpegscripts;
|
||||||
|
|
||||||
const int32_t epoch_length = params.dynamic_epoch_length;
|
const int32_t epoch_length = params.dynamic_epoch_length;
|
||||||
const int32_t epoch_age = pblockindex->nHeight % epoch_length;
|
const int32_t epoch_age = pblockindex->nHeight % epoch_length;
|
||||||
|
|
@ -460,7 +463,8 @@ std::vector<CScript> GetValidFedpegScripts(const CBlockIndex* pblockindex, const
|
||||||
// In mempool and general "enforced next block" RPC we need to look ahead one block
|
// In mempool and general "enforced next block" RPC we need to look ahead one block
|
||||||
// to see if we're on a boundary. If so, put that epoch's fedpegscript in place
|
// to see if we're on a boundary. If so, put that epoch's fedpegscript in place
|
||||||
if (nextblock_validation && epoch_age == epoch_length - 1) {
|
if (nextblock_validation && epoch_age == epoch_length - 1) {
|
||||||
fedpegscripts.push_back(ComputeNextBlockFullCurrentParameters(pblockindex, params).m_fedpegscript);
|
DynaFedParamEntry next_param = ComputeNextBlockFullCurrentParameters(pblockindex, params);
|
||||||
|
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
|
// Next we walk backwards up to two epoch start blocks
|
||||||
|
|
@ -469,17 +473,17 @@ std::vector<CScript> GetValidFedpegScripts(const CBlockIndex* pblockindex, const
|
||||||
|
|
||||||
if (p_current_epoch_start) {
|
if (p_current_epoch_start) {
|
||||||
if (!p_current_epoch_start->dynafed_params.IsNull()) {
|
if (!p_current_epoch_start->dynafed_params.IsNull()) {
|
||||||
fedpegscripts.push_back(p_current_epoch_start->dynafed_params.m_current.m_fedpegscript);
|
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));
|
||||||
} else {
|
} else {
|
||||||
fedpegscripts.push_back(params.fedpegScript);
|
fedpegscripts.push_back(std::make_pair(GetScriptForDestination(ScriptHash(GetScriptForDestination(WitnessV0ScriptHash(params.fedpegScript)))), params.fedpegScript));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_prev_epoch_start) {
|
if (p_prev_epoch_start) {
|
||||||
if (!p_prev_epoch_start->dynafed_params.IsNull()) {
|
if (!p_prev_epoch_start->dynafed_params.IsNull()) {
|
||||||
fedpegscripts.push_back(p_prev_epoch_start->dynafed_params.m_current.m_fedpegscript);
|
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 {
|
} else {
|
||||||
fedpegscripts.push_back(params.fedpegScript);
|
fedpegscripts.push_back(std::make_pair(GetScriptForDestination(ScriptHash(GetScriptForDestination(WitnessV0ScriptHash(params.fedpegScript)))), params.fedpegScript));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ bool GetAmountFromParentChainPegin(CAmount& amount, const CTransaction& txBTC, u
|
||||||
/** Check whether a parent chain block hash satisfies the proof-of-work requirement specified by nBits */
|
/** Check whether a parent chain block hash satisfies the proof-of-work requirement specified by nBits */
|
||||||
bool CheckParentProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
|
bool CheckParentProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
|
||||||
/** Checks pegin witness for validity */
|
/** Checks pegin witness for validity */
|
||||||
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const std::vector<CScript>& fedpegscripts, const COutPoint& prevout, std::string& err_msg, bool check_depth);
|
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const std::vector<std::pair<CScript, CScript>>& fedpegscripts, const COutPoint& prevout, std::string& err_msg, bool check_depth);
|
||||||
// Constructs unblinded output to be used in amount and scriptpubkey checks during pegin
|
// Constructs unblinded output to be used in amount and scriptpubkey checks during pegin
|
||||||
CTxOut GetPeginOutputFromWitness(const CScriptWitness& pegin_witness);
|
CTxOut GetPeginOutputFromWitness(const CScriptWitness& pegin_witness);
|
||||||
|
|
||||||
|
|
@ -34,7 +34,8 @@ bool MatchLiquidWatchman(const CScript& script);
|
||||||
|
|
||||||
/** Get full fedpegscripts from two previous epoch starts based on given index
|
/** Get full fedpegscripts from two previous epoch starts based on given index
|
||||||
* nextblock_validation is false when doing block validation, true for mempool
|
* nextblock_validation is false when doing block validation, true for mempool
|
||||||
* or "lookahead" purposes. Newest epochs first. */
|
* or "lookahead" purposes. Newest epochs first. The first returned element is the
|
||||||
std::vector<CScript> GetValidFedpegScripts(const CBlockIndex* pblockindex, const Consensus::Params& params, bool nextblock_validation);
|
* scriptPubKey for the script, the second is the witnessScript. */
|
||||||
|
std::vector<std::pair<CScript, CScript>> GetValidFedpegScripts(const CBlockIndex* pblockindex, const Consensus::Params& params, bool nextblock_validation);
|
||||||
|
|
||||||
#endif // BITCOIN_PEGINS_H
|
#endif // BITCOIN_PEGINS_H
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ uint256 DynaFedParamEntry::CalculateRoot() const
|
||||||
std::vector<uint256> leaves;
|
std::vector<uint256> leaves;
|
||||||
leaves.push_back(SerializeHash(m_signblockscript, SER_GETHASH, 0));
|
leaves.push_back(SerializeHash(m_signblockscript, SER_GETHASH, 0));
|
||||||
leaves.push_back(SerializeHash(m_signblock_witness_limit, SER_GETHASH, 0));
|
leaves.push_back(SerializeHash(m_signblock_witness_limit, SER_GETHASH, 0));
|
||||||
|
leaves.push_back(SerializeHash(m_fedpeg_program, SER_GETHASH, 0));
|
||||||
leaves.push_back(SerializeHash(m_fedpegscript, SER_GETHASH, 0));
|
leaves.push_back(SerializeHash(m_fedpegscript, SER_GETHASH, 0));
|
||||||
leaves.push_back(SerializeHash(m_extension_space, SER_GETHASH, 0));
|
leaves.push_back(SerializeHash(m_extension_space, SER_GETHASH, 0));
|
||||||
return ComputeFastMerkleRoot(leaves);
|
return ComputeFastMerkleRoot(leaves);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@ public:
|
||||||
unsigned char m_serialize_type; // Determines how it is serialized, defaults to null
|
unsigned char m_serialize_type; // Determines how it is serialized, defaults to null
|
||||||
CScript m_signblockscript;
|
CScript m_signblockscript;
|
||||||
uint32_t m_signblock_witness_limit; // Max block signature witness serialized size
|
uint32_t m_signblock_witness_limit; // Max block signature witness serialized size
|
||||||
CScript m_fedpegscript;
|
CScript m_fedpeg_program; // The "scriptPubKey" of the fedpegscript
|
||||||
|
CScript m_fedpegscript; // The witnessScript for witness v0 or undefined otherwise.
|
||||||
// No consensus meaning to the particular bytes, currently we interpret as PAK keys, details in pak.h
|
// No consensus meaning to the particular bytes, currently we interpret as PAK keys, details in pak.h
|
||||||
std::vector<std::vector<unsigned char>> m_extension_space;
|
std::vector<std::vector<unsigned char>> m_extension_space;
|
||||||
|
|
||||||
|
|
@ -69,7 +70,7 @@ public:
|
||||||
// arguments are given
|
// arguments are given
|
||||||
DynaFedParamEntry() { m_signblock_witness_limit = 0; m_serialize_type = 0; };
|
DynaFedParamEntry() { m_signblock_witness_limit = 0; m_serialize_type = 0; };
|
||||||
DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in) { m_serialize_type = 1; };
|
DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in) { m_serialize_type = 1; };
|
||||||
DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in, const CScript& fedpegscript_in, const std::vector<std::vector<unsigned char>> extension_space_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in), m_fedpegscript(fedpegscript_in), m_extension_space(extension_space_in) { m_serialize_type = 2; };
|
DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in, const CScript& fedpeg_program_in, const CScript& fedpegscript_in, const std::vector<std::vector<unsigned char>> extension_space_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in), m_fedpeg_program(fedpeg_program_in), m_fedpegscript(fedpegscript_in), m_extension_space(extension_space_in) { m_serialize_type = 2; };
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
|
@ -87,6 +88,7 @@ public:
|
||||||
case 2:
|
case 2:
|
||||||
READWRITE(m_signblockscript);
|
READWRITE(m_signblockscript);
|
||||||
READWRITE(m_signblock_witness_limit);
|
READWRITE(m_signblock_witness_limit);
|
||||||
|
READWRITE(m_fedpeg_program);
|
||||||
READWRITE(m_fedpegscript);
|
READWRITE(m_fedpegscript);
|
||||||
READWRITE(m_extension_space);
|
READWRITE(m_extension_space);
|
||||||
break;
|
break;
|
||||||
|
|
@ -102,6 +104,7 @@ public:
|
||||||
return m_serialize_type == 0 &&
|
return m_serialize_type == 0 &&
|
||||||
m_signblockscript.empty() &&
|
m_signblockscript.empty() &&
|
||||||
m_signblock_witness_limit == 0 &&
|
m_signblock_witness_limit == 0 &&
|
||||||
|
m_fedpeg_program.empty() &&
|
||||||
m_fedpegscript.empty() &&
|
m_fedpegscript.empty() &&
|
||||||
m_extension_space.empty();
|
m_extension_space.empty();
|
||||||
|
|
||||||
|
|
@ -110,9 +113,10 @@ public:
|
||||||
void SetNull()
|
void SetNull()
|
||||||
{
|
{
|
||||||
m_serialize_type = 0;
|
m_serialize_type = 0;
|
||||||
m_signblockscript = CScript();
|
m_signblockscript.clear();
|
||||||
m_signblock_witness_limit = 0;
|
m_signblock_witness_limit = 0;
|
||||||
m_fedpegscript = CScript();
|
m_fedpeg_program.clear();
|
||||||
|
m_fedpegscript.clear();
|
||||||
m_extension_space.clear();
|
m_extension_space.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,6 +125,7 @@ public:
|
||||||
return m_serialize_type == other.m_serialize_type &&
|
return m_serialize_type == other.m_serialize_type &&
|
||||||
m_signblockscript == other.m_signblockscript &&
|
m_signblockscript == other.m_signblockscript &&
|
||||||
m_signblock_witness_limit == other.m_signblock_witness_limit &&
|
m_signblock_witness_limit == other.m_signblock_witness_limit &&
|
||||||
|
m_fedpeg_program == other.m_fedpeg_program &&
|
||||||
m_fedpegscript == other.m_fedpegscript &&
|
m_fedpegscript == other.m_fedpegscript &&
|
||||||
m_extension_space == other.m_extension_space;
|
m_extension_space == other.m_extension_space;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2509,6 +2509,11 @@ UniValue getsidechaininfo(const JSONRPCRequest& request)
|
||||||
" \"xxxx\", (string) Hex-encoded active fedpegscript\n"
|
" \"xxxx\", (string) Hex-encoded active fedpegscript\n"
|
||||||
" ...\n"
|
" ...\n"
|
||||||
" ]\n"
|
" ]\n"
|
||||||
|
" \"current_fedpeg_programs\": (array) The currently-enforced fedpegscript scriptPubKeys in hex. Prior to a transition this may be P2SH scriptpubkey, otherwise it will be a native segwit script. Results are paired in-order with current_fedpegscripts.\n"
|
||||||
|
" [\n"
|
||||||
|
" \"xxxx\", (string) Hex-encoded active fedpegscriptscriptPubKeys\n"
|
||||||
|
" ...\n"
|
||||||
|
" ]\n"
|
||||||
" \"pegged_asset\" : \"xxxx\", (string) Pegged asset type in hex\n"
|
" \"pegged_asset\" : \"xxxx\", (string) Pegged asset type in hex\n"
|
||||||
" \"min_peg_diff\" : \"xxxx\", (string) The minimum difficulty parent chain header target. Peg-in headers that have less work will be rejected as an anti-Dos measure.\n"
|
" \"min_peg_diff\" : \"xxxx\", (string) The minimum difficulty parent chain header target. Peg-in headers that have less work will be rejected as an anti-Dos measure.\n"
|
||||||
" \"parent_blockhash\" : \"xxxx\", (string) The parent genesis blockhash as source of pegged-in funds.\n"
|
" \"parent_blockhash\" : \"xxxx\", (string) The parent genesis blockhash as source of pegged-in funds.\n"
|
||||||
|
|
@ -2534,11 +2539,14 @@ UniValue getsidechaininfo(const JSONRPCRequest& request)
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
obj.pushKV("fedpegscript", HexStr(consensus.fedpegScript.begin(), consensus.fedpegScript.end()));
|
obj.pushKV("fedpegscript", HexStr(consensus.fedpegScript.begin(), consensus.fedpegScript.end()));
|
||||||
// We use mempool_validation as true to show what is enforced for *next* block
|
// We use mempool_validation as true to show what is enforced for *next* block
|
||||||
std::vector<CScript> fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), consensus, true /* nextblock_validation */);
|
std::vector<std::pair<CScript, CScript>> fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), consensus, true /* nextblock_validation */);
|
||||||
|
UniValue fedpeg_prog_entries(UniValue::VARR);
|
||||||
UniValue fedpeg_entries(UniValue::VARR);
|
UniValue fedpeg_entries(UniValue::VARR);
|
||||||
for (const auto& script : fedpegscripts) {
|
for (const auto& scripts : fedpegscripts) {
|
||||||
fedpeg_entries.push_back(HexStr(script));
|
fedpeg_prog_entries.push_back(HexStr(scripts.first));
|
||||||
|
fedpeg_entries.push_back(HexStr(scripts.second));
|
||||||
}
|
}
|
||||||
|
obj.pushKV("current_fedpeg_programs", fedpeg_prog_entries);
|
||||||
obj.pushKV("current_fedpegscripts", fedpeg_entries);
|
obj.pushKV("current_fedpegscripts", fedpeg_entries);
|
||||||
obj.pushKV("pegged_asset", consensus.pegged_asset.GetHex());
|
obj.pushKV("pegged_asset", consensus.pegged_asset.GetHex());
|
||||||
obj.pushKV("min_peg_diff", consensus.parentChainPowLimit.GetHex());
|
obj.pushKV("min_peg_diff", consensus.parentChainPowLimit.GetHex());
|
||||||
|
|
|
||||||
|
|
@ -988,7 +988,7 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
|
||||||
// Script verification errors
|
// Script verification errors
|
||||||
UniValue vErrors(UniValue::VARR);
|
UniValue vErrors(UniValue::VARR);
|
||||||
|
|
||||||
const std::vector<CScript> fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
const auto& fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
||||||
|
|
||||||
// ELEMENTS:
|
// ELEMENTS:
|
||||||
// Track an immature peg-in that's otherwise valid, give warning
|
// Track an immature peg-in that's otherwise valid, give warning
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out, const CTxIn& txin, const CScriptWitness& pegin_witness, const std::vector<CScript>& fedpegscripts);
|
int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out, const CTxIn& txin, const CScriptWitness& pegin_witness, const std::vector<std::pair<CScript, CScript>>& fedpegscripts);
|
||||||
void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight);
|
void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight);
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
@ -410,7 +410,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
|
||||||
if (!tx.IsCoinBase()) {
|
if (!tx.IsCoinBase()) {
|
||||||
const COutPoint &out = tx.vin[0].prevout;
|
const COutPoint &out = tx.vin[0].prevout;
|
||||||
Coin coin = undo.vprevout[0];
|
Coin coin = undo.vprevout[0];
|
||||||
std::vector<CScript> fedpegscripts;
|
std::vector<std::pair<CScript, CScript>> fedpegscripts;
|
||||||
ApplyTxInUndo(std::move(coin), *(stack.back()), out, tx.vin[0], CScriptWitness(), fedpegscripts);
|
ApplyTxInUndo(std::move(coin), *(stack.back()), out, tx.vin[0], CScriptWitness(), fedpegscripts);
|
||||||
}
|
}
|
||||||
// Store as a candidate for reconnection
|
// Store as a candidate for reconnection
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,11 @@ BOOST_AUTO_TEST_CASE(witness_valid)
|
||||||
|
|
||||||
std::vector<unsigned char> fedpegscript_bytes = ParseHex(fedpegscript_str);
|
std::vector<unsigned char> fedpegscript_bytes = ParseHex(fedpegscript_str);
|
||||||
CScript fedpegscript(fedpegscript_bytes.begin(), fedpegscript_bytes.end());
|
CScript fedpegscript(fedpegscript_bytes.begin(), fedpegscript_bytes.end());
|
||||||
std::vector<CScript> fedpegscripts;
|
// Test sample was generated as "legacy" with p2sh-p2wsh fedpegscript
|
||||||
|
CScript fedpeg_program(GetScriptForDestination(ScriptHash(GetScriptForDestination(WitnessV0ScriptHash(fedpegscript)))));
|
||||||
|
std::vector<std::pair<CScript, CScript>> fedpegscripts;
|
||||||
// TODO test with additional scripts
|
// TODO test with additional scripts
|
||||||
fedpegscripts.push_back(fedpegscript);
|
fedpegscripts.push_back(std::make_pair(fedpeg_program, fedpegscript));
|
||||||
|
|
||||||
bool valid = IsValidPeginWitness(witness, fedpegscripts, prevout, err, false);
|
bool valid = IsValidPeginWitness(witness, fedpegscripts, prevout, err, false);
|
||||||
BOOST_CHECK(err == "");
|
BOOST_CHECK(err == "");
|
||||||
|
|
|
||||||
|
|
@ -591,7 +591,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CScript> fedpegscripts = GetValidFedpegScripts(p_block_index_new, chainparams.GetConsensus(), true /* nextblock_validation */);
|
const auto& fedpegscripts = GetValidFedpegScripts(p_block_index_new, chainparams.GetConsensus(), true /* nextblock_validation */);
|
||||||
for (size_t nIn = 0; nIn < tx.vin.size(); nIn++) {
|
for (size_t nIn = 0; nIn < tx.vin.size(); nIn++) {
|
||||||
const CTxIn& in = tx.vin[nIn];
|
const CTxIn& in = tx.vin[nIn];
|
||||||
std::string err;
|
std::string err;
|
||||||
|
|
@ -638,7 +638,7 @@ static void CheckInputsAndUpdateCoins(const CTxMemPoolEntry& entry, CCoinsViewCa
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
CAmountMap fee_map;
|
CAmountMap fee_map;
|
||||||
std::set<std::pair<uint256, COutPoint> > setPeginsSpent;
|
std::set<std::pair<uint256, COutPoint> > setPeginsSpent;
|
||||||
std::vector<CScript> fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
const auto& fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
||||||
bool fCheckResult = tx.IsCoinBase() || Consensus::CheckTxInputs(tx, state, mempoolDuplicate, spendheight, fee_map, setPeginsSpent, NULL, false, true, fedpegscripts);
|
bool fCheckResult = tx.IsCoinBase() || Consensus::CheckTxInputs(tx, state, mempoolDuplicate, spendheight, fee_map, setPeginsSpent, NULL, false, true, fedpegscripts);
|
||||||
assert(fCheckResult);
|
assert(fCheckResult);
|
||||||
UpdateCoins(tx, mempoolDuplicate, 1000000);
|
UpdateCoins(tx, mempoolDuplicate, 1000000);
|
||||||
|
|
|
||||||
|
|
@ -700,7 +700,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used when checking peg-ins
|
// Used when checking peg-ins
|
||||||
std::vector<CScript> fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), chainparams.GetConsensus(), true /* nextblock_validation */);
|
std::vector<std::pair<CScript, CScript>> fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), chainparams.GetConsensus(), true /* nextblock_validation */);
|
||||||
|
|
||||||
// do all inputs exist?
|
// do all inputs exist?
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||||
|
|
@ -1634,7 +1634,7 @@ static bool AbortNode(CValidationState& state, const std::string& strMessage, co
|
||||||
* @param out The out point that corresponds to the tx input.
|
* @param out The out point that corresponds to the tx input.
|
||||||
* @return A DisconnectResult as an int
|
* @return A DisconnectResult as an int
|
||||||
*/
|
*/
|
||||||
int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out, const CTxIn& txin, const CScriptWitness& pegin_witness, const std::vector<CScript>& fedpegscripts)
|
int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out, const CTxIn& txin, const CScriptWitness& pegin_witness, const std::vector<std::pair<CScript, CScript>>& fedpegscripts)
|
||||||
{
|
{
|
||||||
bool fClean = true;
|
bool fClean = true;
|
||||||
|
|
||||||
|
|
@ -1728,7 +1728,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore inputs
|
// restore inputs
|
||||||
const std::vector<CScript> fedpegscripts = GetValidFedpegScripts(pindex, Params().GetConsensus(), false /* nextblock_validation */);
|
const auto& fedpegscripts = GetValidFedpegScripts(pindex, Params().GetConsensus(), false /* nextblock_validation */);
|
||||||
if (i > 0) { // not coinbases
|
if (i > 0) { // not coinbases
|
||||||
CTxUndo &txundo = blockUndo.vtxundo[i-1];
|
CTxUndo &txundo = blockUndo.vtxundo[i-1];
|
||||||
if (txundo.vprevout.size() != tx.vin.size()) {
|
if (txundo.vprevout.size() != tx.vin.size()) {
|
||||||
|
|
@ -2145,7 +2145,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
std::set<std::pair<uint256, COutPoint>> setPeginsSpentDummy;
|
std::set<std::pair<uint256, COutPoint>> setPeginsSpentDummy;
|
||||||
|
|
||||||
// Used when checking peg-ins
|
// Used when checking peg-ins
|
||||||
std::vector<CScript> fedpegscripts = GetValidFedpegScripts(pindex, chainparams.GetConsensus(), false /* nextblock_validation */);
|
const auto& fedpegscripts = GetValidFedpegScripts(pindex, chainparams.GetConsensus(), false /* nextblock_validation */);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4857,8 +4857,12 @@ UniValue getpeginaddress(const JSONRPCRequest& request)
|
||||||
pwallet->AddCScript(dest_script);
|
pwallet->AddCScript(dest_script);
|
||||||
|
|
||||||
// Get P2CH deposit address on mainchain from most recent fedpegscript.
|
// Get P2CH deposit address on mainchain from most recent fedpegscript.
|
||||||
const std::vector<CScript>& fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
const auto& fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
||||||
CTxDestination mainchain_dest(ScriptHash(GetScriptForWitness(calculate_contract(fedpegscripts.front(), dest_script))));
|
CTxDestination mainchain_dest(WitnessV0ScriptHash(calculate_contract(fedpegscripts.front().second, dest_script)));
|
||||||
|
// P2SH-wrapped is the only valid choice for non-dynafed chains
|
||||||
|
if (!IsDynaFedEnabled(chainActive.Tip(), Params().GetConsensus())) {
|
||||||
|
mainchain_dest = ScriptHash(GetScriptForDestination(mainchain_dest));
|
||||||
|
}
|
||||||
|
|
||||||
UniValue ret(UniValue::VOBJ);
|
UniValue ret(UniValue::VOBJ);
|
||||||
|
|
||||||
|
|
@ -5386,10 +5390,13 @@ extern UniValue signrawtransaction(const JSONRPCRequest& request);
|
||||||
extern UniValue sendrawtransaction(const JSONRPCRequest& request);
|
extern UniValue sendrawtransaction(const JSONRPCRequest& request);
|
||||||
|
|
||||||
template<typename T_tx>
|
template<typename T_tx>
|
||||||
unsigned int GetPeginTxnOutputIndex(const T_tx& txn, const CScript& witnessProgram, const std::vector<CScript>& fedpegscripts)
|
unsigned int GetPeginTxnOutputIndex(const T_tx& txn, const CScript& witnessProgram, const std::vector<std::pair<CScript, CScript>>& fedpegscripts)
|
||||||
{
|
{
|
||||||
for (auto const& fedpegscript : fedpegscripts) {
|
for (const auto & scripts : fedpegscripts) {
|
||||||
CScript mainchain_script = GetScriptForDestination(ScriptHash(GetScriptForWitness(calculate_contract(fedpegscript, witnessProgram))));
|
CScript mainchain_script = GetScriptForWitness(calculate_contract(scripts.second, witnessProgram));
|
||||||
|
if (scripts.first.IsPayToScriptHash()) {
|
||||||
|
mainchain_script = GetScriptForDestination(ScriptHash(mainchain_script));
|
||||||
|
}
|
||||||
for (unsigned int nOut = 0; nOut < txn.vout.size(); nOut++)
|
for (unsigned int nOut = 0; nOut < txn.vout.size(); nOut++)
|
||||||
if (txn.vout[nOut].scriptPubKey == mainchain_script) {
|
if (txn.vout[nOut].scriptPubKey == mainchain_script) {
|
||||||
return nOut;
|
return nOut;
|
||||||
|
|
@ -5467,7 +5474,7 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
|
||||||
|
|
||||||
CScript witness_script;
|
CScript witness_script;
|
||||||
unsigned int nOut = txBTC.vout.size();
|
unsigned int nOut = txBTC.vout.size();
|
||||||
const std::vector<CScript> fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
const auto fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
||||||
if (request.params.size() > 2) {
|
if (request.params.size() > 2) {
|
||||||
const std::string claim_script = request.params[2].get_str();
|
const std::string claim_script = request.params[2].get_str();
|
||||||
if (!IsHex(claim_script)) {
|
if (!IsHex(claim_script)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue