From c7bcf05da45c7276b5dfe03ea3b49b13c7bb20fa Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Wed, 30 May 2018 18:12:05 -0300 Subject: [PATCH] fix MoM hash calculation --- src/crosschain.cpp | 20 ++++++++++-------- src/komodo_ccdata.h | 45 ++++++++-------------------------------- src/primitives/block.cpp | 15 ++++++++++---- src/primitives/block.h | 2 ++ src/rpcclient.cpp | 4 ---- src/rpccrosschain.cpp | 15 +++++++------- 6 files changed, 41 insertions(+), 60 deletions(-) diff --git a/src/crosschain.cpp b/src/crosschain.cpp index dc45e994c..0e9861cf8 100644 --- a/src/crosschain.cpp +++ b/src/crosschain.cpp @@ -182,6 +182,8 @@ struct notarized_checkpoint* komodo_npptr(int32_t height); int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); +uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth); + /* * On assetchain * in: txid @@ -210,20 +212,20 @@ TxProof GetAssetchainProof(uint256 hash) // build merkle chain from blocks to MoM { - // since the merkle branch code is tied up in a block class - // and we want to make a merkle branch for something that isnt transactions - CBlock fakeBlock; + std::vector leaves, tree; for (int i=0; iMoMdepth; i++) { uint256 mRoot = chainActive[np->notarized_height - i]->hashMerkleRoot; - CTransaction fakeTx; - // first value in CTransaction memory is it's hash - memcpy((void*)&fakeTx, mRoot.begin(), 32); - fakeBlock.vtx.push_back(fakeTx); + leaves.push_back(mRoot); } - branch = fakeBlock.GetMerkleBranch(nIndex); + bool fMutated; + BuildMerkleTree(&fMutated, leaves, tree); + branch = GetMerkleBranch(nIndex, leaves.size(), tree); // Check branch - if (np->MoM != CBlock::CheckMerkleBranch(blockIndex->hashMerkleRoot, branch, nIndex)) + uint256 komodoGets = komodo_calcMoM(np->notarized_height, np->MoMdepth); + uint256 ourResult = SafeCheckMerkleBranch(blockIndex->hashMerkleRoot, branch, nIndex); + printf("Komodo gets:%s, we get:%s\n", komodoGets.GetHex().data(), ourResult.GetHex().data()); + if (np->MoM != ourResult) throw std::runtime_error("Failed merkle block->MoM"); } diff --git a/src/komodo_ccdata.h b/src/komodo_ccdata.h index 058e38cee..637d13557 100644 --- a/src/komodo_ccdata.h +++ b/src/komodo_ccdata.h @@ -19,53 +19,28 @@ struct komodo_ccdata *CC_data; int32_t CC_firstheight; -bits256 iguana_merkle(bits256 *tree,int32_t txn_count) -{ - int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; - if ( txn_count == 1 ) - return(tree[0]); - prev = 0; - while ( txn_count > 1 ) - { - if ( (txn_count & 1) != 0 ) - tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; - n += txn_count; - for (i=0; i> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized)); - } - prev = n; - txn_count >>= 1; - } - return(tree[n]); -} +uint256 BuildMerkleTree(bool* fMutated, const std::vector leaves, std::vector &vMerkleTree); uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth) { - static uint256 zero; bits256 MoM,*tree; CBlockIndex *pindex; int32_t i; + static uint256 zero; CBlockIndex *pindex; int32_t i; std::vector tree, leaves; + bool fMutated; if ( MoMdepth >= height ) return(zero); - tree = (bits256 *)calloc(MoMdepth * 3,sizeof(*tree)); for (i=0; ihashMerkleRoot,sizeof(bits256)); + leaves.push_back(pindex->hashMerkleRoot); else - { - free(tree); return(zero); - } } - MoM = iguana_merkle(tree,MoMdepth); - free(tree); - return(*(uint256 *)&MoM); + return BuildMerkleTree(&fMutated, leaves, tree); } struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi) { - struct komodo_ccdata_entry *allMoMs=0; bits256 *tree,tmp; struct komodo_ccdata *ccdata,*tmpptr; int32_t i,num,max; + struct komodo_ccdata_entry *allMoMs=0; struct komodo_ccdata *ccdata,*tmpptr; int32_t i,num,max; + bool fMutated; std::vector tree, leaves; num = max = 0; portable_mutex_lock(&KOMODO_CC_mutex); DL_FOREACH_SAFE(CC_data,ccdata,tmpptr) @@ -90,11 +65,9 @@ struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t portable_mutex_unlock(&KOMODO_CC_mutex); if ( (*nump= num) > 0 ) { - tree = (bits256 *)calloc(sizeof(bits256),num*3); for (i=0; i CBlock::GetMerkleBranch(int nIndex) const +std::vector GetMerkleBranch(int nIndex, int nLeaves, const std::vector &vMerkleTree) { - if (vMerkleTree.empty()) - BuildMerkleTree(); std::vector vMerkleBranch; int j = 0; - for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + for (int nSize = nLeaves; nSize > 1; nSize = (nSize + 1) / 2) { int i = std::min(nIndex^1, nSize-1); vMerkleBranch.push_back(vMerkleTree[j+i]); @@ -106,6 +104,15 @@ std::vector CBlock::GetMerkleBranch(int nIndex) const return vMerkleBranch; } + +std::vector CBlock::GetMerkleBranch(int nIndex) const +{ + if (vMerkleTree.empty()) + BuildMerkleTree(); + return ::GetMerkleBranch(nIndex, vtx.size(), vMerkleTree); +} + + uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, int nIndex) { if (nIndex == -1) diff --git a/src/primitives/block.h b/src/primitives/block.h index 2d3c0cfe4..6bc06f426 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -142,6 +142,8 @@ public: uint256 BuildMerkleTree(bool* fMutated, const std::vector leaves, std::vector &vMerkleTree); +std::vector GetMerkleBranch(int nIndex, int nLeaves, const std::vector &vMerkleTree); + /** * Custom serializer for CBlockHeader that omits the nonce and solution, for use diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index f93dbbb0f..e84e9085c 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -149,10 +149,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "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 3aed3a2bb..a4b0cb503 100644 --- a/src/rpccrosschain.cpp +++ b/src/rpccrosschain.cpp @@ -145,7 +145,7 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( - "migrate_converttoexport rawTx dest_symbol burn_amount\n" + "migrate_converttoexport rawTx dest_symbol export_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" @@ -169,13 +169,14 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp) if (targetSymbol.size() == 0 || targetSymbol.size() > 32) throw runtime_error("targetSymbol length must be >0 and <=32"); - CAmount burnAmount = params[2].get_int64(); + CAmount burnAmount = AmountFromValue(params[2]); + if (burnAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for export"); { - CAmount needed; - for (int i=0; i payouts; - if (!E_UNMARSHAL(ParseHexV(params[0], "argument 2"), ss >> payouts)) + if (!E_UNMARSHAL(ParseHexV(params[1], "argument 2"), ss >> payouts)) throw runtime_error("Couldn't parse payouts"); uint256 txid = burnTx.GetHash();