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);
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<uint256> leaves, tree;
for (int i=0; i<np->MoMdepth; 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");
}

View File

@@ -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<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 BuildMerkleTree(bool* fMutated, const std::vector<uint256> leaves, std::vector<uint256> &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<uint256> tree, leaves;
bool fMutated;
if ( MoMdepth >= height )
return(zero);
tree = (bits256 *)calloc(MoMdepth * 3,sizeof(*tree));
for (i=0; i<MoMdepth; i++)
{
if ( (pindex= komodo_chainactive(height - i)) != 0 )
memcpy(&tree[i],&pindex->hashMerkleRoot,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<uint256> 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<num; i++)
memcpy(&tree[i],&allMoMs[i].MoM,sizeof(tree[i]));
tmp = iguana_merkle(tree,num);
memcpy(MoMoMp,&tmp,sizeof(*MoMoMp));
leaves.push_back(allMoMs[i].MoM);
*MoMoMp = BuildMerkleTree(&fMutated, leaves, tree);
}
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;
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<uint256> CBlock::GetMerkleBranch(int nIndex) const
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)
{
if (nIndex == -1)

View File

@@ -142,6 +142,8 @@ public:
uint256 BuildMerkleTree(bool* fMutated, const std::vector<uint256> leaves,
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

View File

@@ -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

View File

@@ -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<tx.vout.size(); i++)
needed += tx.vout[i].nValue;
CAmount needed = 0;
for (int i=0; i<tx.vout.size(); i++) needed += tx.vout[i].nValue;
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);
@@ -222,7 +223,7 @@ UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp)
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");
uint256 txid = burnTx.GetHash();