Skip to content

backport: Merge bitcoin#26053, 28230, 28500#7256

Open
vijaydasmp wants to merge 3 commits intodashpay:developfrom
vijaydasmp:Apr_2026_1
Open

backport: Merge bitcoin#26053, 28230, 28500#7256
vijaydasmp wants to merge 3 commits intodashpay:developfrom
vijaydasmp:Apr_2026_1

Conversation

@vijaydasmp
Copy link
Copy Markdown

@vijaydasmp vijaydasmp commented Mar 26, 2026

Bitcoin backports

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 26, 2026

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@vijaydasmp vijaydasmp changed the title backport: Merge bitcoin#26532, 28500, 28230, 26053, 19909, 26656 backport: Merge bitcoin#26532, 28500, 28230, 26053, 19909 Mar 26, 2026
@vijaydasmp vijaydasmp force-pushed the Apr_2026_1 branch 6 times, most recently from bacccf0 to ad5b88e Compare April 2, 2026 14:04
@vijaydasmp vijaydasmp changed the title backport: Merge bitcoin#26532, 28500, 28230, 26053, 19909 backport: Merge bitcoin#19909, 26053, 28230, 28500, 28170 Apr 3, 2026
@vijaydasmp vijaydasmp force-pushed the Apr_2026_1 branch 6 times, most recently from 7d1f6e8 to cc8a5b2 Compare April 7, 2026 15:21
achow101 and others added 3 commits April 9, 2026 08:01
…unless 'inputs' are provided

b00fc44 test: add coverage for 'add_inputs' dynamic default value (furszy)
ddbcfdf RPC: bugfix, 'add_inputs' default value is true unless 'inputs' are provided (furszy)

Pull request description:

  This bugfix was meant to be in bitcoin#25685, but decoupled it to try to make it part of 24.0 release.
  It's a truly misleading functionality.

  This PR doesn't change behavior in any way. Just fixes two invalid RPC help messages and adds test
  coverage for the current behavior.

  #### Description
  In both RPC commands `send()` and `walletcreatefundedpsbt` the help message says
  that `add_inputs` default value is false when it's actually dynamically set by the following statement:

  ```c++
  coin_control.m_allow_other_inputs = rawTx.vin.size() == 0;
  ```

  Which means that, by default, `add_inputs` is true unless there is any pre-set input, in which
  case, the default is false.

ACKs for top commit:
  achow101:
    ACK b00fc44
  S3RK:
    ACK b00fc44

Tree-SHA512: 5c68a40d81c994e0ab6de0817db69c4d3dea3a9a64a60362531bf583b7a4c37d524b740905a3f3a89cdbf221913ff5b504746625adb8622788aea93a35bbcd40
c00000d rpc: Add MaybeArg() and Arg() default helper (MarcoFalke)

Pull request description:

  Currently the RPC method implementations have many issues:

  * Default RPC argument values (and their optionality state) are duplicated in the documentation and the C++ code, with no checks to prevent them from going out of sync.
  * Getting an optional RPC argument is verbose, using a ternary operator, or worse, a multi-line `if`.

  Fix all issues by adding default helper that can be called via `self.Arg<int>(0)`. The helper needs a few lines of code in the `src/rpc/util.h` header file. Everything else will be implemented in the cpp file once and if an RPC method needs it.

  There is also an `self.MaybeArg<int>(0)` helper that works on any arg to return the argument, the default, or a falsy value.

ACKs for top commit:
  ajtowns:
    reACK c00000d
  stickies-v:
    re-ACK c00000d
  TheCharlatan:
    re-ACK c00000d

Tree-SHA512: e7ddcab3faa319bc53edbdf3f89ce83389d2c4e571d5db42401620ff105e522a4a0669dad08e08cde5fd05c790aec3b806f63261a9100c2778865a489e57381e
…ting secure memory

6ef405d key: don't allocate secure mem for null (invalid) key (Pieter Wuille)
d9841a7 Add make_secure_unique helper (Anthony Towns)

Pull request description:

  Bitcoin Core has `secure_allocator`, which allocates inside special "secure" (non-swappable) memory pages, which may be limited in availability. Currently, every `CKey` object uses 32 such secure bytes, even when the `CKey` object contains the (invalid) value zero.

  Change this to not use memory when the `CKey` is invalid. This is particularly relevant for `BIP324Cipher` which briefly holds a `CKey`, but after receiving the remote's public key and initializing the encryption ciphers, the key is wiped. In case secure memory usage is in high demand, it'd be silly to waste it on P2P encryption keys instead of wallet keys.

ACKs for top commit:
  ajtowns:
    ACK 6ef405d
  john-moffett:
    ACK 6ef405d

Tree-SHA512: 987f4376ed825daf034ea4d7c4b4952fe664b25b48f1c09fbcfa6257a40b06c4da7c2caaafa35c346c86bdf298ae21f16c68ea4b1039836990d1a205de2034fd
@vijaydasmp vijaydasmp changed the title backport: Merge bitcoin#19909, 26053, 28230, 28500, 28170 backport: Merge bitcoin#26053, 28230, 28500 Apr 9, 2026
@vijaydasmp vijaydasmp marked this pull request as ready for review April 9, 2026 14:37
@thepastaclaw
Copy link
Copy Markdown

thepastaclaw commented Apr 9, 2026

✅ Review complete (commit e6df404)

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Walkthrough

This pull request refactors key validity tracking and RPC parameter handling across multiple systems. The cryptographic key storage mechanism in src/key.cpp and src/key.h is migrated from a boolean validity flag (fValid) to pointer-based presence checking using a newly introduced secure_unique_ptr<KeyType>, with explicit allocation and clearing operations. A new secure RAII wrapper infrastructure (SecureUniqueDeleter and make_secure_unique) is added to src/support/allocators/secure.h. Concurrently, RPC parameter handling is refactored across src/rpc/util.h and src/rpc/util.cpp to replace manual request.params indexing with a type-safe template-based API (Arg<T>() and MaybeArg<T>()), with supporting implementations and default-value logic. Existing RPC handlers in mining, wallet, and other modules are updated to use the new API, and new functional test coverage is added for the modified wallet funding behavior.

Sequence Diagrams

sequenceDiagram
    participant Handler as RPC Handler
    participant HelpMan as RPCHelpMan
    participant ArgValue as ArgValue Impl
    participant Request as JSONRPCRequest
    
    Handler->>HelpMan: self.Arg<T>(i) or self.MaybeArg<T>(i)
    HelpMan->>HelpMan: store m_req = &request
    HelpMan->>ArgValue: compute ArgValue<T>(i)
    ArgValue->>Request: check param presence & type
    
    alt Arg<T>: required or default present
        ArgValue->>Request: extract and convert value
        ArgValue-->>HelpMan: return T (by value/ref)
    else MaybeArg<T>: optional without default
        ArgValue-->>HelpMan: return empty optional or nullptr
    end
    
    HelpMan-->>Handler: return typed argument
    Handler->>Handler: use typed parameter
Loading
sequenceDiagram
    participant Code as Calling Code
    participant CKey as CKey Instance
    participant Keydata as secure_unique_ptr<KeyType>
    participant Secp as libsecp256k1
    
    Code->>CKey: MakeNewKey() or Load()
    CKey->>CKey: MakeKeyData() - allocate if needed
    CKey->>Keydata: allocate via make_secure_unique
    CKey->>CKey: fill/copy key bytes into *keydata
    
    Code->>CKey: Sign() or Negate()
    CKey->>CKey: assert(keydata != nullptr)
    
    alt keydata present
        CKey->>Secp: pass keydata->data()
        Secp-->>CKey: return result
    else keydata absent (nullptr)
        CKey->>CKey: abort via assert
    end
    
    Code->>CKey: Derive() or other operation
    CKey->>CKey: on failure: ClearKeyData()
    CKey->>Keydata: reset to nullptr
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: backporting three Bitcoin PRs related to RPC improvements and memory optimization.
Description check ✅ Passed The description is very brief but related to the changeset, indicating these are Bitcoin backports without specific details.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/support/allocators/secure.h (1)

12-14: ⚠️ Potential issue | 🔴 Critical

Add #include <utility> and fix the std::forward template argument on line 79.

Line 79 is ill-formed: std::forward requires an explicit template argument. This header is also missing a direct include of <utility>, which declares std::forward, and should not rely on transitive includes.

Proposed fix
 `#include` <memory>
 `#include` <string>
+#include <utility>
 `#include` <vector>
@@
-        return secure_unique_ptr<T>(new (p) T(std::forward(as)...));
+        return secure_unique_ptr<T>(new (p) T(std::forward<Args>(as)...));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/support/allocators/secure.h` around lines 12 - 14, Add a direct include
for <utility> at the top of secure.h and correct the ill-formed std::forward
usage by supplying the proper template parameter; e.g., if the forwarding occurs
inside a template<typename T> function or template<typename... Args> wrapper,
replace std::forward(arg) with std::forward<T>(arg) or std::forward<Args>(arg)
respectively so the template argument is explicit (update the forward call at
the site currently using std::forward without a template argument).
🧹 Nitpick comments (1)
src/rpc/util.h (1)

399-422: Constrain the Arg() / MaybeArg() template API to prevent link-time failures for unsupported types.

The templates accept broad parameter types via if constexpr dispatch, but src/rpc/util.cpp:572-579 provides only six ArgValue specializations: std::optional<double>, std::optional<bool>, const std::string*, int, uint64_t, and const std::string&.

Currently, all call sites (Arg<int>, Arg<uint64_t>, Arg<std::string>, MaybeArg<bool>, MaybeArg<std::string>) are covered. However, adding an unsupported type like Arg<int64_t> or MaybeArg<int> would compile here but fail only at link time.

Consider using static_assert, concepts, or explicit overloads to narrow the API surface and catch misuse in the header.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/rpc/util.h` around lines 399 - 422, The Arg/MaybeArg templates can accept
unsupported R and only fail at link time because ArgValue has a limited set of
specializations; add a compile-time guard in the header to reject unsupported
types: inside template<typename R> auto Arg(size_t i) and template<typename R>
auto MaybeArg(size_t i) add a static_assert (or a small concept) that constrains
R to the explicit types supported by ArgValue (for Arg: int, uint64_t, const
std::string&, and numeric types you actually specialize like double if present;
for MaybeArg: std::optional<double>, std::optional<bool>, const std::string*),
or rewrite the overloads to only provide those valid instantiations; reference
Arg, MaybeArg and ArgValue when implementing the static_assert/concept so misuse
(e.g. Arg<int64_t> or MaybeArg<int>) fails at compile time rather than link
time.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/rpc/util.cpp`:
- Around line 539-549: DetailMaybeArg() currently returns an RPCArg::Default as
if it were an actual UniValue param, causing MaybeArg<T>() to be unable to
distinguish an omitted argument from an explicitly provided default; modify
DetailMaybeArg() (and the similar block at 560-579) so that it returns nullptr
when the request omits the parameter even if param.m_fallback holds
RPCArg::Default, and only return a pointer to the documented default for callers
that expect a materialized default (e.g., Arg()); adjust callers of
DetailMaybeArg()/MaybeArg<T>() accordingly so MaybeArg<T>() treats nullptr as
"omitted" while Arg() still receives the fallback value when necessary.

In `@src/support/allocators/secure.h`:
- Around line 63-66: The SecureUniqueDeleter::operator()(T* t) currently
deallocates storage without running the destructor for non-trivial T; update
operator() to first call std::destroy_at(t) (to run T's destructor) and then
call secure_allocator<T>().deallocate(t, 1) to free the storage. Make sure to
include <memory> or <iterator> as needed for std::destroy_at and keep the
noexcept specification. This change should be made inside the
SecureUniqueDeleter struct's operator() to ensure placement-new constructed
objects are properly destroyed before deallocation.

In `@test/functional/wallet_fundrawtransaction.py`:
- Around line 1089-1090: The loop variable named input in
test/functional/wallet_fundrawtransaction.py shadows the built-in input() (Ruff
A001); rename the loop variable (both occurrences used over decoded_psbt_inputs)
to a non-builtin name like psbt_input or decoded_input and update any uses
inside the loop (e.g., input["txid"]) accordingly so the tests reference the new
variable name everywhere within each loop (check both the loop at the
decoded_psbt_inputs iteration and the later loop around line 1128).

---

Outside diff comments:
In `@src/support/allocators/secure.h`:
- Around line 12-14: Add a direct include for <utility> at the top of secure.h
and correct the ill-formed std::forward usage by supplying the proper template
parameter; e.g., if the forwarding occurs inside a template<typename T> function
or template<typename... Args> wrapper, replace std::forward(arg) with
std::forward<T>(arg) or std::forward<Args>(arg) respectively so the template
argument is explicit (update the forward call at the site currently using
std::forward without a template argument).

---

Nitpick comments:
In `@src/rpc/util.h`:
- Around line 399-422: The Arg/MaybeArg templates can accept unsupported R and
only fail at link time because ArgValue has a limited set of specializations;
add a compile-time guard in the header to reject unsupported types: inside
template<typename R> auto Arg(size_t i) and template<typename R> auto
MaybeArg(size_t i) add a static_assert (or a small concept) that constrains R to
the explicit types supported by ArgValue (for Arg: int, uint64_t, const
std::string&, and numeric types you actually specialize like double if present;
for MaybeArg: std::optional<double>, std::optional<bool>, const std::string*),
or rewrite the overloads to only provide those valid instantiations; reference
Arg, MaybeArg and ArgValue when implementing the static_assert/concept so misuse
(e.g. Arg<int64_t> or MaybeArg<int>) fails at compile time rather than link
time.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9483933d-8d02-4b56-b844-6d794c318a00

📥 Commits

Reviewing files that changed from the base of the PR and between 31c8464 and e6df404.

📒 Files selected for processing (10)
  • src/key.cpp
  • src/key.h
  • src/rpc/mining.cpp
  • src/rpc/util.cpp
  • src/rpc/util.h
  • src/support/allocators/secure.h
  • src/wallet/rpc/coins.cpp
  • src/wallet/rpc/spend.cpp
  • src/wallet/rpc/wallet.cpp
  • test/functional/wallet_fundrawtransaction.py

Comment on lines +539 to +549
static const UniValue* DetailMaybeArg(CheckFn* check, const std::vector<RPCArg>& params, const JSONRPCRequest* req, size_t i)
{
CHECK_NONFATAL(i < params.size());
const UniValue& arg{CHECK_NONFATAL(req)->params[i]};
const RPCArg& param{params.at(i)};
if (check) check(param);

if (!arg.isNull()) return &arg;
if (!std::holds_alternative<RPCArg::Default>(param.m_fallback)) return nullptr;
return &std::get<RPCArg::Default>(param.m_fallback);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep MaybeArg() from materializing documented defaults.

DetailMaybeArg() feeds RPCArg::Default back to both Arg() and MaybeArg(). For MaybeArg<T>(), that makes an omitted parameter with a documented default indistinguishable from an explicitly provided value, which defeats callers that need to detect omission separately.

🛠️ One way to preserve omission for MaybeArg()
-static const UniValue* DetailMaybeArg(CheckFn* check, const std::vector<RPCArg>& params, const JSONRPCRequest* req, size_t i)
+static const UniValue* DetailMaybeArg(CheckFn* check, bool use_default, const std::vector<RPCArg>& params, const JSONRPCRequest* req, size_t i)
 {
     CHECK_NONFATAL(i < params.size());
     const UniValue& arg{CHECK_NONFATAL(req)->params[i]};
     const RPCArg& param{params.at(i)};
     if (check) check(param);

     if (!arg.isNull()) return &arg;
-    if (!std::holds_alternative<RPCArg::Default>(param.m_fallback)) return nullptr;
+    if (!use_default || !std::holds_alternative<RPCArg::Default>(param.m_fallback)) return nullptr;
     return &std::get<RPCArg::Default>(param.m_fallback);
 }

-#define TMPL_INST(check_param, ret_type, return_code)       \
+#define TMPL_INST(check_param, use_default, ret_type, return_code) \
     template <>                                             \
     ret_type RPCHelpMan::ArgValue<ret_type>(size_t i) const \
     {                                                       \
         const UniValue* maybe_arg{                          \
-            DetailMaybeArg(check_param, m_args, m_req, i),  \
+            DetailMaybeArg(check_param, use_default, m_args, m_req, i), \
         };                                                  \
         return return_code                                  \
     }                                                       \
     void force_semicolon(ret_type)

-TMPL_INST(nullptr, std::optional<double>, maybe_arg ? std::optional{maybe_arg->get_real()} : std::nullopt;);
-TMPL_INST(nullptr, std::optional<bool>, maybe_arg ? std::optional{maybe_arg->get_bool()} : std::nullopt;);
-TMPL_INST(nullptr, const std::string*, maybe_arg ? &maybe_arg->get_str() : nullptr;);
+TMPL_INST(nullptr, false, std::optional<double>, maybe_arg ? std::optional{maybe_arg->get_real()} : std::nullopt;);
+TMPL_INST(nullptr, false, std::optional<bool>, maybe_arg ? std::optional{maybe_arg->get_bool()} : std::nullopt;);
+TMPL_INST(nullptr, false, const std::string*, maybe_arg ? &maybe_arg->get_str() : nullptr;);

-TMPL_INST(CheckRequiredOrDefault, int, CHECK_NONFATAL(maybe_arg)->getInt<int>(););
-TMPL_INST(CheckRequiredOrDefault, uint64_t, CHECK_NONFATAL(maybe_arg)->getInt<uint64_t>(););
-TMPL_INST(CheckRequiredOrDefault, const std::string&, CHECK_NONFATAL(maybe_arg)->get_str(););
+TMPL_INST(CheckRequiredOrDefault, true, int, CHECK_NONFATAL(maybe_arg)->getInt<int>(););
+TMPL_INST(CheckRequiredOrDefault, true, uint64_t, CHECK_NONFATAL(maybe_arg)->getInt<uint64_t>(););
+TMPL_INST(CheckRequiredOrDefault, true, const std::string&, CHECK_NONFATAL(maybe_arg)->get_str(););

Also applies to: 560-579

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/rpc/util.cpp` around lines 539 - 549, DetailMaybeArg() currently returns
an RPCArg::Default as if it were an actual UniValue param, causing MaybeArg<T>()
to be unable to distinguish an omitted argument from an explicitly provided
default; modify DetailMaybeArg() (and the similar block at 560-579) so that it
returns nullptr when the request omits the parameter even if param.m_fallback
holds RPCArg::Default, and only return a pointer to the documented default for
callers that expect a materialized default (e.g., Arg()); adjust callers of
DetailMaybeArg()/MaybeArg<T>() accordingly so MaybeArg<T>() treats nullptr as
"omitted" while Arg() still receives the fallback value when necessary.

Comment on lines +63 to +66
struct SecureUniqueDeleter {
void operator()(T* t) noexcept {
secure_allocator<T>().deallocate(t, 1);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In C++20, when a std::unique_ptr uses a custom deleter for an object created with placement new, is the deleter responsible for calling std::destroy_at (or the destructor) before deallocating the raw storage?

💡 Result:

Yes.

std::unique_ptr<T, D>’s destructor does not inherently “know” whether T was created by a normal new expression or by placement new; it simply calls the stored deleter with the stored pointer, and the deleter is required to “dispose of the pointer as appropriate for that deleter” (i.e., do whatever cleanup is correct for how the object/storage were created). [1]

For an object created with placement new, destruction and storage release are separate steps: the destructor is not called implicitly later—you must call it explicitly (e.g., via std::destroy_at(p) or p->~T()), and then (optionally) deallocate the raw storage by whatever mechanism originally provided it. [2] Also, std::destroy_at is purely destruction (it does not deallocate). [3]

So if your unique_ptr owns both:

  • the object lifetime created by placement new, and
  • the raw storage that must later be freed,

then your custom deleter should typically do both:

struct Del {
  void operator()(T* p) const noexcept {
    std::destroy_at(p);          // end lifetime
    ::operator delete(p);        // or pool.free(p), std::free(p), etc.
  }
};

If the storage must not be freed (e.g., stack/arena freed elsewhere), the deleter should destroy only.

Sources: [1] std::unique_ptr deleter requirements / disposal semantics (cppreference) [2] placement-new requires explicit destructor call (ISO C++ FAQ) [3] destroy uses std::destroy_at (cppreference allocator_traits::destroy)


Call std::destroy_at() before deallocating storage.

SecureUniqueDeleter deallocates raw storage without destroying the managed object. For non-trivial types T, this skips the destructor and can leak nested resources or bypass required cleanup. Since the object is created via placement new, the deleter must explicitly destroy it before freeing the storage.

Proposed fix
 template<typename T>
 struct SecureUniqueDeleter {
     void operator()(T* t) noexcept {
-        secure_allocator<T>().deallocate(t, 1);
+        if (t) {
+            std::destroy_at(t);
+            secure_allocator<T>().deallocate(t, 1);
+        }
     }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
struct SecureUniqueDeleter {
void operator()(T* t) noexcept {
secure_allocator<T>().deallocate(t, 1);
}
struct SecureUniqueDeleter {
void operator()(T* t) noexcept {
if (t) {
std::destroy_at(t);
secure_allocator<T>().deallocate(t, 1);
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/support/allocators/secure.h` around lines 63 - 66, The
SecureUniqueDeleter::operator()(T* t) currently deallocates storage without
running the destructor for non-trivial T; update operator() to first call
std::destroy_at(t) (to run T's destructor) and then call
secure_allocator<T>().deallocate(t, 1) to free the storage. Make sure to include
<memory> or <iterator> as needed for std::destroy_at and keep the noexcept
specification. This change should be made inside the SecureUniqueDeleter
struct's operator() to ensure placement-new constructed objects are properly
destroyed before deallocation.

Comment on lines +1089 to +1090
for input in decoded_psbt_inputs:
assert_equal(input["txid"], source_tx["txid"])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify builtin-shadowing occurrences in this test file
rg -nP '\bfor\s+input\s+in\b' test/functional/wallet_fundrawtransaction.py

Repository: dashpay/dash

Length of output: 1769


🏁 Script executed:

#!/bin/bash
# Search for 'for input in' patterns in the wallet_fundrawtransaction.py test file
cd test/functional
if [ -f wallet_fundrawtransaction.py ]; then
    echo "=== Searching for 'for input in' patterns ==="
    rg -n 'for\s+input\s+in' wallet_fundrawtransaction.py
    echo ""
    echo "=== Context around first match (lines 1085-1095) ==="
    sed -n '1085,1095p' wallet_fundrawtransaction.py
    echo ""
    echo "=== Context around second match (lines 1124-1134) ==="
    sed -n '1124,1134p' wallet_fundrawtransaction.py
else
    echo "File not found"
fi

Repository: dashpay/dash

Length of output: 1445


Fix Ruff A001: avoid shadowing builtin input.

Lines 1089 and 1128 use input as a loop variable, which shadows Python's builtin input() function and triggers Ruff A001 linting violations.

Proposed rename
-        for input in decoded_psbt_inputs:
-            assert_equal(input["txid"], source_tx["txid"])
+        for vin in decoded_psbt_inputs:
+            assert_equal(vin["txid"], source_tx["txid"])

This applies to both occurrences at lines 1089 and 1128.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for input in decoded_psbt_inputs:
assert_equal(input["txid"], source_tx["txid"])
for vin in decoded_psbt_inputs:
assert_equal(vin["txid"], source_tx["txid"])
🧰 Tools
🪛 Ruff (0.15.9)

[error] 1089-1089: Variable input is shadowing a Python builtin

(A001)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/functional/wallet_fundrawtransaction.py` around lines 1089 - 1090, The
loop variable named input in test/functional/wallet_fundrawtransaction.py
shadows the built-in input() (Ruff A001); rename the loop variable (both
occurrences used over decoded_psbt_inputs) to a non-builtin name like psbt_input
or decoded_input and update any uses inside the loop (e.g., input["txid"])
accordingly so the tests reference the new variable name everywhere within each
loop (check both the loop at the decoded_psbt_inputs iteration and the later
loop around line 1128).

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6df404452

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

TMPL_INST(nullptr, const std::string*, maybe_arg ? &maybe_arg->get_str() : nullptr;);

// Required arg or optional arg with default value.
TMPL_INST(CheckRequiredOrDefault, int, CHECK_NONFATAL(maybe_arg)->getInt<int>(););
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return type errors for null required RPC args

ArgValue<int>/ArgValue<const std::string&> now does CHECK_NONFATAL(maybe_arg); when a required parameter is explicitly passed as null, DetailMaybeArg() returns nullptr and this path raises NonFatalCheckError instead of a UniValue::type_error. For RPCs switched to self.Arg<...>() (e.g. generatetodescriptor), malformed input now surfaces as internal RPC_MISC_ERROR rather than a normal type error, which changes API behavior and leaks internal-bug messaging for user input.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

I validated the successful agent output against the checked-out source and patch scope. The backport appears mechanically clean overall, but the newly added make_secure_unique helper is not a correct general-purpose forwarding helper because its forwarding expression is malformed and fails on any non-empty argument pack.

Reviewed commit: e6df404

💬 1 nitpick(s)


// initialize in place, and return as secure_unique_ptr
try {
return secure_unique_ptr<T>(new (p) T(std::forward(as)...));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💬 Nitpick: make_secure_unique cannot forward constructor arguments

The new make_secure_unique template is declared as a variadic helper, but it constructs T with std::forward(as)... instead of std::forward<Args>(as).... That expression cannot instantiate for any non-empty argument pack, so the helper only works for default construction despite being introduced as a generic std::make_unique-style utility. The current CKey call site default-constructs KeyType, so this backport still works as used here, but the helper itself is defective as added in this PR.

💡 Suggested change
Suggested change
return secure_unique_ptr<T>(new (p) T(std::forward(as)...));
return secure_unique_ptr<T>(new (p) T(std::forward<Args>(as)...));

source: ['codex-general']

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants