diff --git a/src/cc/import.cpp b/src/cc/import.cpp index b250bb7bf..c569ffaa8 100644 --- a/src/cc/import.cpp +++ b/src/cc/import.cpp @@ -25,7 +25,90 @@ * * This method should control every parameter of the ImportCoin transaction, since it has no signature * to protect it from malleability. + + ##### 0xffffffff is a special CCid for single chain/dual daemon imports */ + +extern std::string ASSETCHAINS_SELFIMPORT; +extern uint16_t ASSETCHAINS_CODAPORT,ASSETCHAINS_BEAMPORT; + +int32_t GetBEAMProof(TxProof &proof,CTransaction burnTx,uint256 hash) +{ + // confirm via ASSETCHAINS_BEAMPORT that burnTx/hash is a valid BEAM burn + return(-1); +} + +int32_t GetCODAProof(TxProof &proof,CTransaction burnTx,uint256 hash) +{ + // confirm via ASSETCHAINS_CODAPORT that burnTx/hash is a valid CODA burn + return(-1); +} + +int32_t GetPUBKEYProof(TxProof &proof,CTransaction burnTx,uint256 hash) +{ + // make sure vin0 is signed by ASSETCHAINS_OVERRIDE_PUBKEY33 + return(-1); +} + +int32_t GetGATEWAYProof(TxProof &proof,CTransaction burnTx,uint256 hash) +{ + // external coin is the assetchains symbol in the burnTx OP_RETURN + return(-1); +} + +int32_t GetSelfimportProof(TxProof &proof,CTransaction burnTx,uint256 hash) // find burnTx with hash from "other" daemon +{ + if ( ASSETCHAINS_SELFIMPORT == "BEAM" ) + { + if ( GetBEAMproof(proof,burnTx,hash) < 0 ) + return(-1); + } + else if ( ASSETCHAINS_SELFIMPORT == "CODA" ) + { + if ( GetCODAproof(proof,burnTx,hash) < 0 ) + return(-1); + } + else if ( ASSETCHAINS_SELFIMPORT == "PUBKEY" ) + { + if ( GetPUBKEYproof(proof,burnTx,hash) < 0 ) + return(-1); + } + else if ( ASSETCHAINS_SELFIMPORT == "GATEWAY" ) + { + if ( GetGATEWAYproof(proof,burnTx,hash) < 0 ) // extract source coin from burnTx opreturn + return(-1); + } + else return(-1); + return(0); +} + +// use proof from the above functions to validate the import + +int32_t CheckBEAMimport(TxProof proof,CTransaction burnTx,td::vector payouts) +{ + // check with dual-BEAM daemon via ASSETCHAINS_BEAMPORT for validity of burnTx + return(-1); +} + +int32_t CheckCODAimport(TxProof proof,CTransaction burnTx,td::vector payouts) +{ + // check with dual-CODA daemon via ASSETCHAINS_CODAPORT for validity of burnTx + return(-1); +} + +int32_t CheckGATEWAYimport(std::string coin,TxProof proof,CTransaction burnTx,td::vector payouts) +{ + // check for valid burn from external coin blockchain and if valid return(0); + return(-1); +} + +int32_t CheckPUBKEYimport(TxProof proof,CTransaction burnTx,td::vector payouts) +{ + // if burnTx has ASSETCHAINS_PUBKEY vin, it is valid return(0); + return(0); + return(-1); +} + bool Eval::ImportCoin(const std::vector params, const CTransaction &importTx, unsigned int nIn) { if (importTx.vout.size() < 2) @@ -52,12 +135,6 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash)) return Invalid("invalid-burn-tx"); - if (targetCcid != GetAssetchainsCC() || targetSymbol != GetAssetchainsSymbol()) - return Invalid("importcoin-wrong-chain"); - - if (targetCcid < KOMODO_FIRSTFUNGIBLEID) - return Invalid("chain-not-fungible"); - // check burn amount { uint64_t burnAmount = burnTx.vout.back().nValue; @@ -74,13 +151,41 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp if (payoutsHash != SerializeHash(payouts)) return Invalid("wrong-payouts"); + if (targetCcid < KOMODO_FIRSTFUNGIBLEID) + return Invalid("chain-not-fungible"); + // Check proof confirms existance of burnTx + if ( targetCcid != 0xffffffff ) { + if (targetCcid != GetAssetchainsCC() || targetSymbol != GetAssetchainsSymbol()) + return Invalid("importcoin-wrong-chain"); uint256 target = proof.second.Exec(burnTx.GetHash()); if (!CheckMoMoM(proof.first, target)) return Invalid("momom-check-fail"); } - + else if ( ASSETCHAINS_SELFIMPORT == targetSymbol || ASSETCHAINS_SELFIMPORT == "GATEWAY" ) // various selfchain imports + { + if ( GetAssetchainsSymbol() == "BEAM" ) + { + if ( CheckBEAMimport(proof,burnTx,payouts) < 0 ) + return Invalid("BEAM-import-failure"); + } + else if ( GetAssetchainsSymbol() == "CODA" ) + { + if ( CheckCODAimport(proof,burnTx,payouts) < 0 ) + return Invalid("CODA-import-failure"); + } + else if ( GetAssetchainsSymbol() == "PUBKEY" ) + { + if ( CheckPUBKEYimport(proof,burnTx,payouts) < 0 ) + return Invalid("PUBKEY-import-failure"); + } + else + { + if ( CheckGATEWAYimport(GetAssetchainsSymbol(),proof,burnTx,payouts) < 0 ) + return Invalid("GATEWAY-import-failure"); + } + } return Valid(); } diff --git a/src/crosschain.cpp b/src/crosschain.cpp index e9444c607..806641f6a 100644 --- a/src/crosschain.cpp +++ b/src/crosschain.cpp @@ -26,6 +26,8 @@ int NOTARISATION_SCAN_LIMIT_BLOCKS = 1440; CBlockIndex *komodo_getblockindex(uint256 hash); +extern std::string ASSETCHAINS_SELFIMPORT; +int32_t GetSelfimportProof(TxProof &proof,CTransaction burnTx,uint256 hash); /* On KMD */ @@ -284,13 +286,20 @@ bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom) * in: txid * out: pair */ -TxProof GetAssetchainProof(uint256 hash) + +TxProof GetAssetchainProof(uint256 hash,CTransaction burnTx) { int nIndex; CBlockIndex* blockIndex; Notarisation nota; std::vector branch; - + if ( ASSETCHAINS_SELFIMPORT.size() > 0 ) + { + TxProof proof; + if ( GetSelfimportProof(proof,burnTx,hash) < 0 ) + throw std::runtime_error("Failed validating selfimport"); + return(proof); + } { uint256 blockHash; CTransaction tx; diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 3e9b84db1..bd28d39f3 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -47,12 +47,12 @@ int COINBASE_MATURITY = _COINBASE_MATURITY;//100; int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1,KOMODO_DEALERNODE,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS; int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1; -std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB; +std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,ASSETCHAINS_SELFIMPORT; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW; bool VERUS_MINTBLOCKS; char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096]; -uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; +uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_BEAMPORT,ASSETCHAINS_CODAPORT; uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT,KOMODO_DPOWCONFS = 1; uint32_t ASSETCHAINS_MAGIC = 2387029918; int64_t ASSETCHAINS_GENESISTXVAL = 5000000000; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 19941a172..2a3617748 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1773,6 +1773,30 @@ void komodo_args(char *argv0) ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0); ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey",""); ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script",""); + ASSETCHAINS_BEAMPORT = GetArg("-ac_beam",0); + ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0); + + ASSETCHAINS_SELFIMPORT = GetArg("-ac_import",""); // BEAM, CODA, PUBKEY, GATEWAY + if ( ASSETCHAINS_SELFIMPORT == "PUBKEY" && strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) != 66 ) + { + fprintf(stderr,"invalid -ac_pubkey for -ac_import=PUBKEY\n"); + ASSETCHAINS_SELFIMPORT = ""; + } + else if ( ASSETCHAINS_SELFIMPORT == "BEAM" && ASSETCHAINS_BEAMPORT == 0 ) + { + fprintf(stderr,"missing -ac_beam for BEAM rpcport\n"); + ASSETCHAINS_SELFIMPORT = ""; + } + else if ( ASSETCHAINS_SELFIMPORT == "CODA" && ASSETCHAINS_CODAPORT == 0 ) + { + fprintf(stderr,"missing -ac_coda for CODA rpcport\n"); + ASSETCHAINS_SELFIMPORT = ""; + } + else if ( ASSETCHAINS_SELFIMPORT != "GATEWAY" ) + { + fprintf(stderr,"invalid -ac_import type\n"); + ASSETCHAINS_SELFIMPORT = ""; + } //ASSETCHAINS_FOUNDERS_PERIOD = GetArg("-ac_period",0); if ( (ASSETCHAINS_STAKED= GetArg("-ac_staked",0)) > 100 ) @@ -1809,7 +1833,7 @@ void komodo_args(char *argv0) } else { - ASSETCHAINS_OVERRIDE_PUBKEY.clear(); + //ASSETCHAINS_OVERRIDE_PUBKEY.clear(); printf("-ac_perc must be set with -ac_pubkey\n"); } } @@ -1827,7 +1851,7 @@ void komodo_args(char *argv0) printf("ASSETCHAINS_FOUNDERS needs an ASETCHAINS_OVERRIDE_PUBKEY\n"); } } - if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 ) + if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 ) { fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size()); extraptr = extrabuf; @@ -1889,6 +1913,14 @@ void komodo_args(char *argv0) //extralen += iguana_rwnum(1,&extraptr[extralen],(int32_t)ASSETCHAINS_SCRIPTPUB.size(),(void *)ASSETCHAINS_SCRIPTPUB.c_str()); fprintf(stderr,"append ac_script %s\n",ASSETCHAINS_SCRIPTPUB.c_str()); } + if ( ASSETCHAINS_SELFIMPORT.size() > 0 ) + { + memcpy(&extraptr[extralen],(char *)ASSETCHAINS_SELFIMPORT.c_str(),ASSETCHAINS_SELFIMPORT.size()); + for (i=0; i 0 ) + { + 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); UniValue ret(UniValue::VOBJ); ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout)))); tx.vout.clear(); @@ -229,7 +236,7 @@ UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp) throw runtime_error("Couldn't parse payouts"); uint256 txid = burnTx.GetHash(); - TxProof proof = GetAssetchainProof(burnTx.GetHash()); + TxProof proof = GetAssetchainProof(burnTx.GetHash(),burnTx); CTransaction importTx = MakeImportCoinTransaction(proof, burnTx, payouts); return HexStr(E_MARSHAL(ss << importTx));