Skip to content

Commit

Permalink
2WP: Allow signed blocks chains as parent chains for pegs
Browse files Browse the repository at this point in the history
  • Loading branch information
jtimon committed May 25, 2018
1 parent c849ded commit 30ec4dd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class CCustomParams : public CChainParams {
consensus.defaultAssumeValid = uint256S(GetArg("-con_defaultassumevalid", "0x00"));
consensus.pegin_min_depth = GetArg("-peginconfirmationdepth", DEFAULT_PEGIN_CONFIRMATION_DEPTH);
consensus.mandatory_coinbase_destination = StrHexToScriptWithDefault(GetArg("-con_mandatorycoinbase", ""), CScript()); // Blank script allows any coinbase destination
consensus.parent_chain_has_pow = GetBoolArg("-con_parent_chain_has_pow", true);
// bitcoin regtest is the parent chain by default
parentGenesisBlockHash = uint256S(GetArg("-parentgenesisblockhash", "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
initialFreeCoins = GetArg("-initialfreecoins", 0);
Expand Down
1 change: 1 addition & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct Params {
uint256 defaultAssumeValid;
uint32_t pegin_min_depth;
CScript mandatory_coinbase_destination;
bool parent_chain_has_pow;
};
} // namespace Consensus

Expand Down
59 changes: 44 additions & 15 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "crypto/hmac_sha256.h"
#include "init.h"
#include "issuance.h"
#include "merkleblock.h"
#include "policy/fees.h"
#include "policy/policy.h"
#include "pow.h"
Expand Down Expand Up @@ -2357,6 +2358,30 @@ CScript calculate_contract(const CScript& federationRedeemScript, const CScript&
return scriptDestination;
}

template<typename T>
static bool GetBlockAndTxFromMerkleBlock(uint256& block_hash, uint256& tx_hash, T& merkle_block, const std::vector<unsigned char>& merkle_block_raw)
{
try {
std::vector<uint256> txHashes;
std::vector<unsigned int> txIndices;
CDataStream merkleBlockStream(merkle_block_raw, SER_NETWORK, PROTOCOL_VERSION);
merkleBlockStream >> merkle_block;
block_hash = merkle_block.header.GetHash();

if (!merkleBlockStream.empty()) {
return false;
}
if (merkle_block.txn.ExtractMatches(txHashes, txIndices) != merkle_block.header.hashMerkleRoot || txHashes.size() != 1) {
return false;
}
tx_hash = txHashes[0];
} catch (std::exception& e) {
// Invalid encoding of merkle block
return false;
}
return true;
}

bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& prevout, bool check_depth) {

// Format on stack is as follows:
Expand Down Expand Up @@ -2421,22 +2446,26 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
}

// Get txout proof
Sidechain::Bitcoin::CMerkleBlock merkle_block;
std::vector<uint256> txHashes;
std::vector<unsigned int> txIndices;

try {
CDataStream merkleBlockStream(stack[5], SER_NETWORK, PROTOCOL_VERSION);
merkleBlockStream >> merkle_block;
if (!merkleBlockStream.empty() || !CheckBitcoinProof(merkle_block.header.GetHash(), merkle_block.header.nBits)) {
return false;
bool parent_chain_has_pow = true;
uint256 block_hash;
uint256 tx_hash;
if (Params().GetConsensus().parent_chain_has_pow) {
Sidechain::Bitcoin::CMerkleBlock merkle_block_pow;
if (!GetBlockAndTxFromMerkleBlock(block_hash, tx_hash, merkle_block_pow, stack[5])) {
return false;
}
if (merkle_block.txn.ExtractMatches(txHashes, txIndices) != merkle_block.header.hashMerkleRoot || txHashes.size() != 1) {
// TODO do this inside to prever DoS ?
if (!CheckBitcoinProof(block_hash, merkle_block_pow.header.nBits)) {
return false;
}
} else {
CMerkleBlock merkle_block;
if (!GetBlockAndTxFromMerkleBlock(block_hash, tx_hash, merkle_block, stack[5])) {
return false;
}
if (!CheckProof(merkle_block.header, Params().GetConsensus())) {
return false;
}
} catch (std::exception& e) {
// Invalid encoding of merkle block
return false;
}

// Check that transaction matches txid
Expand All @@ -2445,7 +2474,7 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p
}

// Check that the merkle proof corresponds to the txid
if (prevout.hash != txHashes[0]) {
if (prevout.hash != tx_hash) {
return false;
}

Expand Down Expand Up @@ -2474,7 +2503,7 @@ bool IsValidPeginWitness(const CScriptWitness& pegin_witness, const COutPoint& p

// Finally, validate peg-in via rpc call
if (check_depth && GetBoolArg("-validatepegin", DEFAULT_VALIDATE_PEGIN)) {
return IsConfirmedBitcoinBlock(merkle_block.header.GetHash(), Params().GetConsensus().pegin_min_depth);
return IsConfirmedBitcoinBlock(block_hash, Params().GetConsensus().pegin_min_depth);
}
return true;
}
Expand Down

0 comments on commit 30ec4dd

Please sign in to comment.