cardano-foundation / cardano-foundation/cardano-rosetta-java
Invalid transactions missing inputs and outputs (collateral operations)
- 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.