fix MoM hash calculation
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user