Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e2dbabe
Add Storage Programs data column to GCR
Oct 10, 2025
b0b062f
Implement Storage Program handlers and validators (Phase 2)
Oct 10, 2025
1bbed30
feat: Phase 3 - HandleGCR integration for Storage Programs
Oct 10, 2025
7a5062f
feat: Phase 4 - Endpoint integration for Storage Programs
Oct 10, 2025
28412a5
feat: Phase 6 - RPC query endpoint for Storage Programs
Oct 10, 2025
db614cc
docs: Add Storage Programs documentation and fix critical bugs
Oct 10, 2025
fdf1a87
updated memories and sdk bump
Oct 10, 2025
06d6941
removed useless files
Oct 10, 2025
9267dce
untracked spec file
Oct 10, 2025
23f4a74
ignored files
Oct 10, 2025
a723f82
Update src/libs/network/routines/transactions/handleStorageProgramTra…
tcsenpai Oct 10, 2025
716d3c1
Update src/libs/blockchain/gcr/handleGCR.ts
tcsenpai Oct 10, 2025
33842c6
Update src/libs/network/endpointHandlers.ts
tcsenpai Oct 10, 2025
224a8fe
Fix Storage Programs code review issues
Oct 10, 2025
2e46a70
Fix Storage Programs operation-specific validation logic
Oct 11, 2025
ce786c4
better comments
Oct 11, 2025
c3f69e0
reviewed pr
Oct 11, 2025
2bc81d8
updated memories
Oct 11, 2025
3dbe737
bump and fixed types
Oct 11, 2025
6690f9b
Improve code clarity for Storage Programs implementation
Oct 11, 2025
d6135a0
safeguarded storage calls
Oct 11, 2025
d427685
Fix Storage Program validation error handling and size calculation cl…
Oct 11, 2025
0f79151
updated memories
Oct 11, 2025
45142fc
updated gitignore
Oct 23, 2025
ba72d0e
fix: strengthen Storage Programs input validation and access control
Oct 23, 2025
325ba7d
chore: bump @kynesyslabs/demosdk to 2.4.24
Oct 23, 2025
bf84c60
ignores
Nov 3, 2025
da5c981
Validate storage program access control inputs
Nov 3, 2025
0c72430
Fix copy-paste error in crosschainOperation error messages
claude Nov 4, 2025
32a34b5
Merge storage branch with bugfix into review branch
claude Nov 4, 2025
75c8209
Merge pull request #491 from kynesyslabs/claude/review-branches-011CU…
tcsenpai Nov 4, 2025
3912cfa
Sync AGENTS.md from testnet
Dec 6, 2025
370fa33
beads init
Dec 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,6 @@ docs/src
src/features/bridges/EVMSmartContract/docs
src/features/bridges/LiquidityTank_UserGuide.md
local_tests
docs/storage_features
STORAGE_PROGRAMS_SPEC.md
temp
126 changes: 126 additions & 0 deletions .serena/memories/session_2025-10-11_storage_programs_review_fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Storage Programs Code Review Fixes Session

## Session Summary
**Date**: 2025-10-11
**Branch**: storage
**Focus**: Addressing critical code review feedback for Storage Programs implementation

## Commits Created

### Commit 1: `224a8fe9` - Initial Code Review Fixes
**Files Modified**: 5 files (+70, -56 lines)

1. **CRITICAL: Access Control Bypass Fixed** (manageNodeCall.ts, server_rpc.ts)
- Added `sender?: string` parameter to manageNodeCall()
- Pass authenticated caller from RPC server headers
- Enforce access control in getStorageProgram endpoint
- Return 403 Forbidden without data leakage
- Private/restricted programs now properly protected

2. **MAJOR: Logger Fix** (handleGCR.ts:527)
- Fixed `log.error("[StorageProgram] Error applying edit:", error)`
- Embedded error message and stack trace in single string
- Prevents TypeScript type error (second param expects boolean)

3. **MAJOR: JSONB Index Removed** (GCR_Main.ts)
- Removed `@Index("idx_gcr_main_data_gin")` decorator
- Storage Programs only use primary key lookups
- Avoids PostgreSQL B-tree rejection on JSONB
- No GIN index needed for current query patterns

### Commit 2: `2e46a704` - Operation Validation Fixes
**Files Modified**: 2 files (+37, -12 lines)

1. **CRITICAL: Validation Guard Added** (handleGCR.ts:324-329)
- Added `context.data.variables` validation
- Prevents runtime error before unsafe access
- Clear error message returned

2. **CRITICAL: Operation-Specific Logic Fixed** (handleGCR.ts:339-406)
- **CREATE**: Requires account does NOT exist
- **WRITE/UPDATE/DELETE**: Requires account DOES exist
- Fixed broken non-CREATE operations
- Moved CREATE into operation-specific branch
- Fixed unreachable code issue

## Key Technical Decisions

### Access Control Architecture
- Caller identity from RPC headers (`"identity"` header)
- Validation using `validateStorageProgramAccess()` function
- Access modes: private, public, restricted, deployer-only
- 401 for missing auth, 403 for denied access

### Storage Program Query Pattern
```typescript
// All queries use primary key lookup
const storageProgram = await gcrRepo.findOne({
where: { pubkey: storageAddress } // Uses primary key index
})
// Then access JSONB in JavaScript
if (storageProgram.data.metadata.deployer === sender) { ... }
```

### Operation Flow
1. **CREATE**: Validate non-existence → Create account → Save → Return success
2. **WRITE**: Validate existence → Check access → Merge data → Validate size → Save
3. **UPDATE_ACCESS_CONTROL**: Validate existence → Check deployer → Update metadata
4. **DELETE**: Validate existence → Check deployer → Delete program

## Patterns Discovered

### Error Handling Pattern
```typescript
log.error(`[Context] Error: ${error instanceof Error ? `${error.message}\nStack: ${error.stack || 'N/A'}` : String(error)}`)
```

### Validation Guard Pattern
```typescript
if (!context.operation) return { success: false, message: "..." }
if (!context.data) return { success: false, message: "..." }
if (!context.data.variables) return { success: false, message: "..." }
// Safe to access context.data.variables
```

### Operation-Specific Existence Pattern
```typescript
if (operation === "CREATE") {
if (account) return { success: false, message: "Already exists" }
// Create logic
return { success: true, message: "Created" }
}
// For all other operations
if (!account) return { success: false, message: "Does not exist" }
// Update/delete logic
```

## Files Modified Summary

1. **src/libs/network/manageNodeCall.ts**
- Added sender parameter
- Added access control enforcement in getStorageProgram

2. **src/libs/network/server_rpc.ts**
- Pass sender to manageNodeCall

3. **src/libs/blockchain/gcr/handleGCR.ts**
- Fixed logger error call
- Added validation guards
- Fixed operation-specific existence logic

4. **src/libs/blockchain/validators/validateStorageProgramAccess.ts**
- Fixed duplicate if statement
- Updated validateCreateAccess comment

5. **src/model/entities/GCRv2/GCR_Main.ts**
- Removed unnecessary JSONB index

## Quality Verification
- All changes verified with `bun run lint:fix`
- No new ESLint errors introduced
- All errors in unrelated test files only

## Next Steps
- Monitor for any access control edge cases in production
- Consider adding metrics for storage program operations
- Potential future optimization: GIN index if JSONB queries added
100 changes: 100 additions & 0 deletions .serena/memories/session_2025_10_11_storage_programs_fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Storage Programs Critical Fixes - Session Summary

## Date: 2025-10-11

## Context
Resolved three critical blocking issues identified by code reviewer for Storage Programs feature. All issues prevented TypeScript compilation and runtime execution.

## Issues Resolved

### Issue #1: DELETE Operation Data Field Validation ✅
**Problem**: `handleGCR.ts:320` rejected DELETE operations because context.data was required
**Location**: `src/libs/blockchain/gcr/handleGCR.ts:318-323`
**Solution**: Made data field optional for DELETE operations
```typescript
if (context.operation !== "DELETE" && !context.data) {
return { success: false, message: "Storage program edit missing data context" }
}
```
**Impact**: DELETE_STORAGE_PROGRAM transactions now process correctly

### Issue #2: Missing SDK Storage Export ✅
**Problem**: Import `@kynesyslabs/demosdk/storage` failed - module not exported
**Location**: `../sdks/package.json:36`
**Solution**: Added storage export to SDK package.json
```json
"./storage": "./build/storage/index.js"
```
**Impact**: All storage type imports now resolve correctly

### Issue #3: Missing GCREdit Type Variant ✅
**Problem**: GCREdit union type missing "storageProgram" variant
**Location**: `../sdks/src/types/blockchain/GCREdit.ts:134-147`
**Solution**: Added complete GCREditStorageProgram interface
```typescript
export interface GCREditStorageProgram {
type: "storageProgram"
target: string
isRollback: boolean
txhash: string
context: {
operation: string
sender: string
data?: { variables: any; metadata: any }
}
}
```
**Impact**: TypeScript compilation successful, all storage operations type-safe

## Additional Fixes Applied

### Type Narrowing in handleGCR.ts
Added type guard for storage program edits to enable property access:
```typescript
if (editOperation.type !== "storageProgram") {
return { success: false, message: "Invalid edit type for storage program handler" }
}
```

### GCREdit Creation Updates
Updated all 4 storage program GCREdit creation points to include required fields:
- CREATE: Added sender to context
- WRITE: Already correct
- UPDATE_ACCESS_CONTROL: Added variables: {} to data
- DELETE: Already correct (no data field)

### SDK GCRGeneration.ts Fix
Updated address normalization to handle target field for storage programs:
```typescript
if (edit.type === "storageProgram") {
if (!edit.target.startsWith("0x")) {
edit.target = "0x" + edit.target
}
} else if ("account" in edit && !edit.account.startsWith("0x")) {
edit.account = "0x" + edit.account
}
```

## Files Modified

### Node Repository
1. `src/libs/blockchain/gcr/handleGCR.ts` - DELETE validation, type narrowing
2. `src/libs/network/routines/transactions/handleStorageProgramTransaction.ts` - GCREdit creation fixes

### SDK Repository
1. `package.json` - Added storage export, version bump to 2.4.22
2. `src/types/blockchain/GCREdit.ts` - Added GCREditStorageProgram interface
3. `src/websdk/GCRGeneration.ts` - Handle target field for storage programs

## Verification Results
- ✅ TypeScript compilation: 0 storage-related errors
- ✅ All imports resolve correctly
- ✅ All 4 storage operations (CREATE, WRITE, UPDATE_ACCESS_CONTROL, DELETE) type-safe
- ✅ SDK published successfully as v2.4.22

## Key Learnings
1. GCREdit interfaces require isRollback and txhash fields consistently
2. Storage programs use 'target' field while other edits use 'account'
3. DELETE operations intentionally exclude data field (only sender required)
4. UPDATE_ACCESS_CONTROL needs variables: {} even when not modifying variables
5. Type narrowing essential for accessing union type-specific properties
121 changes: 121 additions & 0 deletions .serena/memories/storage_programs_access_control_patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Storage Programs Access Control Patterns

## Access Control Implementation

### RPC Endpoint Security
**File**: `src/libs/network/manageNodeCall.ts`

```typescript
// Caller authentication required
if (!sender) {
response.result = 401
response.response = { error: "Caller address required for storage access" }
break
}

// Access control validation
const accessCheck = validateStorageProgramAccess(
"READ_STORAGE",
sender,
storageProgram.data,
)

if (!accessCheck.success) {
response.result = 403
response.response = { error: accessCheck.error || "Access denied" }
break
}
```

### Access Control Modes

**private / deployer-only**:
- Only deployer can read and write
- Most restrictive mode

**public**:
- Anyone can read
- Only deployer can write
- Good for public datasets

**restricted**:
- Only deployer or allowlisted addresses
- Configured via allowedAddresses array
- Good for shared team storage

### Validator Logic
**File**: `src/libs/blockchain/validators/validateStorageProgramAccess.ts`

```typescript
const isDeployer = requestingAddress === deployer

// Admin operations always require deployer
if (operation === "UPDATE_ACCESS_CONTROL" || operation === "DELETE_STORAGE_PROGRAM") {
return isDeployer ? { success: true } : { success: false, error: "..." }
}

// Mode-specific rules
switch (accessControl) {
case "private":
case "deployer-only":
return isDeployer ? { success: true } : { success: false }

case "public":
if (operation === "READ_STORAGE") return { success: true }
if (operation === "WRITE_STORAGE") {
return isDeployer ? { success: true } : { success: false }
}

case "restricted":
if (isDeployer || allowedAddresses.includes(requestingAddress)) {
return { success: true }
}
return { success: false }
}
```

### Authentication Flow

1. **RPC Request** → Headers contain `"identity"` field
2. **Server Validation** → `validateHeaders()` verifies signature
3. **Extract Sender** → `sender = headers.get("identity")`
4. **Pass to Handler** → `manageNodeCall(payload, sender)`
5. **Enforce Access** → `validateStorageProgramAccess(operation, sender, data)`
6. **Return 403/401** → Appropriate error without data leakage

### Security Considerations

**Never leak data on denial**:
```typescript
// ✅ Good - no data in error response
response.response = { error: "Access denied" }

// ❌ Bad - leaks metadata
response.response = { error: "Access denied", metadata: program.metadata }
```

**Always validate sender**:
```typescript
// ✅ Good - check sender exists
if (!sender) return 401

// ❌ Bad - assume sender exists
const accessCheck = validateStorageProgramAccess(operation, sender, data)
```

## Integration Points

### Transaction Handler
**File**: `src/libs/network/routines/transactions/handleStorageProgramTransaction.ts`

- Queues GCR edits with sender context
- Access validation happens in HandleGCR.applyStorageProgramEdit()
- Sender included in context for deferred validation

### GCR Handler
**File**: `src/libs/blockchain/gcr/handleGCR.ts`

- Receives sender from transaction context
- Validates access before applying edits
- Returns error if access denied
- No state changes on validation failure
Loading