Skip to content

Commit

Permalink
Add pegin and pegout RPC calls
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenroose committed Dec 13, 2018
1 parent 70b6e75 commit 36d2ac3
Show file tree
Hide file tree
Showing 3 changed files with 521 additions and 18 deletions.
40 changes: 30 additions & 10 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,30 +151,50 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
}
}

void ScriptPubKeyToUniv(const CScript& scriptPubKey,
UniValue& out, bool fIncludeHex)
// ELEMENTS:
static void SidechainScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex, bool is_parent_chain)
{
const std::string prefix = is_parent_chain ? "pegout_" : "";
txnouttype type;
std::vector<CTxDestination> addresses;
int nRequired;

out.pushKV("asm", ScriptToAsmStr(scriptPubKey));
out.pushKV(prefix + "asm", ScriptToAsmStr(scriptPubKey));
if (fIncludeHex)
out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
out.pushKV(prefix + "hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));

if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
out.pushKV("type", GetTxnOutputType(type));
out.pushKV(prefix + "type", GetTxnOutputType(type));
return;
}

out.pushKV("reqSigs", nRequired);
out.pushKV("type", GetTxnOutputType(type));
out.pushKV(prefix + "reqSigs", nRequired);
out.pushKV(prefix + "type", GetTxnOutputType(type));

UniValue a(UniValue::VARR);
for (const CTxDestination& addr : addresses) {
a.push_back(EncodeDestination(addr));
if (is_parent_chain) {
for (const CTxDestination& addr : addresses) {
a.push_back(EncodeParentDestination(addr));
}
} else {
for (const CTxDestination& addr : addresses) {
a.push_back(EncodeDestination(addr));
}
}
out.pushKV(prefix + "addresses", a);
}

void ScriptPubKeyToUniv(const CScript& scriptPubKey,
UniValue& out, bool fIncludeHex)
{
SidechainScriptPubKeyToJSON(scriptPubKey, out, fIncludeHex, false);

uint256 pegout_chain;
CScript pegout_scriptpubkey;
if (scriptPubKey.IsPegoutScript(pegout_chain, pegout_scriptpubkey)) {
out.pushKV("pegout_chain", pegout_chain.GetHex());
SidechainScriptPubKeyToJSON(pegout_scriptpubkey, out, fIncludeHex, true);
}
out.pushKV("addresses", a);
}

void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags)
Expand Down
41 changes: 33 additions & 8 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
#include <core_io.h>
#include <index/txindex.h>
#include <keystore.h>
#include <validation.h>
#include <validationinterface.h>
#include <key_io.h>
#include <merkleblock.h>
#include <net.h>
Expand All @@ -27,6 +25,8 @@
#include <txmempool.h>
#include <uint256.h>
#include <utilstrencodings.h>
#include <validation.h>
#include <validationinterface.h>
#ifdef ENABLE_WALLET
#include <wallet/rpcwallet.h>
#endif
Expand Down Expand Up @@ -124,7 +124,12 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
" \"addresses\" : [ (json array of string)\n"
" \"address\" (string) bitcoin address\n"
" ,...\n"
" ]\n"
" ],\n"
" \"pegout_chain\" : \"hex\", (string) (only pegout) Hash of genesis block of parent chain'\n"
" \"pegout_asm\":\"asm\", (string) (only pegout) pegout scriptpubkey (asm)'\n"
" \"pegout_hex\":\"hex\", (string) (only pegout) pegout scriptpubkey (hex)'\n"
" \"pegout_type\" : \"pubkeyhash\", (string) (only pegout) The pegout type, eg 'pubkeyhash'\n"
" \"pegout_addresses\" : [ (json array of string) (only pegout)\n"
" }\n"
" }\n"
" ,...\n"
Expand Down Expand Up @@ -866,19 +871,34 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
// Script verification errors
UniValue vErrors(UniValue::VARR);

// ELEMENTS:
// Track an immature peg-in that's otherwise valid, give warning
bool immature_pegin = false;

// Use CTransaction for the constant parts of the
// transaction to avoid rehashing.
const CTransaction txConst(mtx);
// Sign what we can:
// Sign what we can, including pegin inputs:
for (unsigned int i = 0; i < mtx.vin.size(); i++) {
CTxIn& txin = mtx.vin[i];
const Coin& coin = view.AccessCoin(txin.prevout);
if (coin.IsSpent()) {

if (!txin.m_is_pegin && coin.IsSpent()) {
TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
continue;
} else if (txin.m_is_pegin && (!IsValidPeginWitness(txConst.vin[i].m_pegin_witness, txin.prevout, false))) {
TxInErrorToJSON(txin, vErrors, "Peg-in input has invalid proof.");
continue;
}
const CScript& prevPubKey = coin.out.scriptPubKey;
const CAmount& amount = coin.out.nValue;
// Report warning about immature peg-in though
if(txin.m_is_pegin && !IsValidPeginWitness(txConst.vin[i].m_pegin_witness, txin.prevout, true)) {
immature_pegin = true;
}

const CScript& prevPubKey = txin.m_is_pegin ? GetPeginOutputFromWitness(txConst.vin[i].m_pegin_witness).scriptPubKey : coin.out.scriptPubKey;
//TODO(rebase) CT
//const CConfidentialValue& amount = txin.m_is_pegin ? GetPeginOutputFromWitness(txConst.vin[i].m_pegin_witness).nValue : coin.out.nValue;
const CAmount& amount = txin.m_is_pegin ? GetPeginOutputFromWitness(txConst.vin[i].m_pegin_witness).nValue : coin.out.nValue;

SignatureData sigdata = DataFromTransaction(mtx, i, coin.out);
// Only sign SIGHASH_SINGLE if there's a corresponding output:
Expand Down Expand Up @@ -911,6 +931,9 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
if (!vErrors.empty()) {
result.pushKV("errors", vErrors);
}
if (immature_pegin) {
result.pushKV("warning", "Possibly immature peg-in input(s) detected, signed anyways.");
}

return result;
}
Expand Down Expand Up @@ -966,6 +989,7 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
" }\n"
" ,...\n"
" ]\n"
" \"warning\" : \"text\" (string) Warning that a peg-in input signed may be immature. This could mean lack of connectivity to or misconfiguration of the bitcoind."
"}\n"

"\nExamples:\n"
Expand Down Expand Up @@ -1052,6 +1076,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
" }\n"
" ,...\n"
" ]\n"
" \"warning\" : \"text\" (string) Warning that a peg-in input signed may be immature. This could mean lack of connectivity to or misconfiguration of the bitcoind."
"}\n"

"\nExamples:\n"
Expand Down Expand Up @@ -1094,7 +1119,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
}
}

static UniValue sendrawtransaction(const JSONRPCRequest& request)
UniValue sendrawtransaction(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
Expand Down
Loading

0 comments on commit 36d2ac3

Please sign in to comment.