Skip to content

feat: update gRPC to now use kernel_id as a primary tx id#7140

Closed
fluffypony wants to merge 2 commits intotari-project:developmentfrom
fluffypony:kernel_id
Closed

feat: update gRPC to now use kernel_id as a primary tx id#7140
fluffypony wants to merge 2 commits intotari-project:developmentfrom
fluffypony:kernel_id

Conversation

@fluffypony
Copy link
Copy Markdown
Contributor

@fluffypony fluffypony commented May 31, 2025

Description

Implement comprehensive gRPC API unification by transitioning from internal database transaction IDs to human-readable kernel IDs across the entire wallet ecosystem. This PR unifies transaction identification across gRPC API, console wallet UI, and FFI layer, replacing internal database IDs with blockchain-native kernel IDs (hex-encoded excess signatures) while maintaining full backwards compatibility.

Motivation and Context

This PR addresses the fragmented transaction identification system across Tari's wallet ecosystem. Previously, different components used inconsistent transaction identifiers:

  • gRPC API: Used internal database transaction_id and tx_id fields
  • Console wallet UI: Displayed internal transaction IDs
  • FFI layer: Exposed internal database IDs to external applications

The unified approach provides:

  1. Consistent identification: Same kernel ID across all wallet interfaces
  2. Human-readable IDs: Hex-encoded excess signatures that users can verify
  3. Blockchain-native: Kernel IDs are actual blockchain identifiers, not implementation details
  4. Backwards compatibility: All existing integrations continue to work unchanged

How Has This Been Tested?

  • gRPC API: Tested all transaction-related endpoints with new internal_dbid and kernel_id fields
  • Console wallet UI: Verified transaction list and detail views display kernel IDs correctly
  • FFI layer: Tested both new kernel ID functions and existing deprecated functions
  • Integration testing: End-to-end transaction workflows verified across all interfaces
  • Backwards compatibility: Existing gRPC clients and FFI applications tested to ensure no breaking changes
  • Compilation: All components compile successfully with new field mappings

What process can a PR reviewer use to test or verify this change?

  1. gRPC API Testing:

    # Start wallet with gRPC enabled
    # Test transaction endpoints and verify response structure
    # Check that both internal_dbid and kernel_id fields are populated
    # Verify deprecated endpoints still work
  2. Console Wallet UI Testing:

    • Run console wallet: cargo run --bin minotari_console_wallet
    • Navigate to transactions tab and verify "Kernel ID" column headers
    • Check transaction details show kernel IDs and excess signatures
    • Verify kernel ID formatting (truncated display: 12345678...87654321)
  3. FFI Layer Testing:

    cargo test -p minotari_wallet_ffi
    # Test new kernel ID functions: *_get_kernel_id()
    # Test kernel ID lookup functions: *_by_kernel_id()
    # Verify existing *_get_transaction_id() functions still work
  4. Integration Testing:

    • Send a transaction and verify the same kernel ID appears in:
      • gRPC API responses (kernel_id field)
      • Console wallet UI display
      • FFI function returns
    • Test transaction lookup by both internal ID and kernel ID
  5. Backwards Compatibility:

    • Verify existing gRPC clients work with deprecated endpoints
    • Test existing FFI applications continue functioning
    • Check deprecation warnings are properly displayed

Breaking Changes

  • None
  • Requires data directory on base node to be deleted
  • Requires hard fork
  • Other - Please specify
    Exchanges and third-party integrations relying on transaction_id must now use the WalletDeprecated service instead of Wallet.

Summary by CodeRabbit

  • New Features

    • Added a new field, kernel_id, to transaction-related responses for enhanced transaction identification.
    • Introduced a deprecated service to maintain backward compatibility with legacy clients.
    • Added support for fetching blocks by height via a new RPC method.
    • Added a diagnostic method to log all transaction kernel signatures.
    • Added kernel ID display in transaction lists and detailed views in the wallet UI.
  • Refactor

    • Standardized transaction identifier fields from transaction_id/tx_id to internal_dbid across all wallet gRPC responses and requests.
    • Replaced excess signature with kernel ID in transaction info structures and UI.
    • Updated transaction event notifications to show kernel ID or fallback to transaction ID.
  • Chores

    • Updated dependencies to include an additional feature flag for improved functionality.
    • Enhanced transaction status checks to migrate missing kernel signatures by fetching from base node.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented May 31, 2025

## Walkthrough

The changes standardize transaction identifier fields in wallet gRPC protocol buffers and server code from `transaction_id`/`tx_id` to `internal_dbid`, and introduce a new `kernel_id` field for transaction responses. Backward compatibility is maintained by adding a deprecated service and message types using the original field names.

## Changes

| File(s)                                                                                 | Change Summary                                                                                                    |
|-----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| applications/minotari_app_grpc/proto/wallet.proto                                       | Renamed all transaction ID fields to `internal_dbid`, added `kernel_id` to transaction messages, adjusted field numbers, introduced `WalletDeprecated` service and deprecated message types for backward compatibility. |
| applications/minotari_app_grpc/src/conversions/transaction.rs                           | Added `not_found` constructor to `grpc::TransactionInfo`, updated for new identifier fields, annotated deprecated compatibility function. |
| applications/minotari_console_wallet/Cargo.toml                                         | Added `"base_node"` feature to `tari_core` dependency.                                                           |
| applications/minotari_console_wallet/src/grpc/wallet_grpc_server.rs                     | Replaced `transaction_id` with `internal_dbid`, added `kernel_id` to transaction-related responses and conversions throughout the gRPC server implementation. |
| applications/minotari_console_wallet/src/ui/components/transactions_tab.rs              | Added explicit type annotations for transaction list columns, introduced a new "Kernel ID" column in completed transactions list, updated detailed transaction view label and content to show kernel ID. |
| applications/minotari_console_wallet/src/ui/state/app_state.rs                          | Added async method to fetch kernel ID by transaction ID, replaced `excess_signature` field with `kernel_id` in `CompletedTransactionInfo`. |
| applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs               | Replaced raw transaction ID in notifications with kernel ID or fallback to transaction ID via new async helper method. |
| base_layer/core/src/base_node/proto/wallet_rpc.proto                                   | Added `GetBlocksRequest` and `GetBlocksResponse` messages and imported `block.proto`.                            |
| base_layer/core/src/base_node/rpc/mod.rs                                               | Added new RPC method `get_blocks` to `BaseNodeWalletService` trait.                                              |
| base_layer/core/src/base_node/rpc/service.rs                                           | Implemented `get_blocks` RPC method fetching blocks by heights with validation and error handling.               |
| base_layer/wallet/src/transaction_service/service.rs                                  | Added async diagnostic method to log kernel signatures of all completed transactions, invoked at service start.  |
| base_layer/wallet/src/transaction_service/tasks/check_faux_transaction_status.rs      | Extended transaction status check to update missing kernel signatures by fetching blocks from base node and updating transactions accordingly. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Client
    participant WalletGrpcServer
    participant WalletDB

    Client->>WalletGrpcServer: Send transaction-related request
    WalletGrpcServer->>WalletDB: Query or update transaction
    WalletDB-->>WalletGrpcServer: Return transaction with internal_dbid, kernel_id
    WalletGrpcServer-->>Client: Respond with internal_dbid, kernel_id in response message

Possibly related PRs

  • tari-project/tari#7078: Adds new ImportTransactions RPC and related messages using old transaction identifier fields, which are updated in this PR for consistency and backward compatibility.
  • tari-project/tari#7117: Enhances transaction info with input/output commitments and async conversion, related to transaction info handling alongside identifier field changes in this PR.

Suggested reviewers

  • SWvheerden

Poem

In the fields where kernels hide,
Rabbits hop with glee and pride—
“No more tx_id!” they cheer,
“internal_dbid is crystal clear!
Kernel IDs now join the fun,
Backward trails for everyone—
Hop, hop, hop, the migration’s done!” 🐇✨


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=tari-project/tari&utm_content=7140):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@github-actions
Copy link
Copy Markdown

github-actions bot commented May 31, 2025

Test Results (Integration tests)

0 tests  ±0   0 ✅ ±0   0s ⏱️ ±0s
0 suites ±0   0 💤 ±0 
0 files   ±0   0 ❌ ±0 

Results for commit 40b3be2. ± Comparison against base commit c452f40.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions bot commented May 31, 2025

Test Results (CI)

0 tests   0 ✅  0s ⏱️
0 suites  0 💤
0 files    0 ❌

Results for commit 40b3be2.

♻️ This comment has been updated with latest results.

@fluffypony fluffypony requested a review from a team as a code owner June 1, 2025 08:05
Copy link
Copy Markdown
Contributor

@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

🧹 Nitpick comments (1)
base_layer/wallet/src/transaction_service/service.rs (1)

3896-3940: Consider performance optimization and logging level adjustment.

The diagnostic method is well-implemented but has some areas for improvement:

  1. Performance concern: Retrieving and processing ALL completed transactions could be expensive for wallets with many transactions. Consider adding pagination or a transaction limit for the diagnostic.

  2. Logging verbosity: Using INFO level for potentially hundreds/thousands of transactions might be too verbose for production logs. Consider using DEBUG level or adding a configuration flag to control this diagnostic.

  3. Method signature: The method is marked async but doesn't perform any actual async operations - get_completed_transactions() appears to be synchronous.

Consider these improvements:

-    async fn log_all_transaction_signatures(&self) {
+    fn log_all_transaction_signatures(&self) {
         info!(target: LOG_TARGET, "Starting diagnostic dump of all transaction kernel signatures");
         
-        // Get all completed transactions
-        let all_transactions = match self.db.get_completed_transactions(None, None, None) {
+        // Get completed transactions with a reasonable limit for diagnostics
+        let all_transactions = match self.db.get_completed_transactions(None, None, Some(1000)) {
             Ok(txs) => txs,
             Err(e) => {
                 error!(target: LOG_TARGET, "Failed to retrieve completed transactions for diagnostic: {}", e);
                 return;
             }
         };
         
-        info!(target: LOG_TARGET, "Diagnostic: Found {} total completed transactions", all_transactions.len());
+        debug!(target: LOG_TARGET, "Diagnostic: Found {} completed transactions", all_transactions.len());
         
         for tx in all_transactions {
             if let Some(kernel_sig) = tx.transaction.first_kernel_excess_sig() {
                 // ... existing logic ...
                 
-                info!(
+                debug!(
                     target: LOG_TARGET,
                     "Transaction {}: sig_hex={}, nonce_hex={}, is_empty_sig={}, is_empty_nonce={}",
                     tx.tx_id, sig_hex, nonce_hex, is_empty_sig, is_empty_nonce
                 );
             } else {
-                warn!(
+                debug!(
                     target: LOG_TARGET,
                     "Transaction {} has no kernel signatures",
                     tx.tx_id
                 );
             }
         }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a313c69 and 40b3be2.

📒 Files selected for processing (8)
  • applications/minotari_console_wallet/src/ui/components/transactions_tab.rs (7 hunks)
  • applications/minotari_console_wallet/src/ui/state/app_state.rs (4 hunks)
  • applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs (6 hunks)
  • base_layer/core/src/base_node/proto/wallet_rpc.proto (2 hunks)
  • base_layer/core/src/base_node/rpc/mod.rs (2 hunks)
  • base_layer/core/src/base_node/rpc/service.rs (2 hunks)
  • base_layer/wallet/src/transaction_service/service.rs (5 hunks)
  • base_layer/wallet/src/transaction_service/tasks/check_faux_transaction_status.rs (4 hunks)
✅ Files skipped from review due to trivial changes (1)
  • base_layer/core/src/base_node/proto/wallet_rpc.proto
🧰 Additional context used
🧬 Code Graph Analysis (1)
base_layer/core/src/base_node/rpc/mod.rs (1)
base_layer/core/src/base_node/rpc/service.rs (1)
  • get_blocks (713-752)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: test (mainnet, stagenet)
  • GitHub Check: Cucumber tests / FFI
  • GitHub Check: Cucumber tests / Base Layer
  • GitHub Check: test (nextnet, nextnet)
  • GitHub Check: test (testnet, esmeralda)
  • GitHub Check: ci
  • GitHub Check: cargo check with stable
🔇 Additional comments (19)
base_layer/core/src/base_node/rpc/mod.rs (2)

32-33: LGTM! Imports are correctly added.

The new protobuf imports for GetBlocksRequest and GetBlocksResponse are properly added and align with the new RPC method being introduced.


137-141: LGTM! RPC method declaration follows existing patterns.

The new get_blocks method is correctly declared with:

  • Sequential RPC method number (14)
  • Proper async signature
  • Consistent parameter and return types following the existing pattern
applications/minotari_console_wallet/src/ui/state/wallet_event_monitor.rs (5)

107-110: LGTM! Consistent implementation of kernel ID display.

The change to use get_transaction_identifier for the "Finalized Transaction Received" notification aligns with the PR objectives to unify transaction identification using kernel IDs.


118-125: LGTM! Proper transaction identifier usage.

The transaction mined unconfirmed notification correctly uses the new identifier format, maintaining consistency across all notification types.


133-134: LGTM! Transaction confirmed notification updated correctly.

The notification message properly displays the unified transaction identifier format.


144-145: LGTM! All notification messages consistently updated.

All transaction-related notifications now use the new get_transaction_identifier method, ensuring consistent display of kernel IDs across the UI.

Also applies to: 150-152, 158-161, 180-182


408-415: Well-implemented async helper method.

The get_transaction_identifier method correctly:

  • Handles async operations with proper await
  • Provides fallback to transaction ID when kernel ID is unavailable
  • Formats the output consistently with clear labeling
base_layer/core/src/base_node/rpc/service.rs (2)

26-27: LGTM! Imports correctly added.

The protobuf imports for the new get_blocks functionality are properly included.


713-752: Well-implemented RPC method with proper safeguards.

The get_blocks implementation demonstrates good practices:

Strengths:

  • Proper input validation (empty heights check)
  • Rate limiting with reasonable maximum (100 blocks)
  • Graceful error handling that logs issues but doesn't fail the entire request
  • Efficient pre-allocation with Vec::with_capacity
  • Proper async/await usage

Security & Performance:

  • The MAX_BLOCKS_PER_REQUEST limit prevents resource exhaustion attacks
  • Individual block fetch failures are logged but don't crash the service
  • Database operations are properly awaited

The implementation aligns well with the existing codebase patterns and provides the block fetching capability needed for kernel signature updates mentioned in the PR objectives.

applications/minotari_console_wallet/src/ui/components/transactions_tab.rs (5)

104-107: Good code clarity improvement.

Adding explicit type annotations (Vec<ListItem>) to the column vectors improves code readability and makes the intent clearer, especially helpful for maintenance.


208-212: LGTM! Consistent type annotations and new column preparation.

The explicit type annotations are consistently applied, and the new column4_items vector is properly declared for the kernel ID column.


307-319: Well-implemented kernel ID display with good UX.

The kernel ID column implementation demonstrates good practices:

  • Proper handling of empty kernel IDs with "N/A" fallback
  • Sensible truncation (12 characters + "...") for table display
  • Consistent styling with existing columns
  • Clear visual indication of truncated content

326-326: Appropriate column width adjustments.

The changes properly accommodate the new kernel ID column:

  • Source/Destination Address column reduced from 95 to 75 (reasonable compromise)
  • Status column gets fixed width of 15 (good for consistency)
  • Kernel ID column uses remaining space (appropriate for variable-length IDs)

Also applies to: 329-330


354-354: Consistent UI label updates for kernel ID.

The detailed transaction view correctly transitions from "Excess sig" to "Kernel ID":

  • Label consistently updated across the UI
  • Full kernel ID displayed in detail view (not truncated)
  • Proper fallback to "N/A" with appropriate styling
  • Maintains consistent visual hierarchy

Also applies to: 369-369, 401-405, 537-537

base_layer/wallet/src/transaction_service/service.rs (3)

88-88: LGTM: Import addition for hex conversion support.

The Hex trait import is appropriately added to support hexadecimal conversion in the new diagnostic logging method.


400-402: LGTM: Appropriate placement for diagnostic startup logging.

The diagnostic function call is well-placed at the start of the main event loop, ensuring kernel signature information is logged once during service initialization.


1126-1126: LGTM: Necessary clone for parameter passing.

The .clone() addition appears to be required for passing the connectivity parameter to the check_detected_transactions function.

applications/minotari_console_wallet/src/ui/state/app_state.rs (1)

1221-1224: LGTM!

The kernel ID computation correctly extracts the hex-encoded signature from the first kernel, with proper fallback to an empty string when no kernels exist.

base_layer/wallet/src/transaction_service/tasks/check_faux_transaction_status.rs (1)

305-320: LGTM!

Good error handling for the RPC call with appropriate logging and descriptive error messages.

Comment on lines +1175 to +1189
pub async fn get_transaction_kernel_id(&self, tx_id: TxId) -> Option<String> {
let mut tx_service = self.wallet.transaction_service.clone();
if let Ok(Some(tx)) = tx_service.get_any_transaction(tx_id).await {
let completed_tx = tx.into();
if let Ok(tx_info) = CompletedTransactionInfo::from_completed_transaction(
completed_tx,
&self.get_transaction_weight()
) {
if !tx_info.kernel_id.is_empty() {
return Some(tx_info.kernel_id);
}
}
}
None
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider improving error handling and performance

The method silently returns None for all error cases without logging. This makes debugging difficult when kernel IDs are missing.

 pub async fn get_transaction_kernel_id(&self, tx_id: TxId) -> Option<String> {
-    let mut tx_service = self.wallet.transaction_service.clone();
+    let tx_service = &self.wallet.transaction_service;
     if let Ok(Some(tx)) = tx_service.get_any_transaction(tx_id).await {
         let completed_tx = tx.into();
         if let Ok(tx_info) = CompletedTransactionInfo::from_completed_transaction(
             completed_tx,
             &self.get_transaction_weight()
         ) {
             if !tx_info.kernel_id.is_empty() {
                 return Some(tx_info.kernel_id);
             }
+        } else {
+            debug!(target: LOG_TARGET, "Failed to create CompletedTransactionInfo for tx_id: {}", tx_id);
         }
+    } else {
+        trace!(target: LOG_TARGET, "Transaction not found or error fetching tx_id: {}", tx_id);
     }
     None
 }

Also, consider caching kernel IDs to avoid repeated conversions for the same transaction.

📝 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
pub async fn get_transaction_kernel_id(&self, tx_id: TxId) -> Option<String> {
let mut tx_service = self.wallet.transaction_service.clone();
if let Ok(Some(tx)) = tx_service.get_any_transaction(tx_id).await {
let completed_tx = tx.into();
if let Ok(tx_info) = CompletedTransactionInfo::from_completed_transaction(
completed_tx,
&self.get_transaction_weight()
) {
if !tx_info.kernel_id.is_empty() {
return Some(tx_info.kernel_id);
}
}
}
None
}
pub async fn get_transaction_kernel_id(&self, tx_id: TxId) -> Option<String> {
let tx_service = &self.wallet.transaction_service;
if let Ok(Some(tx)) = tx_service.get_any_transaction(tx_id).await {
let completed_tx = tx.into();
if let Ok(tx_info) = CompletedTransactionInfo::from_completed_transaction(
completed_tx,
&self.get_transaction_weight()
) {
if !tx_info.kernel_id.is_empty() {
return Some(tx_info.kernel_id);
}
} else {
debug!(
target: LOG_TARGET,
"Failed to create CompletedTransactionInfo for tx_id: {}",
tx_id
);
}
} else {
trace!(
target: LOG_TARGET,
"Transaction not found or error fetching tx_id: {}",
tx_id
);
}
None
}
🤖 Prompt for AI Agents
In applications/minotari_console_wallet/src/ui/state/app_state.rs around lines
1175 to 1189, the get_transaction_kernel_id method currently suppresses all
errors by returning None without any logging, which hinders debugging. Modify
the method to log errors or unexpected conditions when fetching or processing
the transaction fails. Additionally, implement a caching mechanism to store and
retrieve kernel IDs for transactions to improve performance by avoiding repeated
conversions for the same transaction.

Comment on lines +265 to +468
async fn fetch_and_update_kernel_signatures<TBackend: 'static + TransactionBackend, TWalletConnectivity: WalletConnectivityInterface>(
mut connectivity: TWalletConnectivity,
db: TransactionDatabase<TBackend>,
transactions: Vec<CompletedTransaction>,
) -> Result<(), TransactionServiceError> {
let mut base_node_client = match connectivity.obtain_base_node_wallet_rpc_client().await {
Some(client) => client,
None => {
return Err(TransactionServiceError::ServiceError(
"Could not connect to base node wallet RPC client".to_string(),
));
},
};

// Collect unique block heights for transactions that have mined_in_block
let mut height_to_txs: std::collections::HashMap<u64, Vec<&CompletedTransaction>> = std::collections::HashMap::new();

for tx in &transactions {
if let (Some(_), Some(height)) = (&tx.mined_in_block, tx.mined_height) {
height_to_txs.entry(height).or_insert_with(Vec::new).push(tx);
}
}

if height_to_txs.is_empty() {
info!(
target: LOG_TARGET,
"No transactions with mined height found for kernel signature migration"
);
return Ok(());
}

let heights: Vec<u64> = height_to_txs.keys().cloned().collect();
debug!(
target: LOG_TARGET,
"Fetching {} blocks for kernel signature migration: {:?}",
heights.len(),
heights
);

// Fetch blocks using GetBlocks RPC
let request = base_node_proto::GetBlocksRequest { heights };

let response = match base_node_client.get_blocks(request).await {
Ok(response) => response,
Err(e) => {
warn!(
target: LOG_TARGET,
"Failed to fetch blocks for kernel signature migration: {}",
e
);
return Err(TransactionServiceError::ServiceError(format!(
"Failed to fetch blocks: {}",
e
)));
}
};

let mut updated_count = 0;

// Process each block in the response
for historical_block in response.blocks {
let block_height = historical_block.block.as_ref()
.and_then(|b| b.header.as_ref())
.map(|h| h.height)
.unwrap_or(0);

// Get transactions for this block height
let txs_for_height = match height_to_txs.get(&block_height) {
Some(txs) => txs,
None => continue,
};

let empty_kernels = Vec::new();
let block_kernels = historical_block.block.as_ref()
.and_then(|b| b.body.as_ref())
.map(|b| &b.kernels)
.unwrap_or(&empty_kernels);

debug!(
target: LOG_TARGET,
"Processing block at height {} with {} kernels for {} transactions",
block_height,
block_kernels.len(),
txs_for_height.len()
);

// Process each transaction for this block
for tx in txs_for_height {
let mut transaction_updated = false;
let mut updated_kernels = Vec::new();

for (kernel_index, wallet_kernel) in tx.transaction.body.kernels().iter().enumerate() {
let wallet_excess = &wallet_kernel.excess;

// Find matching kernel in block by excess commitment
let matching_block_kernel = block_kernels.iter().find(|block_kernel| {
block_kernel.excess.as_ref().map_or(false, |e| e.data.as_slice() == wallet_excess.as_bytes())
});

if let Some(block_kernel) = matching_block_kernel {
// Compare signatures
let wallet_sig = &wallet_kernel.excess_sig;
let block_sig = block_kernel.excess_sig.as_ref();

if let Some(block_sig) = block_sig {
// Convert proto signature to internal format
if let Ok(block_signature) = Signature::try_from((*block_sig).clone()) {
if wallet_sig != &block_signature {
info!(
target: LOG_TARGET,
"Found matching kernel for transaction {} kernel {}: updating signature",
tx.tx_id,
kernel_index
);

// Create updated kernel with correct signature
let mut updated_kernel = wallet_kernel.clone();
updated_kernel.excess_sig = block_signature;
updated_kernels.push(updated_kernel);
transaction_updated = true;
} else {
// Kernel signature is already correct
updated_kernels.push(wallet_kernel.clone());
}
} else {
warn!(
target: LOG_TARGET,
"Failed to convert block kernel signature for transaction {} kernel {}",
tx.tx_id,
kernel_index
);
updated_kernels.push(wallet_kernel.clone());
}
} else {
warn!(
target: LOG_TARGET,
"Block kernel has no signature for transaction {} kernel {}",
tx.tx_id,
kernel_index
);
updated_kernels.push(wallet_kernel.clone());
}
} else {
warn!(
target: LOG_TARGET,
"Could not find matching kernel in block at height {} for transaction {} kernel {}",
block_height,
tx.tx_id,
kernel_index
);
// Keep the original kernel if no match found
updated_kernels.push(wallet_kernel.clone());
}
}

// Update the transaction if any kernels were modified
if transaction_updated {
// Create a new transaction with updated kernels
let updated_transaction = Transaction::new(
tx.transaction.body.inputs().clone(),
tx.transaction.body.outputs().clone(),
updated_kernels,
tx.transaction.offset.clone(),
tx.transaction.script_offset.clone(),
);

let mut updated_tx = (*tx).clone();
updated_tx.transaction = updated_transaction;

// Save the updated transaction to the database
if let Err(e) = db.update_completed_transaction(tx.tx_id, updated_tx.clone()) {
warn!(
target: LOG_TARGET,
"Failed to update transaction {} with correct kernel signatures: {}",
tx.tx_id,
e
);
} else {
updated_count += 1;
info!(
target: LOG_TARGET,
"Successfully updated transaction {} with correct kernel signatures",
tx.tx_id
);
}
}
}
}

if updated_count > 0 {
info!(
target: LOG_TARGET,
"Kernel signature migration completed: {} transactions updated with correct signatures",
updated_count
);
} else {
info!(
target: LOG_TARGET,
"Kernel signature migration completed: no transactions needed updating"
);
}

Ok(())
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor complex function and improve kernel matching logic

This function is doing too much and has potential issues:

  1. At 200+ lines, it violates single responsibility principle
  2. The kernel matching assumes order preservation, which may not always be true
  3. No optimization for transactions from the same block

Consider breaking this down into smaller functions:

+/// Match a wallet kernel with a block kernel by excess commitment
+fn find_matching_block_kernel<'a>(
+    wallet_kernel: &TransactionKernel,
+    block_kernels: &'a [base_node_proto::TransactionKernel],
+) -> Option<&'a base_node_proto::TransactionKernel> {
+    block_kernels.iter().find(|block_kernel| {
+        block_kernel.excess.as_ref()
+            .map_or(false, |e| e.data.as_slice() == wallet_kernel.excess.as_bytes())
+    })
+}
+
+/// Update kernel signatures for a single transaction
+async fn update_transaction_kernel_signatures<TBackend: TransactionBackend>(
+    db: &TransactionDatabase<TBackend>,
+    tx: &CompletedTransaction,
+    block_kernels: &[base_node_proto::TransactionKernel],
+) -> Result<bool, TransactionServiceError> {
+    // Extract kernel update logic here
+    // Return true if transaction was updated
+}

 async fn fetch_and_update_kernel_signatures<TBackend: 'static + TransactionBackend, TWalletConnectivity: WalletConnectivityInterface>(
     mut connectivity: TWalletConnectivity,
     db: TransactionDatabase<TBackend>,
     transactions: Vec<CompletedTransaction>,
 ) -> Result<(), TransactionServiceError> {
     // Simplified main function using extracted helpers

Also, add validation to ensure all kernels are matched before updating:

if updated_kernels.len() != tx.transaction.body.kernels().len() {
    warn!(
        target: LOG_TARGET,
        "Kernel count mismatch for transaction {}: expected {}, got {}",
        tx.tx_id,
        tx.transaction.body.kernels().len(),
        updated_kernels.len()
    );
    continue;
}
🤖 Prompt for AI Agents
In
base_layer/wallet/src/transaction_service/tasks/check_faux_transaction_status.rs
between lines 265 and 468, the fetch_and_update_kernel_signatures function is
too large and mixes multiple responsibilities, making it hard to maintain and
test. Refactor by extracting smaller helper functions for tasks like fetching
blocks, grouping transactions by height, matching kernels, and updating
transactions. Improve kernel matching logic to avoid assuming order preservation
by matching kernels based on unique identifiers or commitments. Add validation
before updating a transaction to ensure the number of updated kernels matches
the original kernel count, logging a warning and skipping the update if they
differ, as shown in the suggested code snippet.

Comment on lines +116 to +130
let mut all_completed = match db.get_completed_transactions(None, None, None) {
Ok(txs) => txs,
Err(e) => {
error!(
target: LOG_TARGET,
"Problem retrieving completed transactions for kernel signature check: {}", e
);
return;
},
};
all_detected_transactions.append(&mut all_completed);

// Remove duplicates based on tx_id
all_detected_transactions.sort_by(|a, b| a.tx_id.as_u64().cmp(&b.tx_id.as_u64()));
all_detected_transactions.dedup_by(|a, b| a.tx_id == b.tx_id);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Performance concern: Fetching all completed transactions on every check

Fetching ALL completed transactions on every call to check for missing kernel signatures is inefficient and will degrade performance as the wallet accumulates more transactions over time.

Consider these alternatives:

  1. Only check transactions that are known to have missing kernel signatures (maintain a flag in the database)
  2. Run this migration as a one-time background task rather than on every status check
  3. Add pagination or date filters to limit the scope
-    // Also include ALL completed transactions to check for empty kernel signatures
-    let mut all_completed = match db.get_completed_transactions(None, None, None) {
+    // Only fetch confirmed transactions that may have missing kernel signatures
+    // This could be tracked with a database flag or by checking a specific date range
+    let mut transactions_needing_migration = match db.get_transactions_with_missing_kernel_signatures() {
         Ok(txs) => txs,
         Err(e) => {
             error!(
                 target: LOG_TARGET,
                 "Problem retrieving completed transactions for kernel signature check: {}", e
             );
             return;
         },
     };
-    all_detected_transactions.append(&mut all_completed);
+    all_detected_transactions.append(&mut transactions_needing_migration);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
base_layer/wallet/src/transaction_service/tasks/check_faux_transaction_status.rs
around lines 116 to 130, the code fetches all completed transactions every time,
which is inefficient. To fix this, modify the database query to only retrieve
transactions flagged as missing kernel signatures or apply filters such as date
ranges or pagination to limit the number of transactions fetched. Alternatively,
refactor this logic to run as a one-time background migration task instead of
during every status check.

@fluffypony
Copy link
Copy Markdown
Contributor Author

Deprecated by PayRef

@fluffypony fluffypony closed this Jun 3, 2025
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.

1 participant