Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rpc): Asset Unlock status by index #5776

Merged

Conversation

ogabrielides
Copy link
Collaborator

@ogabrielides ogabrielides commented Dec 19, 2023

Issue being fixed or feature implemented

Platform in the scope of credit withdrawals, need a way to get the status of an Asset Unlock by index.

What was done?

A new RPC was created getassetunlockchainlocks that accepts Asset Unlock indexes array as parameter and return corresponding status for each index.

The possible outcomes per each index are:

  • chainlocked: If the Asset Unlock index is mined on a Chainlocked block.
  • mined: If no Chainlock information is available, and the Asset Unlock index is mined.
  • mempooled: If the Asset Unlock index is in the mempool.
  • unknown: If none of the above are valid.

Note: This RPC is whitelisted for the Platform RPC user.

How Has This Been Tested?

Inserted on feature_asset_locks.py covering cases where Asset Unlock txs are in mempool, mined and not present.

Breaking Changes

no

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

@ogabrielides ogabrielides added this to the 20.1 milestone Dec 19, 2023
@ogabrielides ogabrielides added the RPC Some notable changes to RPC params/behaviour/descriptions label Dec 19, 2023
src/rpc/rawtransaction.cpp Outdated Show resolved Hide resolved
src/rpc/rawtransaction.cpp Outdated Show resolved Hide resolved
src/rpc/rawtransaction.cpp Outdated Show resolved Hide resolved
CBlockIndex* pBlockIndex{nullptr};
bool chainlock_info = false;
llmq::CChainLockSig bestclsig = llmq_ctx.clhandler->GetBestChainLock();
if (bestclsig.IsNull()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should create a separate feat PR which on ProcessBlock we will submit a blocks chain lock to the chain lock system

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/rpc/rawtransaction.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@thephez thephez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about calling it getassetunlockstatus instead since it returns one of several status values?
As discussed, getassetunlockstatuses looks like a better options since it can return status for multiple txs.

UdjinM6
UdjinM6 previously approved these changes Dec 19, 2023
Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Copy link
Collaborator

@thephez thephez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should update the release notes now too so they match

doc/release-notes-5776.md Outdated Show resolved Hide resolved
UdjinM6
UdjinM6 previously approved these changes Dec 19, 2023
Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re-utACK

src/rpc/rawtransaction.cpp Outdated Show resolved Hide resolved
knst
knst previously approved these changes Dec 20, 2023
Copy link
Collaborator

@knst knst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

@ogabrielides ogabrielides marked this pull request as draft December 20, 2023 17:58
knst
knst previously approved these changes Dec 21, 2023
Copy link
Collaborator

@knst knst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

else {
UniValue jnull(UniValue::VNULL);
obj.pushKV(str_indexes[i].get_str(), jnull);
obj.pushKV("status", jnull);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: obj.pushKV("status", UniValue{}); does same, doesn't it?

Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see the following patch; note this changes behavior to not return a null but "unknown"

Subject: [PATCH] lots of lamdas
---
Index: src/rpc/rawtransaction.cpp
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
--- a/src/rpc/rawtransaction.cpp	(revision 22dd732df77f69163293b8adcea1e9af1f3c6c73)
+++ b/src/rpc/rawtransaction.cpp	(date 1703220226644)
@@ -388,25 +388,31 @@
     }
 
     CBlockIndex* pTipBlockIndex{WITH_LOCK(cs_main, return chainman.ActiveChain().Tip())};
-
-    CBlockIndex* pBlockIndexBestCL{nullptr};
-    const llmq::CChainLockSig bestclsig{llmq_ctx.clhandler->GetBestChainLock()};
-    if (bestclsig.IsNull()) {
-        // If no CL info is available, try to use CbTx CL information
-        if (const auto cbtx_best_cl = GetNonNullCoinbaseChainlock(pTipBlockIndex); cbtx_best_cl.has_value()) {
-            pBlockIndexBestCL = pTipBlockIndex->GetAncestor(pTipBlockIndex->nHeight - cbtx_best_cl->second - 1);
-        }
-    }
-
     if (!pTipBlockIndex) {
         throw JSONRPCError(RPC_INTERNAL_ERROR, "No blocks in chain");
     }
 
+    const auto pBlockIndexBestCL = [&]() -> const CBlockIndex* {
+        if (llmq_ctx.clhandler->GetBestChainLock().IsNull()) {
+            // If no CL info is available, try to use CbTx CL information
+            if (const auto cbtx_best_cl = GetNonNullCoinbaseChainlock(pTipBlockIndex)) {
+                return pTipBlockIndex->GetAncestor(pTipBlockIndex->nHeight - cbtx_best_cl->second - 1);
+            }
+        }
+        return nullptr;
+    }();
+
     // We need in 2 credit pools: at tip of chain and on best CL to know if tx is mined or chainlocked
     // Sometimes that's two different blocks, sometimes not and we need to initialize 2nd creditPoolManager
-    std::optional<CCreditPool> poolCL;
-    if (pBlockIndexBestCL != nullptr) poolCL = node.creditPoolManager->GetCreditPool(pBlockIndexBestCL, Params().GetConsensus());
-    std::optional<CCreditPool> poolOnTip{};
+    std::optional<CCreditPool> poolCL = pBlockIndexBestCL ?
+            std::make_optional(node.creditPoolManager->GetCreditPool(pBlockIndexBestCL, Params().GetConsensus())) :
+            std::nullopt;
+    auto poolOnTip = [&]() -> std::optional<CCreditPool> {
+        if (pTipBlockIndex != pBlockIndexBestCL) {
+            return std::make_optional(node.creditPoolManager->GetCreditPool(pTipBlockIndex, Params().GetConsensus()));
+        }
+        return std::nullopt;
+    }();
 
     for (const auto i : irange::range(str_indexes.size())) {
         UniValue obj(UniValue::VOBJ);
@@ -415,39 +421,32 @@
             throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid index");
         }
         obj.pushKV("index", index);
-        if (poolCL.has_value() && poolCL->indexes.Contains(index)) {
-            obj.pushKV("status", "chainlocked");
-            result_arr.push_back(obj);
-            continue;
-        }
-        if (pTipBlockIndex != pBlockIndexBestCL) {
-            if (!poolOnTip.has_value()) poolOnTip = node.creditPoolManager->GetCreditPool(pTipBlockIndex, Params().GetConsensus());
-            if (poolOnTip->indexes.Contains(index)) {
-                obj.pushKV("status", "mined");
-                result_arr.push_back(obj);
-                continue;
+
+        auto status_to_push = [&]() -> std::string {
+            if (poolCL.has_value() && poolCL->indexes.Contains(index)) {
+                return "chainlocked";
+            }
+            if (poolOnTip.has_value() && poolOnTip->indexes.Contains(index)) {
+                return "mined";
             }
-        }
-        LOCK(mempool.cs);
-        bool is_mempooled = false;
-        for (const CTxMemPoolEntry& e : mempool.mapTx) {
-            if (e.GetTx().nType == CAssetUnlockPayload::SPECIALTX_TYPE) {
-                CAssetUnlockPayload assetUnlockTx;
-                if (!GetTxPayload(e.GetTx(), assetUnlockTx)) {
-                    throw JSONRPCError(RPC_TRANSACTION_ERROR, "bad-assetunlocktx-payload");
-                }
-                if (index == assetUnlockTx.getIndex()) {
-                    is_mempooled = true;
-                    break;
-                }
-            }
-        }
-        if (is_mempooled)
-            obj.pushKV("status", "mempooled");
-        else {
-            UniValue jnull(UniValue::VNULL);
-            obj.pushKV("status", jnull);
-        }
+            bool is_mempooled = [&]() {
+                LOCK(mempool.cs);
+                return std::any_of(mempool.mapTx.begin(), mempool.mapTx.end(), [index](const CTxMemPoolEntry &e) {
+                    if (e.GetTx().nType == CAssetUnlockPayload::SPECIALTX_TYPE) {
+                        if (CAssetUnlockPayload assetUnlockTx; GetTxPayload(e.GetTx(), assetUnlockTx)) {
+                            return index == assetUnlockTx.getIndex();
+                        } else {
+                            throw JSONRPCError(RPC_TRANSACTION_ERROR, "bad-assetunlocktx-payload");
+                        }
+                    }
+                    return false;
+                });
+            }();
+            return is_mempooled ? "mempooled" : "unknown";
+        };
+
+        obj.pushKV("status", status_to_push());
+
         result_arr.push_back(obj);
     }
 

src/init.cpp Outdated Show resolved Hide resolved
…l variable.

This fix unifies these objects, but it should be deglobalized instead.
Deglobalization in follow PRs
knst
knst previously approved these changes Dec 22, 2023
Copy link
Collaborator

@knst knst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

@@ -1924,8 +1925,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
node.evodb = std::make_unique<CEvoDB>(nEvoDbCache, false, fReset || fReindexChainState);
node.mnhf_manager.reset();
node.mnhf_manager = std::make_unique<CMNHFManager>(*node.evodb);
node.creditPoolManager.reset();
node.creditPoolManager = std::make_unique<CCreditPoolManager>(*node.evodb);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra \n

UdjinM6
UdjinM6 previously approved these changes Dec 22, 2023
Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

utACK

Co-authored-by: PastaPastaPasta <[email protected]>
Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK for squash merge

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

@PastaPastaPasta PastaPastaPasta merged commit 563cc34 into dashpay:develop Dec 22, 2023
7 of 8 checks passed
@ogabrielides ogabrielides deleted the get_assetunlock_chainlocks_rpc branch December 24, 2023 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RPC Some notable changes to RPC params/behaviour/descriptions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants