IntersectMBO / IntersectMBO/evolution-sdk

Koios getUtxosByOutRef: fails for outputs of Plutus transactions, and drops all but one transaction

Aperta
#540 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
TypeScript
Stelle
22
Fork
30
Merge medio
5h 29m
PR unite (30g)
12

Descrizione

## Summary

In `KoiosEffect.getUtxosByOutRef` (0.5.13; unchanged on `main` at a98c483):

1. **Outputs of a transaction that ran a Plutus script can't be fetched.** The lookup requests `/tx_info` for the creating transaction and decodes the whole row with `TxInfoSchema`. For those transactions Koios returns `null` in three `plutus_contracts[]` fields the schema requires — `address`, `bytecode` and `input.datum` — so decoding fails and the call rejects.
2. **Refs spanning several transactions return outputs from only one.** `const [result] = yield* ...` keeps the first `tx_info` row. Koios does return one row per hash; the others are dropped without an error.

## Reproduce (preprod)

```ts
import { TransactionHash, TransactionInput } from "@evolution-sdk/evolution"
import { Koios } from "@evolution-sdk/evolution/sdk/provider/Koios"

const koios = new Koios("https://preprod.koios.rest/api/v1")
const ref = (hash: string, index: number) =>
new TransactionInput.TransactionInput({ transactionId: TransactionHash.fromHex(hash), index: BigInt(index) })

// 1. An output of a transaction that ran Plutus scripts
try {
await koios.getUtxosByOutRef([ref("01b6275f8fd25c60cf9887fe38ee3a340b3f3b2eca15ae0c80c54c573016dcc6", 0)])
} catch (e) {
console.log((e as Error).message) // Koios getUtxosByOutRef failed
}

// 2. Outputs of two ordinary transactions
const utxos = await koios.getUtxosByOutRef([
ref("37120eda148486250fd331b8c3be6ea134a111b5ccf4f951f659a0f71c4c7c06", 0),
ref("ba269ae6f25b2ba505d3da251bbed9904f10466db05ed87c163edec66145eb3e", 0),
])
console.log(utxos.length) // 1
```

## Expected

1. The output is returned.
2. Both outputs are returned.

## Actual

1. Rejects with `Koios getUtxosByOutRef failed`. The underlying `ParseError` points at `plutus_contracts[0].address: Expected string, actual null`.
2. Logs `1`.

## Notes

- Decoding with `{ errors: "all" }` shows the three fields fail independently, so relaxing only `address` is not enough. On the wallet I tested, 10 of the 13 transactions that created its UTxOs failed this way, matching the API failures one for one.
- `/utxo_info` with `_utxo_refs` (and `_extended: true`) returns exactly the requested outputs without decoding whole transactions: 17 refs across 13 transactions gave 17 rows, including outputs of the failing ones. It would avoid both problems.
- The `ParseError` is attached as the `ProviderError`'s cause, but the Promise API rejects with Effect's `FiberFailure`, where `err.cause` is `undefined`, so Promise callers only see the generic message. That is how this showed up downstream: `@x402/cardano`'s facilitator reports `exact_cardano_facilitator_chain_lookup_failed` / `Koios getUtxosByOutRef failed` when a payment spends an output of such a transaction.

Investigated with AI assistance (Claude Code); the reproduction above was run against preprod on 0.5.13.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Start at KoiosEffect.getUtxosByOutRef and inspect its current /tx_info lookup and TxInfoSchema decoding. Compare that path with the issue's /utxo_info request using _utxo_refs and _extended: true, then run the preprod reproductions. Done means Plutus-created outputs are returned and refs from multiple transactions produce every requested output.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
api, backend
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Attiva
Chiarezza
Specificata chiaramente
Idoneità per principianti
72/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.