rework selfimport
This commit is contained in:
@@ -31,9 +31,12 @@
|
|||||||
|
|
||||||
extern std::string ASSETCHAINS_SELFIMPORT;
|
extern std::string ASSETCHAINS_SELFIMPORT;
|
||||||
extern uint16_t ASSETCHAINS_CODAPORT,ASSETCHAINS_BEAMPORT;
|
extern uint16_t ASSETCHAINS_CODAPORT,ASSETCHAINS_BEAMPORT;
|
||||||
|
int32_t komodo_nextheight();
|
||||||
|
|
||||||
int32_t GetSelfimportProof(TxProof &proof,CTransaction burnTx,uint256 hash) // find burnTx with hash from "other" daemon
|
int32_t GetSelfimportProof(CMutableTransaction &mtx,CScript &scriptPubKey,TxProof &proof,uint64_t burnAmount,std::vector<uint8_t> rawtx,uint256 hash,std::vector<uint8_t> rawproof) // find burnTx with hash from "other" daemon
|
||||||
{
|
{
|
||||||
|
MerkleBranch newBranch; CMutableTransaction &tmpmtx; CTransaction tx,vintx; uint256 blockHash; char destaddr[64],pkaddr[64];
|
||||||
|
tmpmtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),komodo_nextheight());
|
||||||
if ( ASSETCHAINS_SELFIMPORT == "BEAM" )
|
if ( ASSETCHAINS_SELFIMPORT == "BEAM" )
|
||||||
{
|
{
|
||||||
// confirm via ASSETCHAINS_BEAMPORT that burnTx/hash is a valid BEAM burn
|
// confirm via ASSETCHAINS_BEAMPORT that burnTx/hash is a valid BEAM burn
|
||||||
@@ -44,15 +47,45 @@ int32_t GetSelfimportProof(TxProof &proof,CTransaction burnTx,uint256 hash) // f
|
|||||||
// confirm via ASSETCHAINS_CODAPORT that burnTx/hash is a valid CODA burn
|
// confirm via ASSETCHAINS_CODAPORT that burnTx/hash is a valid CODA burn
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
else if ( ASSETCHAINS_SELFIMPORT == "PUBKEY" )
|
else
|
||||||
{
|
{
|
||||||
// make sure vin0 is signed by ASSETCHAINS_OVERRIDE_PUBKEY33
|
if ( !E_UNMARSHAL(rawtx, ss >> tx) )
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
else if ( ASSETCHAINS_SELFIMPORT == "GATEWAY" )
|
|
||||||
{
|
|
||||||
// external coin is the assetchains symbol in the burnTx OP_RETURN
|
|
||||||
return(-1);
|
return(-1);
|
||||||
|
scriptPubKey = tx.vout[0].scriptPubKey;
|
||||||
|
mtx = tx;
|
||||||
|
mtx.fOverwintered = tmptx.fOverwintered;
|
||||||
|
mtx.nExpiryHeight = tmptx.nExpiryHeight;
|
||||||
|
mtx.nVersionGroupId = tmptx.nVersionGroupId;
|
||||||
|
mtx.nVersion = tmptx.nVersion;
|
||||||
|
mtx.vout.clear();
|
||||||
|
mtx.vout.resize(1);
|
||||||
|
mtx.vout[0].nValue = burnAmount;
|
||||||
|
mtx.vout[0].scriptPubKey = scriptPubKey;
|
||||||
|
if ( tx.GetHash() != txid )
|
||||||
|
return(-1);
|
||||||
|
if ( ASSETCHAINS_SELFIMPORT == "PUBKEY" )
|
||||||
|
{
|
||||||
|
// make sure vin0 is signed by ASSETCHAINS_OVERRIDE_PUBKEY33
|
||||||
|
if ( GetTransaction(tx.vin[0].prevout,vintx,blockHash,false) == 0 )
|
||||||
|
return(-1);
|
||||||
|
if ( tx.vin[0].prevn < vintx.vout.size() && Getscriptaddress(destaddr,vintx.vout[tx.vin[0].prevn].scriptPubKey) != 0 )
|
||||||
|
{
|
||||||
|
pubkey2addr(pkaddr,ASSETCHAINS_OVERRIDE_PUBKEY33.data());
|
||||||
|
if ( strcmp(pkaddr,destaddr) == 0 )
|
||||||
|
{
|
||||||
|
proof = std::make_pair(txid,newBranch);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
fprintf(stderr,"vin0[%d] -> %s vs %s\n",tx.vin[0].prevn,destaddr,pkaddr);
|
||||||
|
}
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ASSETCHAINS_SELFIMPORT and external coin is the assetchains symbol in the burnTx OP_RETURN
|
||||||
|
// burnAmount, rawtx and rawproof should be enough for gatewaysdeposit equivalent
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else return(-1);
|
else return(-1);
|
||||||
return(0);
|
return(0);
|
||||||
@@ -81,20 +114,18 @@ int32_t CheckGATEWAYimport(std::string coin,TxProof proof,CTransaction burnTx,st
|
|||||||
int32_t CheckPUBKEYimport(TxProof proof,CTransaction burnTx,std::vector<CTxOut> payouts)
|
int32_t CheckPUBKEYimport(TxProof proof,CTransaction burnTx,std::vector<CTxOut> payouts)
|
||||||
{
|
{
|
||||||
// if burnTx has ASSETCHAINS_PUBKEY vin, it is valid return(0);
|
// if burnTx has ASSETCHAINS_PUBKEY vin, it is valid return(0);
|
||||||
|
fprintf(stderr,"proof txid.%s\n",proof.first.GetHex().ToString().c_str());
|
||||||
return(0);
|
return(0);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn)
|
bool Eval::ImportCoin(const std::vector<uint8_t> params,const CTransaction &importTx,unsigned int nIn)
|
||||||
{
|
{
|
||||||
|
TxProof proof; CTransaction burnTx; std::vector<CTxOut> payouts; uint64_t txfee = 10000;
|
||||||
|
uint32_t targetCcid; std::string targetSymbol; uint256 payoutsHash;
|
||||||
if (importTx.vout.size() < 2)
|
if (importTx.vout.size() < 2)
|
||||||
return Invalid("too-few-vouts");
|
return Invalid("too-few-vouts");
|
||||||
|
|
||||||
// params
|
// params
|
||||||
TxProof proof;
|
|
||||||
CTransaction burnTx;
|
|
||||||
std::vector<CTxOut> payouts;
|
|
||||||
|
|
||||||
if (!UnmarshalImportTx(importTx, proof, burnTx, payouts))
|
if (!UnmarshalImportTx(importTx, proof, burnTx, payouts))
|
||||||
return Invalid("invalid-params");
|
return Invalid("invalid-params");
|
||||||
|
|
||||||
@@ -102,15 +133,9 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
|
|||||||
// It should not be at all malleable
|
// It should not be at all malleable
|
||||||
if (MakeImportCoinTransaction(proof, burnTx, payouts).GetHash() != importTx.GetHash())
|
if (MakeImportCoinTransaction(proof, burnTx, payouts).GetHash() != importTx.GetHash())
|
||||||
return Invalid("non-canonical");
|
return Invalid("non-canonical");
|
||||||
|
|
||||||
// burn params
|
// burn params
|
||||||
uint32_t targetCcid;
|
|
||||||
std::string targetSymbol;
|
|
||||||
uint256 payoutsHash;
|
|
||||||
|
|
||||||
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash))
|
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash))
|
||||||
return Invalid("invalid-burn-tx");
|
return Invalid("invalid-burn-tx");
|
||||||
|
|
||||||
// check burn amount
|
// check burn amount
|
||||||
{
|
{
|
||||||
uint64_t burnAmount = burnTx.vout.back().nValue;
|
uint64_t burnAmount = burnTx.vout.back().nValue;
|
||||||
@@ -119,27 +144,24 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
|
|||||||
uint64_t totalOut = 0;
|
uint64_t totalOut = 0;
|
||||||
for (int i=0; i<importTx.vout.size(); i++)
|
for (int i=0; i<importTx.vout.size(); i++)
|
||||||
totalOut += importTx.vout[i].nValue;
|
totalOut += importTx.vout[i].nValue;
|
||||||
if (totalOut > burnAmount)
|
if (totalOut > burnAmount || totalOut < burnAmount-txfee )
|
||||||
return Invalid("payout-too-high");
|
return Invalid("payout-too-high");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check burntx shows correct outputs hash
|
// Check burntx shows correct outputs hash
|
||||||
if (payoutsHash != SerializeHash(payouts))
|
if (payoutsHash != SerializeHash(payouts))
|
||||||
return Invalid("wrong-payouts");
|
return Invalid("wrong-payouts");
|
||||||
|
|
||||||
if (targetCcid < KOMODO_FIRSTFUNGIBLEID)
|
if (targetCcid < KOMODO_FIRSTFUNGIBLEID)
|
||||||
return Invalid("chain-not-fungible");
|
return Invalid("chain-not-fungible");
|
||||||
|
|
||||||
// Check proof confirms existance of burnTx
|
// Check proof confirms existance of burnTx
|
||||||
if ( targetCcid != 0xffffffff )
|
if ( targetCcid != 0xffffffff )
|
||||||
{
|
{
|
||||||
if (targetCcid != GetAssetchainsCC() || targetSymbol != GetAssetchainsSymbol())
|
if ( targetCcid != GetAssetchainsCC() || targetSymbol != GetAssetchainsSymbol() )
|
||||||
return Invalid("importcoin-wrong-chain");
|
return Invalid("importcoin-wrong-chain");
|
||||||
uint256 target = proof.second.Exec(burnTx.GetHash());
|
uint256 target = proof.second.Exec(burnTx.GetHash());
|
||||||
if (!CheckMoMoM(proof.first, target))
|
if (!CheckMoMoM(proof.first, target))
|
||||||
return Invalid("momom-check-fail");
|
return Invalid("momom-check-fail");
|
||||||
}
|
}
|
||||||
else if ( ASSETCHAINS_SELFIMPORT == targetSymbol || ASSETCHAINS_SELFIMPORT == "GATEWAY" ) // various selfchain imports
|
else if ( ASSETCHAINS_SELFIMPORT == targetSymbol ) // various selfchain imports
|
||||||
{
|
{
|
||||||
if ( ASSETCHAINS_SELFIMPORT == "BEAM" )
|
if ( ASSETCHAINS_SELFIMPORT == "BEAM" )
|
||||||
{
|
{
|
||||||
@@ -158,7 +180,7 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( CheckGATEWAYimport(GetAssetchainsSymbol(),proof,burnTx,payouts) < 0 )
|
if ( CheckGATEWAYimport(targetSymbol,proof,burnTx,payouts) < 0 )
|
||||||
return Invalid("GATEWAY-import-failure");
|
return Invalid("GATEWAY-import-failure");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1798,12 +1798,6 @@ void komodo_args(char *argv0)
|
|||||||
ASSETCHAINS_SELFIMPORT = "";
|
ASSETCHAINS_SELFIMPORT = "";
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
else if ( ASSETCHAINS_SELFIMPORT.size() > 0 && ASSETCHAINS_SELFIMPORT != "GATEWAY" )
|
|
||||||
{
|
|
||||||
fprintf(stderr,"invalid -ac_import type\n");
|
|
||||||
ASSETCHAINS_SELFIMPORT = "";
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if ( ASSETCHAINS_SELFIMPORT.size() > 0 && ASSETCHAINS_CC >= KOMODO_FIRSTFUNGIBLEID )
|
if ( ASSETCHAINS_SELFIMPORT.size() > 0 && ASSETCHAINS_CC >= KOMODO_FIRSTFUNGIBLEID )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"selfimport chains cant be in a fungible cluster\n");
|
fprintf(stderr,"selfimport chains cant be in a fungible cluster\n");
|
||||||
|
|||||||
@@ -46,9 +46,8 @@ int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM
|
|||||||
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);
|
||||||
uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth);
|
uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth);
|
||||||
extern std::string ASSETCHAINS_SELFIMPORT;
|
extern std::string ASSETCHAINS_SELFIMPORT;
|
||||||
int komodo_nextheight();
|
|
||||||
uint256 Parseuint256(char *hexstr);
|
uint256 Parseuint256(char *hexstr);
|
||||||
int32_t GetSelfimportProof(TxProof &proof,CTransaction burnTx,uint256 hash);
|
int32_t GetSelfimportProof(CMutableTransaction &mtx,CScript &scriptPubKey,TxProof &proof,uint64_t burnAmount,std::vector<uint8_t> rawtx,uint256 hash,std::vector<uint8_t> rawproof);
|
||||||
|
|
||||||
|
|
||||||
UniValue assetchainproof(const UniValue& params, bool fHelp)
|
UniValue assetchainproof(const UniValue& params, bool fHelp)
|
||||||
@@ -201,13 +200,7 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp)
|
|||||||
throw runtime_error("export_amount too small");
|
throw runtime_error("export_amount too small");
|
||||||
}
|
}
|
||||||
if ( ASSETCHAINS_SELFIMPORT.size() > 0 )
|
if ( ASSETCHAINS_SELFIMPORT.size() > 0 )
|
||||||
{
|
|
||||||
throw runtime_error("self-import chains cant be fungible");
|
throw runtime_error("self-import chains cant be fungible");
|
||||||
/*if ( ASSETCHAINS_SELFIMPORT == targetSymbol || ASSETCHAINS_SELFIMPORT == "GATEWAY" )
|
|
||||||
{
|
|
||||||
ccid = 0xffffffff;
|
|
||||||
} // else maybe clusters of self-import chains can be supported?*/
|
|
||||||
}
|
|
||||||
CTxOut burnOut = MakeBurnOutput(burnAmount, ccid, targetSymbol, tx.vout);
|
CTxOut burnOut = MakeBurnOutput(burnAmount, ccid, targetSymbol, tx.vout);
|
||||||
UniValue ret(UniValue::VOBJ);
|
UniValue ret(UniValue::VOBJ);
|
||||||
ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout))));
|
ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout))));
|
||||||
@@ -284,33 +277,25 @@ UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
UniValue selfimport(const UniValue& params, bool fHelp)
|
UniValue selfimport(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
CMutableTransaction mtx;
|
||||||
TxProof proof; CTransaction burnTx,tx; CTxOut burnOut,savevout; uint64_t burnAmount; uint256 txid,blockHash; std::vector<CTxOut> vouts;
|
TxProof proof; CTransaction burnTx,tx; CTxOut burnOut; uint64_t burnAmount; uint256 txid,blockHash; std::vector<CTxOut> vouts; std::vector<uint8_t> rawtx,rawproof; CScript scriptPubKey;
|
||||||
if ( ASSETCHAINS_SELFIMPORT.size() == 0 )
|
if ( ASSETCHAINS_SELFIMPORT.size() == 0 )
|
||||||
throw runtime_error("selfimport only works on -ac_import chains");
|
throw runtime_error("selfimport only works on -ac_import chains");
|
||||||
if (fHelp || params.size() != 2)
|
if (fHelp || params.size() < 3 || params.size() > 4)
|
||||||
throw runtime_error("selfimport txid burnamount\n\n"
|
throw runtime_error("selfimport rawtx txid burnamount\n\n"
|
||||||
"creates signed selfimport transaction from txid");
|
"creates signed selfimport transaction from txid");
|
||||||
txid = Parseuint256((char *)params[0].get_str().c_str());
|
rawtx = ParseHex(params[0].get_str().c_str());
|
||||||
burnAmount = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999;
|
txid = Parseuint256((char *)params[1].get_str().c_str()); // allow for txid != hash(rawtx)
|
||||||
// txid is just used to specify the import recv address
|
burnAmount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999;
|
||||||
// in reality it would be rawtx from the other chain and maybe better to specify address
|
if ( params.size() == 4 )
|
||||||
if ( GetTransaction(txid,tx,blockHash,false) == 0 )
|
rawproof = ParseHex(params[3].get_str().c_str());
|
||||||
throw runtime_error("selfimport couldnt find txid");
|
if ( GetSelfimportProof(mtx,scriptPubKey,proof,burnAmount,rawtx,txid,rawproof) < 0 )
|
||||||
savevout = tx.vout[0];
|
throw std::runtime_error("Failed validating selfimport");
|
||||||
mtx = tx;
|
|
||||||
mtx.vout.clear();
|
|
||||||
mtx.vout.resize(1);
|
|
||||||
mtx.vout[0] = savevout;
|
|
||||||
mtx.vout[0].nValue = burnAmount;
|
|
||||||
vouts = mtx.vout;
|
vouts = mtx.vout;
|
||||||
burnOut = MakeBurnOutput(burnAmount,0xffffffff,ASSETCHAINS_SELFIMPORT,vouts);
|
burnOut = MakeBurnOutput(burnAmount,0xffffffff,ASSETCHAINS_SELFIMPORT,vouts);
|
||||||
mtx = tx;
|
|
||||||
mtx.vout.clear();
|
mtx.vout.clear();
|
||||||
mtx.vout.push_back(burnOut);
|
mtx.vout.push_back(burnOut);
|
||||||
burnTx = mtx;
|
burnTx = mtx;
|
||||||
if ( GetSelfimportProof(proof,tx,txid) < 0 )
|
|
||||||
throw std::runtime_error("Failed validating selfimport");
|
|
||||||
return HexStr(E_MARSHAL(ss << MakeImportCoinTransaction(proof,burnTx,vouts)));
|
return HexStr(E_MARSHAL(ss << MakeImportCoinTransaction(proof,burnTx,vouts)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user