marmarachain / marmara

This is the main repository for Marmara Credit Loops Smartchain containing the open source CC Files.
https://marmara.io/
Other
18 stars 8 forks source link

Refactored / optimised EnumLockedInLoop #48

Open DeckerSU opened 1 week ago

DeckerSU commented 1 week ago

Yesterday, I worked on some Marmara optimizations, and here is a draft of the optimized version of the EnumLockedInLoop function. After some measurements, the original function's execution time was around 16,000 ms, while the optimized version took about 13,000–14,000 ms, resulting in a 3,000 ms improvement.

@dimxy, if you have time, please run some performance tests. If everything checks out, we can consider including it in the main Marmara codebase.

Optimized version:

template <class T>
static void EnumLockedInLoop(T func, const CPubKey &pk)
{
    char markeraddr[KOMODO_ADDRESS_BUFSIZE];
    std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue>> markerOutputs;

    struct CCcontract_info *cp, C;
    cp = CCinit(&C, EVAL_MARMARA);
    CPubKey Marmarapk = GetUnspendable(cp, NULL);

    GetCCaddress(cp, markeraddr, Marmarapk);
    SetCCunspents(markerOutputs, markeraddr, true);

    // Collect all unique loopaddrs
    std::set<std::string> uniqueLoopAddrs;
    for (const auto& markerOutput : markerOutputs)
    {
        CTransaction issuanceTx;
        uint256 hashBlock;
        uint256 marker_txid = markerOutput.first.txhash;
        int32_t marker_nvout = (int32_t)markerOutput.first.index;
        CAmount marker_amount = markerOutput.second.satoshis;

        if (marker_nvout == MARMARA_LOOP_MARKER_VOUT && marker_amount == MARMARA_LOOP_MARKER_AMOUNT)
        {
            if (myGetTransaction(marker_txid, issuanceTx, hashBlock))
            {
                if (!issuanceTx.IsCoinBase() && issuanceTx.vout.size() > 2 && issuanceTx.vout.back().nValue == 0)
                {
                    struct SMarmaraCreditLoopOpret loopData;
                    if (MarmaraDecodeLoopOpret(issuanceTx.vout.back().scriptPubKey, loopData, MARMARA_OPRET_VERSION_ANY) == MARMARA_ISSUE)
                    {
                        char loopaddr[KOMODO_ADDRESS_BUFSIZE];
                        CPubKey createtxidPk = CCtxidaddr_tweak(NULL, loopData.createtxid);
                        GetCCaddress1of2(cp, loopaddr, Marmarapk, createtxidPk);
                        uniqueLoopAddrs.insert(loopaddr);
                    }
                }
            }
        }
    }

    // Batch retrieve unspent outputs for all loopaddrs
    std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue>> allLoopOutputs;
    for (const auto& loopaddr : uniqueLoopAddrs)
    {
        std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue>> loopOutputs;
        SetCCunspents(loopOutputs, const_cast<char*>(loopaddr.c_str()), true);
        allLoopOutputs.insert(allLoopOutputs.end(), loopOutputs.begin(), loopOutputs.end());
    }

    // Process all unspent outputs
    for (const auto& loopOutput : allLoopOutputs)
    {
        CTransaction loopTx;
        uint256 hashBlock;
        CBlockIndex *pindex;
        uint256 txid = loopOutput.first.txhash;
        int32_t nvout = (int32_t)loopOutput.first.index;

        if (myGetTransaction(txid, loopTx, hashBlock) && (pindex = komodo_getblockindex(hashBlock)) != nullptr && !myIsutxo_spentinmempool(ignoretxid, ignorevin, txid, nvout))
        {
            if (!loopTx.IsCoinBase() && loopTx.vout.size() > 0)
            {
                char utxoaddr[KOMODO_ADDRESS_BUFSIZE] = "";
                Getscriptaddress(utxoaddr, loopTx.vout[nvout].scriptPubKey);

                if (uniqueLoopAddrs.find(utxoaddr) != uniqueLoopAddrs.end())
                {
                    CScript opret;
                    CPubKey pk_in_opret;

                    CMarmaraLockInLoopOpretChecker lockinloopChecker(CHECK_ONLY_CCOPRET, MARMARA_OPRET_VERSION_DEFAULT);
                    if (get_either_opret(&lockinloopChecker, loopTx, nvout, opret, pk_in_opret))
                    {
                        if (!pk.IsValid() || pk == pk_in_opret)
                        {
                            func(utxoaddr, loopTx, nvout, pindex);
                        }
                    }
                }
            }
        }
    }
}
dimxy commented 5 days ago

This code looks better, thanks. I only suggest to retain the comment about this check (to memorise it):

      Getscriptaddress(utxoaddr, loopTx.vout[nvout].scriptPubKey);

      if (uniqueLoopAddrs.find(utxoaddr) != uniqueLoopAddrs.end())
      ...

IIRC it covers the real-world case when address index contained several entries for the same script pubkey