Skip to content

Storage v2#681

Open
Shitikyan wants to merge 31 commits intotestnetfrom
storage_v2
Open

Storage v2#681
Shitikyan wants to merge 31 commits intotestnetfrom
storage_v2

Conversation

@Shitikyan
Copy link
Contributor

No description provided.

tcsenpai and others added 29 commits December 6, 2025 09:52
Phase 2 of StoragePrograms feature implementation:
- Create GCR_StorageProgram TypeORM entity with full field support
- Add indexes for owner, programName, encoding, storageLocation
- Support JSON and Binary encoding via 'encoding' field
- Include robust ACL (mode, allowed, blacklisted, groups) as jsonb
- Add IPFS stubs (storageLocation, ipfsCid) for future hybrid storage
- Track fees paid (totalFeesPaid) and soft delete (isDeleted)
- Update datasource.ts to register the new entity
- Update to demosdk 2.8.11 with unified StorageProgram types

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 3 of StoragePrograms feature implementation:

- Add GCRStorageProgramRoutines with validation and fee calculation
- validateStorageProgramPayload() for confirm flow validation
- GCRStorageProgramRoutines.apply() for broadcast flow GCREdit handling
- Support CREATE, WRITE, UPDATE_ACL, DELETE operations
- Integrate with handleGCR.ts routing and repository management
- Follow SDK GCREditStorageProgram structure (target, context.operation, context.data)

Fee calculation: 1 DEM per 10KB chunk (minimum 1 DEM)
ACL validation: mode, allowed, blacklisted, groups with permissions
Soft delete pattern with isDeleted flag preservation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 5 of StoragePrograms implementation:
- Add GET /storage-program/:address endpoint for reading by address
- Add GET /storage-program/owner/:owner endpoint for listing by owner
- Implement checkReadPermission in GCRStorageProgramRoutines
- ACL check enforces: public (allow all), owner (only owner), restricted (allowed/groups)
- Proper error handling: NOT_FOUND, PERMISSION_DENIED, INTERNAL_ERROR
- Update SDK to 2.8.13 for HandleStorageProgramOperations support

Related: DEM-548

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add full transaction flow diagram (confirm/broadcast)
- Include examples for all CRUD operations
- Document ACL helper methods and validation utilities
- Add complete working example with error handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add missing owner field to CREATE_STORAGE_PROGRAM spec docs
- Add INVALID_REQUEST error code for malformed requests (routes.ts)
- Remove READ_STORAGE from valid transaction operations (reads are RPC-only)
- Add write permission check in handleWriteStorage (was missing ACL enforcement)
- Fix ACL priority: owner check now before blacklist (owner cannot be blacklisted)
- Add checkWritePermission helper for ACL group/public mode validation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix logging inconsistency: rename chunks variable to rawChunks for raw
  value, use chunks for effective value (min 1) ensuring log output matches
  actual fee calculation
- Add null/object type guard in ACL group validation to prevent runtime
  errors from malformed ACL input

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ctions

StorageProgram transactions use stor-{40 hex chars} format for the 'to'
field instead of Ed25519 public keys. Added validateStorageAddress()
method and modified structured() to route validation based on tx type.

This fixes the TypeError when confirming storage transactions where
validateToField() expected 32-byte Ed25519 keys but received stor- addresses.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add searchStorageProgramsByName to GCRStorageProgramRoutines
- Support exact match and ILIKE partial matching
- Add pagination support (limit, offset)
- Add /storage-program/search?q=name endpoint
- ACL filtering applied to search results

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Modified HandleGCR.apply() to update sender's assignedTxs on success
- Added addAssignedTx() helper with duplicate prevention
- Non-blocking: assignedTxs update failure doesn't fail the operation

Relates to: DEM-549

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add field-level read/write operations for storage programs instead of
full blob operations. This enables efficient granular access to storage
program data.

Read methods (manageNodeCall.ts):
- getStorageProgramFields - list top-level field names
- getStorageProgramValue - get specific field value
- getStorageProgramItem - get array element by index
- hasStorageProgramField - check field existence
- getStorageProgramFieldType - get field type info
- getStorageProgramAll - full data (retrocompat)

Write routines (GCRStorageProgramRoutines.ts):
- SET_FIELD - set/create field value
- SET_ITEM - set array element at index
- APPEND_ITEM - push to array
- DELETE_FIELD - remove field
- DELETE_ITEM - remove array element

Features:
- ACL enforcement on all operations
- Fee calculation based on size delta
- Binary encoding detection (error for granular)
- Bounds checking for array operations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add detailed specifications for Storage Program granular operations:

- 03-operations.mdx: Add GRANULAR_WRITE operation with 5 operation types
  (SET_FIELD, SET_ITEM, APPEND_ITEM, DELETE_FIELD, DELETE_ITEM),
  GranularWriteOperation interface, and comparison table vs WRITE_STORAGE
- 05-rpc-endpoints.mdx: Add all granular read endpoints (/fields, /field/:field,
  /field/:field/item/:index, /has/:field, /type/:field, /all) with request/
  response examples and error codes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Serena session memories for storage program API work
- Add key derivation specification document
…iles and the `run` script, modify `.beads` files and `.gitignore`, and create `AGENTS.md`.
- Implement stress tests for concurrent operations and payload boundaries in `stress.test.ts`.
- Add comprehensive validation tests for storage program payloads in `validation.test.ts`, covering operation validation, data size, JSON nesting depth, and ACL structure.
- Mock necessary dependencies to isolate tests and ensure reliability.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

Important

Review skipped

Too many files!

This PR contains 280 files, which is 130 over the limit of 150.

📥 Commits

Reviewing files that changed from the base of the PR and between 02b1c95 and 8b74b14.

⛔ Files ignored due to path filters (6)
  • documentation/Demos_ Technical Design Decisions.pdf is excluded by !**/*.pdf
  • documentation/demos_yp_v5.pdf is excluded by !**/*.pdf
  • monitoring/grafana/branding/demos-icon.svg is excluded by !**/*.svg
  • monitoring/grafana/branding/demos-logo-morph.svg is excluded by !**/*.svg
  • monitoring/grafana/branding/demos-logo-white.svg is excluded by !**/*.svg
  • monitoring/grafana/branding/favicon.png is excluded by !**/*.png
📒 Files selected for processing (280)
  • .beads/.local_version
  • .github/copilot-instructions.md
  • .github/workflows/claude-merge-fix.yml
  • .github/workflows/claude-merge-notify.yml
  • .github/workflows/fix-beads-conflicts.yml
  • .github/workflows/fix-serena-conflicts.yml
  • .github/workflows/notify-beads-merging.yml
  • .github/workflows/notify-serena-merging.yml
  • .gitignore
  • .serena/memories/_continue_here.md
  • .serena/memories/_index.md
  • .serena/memories/devnet_docker_setup.md
  • .serena/memories/feature_storage_programs_plan.md
  • .serena/memories/omniprotocol_complete_2025_11_11.md
  • .serena/memories/omniprotocol_session_2025-12-01.md
  • .serena/memories/omniprotocol_wave8.1_complete.md
  • .serena/memories/omniprotocol_wave8_tcp_physical_layer.md
  • .serena/memories/project_purpose.md
  • .serena/memories/session_2026-01-18_storage_program_api.md
  • .serena/memories/session_2026-01-19_storage_docs_complete.md
  • .serena/memories/session_2026-01-19_storage_poc_granular_api.md
  • .serena/memories/session_storage_program_queries_2026_01_18.md
  • .serena/memories/session_ud_ownership_verification_2025_10_21.md
  • .serena/memories/session_ud_points_implementation_2025_01_31.md
  • .serena/memories/suggested_commands.md
  • .serena/memories/task_completion_guidelines.md
  • .serena/memories/tlsnotary_integration_context.md
  • .serena/memories/typescript_audit_complete_2025_12_17.md
  • .serena/memories/ud_architecture_patterns.md
  • .serena/memories/ud_integration_complete.md
  • .serena/memories/ud_phase5_complete.md
  • .serena/memories/ud_phases_tracking.md
  • .serena/memories/ud_security_patterns.md
  • .serena/memories/ud_technical_reference.md
  • .serena/project.yml
  • .trunk/actions
  • .trunk/configs/.hadolint.yaml
  • .trunk/configs/.markdownlint.yaml
  • .trunk/configs/.shellcheckrc
  • .trunk/configs/.yamllint.yaml
  • .trunk/configs/svgo.config.mjs
  • .trunk/logs
  • .trunk/notifications
  • .trunk/out
  • .trunk/plugins/trunk
  • .trunk/trunk.yaml
  • CONSOLE_LOG_AUDIT.md
  • CONTRIBUTING.md
  • GUIDELINES/CODING.md
  • GUIDELINES/PR.md
  • GUIDELINES/VIBES.md
  • INSTALL.md
  • OMNIPROTOCOL_SETUP.md
  • OMNIPROTOCOL_TLS_GUIDE.md
  • README.md
  • REPO_ANALYSIS/Onboarding_Documentation.md
  • TG_IDENTITY_PLAN.md
  • TO_FIX.md
  • bunfig.toml
  • devnet/README.md
  • devnet/docker-compose.yml
  • devnet/run-devnet
  • devnet/scripts/attach.sh
  • devnet/scripts/generate-identities.sh
  • devnet/scripts/generate-peerlist.sh
  • devnet/scripts/logs.sh
  • devnet/scripts/setup.sh
  • devnet/scripts/watch-all.sh
  • docs/INDEX.md
  • docs/adr/.gitkeep
  • docs/decisions/.gitkeep
  • docs/discoveries/.gitkeep
  • docs/manifest.json
  • docs/notes/.gitkeep
  • docs/references/.gitkeep
  • docs/runbooks/.gitkeep
  • docs/specs/.gitkeep
  • documentation/bridges/rubic.md
  • documentation/demos_yp_v5.odt
  • documentation/referral-system.md
  • dtr_implementation/DTR_MINIMAL_IMPLEMENTATION.md
  • dtr_implementation/README.md
  • dtr_implementation/validator_status_minimal.md
  • fixtures/address_info.json
  • fixtures/block_header.json
  • fixtures/consensus/greenlight_01.json
  • fixtures/consensus/greenlight_02.json
  • fixtures/consensus/greenlight_03.json
  • fixtures/consensus/greenlight_04.json
  • fixtures/consensus/greenlight_05.json
  • fixtures/consensus/greenlight_06.json
  • fixtures/consensus/greenlight_07.json
  • fixtures/consensus/greenlight_08.json
  • fixtures/consensus/greenlight_09.json
  • fixtures/consensus/greenlight_10.json
  • fixtures/consensus/proposeBlockHash_01.json
  • fixtures/consensus/proposeBlockHash_02.json
  • fixtures/consensus/setValidatorPhase_01.json
  • fixtures/consensus/setValidatorPhase_02.json
  • fixtures/consensus/setValidatorPhase_03.json
  • fixtures/consensus/setValidatorPhase_04.json
  • fixtures/consensus/setValidatorPhase_05.json
  • fixtures/consensus/setValidatorPhase_06.json
  • fixtures/consensus/setValidatorPhase_07.json
  • fixtures/consensus/setValidatorPhase_08.json
  • fixtures/consensus/setValidatorPhase_09.json
  • fixtures/consensus/setValidatorPhase_10.json
  • fixtures/last_block_number.json
  • fixtures/mempool.json
  • fixtures/peerlist.json
  • fixtures/peerlist_hash.json
  • install-deps.sh
  • jest.config.ts
  • knip.json
  • monitoring/README.md
  • monitoring/docker-compose.yml
  • monitoring/grafana/provisioning/dashboards/dashboard.yml
  • monitoring/grafana/provisioning/dashboards/json/consensus-blockchain.json
  • monitoring/grafana/provisioning/dashboards/json/demos-overview.json
  • monitoring/grafana/provisioning/dashboards/json/network-peers.json
  • monitoring/grafana/provisioning/dashboards/json/system-health.json
  • monitoring/grafana/provisioning/datasources/prometheus.yml
  • monitoring/prometheus/prometheus.yml
  • node-doctor
  • package.json
  • reset-node
  • run
  • scripts/ceremony_contribute.sh
  • specs/key_derivation.md
  • specs/storageprogram/01-overview.mdx
  • specs/storageprogram/02-architecture.mdx
  • specs/storageprogram/03-operations.mdx
  • specs/storageprogram/04-acl.mdx
  • specs/storageprogram/05-rpc-endpoints.mdx
  • specs/storageprogram/06-examples.mdx
  • src/benchmark.ts
  • src/features/InstantMessagingProtocol/signalingServer/signalingServer.ts
  • src/features/InstantMessagingProtocol/signalingServer/types/IMMessage.ts
  • src/features/activitypub/fedistore.ts
  • src/features/fhe/fhe_test.ts
  • src/features/incentive/PointSystem.ts
  • src/features/incentive/referrals.ts
  • src/features/mcp/MCPServer.ts
  • src/features/mcp/examples/remoteExample.ts
  • src/features/mcp/examples/simpleExample.ts
  • src/features/mcp/index.ts
  • src/features/mcp/tools/demosTools.ts
  • src/features/metrics/MetricsCollector.ts
  • src/features/metrics/MetricsServer.ts
  • src/features/metrics/MetricsService.ts
  • src/features/multichain/chainwares/aptoswares/Move.toml
  • src/features/multichain/routines/executors/aptos_balance_query.ts
  • src/features/multichain/routines/executors/aptos_contract_write.ts
  • src/features/multichain/routines/executors/balance_query.ts
  • src/features/storageprogram/index.ts
  • src/features/storageprogram/routes.ts
  • src/features/tlsnotary/TLSNotaryService.ts
  • src/features/tlsnotary/ffi.ts
  • src/features/tlsnotary/index.ts
  • src/features/tlsnotary/portAllocator.ts
  • src/features/tlsnotary/proxyManager.ts
  • src/features/tlsnotary/routes.ts
  • src/features/tlsnotary/tokenManager.ts
  • src/features/web2/dahr/DAHR.ts
  • src/features/web2/dahr/DAHRFactory.ts
  • src/features/web2/proxy/Proxy.ts
  • src/index.ts
  • src/libs/abstraction/web2/discord.ts
  • src/libs/blockchain/UDTypes/uns_sol.json
  • src/libs/blockchain/UDTypes/uns_sol.ts
  • src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts
  • src/libs/blockchain/gcr/gcr_routines/GCRTLSNotaryRoutines.ts
  • src/libs/blockchain/gcr/gcr_routines/handleNativeOperations.ts
  • src/libs/blockchain/gcr/gcr_routines/udIdentityManager.ts
  • src/libs/blockchain/gcr/gcr_routines/udSolanaResolverHelper.ts
  • src/libs/blockchain/gcr/handleGCR.ts
  • src/libs/blockchain/mempool_v2.ts
  • src/libs/blockchain/routines/beforeFindGenesisHooks.ts
  • src/libs/blockchain/routines/executeNativeTransaction.ts
  • src/libs/blockchain/routines/subOperations.ts
  • src/libs/blockchain/routines/validateTransaction.ts
  • src/libs/blockchain/transaction.ts
  • src/libs/consensus/v2/interfaces.ts
  • src/libs/consensus/v2/routines/getShard.ts
  • src/libs/consensus/v2/routines/isValidator.ts
  • src/libs/consensus/v2/routines/orderTransactions.ts
  • src/libs/crypto/cryptography.ts
  • src/libs/identity/tools/twitter.ts
  • src/libs/network/dtr/dtrmanager.ts
  • src/libs/network/endpointHandlers.ts
  • src/libs/network/index.ts
  • src/libs/network/manageAuth.ts
  • src/libs/network/manageConsensusRoutines.ts
  • src/libs/network/manageGCRRoutines.ts
  • src/libs/network/manageNativeBridge.ts
  • src/libs/network/middleware/rateLimiter.ts
  • src/libs/network/routines/nodecalls/getBlockByHash.ts
  • src/libs/network/routines/nodecalls/getBlockHeaderByHash.ts
  • src/libs/network/routines/nodecalls/getBlockHeaderByNumber.ts
  • src/libs/network/routines/timeSync.ts
  • src/libs/network/routines/transactions/handleIdentityRequest.ts
  • src/libs/network/routines/transactions/handleWeb2ProxyRequest.ts
  • src/libs/network/server_rpc.ts
  • src/libs/omniprotocol/auth/parser.ts
  • src/libs/omniprotocol/auth/types.ts
  • src/libs/omniprotocol/auth/verifier.ts
  • src/libs/omniprotocol/integration/BaseAdapter.ts
  • src/libs/omniprotocol/integration/consensusAdapter.ts
  • src/libs/omniprotocol/integration/index.ts
  • src/libs/omniprotocol/integration/startup.ts
  • src/libs/omniprotocol/protocol/dispatcher.ts
  • src/libs/omniprotocol/protocol/handlers/consensus.ts
  • src/libs/omniprotocol/protocol/handlers/control.ts
  • src/libs/omniprotocol/protocol/handlers/gcr.ts
  • src/libs/omniprotocol/protocol/handlers/meta.ts
  • src/libs/omniprotocol/protocol/handlers/sync.ts
  • src/libs/omniprotocol/protocol/handlers/transaction.ts
  • src/libs/omniprotocol/protocol/handlers/utils.ts
  • src/libs/omniprotocol/protocol/opcodes.ts
  • src/libs/omniprotocol/protocol/registry.ts
  • src/libs/omniprotocol/ratelimit/RateLimiter.ts
  • src/libs/omniprotocol/serialization/consensus.ts
  • src/libs/omniprotocol/serialization/control.ts
  • src/libs/omniprotocol/serialization/gcr.ts
  • src/libs/omniprotocol/serialization/jsonEnvelope.ts
  • src/libs/omniprotocol/serialization/meta.ts
  • src/libs/omniprotocol/serialization/primitives.ts
  • src/libs/omniprotocol/serialization/sync.ts
  • src/libs/omniprotocol/serialization/transaction.ts
  • src/libs/omniprotocol/server/OmniProtocolServer.ts
  • src/libs/omniprotocol/server/TLSServer.ts
  • src/libs/omniprotocol/tls/certificates.ts
  • src/libs/omniprotocol/tls/initialize.ts
  • src/libs/omniprotocol/tls/types.ts
  • src/libs/omniprotocol/transport/ConnectionFactory.ts
  • src/libs/omniprotocol/transport/ConnectionPool.ts
  • src/libs/omniprotocol/transport/MessageFramer.ts
  • src/libs/omniprotocol/transport/TLSConnection.ts
  • src/libs/omniprotocol/transport/types.ts
  • src/libs/omniprotocol/types/errors.ts
  • src/libs/omniprotocol/types/message.ts
  • src/libs/peer/PeerManager.ts
  • src/libs/peer/routines/broadcast.ts
  • src/libs/peer/routines/getPeerConnectionString.ts
  • src/libs/peer/routines/getPeerIdentity.ts
  • src/libs/peer/routines/peerGossip.ts
  • src/libs/utils/calibrateTime.ts
  • src/libs/utils/demostdlib/groundControl.ts
  • src/libs/utils/keyMaker.ts
  • src/libs/utils/showPubkey.ts
  • src/migrations/AddReferralSupport.ts
  • src/model/datasource.ts
  • src/model/entities/GCRv2/GCRSubnetsTxs.ts
  • src/model/entities/GCRv2/GCR_StorageProgram.ts
  • src/model/entities/GCRv2/GCR_TLSNotary.ts
  • src/model/entities/Mempool.ts
  • src/types/nomis-augmentations.d.ts
  • src/utilities/Diagnostic.ts
  • src/utilities/cli_libraries/wallet.ts
  • src/utilities/mainLoop.ts
  • src/utilities/tui/CategorizedLogger.ts
  • src/utilities/tui/LegacyLoggerAdapter.ts
  • src/utilities/tui/TUIManager.ts
  • src/utilities/validateUint8Array.ts
  • src/utilities/waiter.ts
  • start_db
  • tests/mocks/demosdk-encryption.ts
  • tests/mocks/demosdk-types.ts
  • tests/mocks/demosdk-websdk.ts
  • tests/omniprotocol/consensus.test.ts
  • tests/omniprotocol/fixtures.test.ts
  • tests/omniprotocol/gcr.test.ts
  • tests/omniprotocol/peerOmniAdapter.test.ts
  • tests/omniprotocol/transaction.test.ts
  • tests/storageprogram/acl.test.ts
  • tests/storageprogram/routes.test.ts
  • tests/storageprogram/routines.test.ts
  • tests/storageprogram/stress.test.ts
  • tests/storageprogram/validation.test.ts
  • tlsnotary/docker-compose.yml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch storage_v2

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.

@qodo-code-review
Copy link
Contributor

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Review Summary by Qodo

Storage v2 - StorageProgram GCR routines with comprehensive testing and code formatting improvements

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Implemented comprehensive GCRStorageProgramRoutines module with 1685 lines supporting CREATE,
  WRITE, UPDATE_ACCESS_CONTROL, DELETE operations and granular field operations (SET_FIELD, SET_ITEM,
  APPEND_ITEM, DELETE_FIELD, DELETE_ITEM)
• Added fee calculation system based on data size with 10KB chunk pricing (1 DEM per chunk)
• Implemented ACL (Access Control List) validation and permission checking with support for owner,
  public, and restricted modes
• Added comprehensive test suite with 1000+ lines covering all storage program operations,
  permission validation, data size limits, and edge cases
• Added stress test suite for concurrent operations and boundary testing (payload size limits,
  nesting depth limits, transaction capping)
• Fixed bugs including data validation in simulate mode (Bug #2) and interactionTxs capping (Bug #3)
• Applied consistent code formatting across multiple files (4-space indentation, improved line
  wrapping, consistent import/method signature formatting)
• Updated version from 0.47.0 to 0.49.6
Diagram
flowchart LR
  A["StorageProgram<br/>Operations"] -->|CREATE, WRITE,<br/>UPDATE_ACCESS_CONTROL,<br/>DELETE| B["GCRStorageProgramRoutines"]
  B -->|Field Operations| C["SET_FIELD, SET_ITEM,<br/>APPEND_ITEM,<br/>DELETE_FIELD, DELETE_ITEM"]
  B -->|Fee Calculation| D["Data Size Based<br/>Pricing<br/>1 DEM per 10KB"]
  B -->|ACL Validation| E["Permission Checking<br/>Owner, Public,<br/>Restricted Modes"]
  B -->|Tested By| F["Comprehensive<br/>Test Suite<br/>1000+ lines"]
  B -->|Stress Tested| G["Concurrent Operations<br/>Boundary Testing<br/>Payload & Nesting Limits"]
Loading

Grey Divider

File Changes

Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Feb 24, 2026

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (5) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Storage routes return error.message 📘 Rule violation ⛨ Security
Description
StorageProgram route handlers return error.message directly in HTTP JSON responses, potentially
exposing internal implementation details to callers. This violates secure error handling
expectations for user-facing APIs.
Code

src/features/storageprogram/routes.ts[R252-255]

+            error:
+                error instanceof Error
+                    ? error.message
+                    : "Internal server error",
Evidence
PR Compliance ID 4 forbids exposing internal details in user-facing errors. The new route code
constructs response payloads using error.message when exceptions occur.

Rule 4: Generic: Secure Error Handling
src/features/storageprogram/routes.ts[252-255]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Several StorageProgram endpoints return `error.message` in API responses, which can leak internal exception details.
## Issue Context
User-facing errors should be generic (e.g., &amp;quot;Internal server error&amp;quot;) while detailed error data is written to internal logs only.
## Fix Focus Areas
- src/features/storageprogram/routes.ts[248-258]
- src/features/storageprogram/routes.ts[291-297]
- src/features/storageprogram/routes.ts[359-367]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. wstcp output logged verbatim 📘 Rule violation ⛨ Security
Description
TLSNotary proxy monitoring logs raw wstcp stdout/stderr contents, which may contain sensitive
connection/request data. This creates a high risk of sensitive data leakage into logs.
Code

src/features/tlsnotary/proxyManager.ts[R221-232]

+    process.stdout?.on("data", (data: Buffer) => {
+        proxyInfo.lastActivity = Date.now()
+        log.debug(
+            `[TLSNotary] Proxy ${proxyInfo.domain} stdout: ${data.toString().trim()}`,
+        )
+    })
+
+    process.stderr?.on("data", (data: Buffer) => {
+        proxyInfo.lastActivity = Date.now()
+        log.debug(
+            `[TLSNotary] Proxy ${proxyInfo.domain} stderr: ${data.toString().trim()}`,
+        )
Evidence
PR Compliance ID 5 requires that logs do not contain sensitive data. Logging raw subprocess
stdout/stderr is inherently unsafe because it can include secrets, headers, tokens, or user data
depending on the subprocess output.

Rule 5: Generic: Secure Logging Practices
src/features/tlsnotary/proxyManager.ts[221-232]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The TLSNotary proxy manager logs raw `wstcp` stdout/stderr, which can leak sensitive information into application logs.
## Issue Context
Secure logging requires preventing any PII/PHI/secrets from appearing in logs. Subprocess output is untrusted and may contain sensitive content.
## Fix Focus Areas
- src/features/tlsnotary/proxyManager.ts[221-232]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Untrusted field indexes object 📘 Rule violation ⛨ Security
Description
StorageProgram granular read endpoints use a URL-derived field to check field in data and then
access data[field], which can hit prototype keys like __proto__/constructor. This is unsafe
handling of external input and can cause unexpected behavior or security issues.
Code

src/features/storageprogram/routes.ts[R305-350]

+        const storageAddress = pathParts[2]
+        const field = decodeURIComponent(pathParts[4] || "")
+        const requesterAddress = getRequesterAddress(req)
+
+        if (!field) {
+            return jsonResponse(
+                {
+                    success: false,
+                    error: "Field name is required",
+                    errorCode: "INVALID_REQUEST",
+                } satisfies StorageProgramGranularResponse,
+                400,
+            )
+        }
+
+        const result = await getAccessibleProgram(storageAddress, requesterAddress)
+        if (result.response) {
+            return result.response
+        }
+
+        const program = result.program as GCRStorageProgram
+        if (!program.data || typeof program.data !== "object" || Array.isArray(program.data)) {
+            return jsonResponse(
+                {
+                    success: false,
+                    error: "Field operations are only available for JSON object data",
+                    errorCode: "INVALID_FIELD_TYPE",
+                } satisfies StorageProgramGranularResponse,
+                400,
+            )
+        }
+
+        const data = program.data as Record<string, unknown>
+        if (!(field in data)) {
+            return jsonResponse(
+                {
+                    success: false,
+                    error: `Field not found: ${field}`,
+                    errorCode: "FIELD_NOT_FOUND",
+                } satisfies StorageProgramGranularResponse,
+                404,
+            )
+        }
+
+        const value = data[field]
+        const response: StorageProgramGranularResponse = {
Evidence
PR Compliance ID 6 requires security-first input validation and safe handling of external inputs.
The field path parameter is decoded from the URL and used directly for property existence checks
and indexing without restricting to own-properties or validating allowed key patterns.

Rule 6: Generic: Security-First Input Validation and Data Handling
src/features/storageprogram/routes.ts[305-350]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The `field` URL parameter is used directly for `in` checks and object indexing, which can access prototype keys and behaves unsafely for untrusted input.
## Issue Context
External inputs (URL path parts) should be validated/sanitized. For object key access, prefer own-property checks and disallow dangerous keys like `__proto__`, `prototype`, and `constructor`.
## Fix Focus Areas
- src/features/storageprogram/routes.ts[305-350]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (2)
4. Wildcard routes don't match 🐞 Bug ✓ Correctness
Description
StorageProgram routes are registered with wildcard patterns (e.g. "/storage-program/*"), but
BunServer resolves handlers via exact Map.get(path) lookup, so dynamic StorageProgram endpoints
will 404.
Code

src/features/storageprogram/routes.ts[R803-814]

+export function registerStorageProgramRoutes(server: BunServer): void {
+    // Register specific routes first (more specific paths before wildcards)
+    server.get("/storage-program/search/*", searchByNameHandler)
+    server.get("/storage-program/search", searchByNameHandler)
+    server.get("/storage-program/*/field/*/item/*", getStorageProgramArrayItemHandler)
+    server.get("/storage-program/*/field/*", getStorageProgramFieldValueHandler)
+    server.get("/storage-program/*/fields", getStorageProgramFieldsHandler)
+    server.get("/storage-program/*/has/*", hasStorageProgramFieldHandler)
+    server.get("/storage-program/*/type/*", getStorageProgramFieldTypeHandler)
+    server.get("/storage-program/*/all", getStorageProgramAllDataHandler)
+    server.get("/storage-program/owner/*", listByOwnerHandler)
+    server.get("/storage-program/*", getStorageProgramHandler)
Evidence
The new StorageProgram feature registers wildcard paths, but BunServer does not implement any
wildcard/param matching—only exact pathname lookups—so requests like /storage-program/stor-...
will never find a handler.

src/features/storageprogram/routes.ts[803-814]
src/libs/network/bunServer.ts[39-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
StorageProgram routes are registered using wildcard patterns (e.g. `/storage-program/*`), but `BunServer` only performs an exact pathname lookup, so dynamic routes will always return 404.
## Issue Context
The new feature assumes a router with wildcard/param support, but the in-house `BunServer` currently stores routes in a `Map` keyed by exact `url.pathname`.
## Fix Focus Areas
- src/libs/network/bunServer.ts[39-61]
- src/features/storageprogram/routes.ts[803-814]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. ACL bypass via nodeCall🐞 Bug ⛨ Security
Description
StorageProgram read/query methods are exposed via unauthenticated nodeCall, and they accept
requesterAddress from the request body; callers can spoof this value to satisfy ACL checks and
read restricted programs.
Code

src/libs/network/manageNodeCall.ts[R751-816]

+        // REVIEW: StorageProgram query methods (public, no authentication required)
+        case "getStorageProgram": {
+            const rawStorageAddress = data.storageAddress
+            const requesterAddress = data.requesterAddress // Optional identity for ACL check
+
+            if (!rawStorageAddress) {
+                response.result = 400
+                response.response = null
+                response.extra = { error: "Storage address is required" }
+                break
+            }
+
+            // Normalize address to ensure stor- prefix
+            const storageAddress = normalizeStorageAddress(rawStorageAddress)
+
+            try {
+                const db = await Datasource.getInstance()
+                const repository = db
+                    .getDataSource()
+                    .getRepository(GCRStorageProgram)
+
+                const program =
+                    await GCRStorageProgramRoutines.getStorageProgram(
+                        storageAddress,
+                        repository,
+                    )
+
+                if (!program) {
+                    response.result = 404
+                    response.response = null
+                    response.extra = {
+                        error: `Storage program not found: ${storageAddress}`,
+                    }
+                    break
+                }
+
+                // Check read permission
+                const hasReadAccess =
+                    GCRStorageProgramRoutines.checkReadPermission(
+                        program,
+                        requesterAddress,
+                    )
+
+                if (!hasReadAccess) {
+                    response.result = 403
+                    response.response = null
+                    response.extra = {
+                        error: "Permission denied: You do not have read access to this storage program",
+                    }
+                    break
+                }
+
+                response.response = {
+                    storageAddress: program.storageAddress,
+                    owner: program.owner,
+                    programName: program.programName,
+                    encoding: program.encoding,
+                    data: program.data,
+                    metadata: program.metadata,
+                    storageLocation: program.storageLocation,
+                    sizeBytes: program.sizeBytes,
+                    createdAt: program.createdAt.toISOString(),
+                    updatedAt: program.updatedAt.toISOString(),
+                    createdByTx: program.createdByTx,
+                    lastModifiedByTx: program.lastModifiedByTx,
+                }
Evidence
server_rpc explicitly skips signature/identity validation for the nodeCall method, and
manageNodeCall uses the caller-supplied requesterAddress to make ACL decisions via
checkReadPermission. Since requesterAddress is not cryptographically bound to the caller, an
attacker can set it to the owner/allowed address and bypass ACL enforcement.

src/libs/network/server_rpc.ts[36-37]
src/libs/network/server_rpc.ts[433-449]
src/libs/network/manageNodeCall.ts[751-792]
src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts[981-1014]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
StorageProgram read endpoints under `nodeCall` are unauthenticated and accept `requesterAddress` from the request body, enabling callers to spoof identity and bypass ACL checks.
## Issue Context
`server_rpc` skips `validateHeaders()` for the `nodeCall` method entirely. `manageNodeCall` then uses `data.requesterAddress` as the identity input to `checkReadPermission`.
## Fix Focus Areas
- src/libs/network/server_rpc.ts[36-37]
- src/libs/network/server_rpc.ts[433-449]
- src/libs/network/manageNodeCall.ts[751-816]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

6. Storage error log lacks context 📘 Rule violation ✓ Correctness
Description
When storage reads fail, the error log does not include storageAddress or requester identity,
making it difficult to reconstruct the attempted action for auditing. Critical storage access events
should log actor, target, and outcome consistently.
Code

src/features/storageprogram/routes.ts[R249-255]

+        log.error(`[StorageProgram] Error reading storage program: ${error}`)
+        const response: StorageProgramResponse = {
+            success: false,
+            error:
+                error instanceof Error
+                    ? error.message
+                    : "Internal server error",
Evidence
PR Compliance ID 1 requires audit logs for critical actions with sufficient context (who did what
and outcome). The failure log line records only the error without identifying the target storage
program or the requester, preventing reliable event reconstruction.

Rule 1: Generic: Comprehensive Audit Trails
src/features/storageprogram/routes.ts[249-255]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
StorageProgram read failures are logged without enough audit context (missing requester and storage address), reducing forensic/audit value.
## Issue Context
Audit trails should capture actor (user/requester), action target (storage address), timestamp (usually via logger), and outcome (success/failure).
## Fix Focus Areas
- src/features/storageprogram/routes.ts[244-258]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Generic data and result 📘 Rule violation ✓ Correctness
Description
New StorageProgram routes use generic identifiers like result and data, which reduces clarity
and self-documentation. More descriptive names would make intent and contents easier to understand
and maintain.
Code

src/features/storageprogram/routes.ts[R320-350]

+        const result = await getAccessibleProgram(storageAddress, requesterAddress)
+        if (result.response) {
+            return result.response
+        }
+
+        const program = result.program as GCRStorageProgram
+        if (!program.data || typeof program.data !== "object" || Array.isArray(program.data)) {
+            return jsonResponse(
+                {
+                    success: false,
+                    error: "Field operations are only available for JSON object data",
+                    errorCode: "INVALID_FIELD_TYPE",
+                } satisfies StorageProgramGranularResponse,
+                400,
+            )
+        }
+
+        const data = program.data as Record<string, unknown>
+        if (!(field in data)) {
+            return jsonResponse(
+                {
+                    success: false,
+                    error: `Field not found: ${field}`,
+                    errorCode: "FIELD_NOT_FOUND",
+                } satisfies StorageProgramGranularResponse,
+                404,
+            )
+        }
+
+        const value = data[field]
+        const response: StorageProgramGranularResponse = {
Evidence
PR Compliance ID 2 requires meaningful naming and explicitly calls out generic names like data and
result as failure cases. The new handler code introduces result and data variables in
request-processing logic where more descriptive naming would improve readability.

Rule 2: Generic: Meaningful Naming and Self-Documenting Code
src/features/storageprogram/routes.ts[320-350]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new routes rely on generic variable names (`result`, `data`) that obscure intent.
## Issue Context
Self-documenting code improves maintainability and reduces mistakes during future changes.
## Fix Focus Areas
- src/features/storageprogram/routes.ts[320-350]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Unsafe metadata deep-merge 🐞 Bug ⛨ Security
Description
deepMerge merges untrusted metadata objects without blocking dangerous keys like
__proto__/constructor/prototype, enabling prototype pollution on persisted metadata objects
and any downstream consumers of that object.
Code

src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts[R28-50]

+function deepMerge(
+    target: Record<string, unknown>,
+    source: Record<string, unknown>,
+): Record<string, unknown> {
+    const result = { ...target }
+    for (const key of Object.keys(source)) {
+        const tVal = target[key]
+        const sVal = source[key]
+        if (
+            tVal && sVal &&
+            typeof tVal === "object" && !Array.isArray(tVal) &&
+            typeof sVal === "object" && !Array.isArray(sVal)
+        ) {
+            result[key] = deepMerge(
+                tVal as Record<string, unknown>,
+                sVal as Record<string, unknown>,
+            )
+        } else {
+            result[key] = sVal
+        }
+    }
+    return result
+}
Evidence
StorageProgram metadata is taken from edit.context.data (transaction-provided) and deep-merged
key-by-key into a plain object with no key allow/deny list. This enables insertion of special keys
that can mutate the resulting object's prototype chain.

src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts[28-50]
src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts[520-609]
src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts[759-767]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`deepMerge()` merges untrusted metadata into a plain object without filtering special keys, which can enable prototype pollution on the resulting metadata object.
## Issue Context
Metadata is accepted from `edit.context.data?.metadata` / `variables.metadata` and merged during write operations.
## Fix Focus Areas
- src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts[28-50]
- src/libs/blockchain/gcr/gcr_routines/GCRStorageProgramRoutines.ts[759-767]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +252 to +255
error:
error instanceof Error
? error.message
: "Internal server error",
Copy link
Contributor

Choose a reason for hiding this comment

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

Action required

1. Storage routes return error.message 📘 Rule violation ⛨ Security

StorageProgram route handlers return error.message directly in HTTP JSON responses, potentially
exposing internal implementation details to callers. This violates secure error handling
expectations for user-facing APIs.
Agent Prompt
## Issue description
Several StorageProgram endpoints return `error.message` in API responses, which can leak internal exception details.

## Issue Context
User-facing errors should be generic (e.g., "Internal server error") while detailed error data is written to internal logs only.

## Fix Focus Areas
- src/features/storageprogram/routes.ts[248-258]
- src/features/storageprogram/routes.ts[291-297]
- src/features/storageprogram/routes.ts[359-367]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +221 to +232
process.stdout?.on("data", (data: Buffer) => {
proxyInfo.lastActivity = Date.now()
log.debug(
`[TLSNotary] Proxy ${proxyInfo.domain} stdout: ${data.toString().trim()}`,
)
})

process.stderr?.on("data", (data: Buffer) => {
proxyInfo.lastActivity = Date.now()
log.debug(
`[TLSNotary] Proxy ${proxyInfo.domain} stderr: ${data.toString().trim()}`,
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Action required

2. wstcp output logged verbatim 📘 Rule violation ⛨ Security

TLSNotary proxy monitoring logs raw wstcp stdout/stderr contents, which may contain sensitive
connection/request data. This creates a high risk of sensitive data leakage into logs.
Agent Prompt
## Issue description
The TLSNotary proxy manager logs raw `wstcp` stdout/stderr, which can leak sensitive information into application logs.

## Issue Context
Secure logging requires preventing any PII/PHI/secrets from appearing in logs. Subprocess output is untrusted and may contain sensitive content.

## Fix Focus Areas
- src/features/tlsnotary/proxyManager.ts[221-232]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +305 to +350
const storageAddress = pathParts[2]
const field = decodeURIComponent(pathParts[4] || "")
const requesterAddress = getRequesterAddress(req)

if (!field) {
return jsonResponse(
{
success: false,
error: "Field name is required",
errorCode: "INVALID_REQUEST",
} satisfies StorageProgramGranularResponse,
400,
)
}

const result = await getAccessibleProgram(storageAddress, requesterAddress)
if (result.response) {
return result.response
}

const program = result.program as GCRStorageProgram
if (!program.data || typeof program.data !== "object" || Array.isArray(program.data)) {
return jsonResponse(
{
success: false,
error: "Field operations are only available for JSON object data",
errorCode: "INVALID_FIELD_TYPE",
} satisfies StorageProgramGranularResponse,
400,
)
}

const data = program.data as Record<string, unknown>
if (!(field in data)) {
return jsonResponse(
{
success: false,
error: `Field not found: ${field}`,
errorCode: "FIELD_NOT_FOUND",
} satisfies StorageProgramGranularResponse,
404,
)
}

const value = data[field]
const response: StorageProgramGranularResponse = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Action required

3. Untrusted field indexes object 📘 Rule violation ⛨ Security

StorageProgram granular read endpoints use a URL-derived field to check field in data and then
access data[field], which can hit prototype keys like __proto__/constructor. This is unsafe
handling of external input and can cause unexpected behavior or security issues.
Agent Prompt
## Issue description
The `field` URL parameter is used directly for `in` checks and object indexing, which can access prototype keys and behaves unsafely for untrusted input.

## Issue Context
External inputs (URL path parts) should be validated/sanitized. For object key access, prefer own-property checks and disallow dangerous keys like `__proto__`, `prototype`, and `constructor`.

## Fix Focus Areas
- src/features/storageprogram/routes.ts[305-350]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +803 to +814
export function registerStorageProgramRoutes(server: BunServer): void {
// Register specific routes first (more specific paths before wildcards)
server.get("/storage-program/search/*", searchByNameHandler)
server.get("/storage-program/search", searchByNameHandler)
server.get("/storage-program/*/field/*/item/*", getStorageProgramArrayItemHandler)
server.get("/storage-program/*/field/*", getStorageProgramFieldValueHandler)
server.get("/storage-program/*/fields", getStorageProgramFieldsHandler)
server.get("/storage-program/*/has/*", hasStorageProgramFieldHandler)
server.get("/storage-program/*/type/*", getStorageProgramFieldTypeHandler)
server.get("/storage-program/*/all", getStorageProgramAllDataHandler)
server.get("/storage-program/owner/*", listByOwnerHandler)
server.get("/storage-program/*", getStorageProgramHandler)
Copy link
Contributor

Choose a reason for hiding this comment

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

Action required

4. Wildcard routes don't match 🐞 Bug ✓ Correctness

StorageProgram routes are registered with wildcard patterns (e.g. "/storage-program/*"), but
BunServer resolves handlers via exact Map.get(path) lookup, so dynamic StorageProgram endpoints
will 404.
Agent Prompt
## Issue description
StorageProgram routes are registered using wildcard patterns (e.g. `/storage-program/*`), but `BunServer` only performs an exact pathname lookup, so dynamic routes will always return 404.

## Issue Context
The new feature assumes a router with wildcard/param support, but the in-house `BunServer` currently stores routes in a `Map` keyed by exact `url.pathname`.

## Fix Focus Areas
- src/libs/network/bunServer.ts[39-61]
- src/features/storageprogram/routes.ts[803-814]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

⚠️ MCP Memory Files Detected

This PR modifies .serena/ files. After merge, these changes will be automatically reverted to preserve branch-specific MCP memories.

Files that will be reverted:

  • .serena/memories/_continue_here.md
  • .serena/memories/_index.md
  • .serena/memories/devnet_docker_setup.md
  • .serena/memories/feature_storage_programs_plan.md
  • .serena/memories/omniprotocol_complete_2025_11_11.md
  • .serena/memories/omniprotocol_session_2025-12-01.md
  • .serena/memories/omniprotocol_wave8.1_complete.md
  • .serena/memories/omniprotocol_wave8_tcp_physical_layer.md
  • .serena/memories/project_purpose.md
  • .serena/memories/session_2026-01-18_storage_program_api.md
  • .serena/memories/session_2026-01-19_storage_docs_complete.md
  • .serena/memories/session_2026-01-19_storage_poc_granular_api.md
  • .serena/memories/session_storage_program_queries_2026_01_18.md
  • .serena/memories/session_ud_ownership_verification_2025_10_21.md
  • .serena/memories/session_ud_points_implementation_2025_01_31.md
  • .serena/memories/suggested_commands.md
  • .serena/memories/task_completion_guidelines.md
  • .serena/memories/tlsnotary_integration_context.md
  • .serena/memories/typescript_audit_complete_2025_12_17.md
  • .serena/memories/ud_architecture_patterns.md
  • .serena/memories/ud_integration_complete.md
  • .serena/memories/ud_phase5_complete.md
  • .serena/memories/ud_phases_tracking.md
  • .serena/memories/ud_security_patterns.md
  • .serena/memories/ud_technical_reference.md
  • .serena/project.yml

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 2, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
12.7% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

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.

2 participants