Skip to content

Commit

Permalink
Merge bitcoin#458: [0.17] Add pegin validation
Browse files Browse the repository at this point in the history
d358364 Integration test for pegins and pegouts (Steven Roose)
d888540 Add support for signed-blocks parent chains (Steven Roose)
b56f7da Add pegin and pegout RPC calls (Steven Roose)
7bb9380 Recognize pegout scripts (Steven Roose)
4688e3e Add periodic RPC recheck and invalid block recheck (Steven Roose)
0e4e834 Add pegin validation unit tests (Steven Roose)
5cbb014 Validation of pegin inputs (Steven Roose)
f4adb46 Add spentness flag to pegin coins (Steven Roose)
0d07d21 Change CCoinsMapKey to use chain-aware outpoints (Steven Roose)
22ec499 Add "vdata" field to createrawtransaction rpc (Steven Roose)
2db1f2b Add tweakfedpegscript rpc (Steven Roose)
d6686b6 Add getsidechaininfo rpc (Steven Roose)
fb8a453 Add pegin validation utility methods (Steven Roose)
037b260 Serialize parent blocks without pegin flags (Steven Roose)
89613b8 Skip normal validation of pegin inputs (Steven Roose)
ae54d4a Add pegin input serialization (Steven Roose)
ac1eadd Add support for NullData addresses (OP_RETURN) (Steven Roose)
18ee341 Add parent address encoding (Steven Roose)
d39d440 Add mainchain rpc client (Steven Roose)
238a72b Add arguments for parent chain characteristics (Steven Roose)
  • Loading branch information
instagibbs committed Jan 2, 2019
2 parents 948f968 + d358364 commit 5a18be3
Show file tree
Hide file tree
Showing 65 changed files with 3,309 additions and 321 deletions.
4 changes: 4 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ BITCOIN_CORE_H = \
dbwrapper.h \
limitedmap.h \
logging.h \
mainchainrpc.h \
memusage.h \
merkleblock.h \
miner.h \
Expand All @@ -141,6 +142,7 @@ BITCOIN_CORE_H = \
netmessagemaker.h \
noui.h \
outputtype.h \
pegins.h \
policy/feerate.h \
policy/fees.h \
policy/policy.h \
Expand Down Expand Up @@ -232,12 +234,14 @@ libbitcoin_server_a_SOURCES = \
index/txindex.cpp \
init.cpp \
dbwrapper.cpp \
mainchainrpc.cpp \
merkleblock.cpp \
miner.cpp \
net.cpp \
net_processing.cpp \
noui.cpp \
outputtype.cpp \
pegins.cpp \
policy/fees.cpp \
policy/policy.cpp \
policy/rbf.cpp \
Expand Down
5 changes: 4 additions & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ BITCOIN_TESTS =\
test/uint256_tests.cpp \
test/util_tests.cpp \
test/validation_block_tests.cpp \
test/versionbits_tests.cpp
test/versionbits_tests.cpp \
test/pegin_spent_tests.cpp \
test/pegin_witness_tests.cpp
# ELEMENTS IN THE END

if ENABLE_WALLET
BITCOIN_TESTS += \
Expand Down
4 changes: 3 additions & 1 deletion src/bench/mempool_eviction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& po
bool spendsCoinbase = false;
unsigned int sigOpCost = 4;
LockPoints lp;
std::set<std::pair<uint256, COutPoint>> setPeginsSpent;
pool.addUnchecked(tx->GetHash(), CTxMemPoolEntry(
tx, nFee, nTime, nHeight,
spendsCoinbase, sigOpCost, lp));
spendsCoinbase, sigOpCost, lp,
setPeginsSpent));
}

// Right now this is only testing eviction performance in an extremely small
Expand Down
5 changes: 5 additions & 0 deletions src/block_proof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ bool CheckProof(const CBlockHeader& block, const Consensus::Params& params)
}
}

bool CheckProofSignedParent(const CBlockHeader& block, const Consensus::Params& params)
{
return CheckProofGeneric(block, params, params.parent_chain_signblockscript);
}

void ResetProof(CBlockHeader& block)
{
block.proof.solution.clear();
Expand Down
1 change: 1 addition & 0 deletions src/block_proof.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class CScript;

/** Check on header proof, depending on chain type, PoW or signed **/
bool CheckProof(const CBlockHeader& block, const Consensus::Params&);
bool CheckProofSignedParent(const CBlockHeader& block, const Consensus::Params&);
void ResetProof(CBlockHeader& block);
bool CheckChallenge(const CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params&);
void ResetChallenge(CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params&);
Expand Down
96 changes: 66 additions & 30 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,25 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

static CScript StrHexToScriptWithDefault(std::string strScript, const CScript defaultScript)
{
CScript returnScript;
if (!strScript.empty()) {
std::vector<unsigned char> scriptData = ParseHex(strScript);
returnScript = CScript(scriptData.begin(), scriptData.end());
} else {
returnScript = defaultScript;
}
return returnScript;
}

// Safer for users if they load incorrect parameters via arguments.
static std::vector<unsigned char> CommitToArguments(const Consensus::Params& params, const std::string& networkID)
{
CSHA256 sha2;
unsigned char commitment[32];
sha2.Write((const unsigned char*)networkID.c_str(), networkID.length());
//sha2.Write((const unsigned char*)HexStr(params.fedpegScript).c_str(), HexStr(params.fedpegScript).length());
sha2.Write((const unsigned char*)HexStr(params.fedpegScript).c_str(), HexStr(params.fedpegScript).length());
sha2.Write((const unsigned char*)HexStr(params.signblockscript).c_str(), HexStr(params.signblockscript).length());
sha2.Finalize(commitment);
return std::vector<unsigned char>(commitment, commitment + 32);
Expand Down Expand Up @@ -466,33 +478,6 @@ class CCustomParams : public CRegTestParams {
consensus.nMinimumChainWork = uint256S(args.GetArg("-con_nminimumchainwork", "0x0"));
consensus.defaultAssumeValid = uint256S(args.GetArg("-con_defaultassumevalid", "0x00"));

// No subsidy for custom chains by default
consensus.genesis_subsidy = args.GetArg("-con_blocksubsidy", 0);

// Note: This global is needed to avoid circular dependency
// Defaults to true for custom chains.
g_con_blockheightinheader = gArgs.GetBoolArg("-con_blockheightinheader", true);

// All non-zero coinbase outputs must go to this scriptPubKey
std::vector<unsigned char> man_bytes = ParseHex(gArgs.GetArg("-con_mandatorycoinbase", ""));
consensus.mandatory_coinbase_destination = CScript(man_bytes.begin(), man_bytes.end()); // Blank script allows any coinbase destination
initialFreeCoins = gArgs.GetArg("-initialfreecoins", 0);

// Determines type of genesis block
consensus.genesis_style = gArgs.GetArg("-con_genesis_style", "elements");

// Block signing encumberance script, default of 51 aka OP_TRUE
std::vector<unsigned char> sign_bytes = ParseHex(gArgs.GetArg("-signblockscript", "51"));
consensus.signblockscript = CScript(sign_bytes.begin(), sign_bytes.end());
// Default signature size is the size of dummy push, and single 72 byte DER signature
consensus.max_block_signature_size = gArgs.GetArg("-con_max_block_sig_size", 74);
g_signed_blocks = gArgs.GetBoolArg("-con_signed_blocks", true);

// Custom chains connect coinbase outputs to db by default
consensus.connect_genesis_outputs = gArgs.GetArg("-con_connect_coinbase", true);

anyonecanspend_aremine = gArgs.GetBoolArg("-anyonecanspendaremine", true);

nPruneAfterHeight = (uint64_t)args.GetArg("-npruneafterheight", nPruneAfterHeight);
fDefaultConsistencyChecks = args.GetBoolArg("-fdefaultconsistencychecks", fDefaultConsistencyChecks);
fMineBlocksOnDemand = args.GetBoolArg("-fmineblocksondemand", fMineBlocksOnDemand);
Expand All @@ -517,12 +502,63 @@ class CCustomParams : public CRegTestParams {
std::copy(begin(magic_byte), end(magic_byte), pchMessageStart);

vSeeds.clear();
if (gArgs.IsArgSet("-seednode")) {
const auto seednodes = gArgs.GetArgs("-seednode");
if (args.IsArgSet("-seednode")) {
const auto seednodes = args.GetArgs("-seednode");
if (seednodes.size() != 1 || seednodes[0] != "0") {
vSeeds = seednodes;
}
}

//
// ELEMENTS fields

// Determines type of genesis block
consensus.genesis_style = gArgs.GetArg("-con_genesis_style", "elements");

// Block signing encumberance script, default of 51 aka OP_TRUE
std::vector<unsigned char> sign_bytes = ParseHex(gArgs.GetArg("-signblockscript", "51"));
consensus.signblockscript = CScript(sign_bytes.begin(), sign_bytes.end());
// Default signature size is the size of dummy push, and single 72 byte DER signature
consensus.max_block_signature_size = gArgs.GetArg("-con_max_block_sig_size", 74);
g_signed_blocks = gArgs.GetBoolArg("-con_signed_blocks", true);

// Note: This global is needed to avoid circular dependency
// Defaults to true for custom chains.
g_con_blockheightinheader = args.GetBoolArg("-con_blockheightinheader", true);

// No subsidy for custom chains by default
consensus.genesis_subsidy = args.GetArg("-con_blocksubsidy", 0);

// All non-zero coinbase outputs must go to this scriptPubKey
std::vector<unsigned char> man_bytes = ParseHex(args.GetArg("-con_mandatorycoinbase", ""));
consensus.mandatory_coinbase_destination = CScript(man_bytes.begin(), man_bytes.end()); // Blank script allows any coinbase destination

// Custom chains connect coinbase outputs to db by default
consensus.connect_genesis_outputs = args.GetArg("-con_connect_coinbase", true);

initialFreeCoins = gArgs.GetArg("-initialfreecoins", 0);

anyonecanspend_aremine = args.GetBoolArg("-anyonecanspendaremine", true);

consensus.has_parent_chain = args.GetBoolArg("-con_has_parent_chain", true);
// bitcoin regtest is the parent chain by default
parentGenesisBlockHash = uint256S(args.GetArg("-parentgenesisblockhash", "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
// Either it has a parent chain or not
const bool parent_genesis_is_null = parentGenesisBlockHash == uint256();
assert(consensus.has_parent_chain != parent_genesis_is_null);
consensus.parentChainPowLimit = uint256S(args.GetArg("-con_parentpowlimit", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
consensus.parent_chain_signblockscript = StrHexToScriptWithDefault(args.GetArg("-con_parent_chain_signblockscript", ""), CScript());
consensus.pegin_min_depth = args.GetArg("-peginconfirmationdepth", DEFAULT_PEGIN_CONFIRMATION_DEPTH);

const CScript default_script(CScript() << OP_TRUE);
consensus.fedpegScript = StrHexToScriptWithDefault(args.GetArg("-fedpegscript", ""), default_script);

base58Prefixes[PARENT_PUBKEY_ADDRESS] = std::vector<unsigned char>(1, args.GetArg("-parentpubkeyprefix", 111));
base58Prefixes[PARENT_SCRIPT_ADDRESS] = std::vector<unsigned char>(1, args.GetArg("-parentscriptprefix", 196));
parent_bech32_hrp = args.GetArg("-parent_bech32_hrp", "bcrt");

// END ELEMENTS fields
//
}

void SetGenesisBlock() {
Expand Down
10 changes: 10 additions & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class CChainParams
SECRET_KEY,
EXT_PUBLIC_KEY,
EXT_SECRET_KEY,
// ELEMENTS
PARENT_PUBKEY_ADDRESS,
PARENT_SCRIPT_ADDRESS,

MAX_BASE58_TYPES
};
Expand Down Expand Up @@ -80,7 +83,11 @@ class CChainParams
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
const ChainTxData& TxData() const { return chainTxData; }
// ELEMENTS extra fields:
const uint256 ParentGenesisBlockHash() const { return parentGenesisBlockHash; }
bool anyonecanspend_aremine;
const std::string& ParentBech32HRP() const { return parent_bech32_hrp; }

protected:
CChainParams() {}

Expand All @@ -101,6 +108,9 @@ class CChainParams
CCheckpointData checkpointData;
ChainTxData chainTxData;
bool m_fallback_fee_enabled;
// ELEMENTS extra fields:
uint256 parentGenesisBlockHash;
std::string parent_bech32_hrp;
};

/**
Expand Down
16 changes: 12 additions & 4 deletions src/chainparamsbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ void SetupChainParamsBaseOptions()
gArgs.AddArg("-con_signed_blocks", "Signed blockchain. Uses input of `-signblockscript` to define what signatures are necessary to solve it.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-signblockscript", "Signed blockchain enumberance. Only active when `-con_signed_blocks` set to true.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_max_block_sig_size", "Max allowed witness data for the signed block header.", false, OptionsCategory::CHAINPARAMS);

gArgs.AddArg("-con_has_parent_chain", "Whether or not there is a parent chain.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-parentgenesisblockhash", "The genesis blockhash of the parent chain.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_parentpowlimit", "The proof-of-work limit value for the parent chain.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_parent_chain_signblockscript", "Whether parent chain uses pow or signed blocks. If the parent chain uses signed blocks, the challenge (scriptPubKey) script. If not, an empty string. (default: empty script [ie parent uses pow])", false, OptionsCategory::CHAINPARAMS);

gArgs.AddArg("-fedpegscript", "The script for the federated peg.", false, OptionsCategory::CHAINPARAMS);
}

static std::unique_ptr<CBaseChainParams> globalChainBaseParams;
Expand All @@ -44,13 +51,14 @@ const CBaseChainParams& BaseParams()
std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
return MakeUnique<CBaseChainParams>("", 8332);
return MakeUnique<CBaseChainParams>("", 8332, 18332);
else if (chain == CBaseChainParams::TESTNET)
return MakeUnique<CBaseChainParams>("testnet3", 18332);
return MakeUnique<CBaseChainParams>("testnet3", 18332, 8332);
else if (chain == CBaseChainParams::REGTEST)
return MakeUnique<CBaseChainParams>("regtest", 18443);
return MakeUnique<CBaseChainParams>("regtest", 18443, 18332);

return MakeUnique<CBaseChainParams>(chain, 18553);
// ELEMENTS:
return MakeUnique<CBaseChainParams>(chain, 7041, 18332);
}

void SelectBaseParams(const std::string& chain)
Expand Down
4 changes: 3 additions & 1 deletion src/chainparamsbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ class CBaseChainParams

const std::string& DataDir() const { return strDataDir; }
int RPCPort() const { return nRPCPort; }
int MainchainRPCPort() const { return nMainchainRPCPort; }

CBaseChainParams() = delete;
CBaseChainParams(const std::string& data_dir, int rpc_port) : nRPCPort(rpc_port), strDataDir(data_dir) {}
CBaseChainParams(const std::string& data_dir, int rpc_port, int mainchain_rpc_port) : nRPCPort(rpc_port), nMainchainRPCPort(mainchain_rpc_port), strDataDir(data_dir) {}

private:
int nRPCPort;
int nMainchainRPCPort;
std::string strDataDir;
};

Expand Down

0 comments on commit 5a18be3

Please sign in to comment.