cross chain rpc methods

This commit is contained in:
Scott Sadler
2018-05-18 19:29:33 -03:00
parent 06c960d2b7
commit e4f943d86d
18 changed files with 264 additions and 305 deletions

View File

@@ -5,29 +5,33 @@
/* On KMD */
uint256 GetProofRoot(char* symbol, uint32_t targetCCid, int kmdHeight, std::vector<uint256> &moms, int* assetChainHeight)
uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeight,
std::vector<uint256> &moms, uint256 &destNotarisationTxid)
{
/*
* Notaries don't wait for confirmation on KMD before performing a backnotarisation,
* but we need a determinable range that will encompass all merkle roots. Include MoMs
* including the block height of the last notarisation until the height before the
* previous notarisation.
*
* kmdHeight notarisations-0 notarisations-1
* | |********************|
* > scan backwards >
*/
*assetChainHeight = -1;
if (targetCCid <= 1)
return uint256();
int seenOwnNotarisations = 0;
if (kmdHeight < 0 || kmdHeight > chainActive.Height())
return uint256();
// TODO: test height out of range
// TODO: Make sure that boundary for moms is notarisation tx not block
int seenOwnNotarisations = 0;
for (int i=0; i<1440; i++) {
if (i > kmdHeight) break;
NotarisationsInBlock notarisations;
uint256 blockHash = *chainActive[kmdHeight-i]->phashBlock;
if (!pnotarisations->Read(blockHash, notarisations))
if (!GetBlockNotarisations(blockHash, notarisations))
continue;
BOOST_FOREACH(Notarisation& nota, notarisations) {
NotarisationData& data = nota.second;
@@ -36,32 +40,24 @@ uint256 GetProofRoot(char* symbol, uint32_t targetCCid, int kmdHeight, std::vect
if (strcmp(data.symbol, symbol) == 0)
{
seenOwnNotarisations++;
printf("seenOwnNotarisations:%i\n", seenOwnNotarisations);
if (seenOwnNotarisations == 2)
goto end;
if (seenOwnNotarisations == 1)
*assetChainHeight = data.height; // TODO: Needed?
destNotarisationTxid = nota.first;
}
if (seenOwnNotarisations == 1) {
if (seenOwnNotarisations == 1)
moms.push_back(data.MoM);
printf("Pushed a MoM@%i:%s\n", kmdHeight-i, data.MoM.GetHex().data());
}
}
}
end:
printf("GetProofRoot {\n");
printf(" CC:%i S:%s H:%i\n", targetCCid, symbol, kmdHeight);
for (int i=0; i<moms.size(); i++) printf(" %s", moms[i].GetHex().data());
printf("\n R:%s\n", GetMerkleRoot(moms).GetHex().data());
printf("}\n");
return GetMerkleRoot(moms);
}
/* On KMD */
MerkleBranch GetCrossChainProof(uint256 txid, char* targetSymbol,
uint32_t targetCCid, uint256 notarisationTxid, MerkleBranch assetChainProof)
TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_t targetCCid,
const TxProof assetChainProof)
{
/*
* Here we are given a proof generated by an assetchain A which goes from given txid to
@@ -70,7 +66,7 @@ MerkleBranch GetCrossChainProof(uint256 txid, char* targetSymbol,
* that range, and finally extend the proof to lead to the MoMoM (proof root).
*/
EvalRef eval;
uint256 MoM = assetChainProof.Exec(txid);
uint256 MoM = assetChainProof.second.Exec(txid);
// Get a kmd height for given notarisation Txid
int kmdHeight;
@@ -78,9 +74,9 @@ MerkleBranch GetCrossChainProof(uint256 txid, char* targetSymbol,
CTransaction sourceNotarisation;
uint256 hashBlock;
CBlockIndex blockIdx;
if (eval->GetTxConfirmed(notarisationTxid, sourceNotarisation, blockIdx))
if (eval->GetTxConfirmed(assetChainProof.first, sourceNotarisation, blockIdx))
kmdHeight = blockIdx.nHeight;
else if (eval->GetTxUnconfirmed(notarisationTxid, sourceNotarisation, hashBlock))
else if (eval->GetTxUnconfirmed(assetChainProof.first, sourceNotarisation, hashBlock))
kmdHeight = chainActive.Tip()->nHeight;
else
throw std::runtime_error("Notarisation not found");
@@ -88,16 +84,14 @@ MerkleBranch GetCrossChainProof(uint256 txid, char* targetSymbol,
// Get MoMs for kmd height and symbol
std::vector<uint256> moms;
int targetChainStartHeight;
printf("Getting Proof Root\n");
uint256 MoMoM = GetProofRoot(targetSymbol, targetCCid, kmdHeight, moms, &targetChainStartHeight);
uint256 targetChainNotarisationTxid;
uint256 MoMoM = CalculateProofRoot(targetSymbol, targetCCid, kmdHeight, moms, targetChainNotarisationTxid);
if (MoMoM.IsNull())
throw std::runtime_error("No MoMs found");
// Find index of source MoM in MoMoM
int nIndex;
for (nIndex=0; nIndex<moms.size(); nIndex++) {
printf("findMoM: %s == %s\n", moms[nIndex].GetHex().data(), MoM.GetHex().data());
if (moms[nIndex] == MoM)
goto cont;
}
@@ -105,7 +99,7 @@ MerkleBranch GetCrossChainProof(uint256 txid, char* targetSymbol,
cont:
// Create a branch
std::vector<uint256> newBranch;
std::vector<uint256> vBranch;
{
CBlock fakeBlock;
for (int i=0; i<moms.size(); i++) {
@@ -114,39 +108,48 @@ cont:
memcpy((void*)&fakeTx, moms[i].begin(), 32);
fakeBlock.vtx.push_back(fakeTx);
}
newBranch = fakeBlock.GetMerkleBranch(nIndex);
vBranch = fakeBlock.GetMerkleBranch(nIndex);
}
// Concatenate branches
MerkleBranch newProof = assetChainProof;
newProof << MerkleBranch(nIndex, newBranch);
MerkleBranch newBranch = assetChainProof.second;
newBranch << MerkleBranch(nIndex, vBranch);
// Check proof
printf("GetCrossChainProof {\n txid: %s\n momom: %s\n", txid.GetHex().data(), MoMoM.GetHex().data());
printf(" idx: %i\n", newProof.nIndex);
for (int i=0; i<newProof.branch.size(); i++) printf(" %s", newProof.branch[i].GetHex().data());
printf("\n}\n");
if (newProof.Exec(txid) != MoMoM)
if (newBranch.Exec(txid) != MoMoM)
throw std::runtime_error("Proof check failed");
return newProof;
return std::make_pair(targetChainNotarisationTxid,newBranch);
}
struct notarized_checkpoint *komodo_npptr_at(int idx);
struct notarized_checkpoint *komodo_npptr_for_height(int32_t height, int *idx);
/* On assetchain */
bool ValidateCrossChainProof(uint256 txid, int notarisationHeight, MerkleBranch proof)
bool GetNextBacknotarisation(uint256 kmdNotarisationTxid, std::pair<uint256,NotarisationData> &out)
{
/*
* Here we are given a notarisation txid, and a proof.
* We go from the notarisation to get the backnotarisation, and verify the proof
* against the MoMoM it contains.
* Here we are given a txid, and a proof.
* We go from the KMD notarisation txid to the backnotarisation,
* then jump to the next backnotarisation, which contains the corresponding MoMoM.
*/
Notarisation bn;
if (!GetBackNotarisation(kmdNotarisationTxid, bn))
return false;
int npIdx;
struct notarized_checkpoint* np = komodo_npptr_for_height(bn.second.height, &npIdx);
if (!(np = komodo_npptr_at(npIdx+1)))
return false;
return GetBackNotarisation(np->notarized_desttxid, out);
throw std::runtime_error("Can't get backnotarisation");
}
struct notarized_checkpoint* komodo_npptr_for_height(int32_t height, int *idx);
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);
@@ -155,7 +158,7 @@ int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_
* in: txid
* out: pair<notarisationTxHash,merkleBranch>
*/
std::pair<uint256,MerkleBranch> GetAssetchainProof(uint256 hash, int &npIdx)
TxProof GetAssetchainProof(uint256 hash)
{
int nIndex;
CBlockIndex* blockIndex;
@@ -169,11 +172,10 @@ std::pair<uint256,MerkleBranch> GetAssetchainProof(uint256 hash, int &npIdx)
throw std::runtime_error("cannot find transaction");
blockIndex = mapBlockIndex[blockHash];
if (!(np = komodo_npptr_for_height(blockIndex->nHeight, &npIdx)))
if (!(np = komodo_npptr(blockIndex->nHeight)))
throw std::runtime_error("notarisation not found");
// index of block in MoM leaves
printf("notarised at: %i\n", np->notarized_height);
nIndex = np->notarized_height - blockIndex->nHeight;
}