]> Git Repo - VerusCoin.git/commitdiff
VRSC and VRSCTEST import/export thread at PBaaS activation
authormiketout <[email protected]>
Sat, 4 Apr 2020 04:09:15 +0000 (21:09 -0700)
committermiketout <[email protected]>
Sat, 4 Apr 2020 04:09:15 +0000 (21:09 -0700)
src/init.cpp
src/main.cpp
src/main.h
src/miner.cpp
src/pbaas/identity.cpp
src/pbaas/pbaas.cpp
src/rpc/pbaasrpc.cpp

index 268ec3954530f47ccdea9cd5128cf019d01e9e03..3093567ef72b2391aa0281409e1ee64b2f49b361 100644 (file)
@@ -1961,6 +1961,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
         if ( !ActivateBestChain(state, Params()))
             strErrors << "Failed to connect best block";
     }
+    InitializePremineSupply();
     std::vector<boost::filesystem::path> vImportFiles;
     if (mapArgs.count("-loadblock"))
     {
index f83fe3f9b054b879303d718be109ee35c8fed6c2..4a644598bbe551fcada5f0d53c77ea238c83ee1f 100644 (file)
@@ -727,6 +727,16 @@ bool IsBlockBoundTransaction(const CTransaction &tx, const uint256 &cbHash)
     return bindingFound;
 }
 
+void InitializePremineSupply()
+{
+    LOCK(cs_main);
+    if (chainActive.Height() > 0)
+    {
+        extern uint64_t ASSETCHAINS_SUPPLY;
+        ASSETCHAINS_SUPPLY = ConnectedChains.ThisChain().GetTotalPreallocation();
+    }
+}
+
 bool IsStandardTx(const CTransaction& tx, string& reason, const CChainParams& chainparams, const int nHeight)
 {
     bool overwinterActive = chainparams.GetConsensus().NetworkUpgradeActive(nHeight,  Consensus::UPGRADE_OVERWINTER);
@@ -3445,6 +3455,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
         return(false);
     //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight());
     AssertLockHeld(cs_main);
+
+    // either set at activate best chain or when we connect block 1
+    if (pindex->GetHeight() == 1)
+    {
+        InitializePremineSupply();
+    }
+
     bool fExpensiveChecks = true;
     if (fCheckpointsEnabled) {
         CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
index 5be35c215914bc681bd87f1afc18c501608fc7ac..79100862dbe68781e1f23c3be6acff98a22a7737 100644 (file)
@@ -576,4 +576,9 @@ CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Para
  */
 bool IsBlockBoundTransaction(const CTransaction &tx, const uint256 &cbHash);
 
+/**
+ * Sets the premine from chain definition
+ */
+void InitializePremineSupply();
+
 #endif // BITCOIN_MAIN_H
index 2b7b1e5e413ed885c531ef6fa964d9931fdf44dc..e1390ee8e94f2b6075f9688ab0f77b3212a58272 100644 (file)
@@ -311,6 +311,134 @@ CPubKey GetScriptPublicKey(const CScript &scriptPubKey)
     return CPubKey();
 }
 
+void ProcessNewImports(const uint160 &sourceChainID, const CTransaction &lastConfirmed, int32_t nHeight)
+{
+    uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
+
+    // get any pending imports from the source chain. if the source chain is this chain, we don't need notarization
+    CCurrencyDefinition thisChain = ConnectedChains.ThisChain();
+
+    CTransaction lastImportTx;
+
+    // we need to find the last unspent import transaction
+    std::vector<CAddressUnspentDbEntry> unspentOutputs;
+
+    bool found = false;
+
+    // we cannot get export to a chain that has shut down
+    // if the chain definition is spent, a chain is inactive
+    if (GetAddressUnspent(CKeyID(CCrossChainRPCData::GetConditionID(sourceChainID, EVAL_CROSSCHAIN_IMPORT)), 1, unspentOutputs))
+    {
+        // if one spends the prior one, get the one that is not spent
+        for (auto txidx : unspentOutputs)
+        {
+            uint256 blkHash;
+            CTransaction itx;
+            if (myGetTransaction(txidx.first.txhash, lastImportTx, blkHash) &&
+                CCrossChainImport(lastImportTx).IsValid() &&
+                (lastImportTx.IsCoinBase() ||
+                (myGetTransaction(lastImportTx.vin[0].prevout.hash, itx, blkHash) &&
+                CCrossChainImport(itx).IsValid())))
+            {
+                found = true;
+                break;
+            }
+        }
+    }
+
+    if (found && pwalletMain)
+    {
+        UniValue params(UniValue::VARR);
+        UniValue param(UniValue::VOBJ);
+
+        CMutableTransaction txTemplate = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nHeight);
+        int i;
+        for (i = 0; i < lastImportTx.vout.size(); i++)
+        {
+            COptCCParams p;
+            if (lastImportTx.vout[i].scriptPubKey.IsPayToCryptoCondition(p) && p.IsValid() && p.evalCode == EVAL_CROSSCHAIN_IMPORT)
+            {
+                txTemplate.vin.push_back(CTxIn(lastImportTx.GetHash(), (uint32_t)i));
+                break;
+            }
+        }
+
+        UniValue result = NullUniValue;
+        if (i < lastImportTx.vout.size())
+        {
+            param.push_back(Pair("name", EncodeDestination(CIdentityID(thisChain.GetID()))));
+            param.push_back(Pair("lastimporttx", EncodeHexTx(lastImportTx)));
+            param.push_back(Pair("lastconfirmednotarization", EncodeHexTx(lastConfirmed)));
+            param.push_back(Pair("importtxtemplate", EncodeHexTx(txTemplate)));
+            param.push_back(Pair("totalimportavailable", lastImportTx.vout[txTemplate.vin[0].prevout.n].nValue));
+            params.push_back(param);
+
+            try
+            {
+                if (sourceChainID == thisChain.GetID())
+                {
+                    UniValue getlatestimportsout(const UniValue& params, bool fHelp);
+                    result = getlatestimportsout(params, false);
+                }
+                else
+                {
+                    result = find_value(RPCCallRoot("getlatestimportsout", params), "result");
+                }
+            } catch (exception e)
+            {
+                printf("Could not get latest imports from notary chain\n");
+            }
+        }
+
+        if (result.isArray() && result.size())
+        {
+            LOCK(pwalletMain->cs_wallet);
+
+            uint256 lastImportHash = lastImportTx.GetHash();
+            for (int i = 0; i < result.size(); i++)
+            {
+                CTransaction itx;
+                if (result[i].isStr() && DecodeHexTx(itx, result[i].get_str()) && itx.vin.size() && itx.vin[0].prevout.hash == lastImportHash)
+                {
+                    // sign the transaction spending the last import and add to mempool
+                    CMutableTransaction mtx(itx);
+                    CCrossChainImport cci(lastImportTx);
+
+                    bool signSuccess;
+                    SignatureData sigdata;
+                    CAmount value;
+                    const CScript *pScriptPubKey;
+
+                    signSuccess = ProduceSignature(
+                        TransactionSignatureCreator(pwalletMain, &itx, 0, lastImportTx.vout[itx.vin[0].prevout.n].nValue, SIGHASH_ALL), lastImportTx.vout[itx.vin[0].prevout.n].scriptPubKey, sigdata, consensusBranchId);
+
+                    if (!signSuccess)
+                    {
+                        break;
+                    }
+
+                    UpdateTransaction(mtx, 0, sigdata);
+                    itx = CTransaction(mtx);
+
+                    // commit to mempool and remove any conflicts
+                    std::list<CTransaction> removed;
+                    mempool.removeConflicts(itx, removed);
+                    CValidationState state;
+                    if (!myAddtomempool(itx, &state))
+                    {
+                        LogPrintf("Failed to add import transactions to the mempool due to: %s\n", state.GetRejectReason().c_str());
+                        printf("Failed to add import transactions to the mempool due to: %s\n", state.GetRejectReason().c_str());
+                        break;  // if we failed to add one, the others will fail to spend it
+                    }
+
+                    lastImportTx = itx;
+                    lastImportHash = itx.GetHash();
+                }
+            }
+        }
+    }
+}
+
 CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
 {
     CScript scriptPubKeyIn(_scriptPubKeyIn);
@@ -875,12 +1003,7 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& _
                 indexDests = std::vector<CTxDestination>({CKeyID(CCrossChainRPCData::GetConditionID(ConnectedChains.notaryChain.GetID(), EVAL_CROSSCHAIN_IMPORT))});
                 dests = std::vector<CTxDestination>({pkCC});
 
-                CCurrencyValueMap cvm;
-                for (auto &inPair : ConnectedChains.ThisChain().preAllocation)
-                {
-                    cvm.valueMap[inPair.first] = inPair.second;
-                }
-                CCrossChainImport cci = CCrossChainImport(ConnectedChains.notaryChain.GetID(), cvm);
+                CCrossChainImport cci = CCrossChainImport(ConnectedChains.notaryChain.GetID(), CCurrencyValueMap());
                 coinbaseTx.vout.push_back(CTxOut(currencyState.ReserveToNativeRaw(CCurrencyValueMap(thisChain.currencies, thisChain.preconverted), thisChain.conversions),
                                                  MakeMofNCCScript(CConditionObj<CCrossChainImport>(EVAL_CROSSCHAIN_IMPORT, dests, 1, &cci), &indexDests)));
 
@@ -1007,127 +1130,67 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& _
                 // if we have a last confirmed notarization, then check for new imports from the notary chain
                 if (lastConfirmed.vout.size())
                 {
-                    // we need to find the last unspent import transaction
-                    std::vector<CAddressUnspentDbEntry> unspentOutputs;
-
-                    bool found = false;
-
-                    // we cannot get export to a chain that has shut down
-                    // if the chain definition is spent, a chain is inactive
-                    if (GetAddressUnspent(CKeyID(CCrossChainRPCData::GetConditionID(ConnectedChains.NotaryChain().GetID(), EVAL_CROSSCHAIN_IMPORT)), 1, unspentOutputs))
-                    {
-                        // if one spends the prior one, get the one that is not spent
-                        for (auto txidx : unspentOutputs)
-                        {
-                            uint256 blkHash;
-                            CTransaction itx;
-                            if (myGetTransaction(txidx.first.txhash, lastImportTx, blkHash) &&
-                                CCrossChainImport(lastImportTx).IsValid() &&
-                                (lastImportTx.IsCoinBase() ||
-                                (myGetTransaction(lastImportTx.vin[0].prevout.hash, itx, blkHash) &&
-                                CCrossChainImport(itx).IsValid())))
-                            {
-                                found = true;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (found && pwalletMain)
-                    {
-                        UniValue params(UniValue::VARR);
-                        UniValue param(UniValue::VOBJ);
-
-                        CMutableTransaction txTemplate = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nHeight);
-                        int i;
-                        for (i = 0; i < lastImportTx.vout.size(); i++)
-                        {
-                            COptCCParams p;
-                            if (lastImportTx.vout[i].scriptPubKey.IsPayToCryptoCondition(p) && p.IsValid() && p.evalCode == EVAL_CROSSCHAIN_IMPORT)
-                            {
-                                txTemplate.vin.push_back(CTxIn(lastImportTx.GetHash(), (uint32_t)i));
-                                break;
-                            }
-                        }
-
-                        UniValue result = NullUniValue;
-                        if (i < lastImportTx.vout.size())
-                        {
-                            param.push_back(Pair("name", thisChain.name));
-                            param.push_back(Pair("lastimporttx", EncodeHexTx(lastImportTx)));
-                            param.push_back(Pair("lastconfirmednotarization", EncodeHexTx(lastConfirmed)));
-                            param.push_back(Pair("importtxtemplate", EncodeHexTx(txTemplate)));
-                            param.push_back(Pair("totalimportavailable", lastImportTx.vout[txTemplate.vin[0].prevout.n].nValue));
-                            params.push_back(param);
-
-                            try
-                            {
-                                result = find_value(RPCCallRoot("getlatestimportsout", params), "result");
-                            } catch (exception e)
-                            {
-                                printf("Could not get latest imports from notary chain\n");
-                            }
-                        }
-
-                        if (result.isArray() && result.size())
-                        {
-                            LOCK(pwalletMain->cs_wallet);
-
-                            uint256 lastImportHash = lastImportTx.GetHash();
-                            for (int i = 0; i < result.size(); i++)
-                            {
-                                CTransaction itx;
-                                if (result[i].isStr() && DecodeHexTx(itx, result[i].get_str()) && itx.vin.size() && itx.vin[0].prevout.hash == lastImportHash)
-                                {
-                                    // sign the transaction spending the last import and add to mempool
-                                    CMutableTransaction mtx(itx);
-                                    CCrossChainImport cci(lastImportTx);
-
-                                    bool signSuccess;
-                                    SignatureData sigdata;
-                                    CAmount value;
-                                    const CScript *pScriptPubKey;
-
-                                    signSuccess = ProduceSignature(
-                                        TransactionSignatureCreator(pwalletMain, &itx, 0, lastImportTx.vout[itx.vin[0].prevout.n].nValue, SIGHASH_ALL), lastImportTx.vout[itx.vin[0].prevout.n].scriptPubKey, sigdata, consensusBranchId);
-
-                                    if (!signSuccess)
-                                    {
-                                        break;
-                                    }
-
-                                    UpdateTransaction(mtx, 0, sigdata);
-                                    itx = CTransaction(mtx);
-
-                                    // commit to mempool and remove any conflicts
-                                    std::list<CTransaction> removed;
-                                    mempool.removeConflicts(itx, removed);
-                                    CValidationState state;
-                                    if (!myAddtomempool(itx, &state))
-                                    {
-                                        LogPrintf("Failed to add import transactions to the mempool due to: %s\n", state.GetRejectReason().c_str());
-                                        printf("Failed to add import transactions to the mempool due to: %s\n", state.GetRejectReason().c_str());
-                                        break;  // if we failed to add one, the others will fail to spend it
-                                    }
-
-                                    lastImportTx = itx;
-                                    lastImportHash = itx.GetHash();
-                                }
-                            }
-                        }
-                    }
+                    ProcessNewImports(ConnectedChains.NotaryChain().GetID(), lastConfirmed, nHeight);
                 }
             }
         }
         else
         {
-            CAmount blockOnePremine = thisChain.GetTotalPreallocation();
-            SetBlockOnePremine(blockOnePremine);
+            if (nHeight == 1)
+            {
+                SetBlockOnePremine(thisChain.GetTotalPreallocation());
+            }
             totalEmission = GetBlockSubsidy(nHeight, consensusParams);
             blockSubsidy = totalEmission;
             currencyState.UpdateWithEmission(totalEmission);
+
+            if (CConstVerusSolutionVector::activationHeight.IsActivationHeight(CActivationHeight::ACTIVATE_PBAAS, nHeight))
+            {
+                // at activation height for PBaaS on VRSC or VRSCTEST, add currency definition, import, and export outputs to the coinbase
+                // create a currency definition output for this currency, the notary currency, and all reserves
+                CCcontract_info CC;
+                CCcontract_info *cp;
+                cp = CCinit(&CC, EVAL_CURRENCY_DEFINITION);
+                pkCC = CPubKey(ParseHex(CC.CChexstr));
+
+                std::vector<CTxDestination> indexDests({CKeyID(ConnectedChains.ThisChain().GetConditionID(EVAL_CURRENCY_DEFINITION))});
+                std::vector<CTxDestination> dests({pkCC});
+
+                coinbaseTx.vout.push_back(CTxOut(0,
+                                            MakeMofNCCScript(CConditionObj<CCurrencyDefinition>(EVAL_CURRENCY_DEFINITION, dests, 1, 
+                                                             &ConnectedChains.ThisChain()),
+                                            &indexDests)));
+            }
+        }
+
+        // on all chains, we add an export and import to ourselves at PBaaS activation height (1 for PBaaS chains)
+        if (CConstVerusSolutionVector::activationHeight.IsActivationHeight(CActivationHeight::ACTIVATE_PBAAS, nHeight))
+        {
+            // create the import thread output
+            cp = CCinit(&CC, EVAL_CROSSCHAIN_IMPORT);
+            pkCC = CPubKey(ParseHex(CC.CChexstr));
+
+            // import thread from self
+            std::vector<CTxDestination> indexDests = std::vector<CTxDestination>({CKeyID(CCrossChainRPCData::GetConditionID(ConnectedChains.ThisChain().GetID(), EVAL_CROSSCHAIN_IMPORT))});
+            std::vector<CTxDestination> dests = std::vector<CTxDestination>({pkCC});
+
+            CCrossChainImport cci = CCrossChainImport(ConnectedChains.ThisChain().GetID(), CCurrencyValueMap());
+            coinbaseTx.vout.push_back(CTxOut(0, MakeMofNCCScript(CConditionObj<CCrossChainImport>(EVAL_CROSSCHAIN_IMPORT, dests, 1, &cci), &indexDests)));
+
+            // export thread to self
+            cp = CCinit(&CC, EVAL_CROSSCHAIN_EXPORT);
+            pkCC = CPubKey(ParseHex(CC.CChexstr));
+            indexDests = std::vector<CTxDestination>({CKeyID(CCrossChainRPCData::GetConditionID(ConnectedChains.ThisChain().GetID(), EVAL_CROSSCHAIN_EXPORT))});
+            dests = std::vector<CTxDestination>({pkCC});
+
+            CCrossChainExport ccx(ConnectedChains.ThisChain().GetID(), 0, CCurrencyValueMap(), CCurrencyValueMap());
+            coinbaseTx.vout.push_back(CTxOut(0, MakeMofNCCScript(CConditionObj<CCrossChainExport>(EVAL_CROSSCHAIN_EXPORT, dests, 1, &ccx), &indexDests)));
         }
 
+        // process any imports from the current chain to itself, to suport token launches, etc.
+        // TODO: should also add refund checking here
+        ProcessNewImports(ConnectedChains.ThisChain().GetID(), CTransaction(), nHeight);
+
         // coinbase should have all necessary outputs (TODO: timelock is not supported yet)
         uint32_t nCoinbaseSize = GetSerializeSize(coinbaseTx, SER_NETWORK, PROTOCOL_VERSION);
         nBlockSize += nCoinbaseSize;
index 86c9782a4b91bb6b4fa2b63d3ea509861999654a..33d8a5093e12d7834e87572875d51a4b665577ad 100644 (file)
@@ -163,7 +163,7 @@ UniValue CIdentity::ToUniValue() const
     UniValue obj = ((CPrincipal *)this)->ToUniValue();
 
     obj.push_back(Pair("identityaddress", EncodeDestination(CIdentityID(GetID()))));
-    obj.push_back(Pair("parent", EncodeDestination(CKeyID(parent))));
+    obj.push_back(Pair("parent", EncodeDestination(CIdentityID(parent))));
     obj.push_back(Pair("name", name));
 
     UniValue hashes(UniValue::VOBJ);
index 41896a2dcc77c36bf65dd72d5089e3dab61a9c1a..ddae647a3215d2d7503f47f5491fd4aedd7cef4c 100644 (file)
@@ -1003,9 +1003,22 @@ void CConnectedChains::AggregateChainTransfers(const CTxDestination &feeOutput,
 
                 // if this is a currency without its own chain that starts at a height greater than this one,
                 // skip this tranfer for now. all transfers posted should be able to be imported when the system starts.
-                if (destDef.systemID == ASSETCHAINS_CHAINID && destDef.startBlock > nHeight)
+                if (destDef.systemID == ASSETCHAINS_CHAINID)
                 {
-                    continue;
+                    if (destDef.startBlock > nHeight)
+                    {
+                        continue;
+                    }
+
+                    // if the chain has failed to launch, we are done
+                    CCurrencyValueMap minPreMap, preConvertedMap;
+                    if (destDef.minPreconvert.size() &&
+                        (minPreMap = CCurrencyValueMap(destDef.currencies, destDef.minPreconvert)) > preConvertedMap &&
+                        (preConvertedMap = CCurrencyValueMap(destDef.currencies, GetInitialCurrencyState(destDef).reserveIn)) < minPreMap)
+                    {
+                        // this chain should get refunded, nothing more should get aggregated
+                        continue;
+                    }
                 }
 
                 it = currencyDefCache.find(output.second.second.systemID);
index 292f7a30131fc6f3582e0349152d4a2c357e2180..d0d2d7be560bee45da4c5fd0aa2d76f072ed79f3 100644 (file)
@@ -468,10 +468,11 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &systemDef,
 {
     uint160 systemID = systemDef.GetID();
     uint160 thisChainID = thisChain.GetID();
+    bool isTokenImport = systemID == thisChainID;
     CCurrencyValueMap totalAvailableInput(AvailableTokenInput);
 
     CPBaaSNotarization lastConfirmed(lastConfirmedNotarization);
-    if (!lastConfirmed.IsValid() || (chainActive.LastTip() == NULL) || lastConfirmed.notarizationHeight > chainActive.LastTip()->GetHeight())
+    if (!isTokenImport && (!lastConfirmed.IsValid() || (chainActive.LastTip() == NULL) || lastConfirmed.notarizationHeight > chainActive.LastTip()->GetHeight()))
     {
         LogPrintf("%s: Invalid lastConfirmedNotarization transaction\n", __func__);
         printf("%s: Invalid lastConfirmedNotarization transaction\n", __func__);
@@ -505,6 +506,12 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &systemDef,
 
     LOCK2(cs_main, mempool.cs);
 
+    // confirmation of tokens are simultaneous to blocks
+    if (isTokenImport)
+    {
+        lastConfirmed.notarizationHeight = chainActive.Height();
+    }
+
     uint256 lastExportHash;
     CCrossChainProof exportProof;
     CTransaction lastExportTx;
@@ -575,8 +582,6 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &systemDef,
         return false;
     }
 
-    bool importToNotaryChain = !isVerusActive && systemID != thisChainID && systemID == notaryChain.GetID();
-
     // which transaction are we in this block?
     std::vector<std::pair<CAddressIndexKey, CAmount>> addressIndex;
 
@@ -736,8 +741,8 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &systemDef,
             CBlock block;
             if (!ReadBlockFromDisk(block, chainActive[aixIt->second.first.blockHeight], Params().GetConsensus(), false))
             {
-                LogPrintf("%s: POSSIBLE CORRUPTION cannot read block %s\n", __func__, chainActive[lastConfirmed.notarizationHeight]->GetBlockHash().GetHex().c_str());
-                printf("%s: POSSIBLE CORRUPTION cannot read block %s\n", __func__, chainActive[lastConfirmed.notarizationHeight]->GetBlockHash().GetHex().c_str());
+                LogPrintf("%s: POSSIBLE CORRUPTION cannot read block %s\n", __func__, chainActive[aixIt->second.first.blockHeight]->GetBlockHash().GetHex().c_str());
+                printf("%s: POSSIBLE CORRUPTION cannot read block %s\n", __func__, chainActive[aixIt->second.first.blockHeight]->GetBlockHash().GetHex().c_str());
                 return false;
             }
 
@@ -749,6 +754,8 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &systemDef,
             // prove our transaction up to the MMR root of the last transaction
             auto exportProof = block.GetPartialTransactionProof(aixIt->second.second, aixIt->second.first.index, parts);
             exportProof.txProof << block.MMRProofBridge();
+
+            // don't include chain MMR proof for exports from the same chain
             ChainMerkleMountainView(chainActive.GetMMR(), lastConfirmed.notarizationHeight).GetProof(exportProof.txProof, aixIt->second.first.blockHeight);
 
             // add it to the export transaction proof, now proven up to the MMR root of the last confirmed transaction
@@ -756,7 +763,7 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &systemDef,
 
             CChainObject<CCrossChainProof> exportXProof(CHAINOBJ_CROSSCHAINPROOF, exportTransactionProof);
 
-            // add the opret with the transaction and its proof that references the notarization with the correct MMR
+            // add the opret with the transaction and proof
             newImportTx.vout.push_back(CTxOut(0, StoreOpRetArray(std::vector<CBaseChainObject *>({&exportXProof}))));
 
             // we now have an Import transaction for the chainID chain, it is the latest, and the export we used is now the latest as well
@@ -4381,7 +4388,7 @@ UniValue definecurrency(const UniValue& params, bool fHelp)
                                                  CIdentityExport::DEFAULT_EXPORT_FEE, 
                                                  false});
         }
-    }
+    }    
 
     // make the outputs for initial contributions
     if (newChain.contributions.size() && newChain.contributions.size() == newChain.currencies.size())
This page took 0.068793 seconds and 4 git commands to generate.