Skip to content

Commit 23af084

Browse files
committed
2WP: QA: Introduce -con_parent_chain_has_pow to test...
Allow other elements chains as parent chains for pegs for now it also assumes that the parent chain has CT/CA tx format, which is orthogonal to the parent chain having pow or signed blocks It would be nice to also test bitcoin-like chains with signed blocks instead of pow by adding another parameter -con_parent_chain_has_CT or similar and decouple the logic CT: Introduce GetAmountFromParentChainPegin for CT txs RPC: Adapt rpcwallet to initial -con_parent_chain_has_pow
1 parent 68d74d5 commit 23af084

File tree

6 files changed

+79
-24
lines changed

6 files changed

+79
-24
lines changed

src/chainparams.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class CCustomParams : public CChainParams {
130130
consensus.defaultAssumeValid = uint256S(GetArg("-con_defaultassumevalid", "0x00"));
131131
consensus.pegin_min_depth = GetArg("-peginconfirmationdepth", DEFAULT_PEGIN_CONFIRMATION_DEPTH);
132132
consensus.mandatory_coinbase_destination = StrHexToScriptWithDefault(GetArg("-con_mandatorycoinbase", ""), CScript()); // Blank script allows any coinbase destination
133+
consensus.parent_chain_has_pow = GetBoolArg("-con_parent_chain_has_pow", true);
133134
// bitcoin regtest is the parent chain by default
134135
parentGenesisBlockHash = uint256S(GetArg("-parentgenesisblockhash", "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
135136
initialFreeCoins = GetArg("-initialfreecoins", 0);
@@ -276,4 +277,3 @@ void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_
276277
{
277278
globalChainParams->UpdateBIP9Parameters(d, nStartTime, nTimeout);
278279
}
279-

src/consensus/params.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ struct Params {
7171
uint256 defaultAssumeValid;
7272
uint32_t pegin_min_depth;
7373
CScript mandatory_coinbase_destination;
74+
bool parent_chain_has_pow;
7475
};
7576
} // namespace Consensus
7677

src/init.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ std::string HelpMessage(HelpMessageMode mode)
516516
strUsage += HelpMessageOpt("-initialfreecoins", strprintf(_("The amount of OP_TRUE coins created in the genesis block. Primarily for testing. (default: %d)"), 0));
517517
strUsage += HelpMessageOpt("-parentpubkeyprefix", strprintf(_("The byte prefix, in decimal, of the parent chain's base58 pubkey address. (default: %d)"), 111));
518518
strUsage += HelpMessageOpt("-parentscriptprefix", strprintf(_("The byte prefix, in decimal, of the parent chain's base58 script address. (default: %d)"), 196));
519-
519+
strUsage += HelpMessageOpt("-con_parent_chain_has_pow", _("Whether parent chain uses pow or signed blocks. (default: 1)"));
520520
}
521521
strUsage += HelpMessageOpt("-validatepegin", strprintf(_("Validate pegin claims. All functionaries must run this. (default: %u)"), DEFAULT_VALIDATE_PEGIN));
522522
strUsage += HelpMessageOpt("-mainchainrpchost=<addr>", strprintf("The address which the daemon will try to connect to validate peg-ins, if enabled. (default: cookie auth)"));
@@ -1022,7 +1022,7 @@ bool AppInitParameterInteraction()
10221022
nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
10231023

10241024
policyAsset = CAsset(uint256S(GetArg("-feeasset", chainparams.GetConsensus().pegged_asset.GetHex())));
1025-
1025+
10261026
// Fee-per-kilobyte amount considered the same as "free"
10271027
// If you are mining, be careful setting this:
10281028
// if you set it to zero then

src/validation.cpp

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "crypto/hmac_sha256.h"
1818
#include "init.h"
1919
#include "issuance.h"
20+
#include "merkleblock.h"
2021
#include "policy/fees.h"
2122
#include "policy/policy.h"
2223
#include "pow.h"
@@ -2365,6 +2366,15 @@ bool GetAmountFromParentChainPegin(CAmount& amount, const Sidechain::Bitcoin::CT
23652366
return true;
23662367
}
23672368

2369+
bool GetAmountFromParentChainPegin(CAmount& amount, const CTransaction& txBTC, unsigned int nOut)
2370+
{
2371+
if (!txBTC.vout[nOut].nValue.IsExplicit()) {
2372+
return false;
2373+
}
2374+
amount = txBTC.vout[nOut].nValue.GetAmount();
2375+
return true;
2376+
}
2377+
23682378
template<typename T>
23692379
static bool GetBlockAndTxFromMerkleBlock(uint256& block_hash, uint256& tx_hash, T& merkle_block, const std::vector<unsigned char>& merkle_block_raw)
23702380
{
@@ -2483,21 +2493,37 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
24832493

24842494
uint256 block_hash;
24852495
uint256 tx_hash;
2486-
24872496
// Get txout proof
2488-
Sidechain::Bitcoin::CMerkleBlock merkle_block;
2489-
if (!GetBlockAndTxFromMerkleBlock(block_hash, tx_hash, merkle_block, stack[5])) {
2490-
return false;
2491-
}
2492-
// TODO do this before to prevent DoS ?
2493-
if (!CheckBitcoinProof(block_hash, merkle_block.header.nBits)) {
2494-
return false;
2495-
}
2497+
if (Params().GetConsensus().parent_chain_has_pow) {
24962498

2497-
// Get serialized transaction
2498-
Sidechain::Bitcoin::CTransactionRef pegtx;
2499-
if (!CheckPeginTx(stack[4], pegtx, prevout, value, claim_script)) {
2500-
return false;
2499+
Sidechain::Bitcoin::CMerkleBlock merkle_block_pow;
2500+
if (!GetBlockAndTxFromMerkleBlock(block_hash, tx_hash, merkle_block_pow, stack[5])) {
2501+
return false;
2502+
}
2503+
// TODO do this before to prevent DoS ?
2504+
if (!CheckBitcoinProof(block_hash, merkle_block_pow.header.nBits)) {
2505+
return false;
2506+
}
2507+
2508+
Sidechain::Bitcoin::CTransactionRef pegtx;
2509+
if (!CheckPeginTx(stack[4], pegtx, prevout, value, claim_script)) {
2510+
return false;
2511+
}
2512+
} else {
2513+
2514+
CMerkleBlock merkle_block;
2515+
if (!GetBlockAndTxFromMerkleBlock(block_hash, tx_hash, merkle_block, stack[5])) {
2516+
return false;
2517+
}
2518+
2519+
if (!CheckProof(merkle_block.header, Params().GetConsensus())) {
2520+
return false;
2521+
}
2522+
2523+
CTransactionRef pegtx;
2524+
if (!CheckPeginTx(stack[4], pegtx, prevout, value, claim_script)) {
2525+
return false;
2526+
}
25012527
}
25022528

25032529
// Check that the merkle proof corresponds to the txid

src/validation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ void ThreadScriptCheck();
267267
/** Check if bitcoind connection via RPC is correctly working*/
268268
bool BitcoindRPCCheck(bool init);
269269
bool GetAmountFromParentChainPegin(CAmount& amount, const Sidechain::Bitcoin::CTransaction& txBTC, unsigned int nOut);
270+
bool GetAmountFromParentChainPegin(CAmount& amount, const CTransaction& txBTC, unsigned int nOut);
270271
/** Checks pegin witness for validity */
271272
bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& prevout, bool check_depth = true);
272273
/** Extracts an output from pegin witness for evaluation as a normal output */

src/wallet/rpcwallet.cpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,7 +2078,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
20782078
" \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
20792079
" 'send' category of transactions.\n"
20802080
" \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
2081-
" 'send' category of transactions.\n"
2081+
" 'send' category of transactions.\n"
20822082
" }\n"
20832083
" ,...\n"
20842084
" ],\n"
@@ -3508,7 +3508,8 @@ UniValue sendtomainchain(const JSONRPCRequest& request)
35083508
extern UniValue signrawtransaction(const JSONRPCRequest& request);
35093509
extern UniValue sendrawtransaction(const JSONRPCRequest& request);
35103510

3511-
unsigned int GetPeginTxnOutputIndex(const Sidechain::Bitcoin::CTransaction& txn, const CScript& witnessProgram)
3511+
template<typename T_tx>
3512+
unsigned int GetPeginTxnOutputIndex(const T_tx& txn, const CScript& witnessProgram)
35123513
{
35133514
unsigned int nOut = 0;
35143515
//Call contracthashtool
@@ -3519,7 +3520,8 @@ unsigned int GetPeginTxnOutputIndex(const Sidechain::Bitcoin::CTransaction& txn,
35193520
return nOut;
35203521
}
35213522

3522-
UniValue createrawpegin(const JSONRPCRequest& request)
3523+
template<typename T_tx_ref, typename T_tx, typename T_merkle_block>
3524+
static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef, T_tx& tx_aux, T_merkle_block& merkleBlock)
35233525
{
35243526
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
35253527
throw std::runtime_error(
@@ -3548,27 +3550,26 @@ UniValue createrawpegin(const JSONRPCRequest& request)
35483550

35493551
std::vector<unsigned char> txData = ParseHex(request.params[0].get_str());
35503552
CDataStream ssTx(txData, SER_NETWORK, PROTOCOL_VERSION);
3551-
Sidechain::Bitcoin::CTransactionRef txBTCRef;
35523553
try {
35533554
ssTx >> txBTCRef;
35543555
}
35553556
catch (...) {
35563557
throw JSONRPCError(RPC_TYPE_ERROR, "The included bitcoinTx is malformed. Are you sure that is the whole string?");
35573558
}
3558-
Sidechain::Bitcoin::CTransaction txBTC(*txBTCRef);
3559+
T_tx txBTC(*txBTCRef);
35593560

35603561
std::vector<unsigned char> txOutProofData = ParseHex(request.params[1].get_str());
35613562
CDataStream ssTxOutProof(txOutProofData, SER_NETWORK, PROTOCOL_VERSION);
3562-
Sidechain::Bitcoin::CMerkleBlock merkleBlock;
35633563
try {
35643564
ssTxOutProof >> merkleBlock;
35653565
}
35663566
catch (...) {
35673567
throw JSONRPCError(RPC_TYPE_ERROR, "The included txoutproof is malformed. Are you sure that is the whole string?");
35683568
}
35693569

3570-
if (!ssTxOutProof.empty() || !CheckBitcoinProof(merkleBlock.header.GetHash(), merkleBlock.header.nBits))
3570+
if (!ssTxOutProof.empty()) {
35713571
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid tx out proof");
3572+
}
35723573

35733574
std::vector<uint256> txHashes;
35743575
std::vector<unsigned int> txIndices;
@@ -3618,7 +3619,10 @@ UniValue createrawpegin(const JSONRPCRequest& request)
36183619
throw JSONRPCError(RPC_INVALID_PARAMETER, "Given or recovered script is not a witness program.");
36193620
}
36203621

3621-
CAmount value = txBTC.vout[nOut].nValue;
3622+
CAmount value = 0;
3623+
if (!GetAmountFromParentChainPegin(value, txBTC, nOut)) {
3624+
throw JSONRPCError(RPC_INVALID_PARAMETER, "Amounts to pegin must be explicit");
3625+
}
36223626

36233627
CDataStream stream(0, 0);
36243628
try {
@@ -3699,6 +3703,29 @@ UniValue createrawpegin(const JSONRPCRequest& request)
36993703
return ret;
37003704
}
37013705

3706+
UniValue createrawpegin(const JSONRPCRequest& request)
3707+
{
3708+
UniValue ret(UniValue::VOBJ);
3709+
if (Params().GetConsensus().parent_chain_has_pow) {
3710+
Sidechain::Bitcoin::CTransactionRef txBTCRef;
3711+
Sidechain::Bitcoin::CTransaction tx_aux;
3712+
Sidechain::Bitcoin::CMerkleBlock merkleBlock;
3713+
ret = createrawpegin(request, txBTCRef, tx_aux, merkleBlock);
3714+
if (!CheckBitcoinProof(merkleBlock.header.GetHash(), merkleBlock.header.nBits)) {
3715+
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid tx out proof");
3716+
}
3717+
} else {
3718+
CTransactionRef txBTCRef;
3719+
CTransaction tx_aux;
3720+
CMerkleBlock merkleBlock;
3721+
ret = createrawpegin(request, txBTCRef, tx_aux, merkleBlock);
3722+
if (!CheckProof(merkleBlock.header, Params().GetConsensus())) {
3723+
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid tx out proof");
3724+
}
3725+
}
3726+
return ret;
3727+
}
3728+
37023729
UniValue claimpegin(const JSONRPCRequest& request)
37033730
{
37043731

0 commit comments

Comments
 (0)