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

remove zero withdrawal from the transaction response

Open
#780 0 comments 0 reactions 0 assignees View on GitHub
cip-113
Dominant language
Java
Stars
26
Forks
15
Avg merge
5d 3h
Merged PRs (30d)
2

Description

### Background

CIP-113 transactions contain withdraw-zero operations — withdrawals of exactly 0 lovelace used to invoke the programmable-logic-global and transfer-logic stake validators. This is the standard withdraw-zero validation pattern; the withdrawal carries no value and moves no funds. These are internal mechanics and must NOT appear in Rosetta responses.

They are currently exposed. For the CIP-113 reference transaction `dfd2e3e93ff7b36a4ff9c5c07ec1f8a685ccddeb3258eac6313e82410c35dca2` on preview, `/block/transaction` returns:

```json
{
"operation_identifier": { "index": 2 },
"type": "withdrawal",
"status": "success",
"account": { "address": "stake_test17z2q7d9gzdfshwpympegqf9nqnq0tyh44hq9ar8e36420sg2fnnrw" },
"metadata": { "withdrawalAmount": { "value": "0", "currency": { "symbol": "ADA", "decimals": 6 } } }
}
```

The operation is accurate — the transaction really does contain a zero withdrawal — but it represents script invocation rather than a balance change, and surfacing it as a withdrawal is misleading to integrators reconciling account activity.

This does not affect balance reconciliation (a zero withdrawal contributes 0 either way), so it is a display correctness issue rather than a balance correctness issue.

### Expected Behavior

Withdrawal operations whose value is 0 are removed from the operation list before the response is built, in `OperationMapperService`. Because that mapper is shared, this applies to `/block`, `/block/transaction` and `/search/transactions` at once.

Remaining operations are re-indexed so `operation_identifier.index` stays contiguous from 0.

**Scoping decision needed.** Two options, and this should be settled before implementation:

- **Filter all zero-value withdrawals unconditionally.** Simple, needs no configuration. A zero withdrawal in a non-CIP-113 transaction is also script invocation rather than a balance change, so the same reasoning applies. Changes behavior for any Plutus transaction using the withdraw-zero pattern.
- **Filter only within CIP-113 transactions.** Narrower blast radius, but requires CIP-113 detection via the `programmableLogicBase` script hash from configuration, which means this issue then depends on that configuration landing.

The first option is recommended: the operation is equally uninformative in both cases, and it keeps this change independent of CIP-113 configuration.

### Acceptance Criteria

- [ ] Zero-value withdrawal operations do not appear in `/block`, `/block/transaction` or `/search/transactions`
- [ ] Non-zero withdrawal operations are unaffected
- [ ] Remaining operation indexes are contiguous from 0 after filtering
- [ ] `related_operations` references, if any, remain valid after re-indexing
- [ ] A transaction consisting only of a zero withdrawal and its inputs/outputs still returns those inputs/outputs
- [ ] Balance reconciliation is unchanged (zero withdrawals contributed 0 before and after)

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in OperationMapperService and trace how its output feeds /block, /block/transaction, and /search/transactions. Use the reference transaction dfd2e3e93ff7b36a4ff9c5c07ec1f8a685ccddeb3258eac6313e82410c35dca2 to verify zero withdrawals are omitted, indexes and related_operations remain valid, and other operations are preserved. Confirm non-zero withdrawals and balance reconciliation are unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, blockchain
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.