mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-19 13:27:35 +02:00
Allow specifying peg-in info in raw transaction RPC inputs
This commit is contained in:
parent
42babb81f0
commit
cefe40767d
3 changed files with 44 additions and 5 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <asset.h>
|
#include <asset.h>
|
||||||
|
#include <block_proof.h>
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <coins.h>
|
#include <coins.h>
|
||||||
#include <compat/byteswap.h>
|
#include <compat/byteswap.h>
|
||||||
|
|
@ -483,7 +484,7 @@ void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, Sidechain::B
|
||||||
CreatePegInInputInner(mtx, input_idx, tx_btc, merkle_block, claim_scripts, txData, txOutProofData);
|
CreatePegInInputInner(mtx, input_idx, tx_btc, merkle_block, claim_scripts, txData, txOutProofData);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, const UniValue& rbf, const UniValue& assets_in, std::vector<CPubKey>* output_pubkeys_out)
|
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, const UniValue& rbf, const UniValue& assets_in, std::vector<CPubKey>* output_pubkeys_out, bool allow_peg_in)
|
||||||
{
|
{
|
||||||
if (inputs_in.isNull() || outputs_in.isNull())
|
if (inputs_in.isNull() || outputs_in.isNull())
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
|
||||||
|
|
@ -542,8 +543,43 @@ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniVal
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
|
CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
|
||||||
|
|
||||||
rawTx.vin.push_back(in);
|
rawTx.vin.push_back(in);
|
||||||
|
|
||||||
|
// Get the pegin stuff if it's there
|
||||||
|
const UniValue& pegin_tx = find_value(o, "pegin_bitcoin_tx");
|
||||||
|
const UniValue& pegin_tx_proof = find_value(o, "pegin_txout_proof");
|
||||||
|
const UniValue& pegin_script = find_value(o, "pegin_claim_script");
|
||||||
|
if (!pegin_tx.isNull() && !pegin_tx_proof.isNull() && !pegin_script.isNull() && allow_peg_in) {
|
||||||
|
if (!IsHex(pegin_script.get_str())) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Given claim_script is not hex.");
|
||||||
|
}
|
||||||
|
// If given manually, no need for it to be a witness script
|
||||||
|
std::vector<unsigned char> claim_script_bytes(ParseHex(pegin_script.get_str()));
|
||||||
|
CScript claim_script(claim_script_bytes.begin(), claim_script_bytes.end());
|
||||||
|
std::set<CScript> claim_scripts;
|
||||||
|
claim_scripts.insert(std::move(claim_script));
|
||||||
|
if (Params().GetConsensus().ParentChainHasPow()) {
|
||||||
|
Sidechain::Bitcoin::CTransactionRef tx_btc;
|
||||||
|
Sidechain::Bitcoin::CMerkleBlock merkle_block;
|
||||||
|
CreatePegInInput(rawTx, idx, tx_btc, merkle_block, claim_scripts, ParseHex(pegin_tx.get_str()), ParseHex(pegin_tx_proof.get_str()));
|
||||||
|
if (!CheckParentProofOfWork(merkle_block.header.GetHash(), merkle_block.header.nBits, Params().GetConsensus())) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid tx out proof");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CTransactionRef tx_btc;
|
||||||
|
CMerkleBlock merkle_block;
|
||||||
|
CreatePegInInput(rawTx, idx, tx_btc, merkle_block, claim_scripts, ParseHex(pegin_tx.get_str()), ParseHex(pegin_tx_proof.get_str()));
|
||||||
|
if (!CheckProofSignedParent(merkle_block.header, Params().GetConsensus())) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid tx out proof");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!pegin_tx.isNull() || !pegin_tx_proof.isNull() || !pegin_script.isNull()) {
|
||||||
|
if (allow_peg_in) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Some but not all pegin_ arguments provided");
|
||||||
|
} else {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "pegin_ arguments provided but this command does not support peg-ins");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!outputs_is_obj) {
|
if (!outputs_is_obj) {
|
||||||
|
|
@ -678,6 +714,9 @@ static UniValue createrawtransaction(const JSONRPCRequest& request)
|
||||||
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
|
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
|
||||||
{"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
|
{"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
|
||||||
{"sequence", RPCArg::Type::NUM, /* default */ "depends on the value of the 'replaceable' and 'locktime' arguments", "The sequence number"},
|
{"sequence", RPCArg::Type::NUM, /* default */ "depends on the value of the 'replaceable' and 'locktime' arguments", "The sequence number"},
|
||||||
|
{"pegin_bitcoin_tx", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress"},
|
||||||
|
{"pegin_txout_proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A rawtxoutproof (in hex) generated by the mainchain daemon's `gettxoutproof` containing a proof of only bitcoin_tx"},
|
||||||
|
{"pegin_claim_script", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The claim script generated by getpeginaddress."},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -2072,7 +2111,7 @@ UniValue createpsbt(const JSONRPCRequest& request)
|
||||||
);
|
);
|
||||||
|
|
||||||
std::vector<CPubKey> output_pubkeys;
|
std::vector<CPubKey> output_pubkeys;
|
||||||
CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], request.params[3], request.params[4], &output_pubkeys);
|
CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], request.params[3], request.params[4], &output_pubkeys, false /* allow_peg_in */);
|
||||||
|
|
||||||
// Make a blank psbt
|
// Make a blank psbt
|
||||||
PartiallySignedTransaction psbtx(rawTx);
|
PartiallySignedTransaction psbtx(rawTx);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
|
||||||
/** Create a transaction from univalue parameters. If (and only if)
|
/** Create a transaction from univalue parameters. If (and only if)
|
||||||
output_pubkeys_out is null, the "nonce hack" of storing Confidential
|
output_pubkeys_out is null, the "nonce hack" of storing Confidential
|
||||||
Assets output pubkeys in nonces will be used. */
|
Assets output pubkeys in nonces will be used. */
|
||||||
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, const UniValue& rbf, const UniValue& assets_in, std::vector<CPubKey>* output_pubkeys_out = nullptr);
|
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, const UniValue& rbf, const UniValue& assets_in, std::vector<CPubKey>* output_pubkeys_out = nullptr, bool allow_peg_in = true);
|
||||||
|
|
||||||
/** Create a peg-in input */
|
/** Create a peg-in input */
|
||||||
void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, CTransactionRef& tx_btc, CMerkleBlock& merkle_block, const std::set<CScript>& claim_scripts, const std::vector<unsigned char>& txData, const std::vector<unsigned char>& txOutProofData);
|
void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, CTransactionRef& tx_btc, CMerkleBlock& merkle_block, const std::set<CScript>& claim_scripts, const std::vector<unsigned char>& txData, const std::vector<unsigned char>& txOutProofData);
|
||||||
|
|
|
||||||
|
|
@ -4672,7 +4672,7 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request)
|
||||||
// It's hard to control the behavior of FundTransaction, so we will wait
|
// It's hard to control the behavior of FundTransaction, so we will wait
|
||||||
// until after it's done, then extract the blinding keys from the output
|
// until after it's done, then extract the blinding keys from the output
|
||||||
// nonces.
|
// nonces.
|
||||||
CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], request.params[3]["replaceable"], NullUniValue /* CA: assets_in */);
|
CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], request.params[3]["replaceable"], NullUniValue /* CA: assets_in */, nullptr /* output_pubkeys_out */, false /* allow_peg_in */);
|
||||||
FundTransaction(pwallet, rawTx, fee, change_position, request.params[3]);
|
FundTransaction(pwallet, rawTx, fee, change_position, request.params[3]);
|
||||||
|
|
||||||
// Make a blank psbt
|
// Make a blank psbt
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue