mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Be able to fund transactions with peg-ins
This commit is contained in:
parent
74c4d37788
commit
1ce74e07f3
3 changed files with 63 additions and 7 deletions
|
|
@ -83,6 +83,16 @@ public:
|
|||
m_external_txouts.emplace(outpoint, txout);
|
||||
}
|
||||
|
||||
void Select(const COutPoint& outpoint, const Sidechain::Bitcoin::CTxOut& txout_in)
|
||||
{
|
||||
setSelected.insert(outpoint);
|
||||
CTxOut txout;
|
||||
txout.scriptPubKey = txout_in.scriptPubKey;
|
||||
txout.nValue.SetToAmount(txout_in.nValue);
|
||||
txout.nAsset.SetToAsset(Params().GetConsensus().pegged_asset);
|
||||
m_external_txouts.emplace(outpoint, txout);
|
||||
}
|
||||
|
||||
void UnSelect(const COutPoint& output)
|
||||
{
|
||||
setSelected.erase(output);
|
||||
|
|
|
|||
|
|
@ -3381,10 +3381,22 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
|
|||
setSubtractFeeFromOutputs.insert(pos);
|
||||
}
|
||||
|
||||
// Check any existing inputs for peg-in data and add to external txouts if so
|
||||
// Fetch specified UTXOs from the UTXO set
|
||||
const auto& fedpegscripts = GetValidFedpegScripts(chainActive.Tip(), Params().GetConsensus(), true /* nextblock_validation */);
|
||||
std::map<COutPoint, Coin> coins;
|
||||
for (const CTxIn& txin : tx.vin) {
|
||||
for (unsigned int i = 0; i < tx.vin.size(); ++i ) {
|
||||
const CTxIn& txin = tx.vin[i];
|
||||
coins[txin.prevout]; // Create empty map entry keyed by prevout.
|
||||
if (txin.m_is_pegin) {
|
||||
std::string err;
|
||||
if (tx.witness.vtxinwit.size() != tx.vin.size() || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, fedpegscripts, txin.prevout, err, false)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Transaction contains invalid peg-in input: %s", err));
|
||||
}
|
||||
CScriptWitness& pegin_witness = tx.witness.vtxinwit[i].m_pegin_witness;
|
||||
CTxOut txout = GetPeginOutputFromWitness(pegin_witness);
|
||||
coinControl.SelectExternal(txin.prevout, txout);
|
||||
}
|
||||
}
|
||||
CCoinsView viewDummy;
|
||||
CCoinsViewCache view(&viewDummy);
|
||||
|
|
@ -4671,6 +4683,9 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request)
|
|||
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
|
||||
{"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
|
||||
{"sequence", RPCArg::Type::NUM, RPCArg::Optional::NO, "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 witness program generated by getpeginaddress."},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -4768,7 +4783,7 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request)
|
|||
// 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
|
||||
// nonces.
|
||||
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 */);
|
||||
CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], request.params[3]["replaceable"], NullUniValue /* CA: assets_in */, nullptr /* output_pubkeys_out */, true /* allow_peg_in */);
|
||||
FundTransaction(pwallet, rawTx, fee, change_position, request.params[3], request.params[5]);
|
||||
|
||||
// Make a blank psbt
|
||||
|
|
@ -4789,6 +4804,42 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request)
|
|||
throw JSONRPCTransactionError(err);
|
||||
}
|
||||
|
||||
// Add peg-in stuff if it's there
|
||||
for (unsigned int i = 0; i < rawTx.vin.size(); ++i) {
|
||||
if (psbtx.tx->vin[i].m_is_pegin) {
|
||||
CScriptWitness& pegin_witness = psbtx.tx->witness.vtxinwit[i].m_pegin_witness;
|
||||
CAmount val;
|
||||
VectorReader vr_val(SER_NETWORK, PROTOCOL_VERSION, pegin_witness.stack[0], 0);
|
||||
vr_val >> val;
|
||||
psbtx.inputs[i].value = val;
|
||||
VectorReader vr_asset(SER_NETWORK, PROTOCOL_VERSION, pegin_witness.stack[1], 0);
|
||||
vr_asset >> psbtx.inputs[i].asset;
|
||||
VectorReader vr_genesis(SER_NETWORK, PROTOCOL_VERSION, pegin_witness.stack[2], 0);
|
||||
vr_genesis >> psbtx.inputs[i].genesis_hash;
|
||||
psbtx.inputs[i].claim_script.assign(pegin_witness.stack[3].begin(), pegin_witness.stack[3].end());
|
||||
|
||||
VectorReader vr_tx(SER_NETWORK, PROTOCOL_VERSION, pegin_witness.stack[4], 0);
|
||||
VectorReader vr_proof(SER_NETWORK, PROTOCOL_VERSION, pegin_witness.stack[5], 0);
|
||||
if (Params().GetConsensus().ParentChainHasPow()) {
|
||||
Sidechain::Bitcoin::CTransactionRef tx_btc;
|
||||
vr_tx >> tx_btc;
|
||||
psbtx.inputs[i].peg_in_tx = tx_btc;
|
||||
Sidechain::Bitcoin::CMerkleBlock tx_proof;
|
||||
vr_proof >> tx_proof;
|
||||
psbtx.inputs[i].txout_proof = tx_proof;
|
||||
} else {
|
||||
CTransactionRef tx_btc;
|
||||
vr_tx >> tx_btc;
|
||||
psbtx.inputs[i].peg_in_tx = tx_btc;
|
||||
CMerkleBlock tx_proof;
|
||||
vr_proof >> tx_proof;
|
||||
psbtx.inputs[i].txout_proof = tx_proof;
|
||||
}
|
||||
pegin_witness.SetNull();
|
||||
psbtx.tx->vin[i].m_is_pegin = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize the PSBT
|
||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ssTx << psbtx;
|
||||
|
|
|
|||
|
|
@ -524,11 +524,6 @@ class PSBTTest(BitcoinTestFramework):
|
|||
# Some Confidential-Assets-specific tests
|
||||
self.run_ca_tests()
|
||||
|
||||
# Check that peg-ins are disallowed for walletcreatefundedpsbt
|
||||
assert_raises_rpc_error(-8, 'pegin_ arguments provided but this command does not support peg-ins', self.nodes[0].walletcreatefundedpsbt, [{"txid": "0000000000000000000000000000000000000000000000000000000000000000", "vout": 0, "pegin_bitcoin_tx": "00"}], [{self.nodes[0].getnewaddress(): 1}])
|
||||
assert_raises_rpc_error(-8, 'pegin_ arguments provided but this command does not support peg-ins', self.nodes[0].walletcreatefundedpsbt, [{"txid": "0000000000000000000000000000000000000000000000000000000000000000", "vout": 0, "pegin_txout_proof": "00"}], [{self.nodes[0].getnewaddress(): 1}])
|
||||
assert_raises_rpc_error(-8, 'pegin_ arguments provided but this command does not support peg-ins', self.nodes[0].walletcreatefundedpsbt, [{"txid": "0000000000000000000000000000000000000000000000000000000000000000", "vout": 0, "pegin_claim_script": "00"}], [{self.nodes[0].getnewaddress(): 1}])
|
||||
|
||||
# Tests added in the 0.18 rebase don't pass on Elements yet.
|
||||
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue