cardano-foundation / cardano-foundation/cardano-rosetta-java

Invalid transactions missing inputs and outputs (collateral operations)

Open
#602 1 comment 0 reactions 0 assignees View on GitHub
Known Limitation
Dominant language
Java
Stars
26
Forks
15
Avg merge
5d 3h
Merged PRs (30d)
2

Description

### Context & versions
- **rosetta-java** v1.3.2
- **Network**: preprod
- **Transaction example**: `2bb415e28c4bbc81b3be24499ba8fa216fe728b1e828ebc35b5a58c079f9fec8` (Block 3422820)
- **Issue**: rosetta-java only shows invalid operations (failed script attempts), missing the valid collateral operations that actually succeeded

### Steps to reproduce
1. Start rosetta-java on preprod
2. Query invalid transaction via `/block/transaction`:
```bash
curl -X POST http://localhost:8083/block/transaction \
-H "Content-Type: application/json" \
-d '{
"network_identifier": {"blockchain": "cardano", "network": "preprod"},
"block_identifier": {"index": 3422820, "hash": "5d8c7e399374b40693ec8c05e5003dc3b7c3ef7c7e04d68507371a1e262281be"},
"transaction_identifier": {"hash": "2bb415e28c4bbc81b3be24499ba8fa216fe728b1e828ebc35b5a58c079f9fec8"}
}'
```
3. Observe response shows only invalid script input operation
4. Verify script UTXO still exists using cardano-cli (wasn't actually consumed)
5. Note collateral operations are completely missing

### Actual behavior

#### rosetta-java response (INCOMPLETE)
```json
{
"operations": [
{
"type": "input",
"status": "invalid", // ✓ Correct status - this operation failed
"account": {"address": "addr_test1wr3cmj7uzdl89zkrgdqk55sn9ka3368stgaky3xm59elfrg49uvlm"},
"amount": {"value": "-5000000"}, // ✓ Shows attempted amount
"coin_change": {
"coin_identifier": {"identifier": "39bdb7ca1f83ab998811a1b29c57e3bb24336e8c8e10a6fd19e662c2c4a0f29f:0"},
"coin_action": "coin_spent"
}
}
]
}
```
**Problem**: Only shows invalid operations. Missing the VALID collateral operations that succeeded.

**UTXO Search for `39bdb7ca...#0` (the script input shown with invalid status):**
```bash
curl -X POST http://localhost:8083/search/transactions \
-H "Content-Type: application/json" \
-d '{"network_identifier": {"blockchain": "cardano", "network": "preprod"},
"coin_identifier": {"identifier": "39bdb7ca1f83ab998811a1b29c57e3bb24336e8c8e10a6fd19e662c2c4a0f29f:0"}}'
```
**Response:**
```json
{
"total_count": 1, // ONLY ONE TRANSACTION - THE CREATION!
"transactions": [
{
"block_identifier": {"index": 3413492},
"transaction": {
"transaction_identifier": {"hash": "39bdb7ca1f83ab998811a1b29c57e3bb24336e8c8e10a6fd19e662c2c4a0f29f"},
"operations": [
// ... shows this UTXO being CREATED as output #0 with 5 ADA
]
}
}
]
}
```

**But via cardano-cli:**
```bash
cardano-cli query utxo --address addr_test1wr3cmj7uzdl89zkrgdqk55sn9ka3368stgaky3xm59elfrg49uvlm --testnet-magic 1
```
**Result:**
```
TxHash TxIx Amount
--------------------------------------------------------------------------------------
39bdb7ca1f83ab998811a1b29c57e3bb24336e8c8e10a6fd19e662c2c4a0f29f 0 5000000 lovelace + TxOutDatumInline
```
**THIS UTXO STILL EXISTS!** Confirms the operation correctly has status="invalid" (wasn't consumed).

**Collateral UTXO `fe079cee...#2` (what rosetta-ts shows but rosetta-java misses):**
```bash
curl -X POST http://localhost:8083/search/transactions \
-H "Content-Type: application/json" \
-d '{"network_identifier": {"blockchain": "cardano", "network": "preprod"},
"coin_identifier": {"identifier": "fe079ceee24e55afccdb6662c8b22ea228348f56b57587fb8e95a867969d31c3:2"}}'
```
**Response:**
```json
{
"total_count": 2, // TWO TRANSACTIONS - CREATED AND SPENT!
"transactions": [
"2bb415e28c4bbc81b3be24499ba8fa216fe728b1e828ebc35b5a58c079f9fec8", // SPENT HERE (our invalid tx)
"fe079ceee24e55afccdb6662c8b22ea228348f56b57587fb8e95a867969d31c3" // CREATED HERE
]
}
```

**Collateral return verification via cardano-cli:**
```bash
cardano-cli query utxo --address addr_test1vz8dlkd8zg4rxzs26fq95fheupph8mmgpf78rh3c5nyalsq5rgkvr --testnet-magic 1
```
**Result:**
```
TxHash TxIx Amount
--------------------------------------------------------------------------------------
2bb415e28c4bbc81b3be24499ba8fa216fe728b1e828ebc35b5a58c079f9fec8 2 13165743 lovelace
```
**Collateral was consumed and returned!** This is what rosetta should show.

#### rosetta-ts response (partially correct)
```json
{
"operations": [
{
"type": "input",
"status": "invalid", // ❌ Should be "success" - this WAS consumed!
"account": {"address": "addr_test1vz8dlkd8zg4rxzs26fq95fheupph8mmgpf78rh3c5nyalsq5rgkvr"},
"amount": {"value": "-13720235"}, // 13.72 ADA - COLLATERAL
"coin_change": {
"coin_identifier": {"identifier": "fe079ceee24e55afccdb6662c8b22ea228348f56b57587fb8e95a867969d31c3:2"},
"coin_action": "coin_spent"
}
},
{
"type": "output",
"status": "invalid", // ❌ Should be "success" - this WAS created!
"account": {"address": "addr_test1vz8dlkd8zg4rxzs26fq95fheupph8mmgpf78rh3c5nyalsq5rgkvr"},
"amount": {"value": "13165743"}, // 13.16 ADA - COLLATERAL RETURN
"coin_change": {
"coin_identifier": {"identifier": "2bb415e28c4bbc81b3be24499ba8fa216fe728b1e828ebc35b5a58c079f9fec8:2"},
"coin_action": "coin_created"
}
}
// ❌ MISSING: Script input operation with status "invalid" (the actual failed operation)
]
}
```
**Problems with rosetta-ts:**
- Shows the RIGHT UTXOs (collateral) but WRONG status (should be "success" for collateral ops)
- Missing the actual invalid operation (script input that failed to be consumed)

#### What Actually Happened
```mermaid
graph LR
subgraph "BEFORE Transaction"
U1["Contract Wallet
addr_test1wr3cmj7..."]
U1 --> UTXO1["39bdb7ca...#0
5 ADA
(script input)"]

U2["User Wallet
addr_test1vz8dlkd..."]
U2 --> UTXO3["fe079cee...#2
13.72 ADA
(COLLATERAL)"]
end

subgraph "Transaction Attempt"
TX["TX: 2bb415e...
Script Execution FAILS
Phase 2 Validation ❌"]
UTXO1 -.->|"TRIED to spend
(but failed)"|TX
UTXO3 ==>|"ACTUALLY SPENT
(collateral)"|TX
end

subgraph "AFTER Transaction"
TX ==>|"Collateral Return
13.16 ADA"|UTXO4["2bb415e...#2
13.16 ADA
(collateral return)"]
TX ==>|"Fee to Network
0.554 ADA"|FEE["Network Fee Pot"]

UTXO1 -->|"STILL EXISTS
(unspent)"|U1B["Contract Wallet
addr_test1wr3cmj7..."]
UTXO4 -->|"NEW UTXO"|U2B["User Wallet
addr_test1vz8dlkd..."]
end

style UTXO1 fill:#f5f5f5,stroke:#666,stroke-width:1px
style UTXO3 fill:#fff,stroke:#000,stroke-width:2px
style UTXO4 fill:#fff,stroke:#000,stroke-width:2px
style FEE fill:#fff,stroke:#333,stroke-width:1px
style TX fill:#fafafa,stroke:#000,stroke-width:2px
style U1 fill:#fff,stroke:#333,stroke-width:1px
style U2 fill:#fff,stroke:#333,stroke-width:1px
style U1B fill:#fff,stroke:#333,stroke-width:1px
style U2B fill:#fff,stroke:#333,stroke-width:1px
```

- **Script input** (`39bdb7ca...#0`): ATTEMPTED but FAILED - rosetta-java correctly shows this as invalid ✓
- **Collateral** (`fe079cee...#2`): SUCCESSFULLY consumed, 13.16 ADA returned - rosetta-java doesn't show this ✗
- **Fee**: 0.554 ADA taken from collateral
- **Core problem**: Incomplete representation showing only failures, not successes

### Expected behavior
For phase 2 validation failures, should show ALL operations (both intended and actual) with correct statuses, network_index, and related_operations:

```json
{
"operations": [
{
"operation_identifier": {"index": 0, "network_index": 0},
"type": "input",
"status": "invalid", // Script execution failed - UTXO NOT consumed
"account": {"address": "addr_test1wr3cmj7uzdl89zkrgdqk55sn9ka3368stgaky3xm59elfrg49uvlm"},
"amount": {"value": "-5000000"},
"coin_change": {
"coin_identifier": {"identifier": "39bdb7ca1f83ab998811a1b29c57e3bb24336e8c8e10a6fd19e662c2c4a0f29f:0"},
"coin_action": "coin_spent"
}
},
{
"operation_identifier": {"index": 1, "network_index": 0},
"related_operations": [{"index": 0}], // References the script input that would have funded it
"type": "output",
"status": "invalid", // Intended output NOT created (script failed)
"account": {"address": "addr_test1wr3cmj7uzdl89zkrgdqk55sn9ka3368stgaky3xm59elfrg49uvlm"},
"amount": {"value": "1611940"} // 1.61 ADA
},
{
"operation_identifier": {"index": 2, "network_index": 1},
"related_operations": [{"index": 0}], // References the script input that would have funded it
"type": "output",
"status": "invalid", // Intended output NOT created (script failed)
"account": {"address": "addr_test1vz8dlkd8zg4rxzs26fq95fheupph8mmgpf78rh3c5nyalsq5rgkvr"},
"amount": {"value": "3018399"} // 3.01 ADA
},
{
"operation_identifier": {"index": 3, "network_index": 0}, // Position in body.collateralInputs[]
"type": "collateralInput", // Different type for collateral!
"status": "success", // Collateral WAS consumed
"account": {"address": "addr_test1vz8dlkd8zg4rxzs26fq95fheupph8mmgpf78rh3c5nyalsq5rgkvr"},
"amount": {"value": "-13720235"},
"coin_change": {
"coin_identifier": {"identifier": "fe079ceee24e55afccdb6662c8b22ea228348f56b57587fb8e95a867969d31c3:2"},
"coin_action": "coin_spent"
}
},
{
"operation_identifier": {"index": 4, "network_index": 0}, // network_index=0 for consistency
"related_operations": [{"index": 3}], // References the collateral input that funded it
"type": "collateralReturn", // Different type for collateral return!
"status": "success", // Collateral return WAS created
"account": {"address": "addr_test1vz8dlkd8zg4rxzs26fq95fheupph8mmgpf78rh3c5nyalsq5rgkvr"},
"amount": {"value": "13165743"},
"coin_change": {
"coin_identifier": {"identifier": "2bb415e28c4bbc81b3be24499ba8fa216fe728b1e828ebc35b5a58c079f9fec8:2"},
"coin_action": "coin_created"
}
}
]
}
```

**Note on implementation**: The complete fix with correct `network_index` values ideally requires implementing separate operation types for collateral operations (`collateralInput` and `collateralReturn`), as detailed in the sub-issue proposal. This ensures each operation's network_index correctly represents its position within its respective transaction body array.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.