From 0b485d3c6649c238630401715ded3dc0d829281b Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Tue, 22 May 2018 15:16:37 -0300 Subject: [PATCH] rpc methods for cross chain transactions --- src/crosschain.cpp | 31 +++++++++++++++++++++++++++ src/crosschain.h | 3 +-- src/importcoin.cpp | 1 + src/importcoin.h | 1 - src/rpcclient.cpp | 17 +++++++++++---- src/rpccrosschain.cpp | 33 ++++++++++------------------- src/rpcserver.cpp | 3 +++ src/rpcserver.h | 4 ++++ src/test-komodo/test_crosschain.cpp | 13 +++++++++--- 9 files changed, 74 insertions(+), 32 deletions(-) diff --git a/src/crosschain.cpp b/src/crosschain.cpp index b68b77b33..dc45e994c 100644 --- a/src/crosschain.cpp +++ b/src/crosschain.cpp @@ -1,9 +1,14 @@ #include "cc/eval.h" +#include "importcoin.h" #include "main.h" #include "notarisationdb.h" #include "komodo_structs.h" +/* + * This file is built in the server + */ + /* On KMD */ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeight, std::vector &moms, uint256 &destNotarisationTxid) @@ -123,6 +128,30 @@ cont: } +/* + * Takes an importTx that has proof leading to assetchain root + * and extends proof to cross chain root + */ +void CompleteImportTransaction(CTransaction &importTx) +{ + TxProof proof; + CTransaction burnTx; + std::vector payouts; + if (!UnmarshalImportTx(importTx, proof, burnTx, payouts)) + throw std::runtime_error("Couldn't parse importTx"); + + std::string targetSymbol; + uint32_t targetCCid; + uint256 payoutsHash; + if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCCid, payoutsHash)) + throw std::runtime_error("Couldn't parse burnTx"); + + proof = GetCrossChainProof(burnTx.GetHash(), targetSymbol.data(), targetCCid, proof); + + importTx = MakeImportCoinTransaction(proof, burnTx, importTx.vout); +} + + struct notarized_checkpoint *komodo_npptr_at(int idx); struct notarized_checkpoint *komodo_npptr_for_height(int32_t height, int *idx); @@ -236,3 +265,5 @@ TxProof GetAssetchainProof(uint256 hash) CDataStream ssProof(SER_NETWORK, PROTOCOL_VERSION); return std::make_pair(np->notarized_desttxid, MerkleBranch(nIndex, branch)); } + + diff --git a/src/crosschain.h b/src/crosschain.h index 64bacb759..15452ac63 100644 --- a/src/crosschain.h +++ b/src/crosschain.h @@ -10,10 +10,9 @@ TxProof GetAssetchainProof(uint256 hash); /* On KMD */ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeight, std::vector &moms, uint256 &destNotarisationTxid); - -/* On KMD */ TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_t targetCCid, const TxProof assetChainProof); +void CompleteImportTransaction(CTransaction &importTx); /* On assetchain */ bool GetNextBacknotarisation(uint256 txid, std::pair &bn); diff --git a/src/importcoin.cpp b/src/importcoin.cpp index bbada7e99..55717fc69 100644 --- a/src/importcoin.cpp +++ b/src/importcoin.cpp @@ -1,3 +1,4 @@ +#include "crosschain.h" #include "importcoin.h" #include "cc/utils.h" #include "coins.h" diff --git a/src/importcoin.h b/src/importcoin.h index 8e43f9376..f62bb45a1 100644 --- a/src/importcoin.h +++ b/src/importcoin.h @@ -21,7 +21,6 @@ bool UnmarshalImportTx(const CTransaction &importTx, TxProof &proof, CTransactio bool VerifyCoinImport(const CScript& scriptSig, TransactionSignatureChecker& checker, CValidationState &state); - void AddImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs, int nHeight); void RemoveImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs); int ExistsImportTombstone(const CTransaction &importTx, const CCoinsViewCache &inputs); diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index e421feb4c..f93dbbb0f 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -134,16 +134,25 @@ static const CRPCConvertParam vRPCConvertParams[] = { "paxprices", 3 }, { "paxpending", 0 }, { "notaries", 2 }, - { "height_MoM", 1 }, - { "MoMoMdata", 3 }, - { "txMoMproof", 1 }, { "minerids", 1 }, { "kvsearch", 1 }, { "kvupdate", 4 }, { "z_importkey", 2 }, { "z_importviewingkey", 2 }, { "z_getpaymentdisclosure", 1}, - { "z_getpaymentdisclosure", 2} + { "z_getpaymentdisclosure", 2}, + + // crosschain + { "assetchainproof", 1}, + { "crosschainproof", 1}, + { "getproofroot", 2}, + { "height_MoM", 1}, + { "MoMoMdata", 3}, + { "calc_MoM", 2}, + { "migrate_converttoexport", 3}, + { "migrate_createimporttransaction", 2}, + { "migrate_completeimporttransaction", 1} + }; class CRPCConvertTable diff --git a/src/rpccrosschain.cpp b/src/rpccrosschain.cpp index c66a805e7..b2414a651 100644 --- a/src/rpccrosschain.cpp +++ b/src/rpccrosschain.cpp @@ -164,12 +164,12 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( - "migrate_converttoexport \"hexstring\" \"dest_symbol\" \"burn_amount\"\n" + "migrate_converttoexport rawTx dest_symbol burn_amount\n" "\nConvert a raw transaction to a cross-chain export.\n" "If neccesary, the transaction should be funded using fundrawtransaction.\n" "Finally, the transaction should be signed using signrawtransaction\n" - "The finished export transaction, plus the vouts, should be passed to " - "the \"importtransaction\" method on a KMD node to get the corresponding " + "The finished export transaction, plus the payouts, should be passed to " + "the \"migrate_createimporttransaction\" method on a KMD node to get the corresponding " "import transaction.\n" ); @@ -199,7 +199,7 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp) CTxOut burnOut = MakeBurnOutput(burnAmount, ASSETCHAINS_CC, targetSymbol, tx.vout); UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("vouts", HexStr(E_MARSHAL(ss << tx.vout)))); + ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout)))); tx.vout.clear(); tx.vout.push_back(burnOut); ret.push_back(Pair("exportTx", HexStr(E_MARSHAL(ss << tx)))); @@ -224,7 +224,8 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp) UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) - throw runtime_error(""); + throw runtime_error("migrate_createimporttransaction burnTx payouts\n\n" + "Create an importTx given a burnTx and the corresponding payouts, hex encoded"); if (ASSETCHAINS_CC < 2) throw runtime_error("-ac_cc < 2"); @@ -254,30 +255,18 @@ UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp) UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) - throw runtime_error(""); + throw runtime_error("migrate_completeimporttransaction importTx\n\n" + "Takes a cross chain import tx with proof generated on assetchain " + "and extends proof to target chain proof root"); if (ASSETCHAINS_SYMBOL[0] != 0) throw runtime_error("Must be called on KMD"); CTransaction importTx; - if (!E_UNMARSHAL(ParseHexV(params[0], "argument 2"), ss >> importTx)) + if (!E_UNMARSHAL(ParseHexV(params[0], "argument 1"), ss >> importTx)) throw runtime_error("Couldn't parse importTx"); - TxProof proof; - CTransaction burnTx; - vector payouts; - if (!UnmarshalImportTx(importTx, proof, burnTx, payouts)) - throw runtime_error("Couldn't parse importTx data"); - - std::string targetSymbol; - uint32_t targetCCid; - uint256 payoutsHash; - if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCCid, payoutsHash)) - throw runtime_error("Couldn't parse burnTx data"); - - proof = GetCrossChainProof(burnTx.GetHash(), targetSymbol.data(), targetCCid, proof); - - importTx = MakeImportCoinTransaction(proof, burnTx, importTx.vout); + CompleteImportTransaction(importTx); return HexStr(E_MARSHAL(ss << importTx)); } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index cd579c83c..97b2bab1b 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -312,6 +312,9 @@ static const CRPCCommand vRPCCommands[] = { "crosschain", "height_MoM", &height_MoM, true }, { "crosschain", "assetchainproof", &assetchainproof, true }, { "crosschain", "crosschainproof", &crosschainproof, true }, + { "crosschain", "migrate_converttoexport", &migrate_converttoexport, true }, + { "crosschain", "migrate_createimporttransaction", &migrate_createimporttransaction, true }, + { "crosschain", "migrate_completeimporttransaction", &migrate_completeimporttransaction, true }, /* Mining */ { "mining", "getblocktemplate", &getblocktemplate, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 7d7ef5d7e..1f64d9d07 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -317,6 +317,10 @@ extern UniValue calc_MoM(const UniValue& params, bool fHelp); extern UniValue height_MoM(const UniValue& params, bool fHelp); extern UniValue assetchainproof(const UniValue& params, bool fHelp); extern UniValue crosschainproof(const UniValue& params, bool fHelp); +extern UniValue migrate_converttoexport(const UniValue& params, bool fHelp); +extern UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp); +extern UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp); + extern UniValue notaries(const UniValue& params, bool fHelp); extern UniValue minerids(const UniValue& params, bool fHelp); extern UniValue kvsearch(const UniValue& params, bool fHelp); diff --git a/src/test-komodo/test_crosschain.cpp b/src/test-komodo/test_crosschain.cpp index 6ff261247..356a7ab6c 100644 --- a/src/test-komodo/test_crosschain.cpp +++ b/src/test-komodo/test_crosschain.cpp @@ -133,7 +133,7 @@ TEST_F(TestCrossChain, testCreateAndValidateImportProof) } /* - * Generate proof + * Test a proof */ uint256 txid = blocks[7].vtx[0].GetHash(); TxProof proof = GetAssetchainProof(txid); @@ -141,8 +141,15 @@ TEST_F(TestCrossChain, testCreateAndValidateImportProof) E_UNMARSHAL(RecvIPC(), ss >> proof); std::pair bn; - if (!GetNextBacknotarisation(proof.first, bn)) return 1; - return proof.second.Exec(txid) == bn.second.MoMoM ? 0 : 1; + if (!GetNextBacknotarisation(proof.first, bn)) { + printf("GetNextBackNotarisation failed\n"); + return 1; + } + if (proof.second.Exec(txid) != bn.second.MoMoM) { + printf("MoMom incorrect\n"); + return 1; + } + return 0; }; auto RunTestKmd = [&] ()