mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-13 12:33:42 +02:00
Refactor peg-in witness construction to it's own function
Also changes to Use CVectorWriter instead of casting for peg-in value serialization
This commit is contained in:
parent
5af17a42bc
commit
a90d1521c8
3 changed files with 50 additions and 26 deletions
|
|
@ -496,3 +496,45 @@ std::vector<std::pair<CScript, CScript>> GetValidFedpegScripts(const CBlockIndex
|
|||
fedpegscripts.resize(std::min(fedpegscripts.size(), params.total_valid_epochs));
|
||||
return fedpegscripts;
|
||||
}
|
||||
|
||||
template<typename T_tx_ref, typename T_merkle_block>
|
||||
CScriptWitness CreatePeginWitnessInner(const CAmount& value, const CAsset& asset, const uint256& genesis_hash, const CScript& claim_script, const T_tx_ref& tx_ref, const T_merkle_block& merkle_block)
|
||||
{
|
||||
std::vector<unsigned char> value_bytes;
|
||||
CVectorWriter ss_val(0, 0, value_bytes, 0);
|
||||
try {
|
||||
ss_val << value;
|
||||
} catch (...) {
|
||||
throw std::ios_base::failure("Amount serialization is invalid.");
|
||||
}
|
||||
|
||||
// Strip witness data for proof inclusion since only TXID-covered fields matters
|
||||
CDataStream ss_tx(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
|
||||
ss_tx << tx_ref;
|
||||
std::vector<unsigned char> tx_data_stripped(ss_tx.begin(), ss_tx.end());
|
||||
|
||||
// Serialize merkle block
|
||||
CDataStream ss_txout_proof(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
|
||||
ss_txout_proof << merkle_block;
|
||||
std::vector<unsigned char> txout_proof_bytes(ss_txout_proof.begin(), ss_txout_proof.end());
|
||||
|
||||
// Construct pegin proof
|
||||
CScriptWitness pegin_witness;
|
||||
std::vector<std::vector<unsigned char> >& stack = pegin_witness.stack;
|
||||
stack.push_back(value_bytes);
|
||||
stack.push_back(std::vector<unsigned char>(asset.begin(), asset.end()));
|
||||
stack.push_back(std::vector<unsigned char>(genesis_hash.begin(), genesis_hash.end()));
|
||||
stack.push_back(std::vector<unsigned char>(claim_script.begin(), claim_script.end()));
|
||||
stack.push_back(tx_data_stripped);
|
||||
stack.push_back(txout_proof_bytes);
|
||||
return pegin_witness;
|
||||
}
|
||||
|
||||
CScriptWitness CreatePeginWitness(const CAmount& value, const CAsset& asset, const uint256& genesis_hash, const CScript& claim_script, const CTransactionRef& tx_ref, const CMerkleBlock& merkle_block)
|
||||
{
|
||||
return CreatePeginWitnessInner(value, asset, genesis_hash, claim_script, tx_ref, merkle_block);
|
||||
}
|
||||
CScriptWitness CreatePeginWitness(const CAmount& value, const CAsset& asset, const uint256& genesis_hash, const CScript& claim_script, const Sidechain::Bitcoin::CTransactionRef& tx_ref, const Sidechain::Bitcoin::CMerkleBlock& merkle_block)
|
||||
{
|
||||
return CreatePeginWitnessInner(value, asset, genesis_hash, claim_script, tx_ref, merkle_block);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
#include <amount.h>
|
||||
#include <consensus/params.h>
|
||||
#include <merkleblock.h>
|
||||
#include <primitives/bitcoin/transaction.h>
|
||||
#include <primitives/bitcoin/merkleblock.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <chain.h>
|
||||
|
|
@ -38,4 +40,9 @@ bool MatchLiquidWatchman(const CScript& script);
|
|||
* 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);
|
||||
|
||||
/** Create the peg-in witness stack */
|
||||
CScriptWitness CreatePeginWitness(const CAmount& value, const CAsset& asset, const uint256& genesis_hash, const CScript& claim_script, const CTransactionRef& tx_ref, const CMerkleBlock& merkle_block);
|
||||
CScriptWitness CreatePeginWitness(const CAmount& value, const CAsset& asset, const uint256& genesis_hash, const CScript& claim_script, const Sidechain::Bitcoin::CTransactionRef& tx_ref, const Sidechain::Bitcoin::CMerkleBlock& merkle_block);
|
||||
|
||||
|
||||
#endif // BITCOIN_PEGINS_H
|
||||
|
|
|
|||
|
|
@ -5530,19 +5530,6 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Amounts to pegin must be explicit and asset must be %s", Params().GetConsensus().parent_pegged_asset.GetHex()));
|
||||
}
|
||||
|
||||
CDataStream stream(0, 0);
|
||||
try {
|
||||
stream << value;
|
||||
} catch (...) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Amount serialization is invalid.");
|
||||
}
|
||||
// Need to reinterpret bytes as unsigned chars before adding to witness
|
||||
char* buf = stream.data();
|
||||
unsigned char* membuf = reinterpret_cast<unsigned char*>(buf);
|
||||
std::vector<unsigned char> value_bytes(membuf, membuf + stream.size());
|
||||
|
||||
uint256 genesisBlockHash = Params().ParentGenesisBlockHash();
|
||||
|
||||
// Manually construct peg-in transaction, sign it, and send it off.
|
||||
// Decrement the output value as much as needed given the total vsize to
|
||||
// pay the fees.
|
||||
|
|
@ -5566,20 +5553,8 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
|
|||
mtx.vout.push_back(CTxOut(Params().GetConsensus().pegged_asset, value, GetScriptForDestination(wpkhash)));
|
||||
mtx.vout.push_back(CTxOut(Params().GetConsensus().pegged_asset, 0, CScript()));
|
||||
|
||||
// Strip witness data for proof inclusion since only TXID-covered fields matters
|
||||
CDataStream ssTxBack(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
|
||||
ssTxBack << txBTC;
|
||||
std::vector<unsigned char> tx_data_stripped(ssTxBack.begin(), ssTxBack.end());
|
||||
|
||||
// Construct pegin proof
|
||||
CScriptWitness pegin_witness;
|
||||
std::vector<std::vector<unsigned char> >& stack = pegin_witness.stack;
|
||||
stack.push_back(value_bytes);
|
||||
stack.push_back(std::vector<unsigned char>(Params().GetConsensus().pegged_asset.begin(), Params().GetConsensus().pegged_asset.end()));
|
||||
stack.push_back(std::vector<unsigned char>(genesisBlockHash.begin(), genesisBlockHash.end()));
|
||||
stack.push_back(std::vector<unsigned char>(witness_script.begin(), witness_script.end()));
|
||||
stack.push_back(tx_data_stripped);
|
||||
stack.push_back(txOutProofData);
|
||||
CScriptWitness pegin_witness = CreatePeginWitness(value, Params().GetConsensus().pegged_asset, Params().ParentGenesisBlockHash(), witness_script, txBTCRef, merkleBlock);
|
||||
|
||||
// Peg-in witness isn't valid, even though the block header is(without depth check)
|
||||
// We re-check depth before returning with more descriptive result
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue