fix MoM hash calculation

This commit is contained in:
Scott Sadler
2018-05-30 18:12:05 -03:00
parent 81389fc7b4
commit c7bcf05da4
6 changed files with 41 additions and 60 deletions

View File

@@ -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); 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 * On assetchain
* in: txid * in: txid
@@ -210,20 +212,20 @@ TxProof GetAssetchainProof(uint256 hash)
// build merkle chain from blocks to MoM // build merkle chain from blocks to MoM
{ {
// since the merkle branch code is tied up in a block class std::vector<uint256> leaves, tree;
// and we want to make a merkle branch for something that isnt transactions
CBlock fakeBlock;
for (int i=0; i<np->MoMdepth; i++) { for (int i=0; i<np->MoMdepth; i++) {
uint256 mRoot = chainActive[np->notarized_height - i]->hashMerkleRoot; uint256 mRoot = chainActive[np->notarized_height - i]->hashMerkleRoot;
CTransaction fakeTx; leaves.push_back(mRoot);
// first value in CTransaction memory is it's hash
memcpy((void*)&fakeTx, mRoot.begin(), 32);
fakeBlock.vtx.push_back(fakeTx);
} }
branch = fakeBlock.GetMerkleBranch(nIndex); bool fMutated;
BuildMerkleTree(&fMutated, leaves, tree);
branch = GetMerkleBranch(nIndex, leaves.size(), tree);
// Check branch // 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"); throw std::runtime_error("Failed merkle block->MoM");
} }

View File

@@ -19,53 +19,28 @@
struct komodo_ccdata *CC_data; struct komodo_ccdata *CC_data;
int32_t CC_firstheight; int32_t CC_firstheight;
bits256 iguana_merkle(bits256 *tree,int32_t txn_count) uint256 BuildMerkleTree(bool* fMutated, const std::vector<uint256> leaves, std::vector<uint256> &vMerkleTree);
{
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<txn_count; i+=2)
{
iguana_rwbignum(1,serialized,sizeof(*tree),tree[prev + i].bytes);
iguana_rwbignum(1,&serialized[sizeof(*tree)],sizeof(*tree),tree[prev + i + 1].bytes);
tree[n + (i >> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized));
}
prev = n;
txn_count >>= 1;
}
return(tree[n]);
}
uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth) 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<uint256> tree, leaves;
bool fMutated;
if ( MoMdepth >= height ) if ( MoMdepth >= height )
return(zero); return(zero);
tree = (bits256 *)calloc(MoMdepth * 3,sizeof(*tree));
for (i=0; i<MoMdepth; i++) for (i=0; i<MoMdepth; i++)
{ {
if ( (pindex= komodo_chainactive(height - i)) != 0 ) if ( (pindex= komodo_chainactive(height - i)) != 0 )
memcpy(&tree[i],&pindex->hashMerkleRoot,sizeof(bits256)); leaves.push_back(pindex->hashMerkleRoot);
else else
{
free(tree);
return(zero); return(zero);
}
} }
MoM = iguana_merkle(tree,MoMdepth); return BuildMerkleTree(&fMutated, leaves, tree);
free(tree);
return(*(uint256 *)&MoM);
} }
struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi) 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<uint256> tree, leaves;
num = max = 0; num = max = 0;
portable_mutex_lock(&KOMODO_CC_mutex); portable_mutex_lock(&KOMODO_CC_mutex);
DL_FOREACH_SAFE(CC_data,ccdata,tmpptr) 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); portable_mutex_unlock(&KOMODO_CC_mutex);
if ( (*nump= num) > 0 ) if ( (*nump= num) > 0 )
{ {
tree = (bits256 *)calloc(sizeof(bits256),num*3);
for (i=0; i<num; i++) for (i=0; i<num; i++)
memcpy(&tree[i],&allMoMs[i].MoM,sizeof(tree[i])); leaves.push_back(allMoMs[i].MoM);
tmp = iguana_merkle(tree,num); *MoMoMp = BuildMerkleTree(&fMutated, leaves, tree);
memcpy(MoMoMp,&tmp,sizeof(*MoMoMp));
} }
else else
{ {

View File

@@ -90,13 +90,11 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const
} }
std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const std::vector<uint256> GetMerkleBranch(int nIndex, int nLeaves, const std::vector<uint256> &vMerkleTree)
{ {
if (vMerkleTree.empty())
BuildMerkleTree();
std::vector<uint256> vMerkleBranch; std::vector<uint256> vMerkleBranch;
int j = 0; 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); int i = std::min(nIndex^1, nSize-1);
vMerkleBranch.push_back(vMerkleTree[j+i]); vMerkleBranch.push_back(vMerkleTree[j+i]);
@@ -106,6 +104,15 @@ std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
return vMerkleBranch; return vMerkleBranch;
} }
std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
{
if (vMerkleTree.empty())
BuildMerkleTree();
return ::GetMerkleBranch(nIndex, vtx.size(), vMerkleTree);
}
uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex) uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{ {
if (nIndex == -1) if (nIndex == -1)

View File

@@ -142,6 +142,8 @@ public:
uint256 BuildMerkleTree(bool* fMutated, const std::vector<uint256> leaves, uint256 BuildMerkleTree(bool* fMutated, const std::vector<uint256> leaves,
std::vector<uint256> &vMerkleTree); std::vector<uint256> &vMerkleTree);
std::vector<uint256> GetMerkleBranch(int nIndex, int nLeaves, const std::vector<uint256> &vMerkleTree);
/** /**
* Custom serializer for CBlockHeader that omits the nonce and solution, for use * Custom serializer for CBlockHeader that omits the nonce and solution, for use

View File

@@ -149,10 +149,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "height_MoM", 1}, { "height_MoM", 1},
{ "MoMoMdata", 3}, { "MoMoMdata", 3},
{ "calc_MoM", 2}, { "calc_MoM", 2},
{ "migrate_converttoexport", 3},
{ "migrate_createimporttransaction", 2},
{ "migrate_completeimporttransaction", 1}
}; };
class CRPCConvertTable class CRPCConvertTable

View File

@@ -145,7 +145,7 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp)
{ {
if (fHelp || params.size() != 3) if (fHelp || params.size() != 3)
throw runtime_error( 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" "\nConvert a raw transaction to a cross-chain export.\n"
"If neccesary, the transaction should be funded using fundrawtransaction.\n" "If neccesary, the transaction should be funded using fundrawtransaction.\n"
"Finally, the transaction should be signed using signrawtransaction\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) if (targetSymbol.size() == 0 || targetSymbol.size() > 32)
throw runtime_error("targetSymbol length must be >0 and <=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; CAmount needed = 0;
for (int i=0; i<tx.vout.size(); i++) for (int i=0; i<tx.vout.size(); i++) needed += tx.vout[i].nValue;
needed += tx.vout[i].nValue;
if (burnAmount < needed) if (burnAmount < needed)
throw runtime_error("burnAmount too small"); throw runtime_error("export_amount too small");
} }
CTxOut burnOut = MakeBurnOutput(burnAmount, ASSETCHAINS_CC, targetSymbol, tx.vout); CTxOut burnOut = MakeBurnOutput(burnAmount, ASSETCHAINS_CC, targetSymbol, tx.vout);
@@ -222,7 +223,7 @@ UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp)
vector<CTxOut> payouts; vector<CTxOut> 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"); throw runtime_error("Couldn't parse payouts");
uint256 txid = burnTx.GetHash(); uint256 txid = burnTx.GetHash();