Skip to content

Provide opt-in deterministic reference-input ordering for newly built transactions #504

Description

@Cerkoryn

Is your feature request related to a problem? Please describe.

Our defi-kernel trading engine needs reproducible candidate bytes for evaluation, authorization and recovery. TransactionBuilder.reference_inputs is a Python set; _build_tx_body serializes its iteration order. The same inserted references produce different body hashes across Python hash seeds, so we currently override a private method.

Describe the solution you'd like

A supported opt-in ordering policy for newly constructed candidates, using a stable out-ref order before evaluation and protocol-index resolution. Preserve existing default behavior and never normalize decoded/imported transaction CBOR: that would change existing hashes/signatures.

Describe alternatives you've considered

A private builder override works locally but is fragile. A fixed process hash seed does not establish a portable ordering contract.

Additional context

Offline reproduction, Linux/Python 3.12.14; reproduced on PyCardano 0.18.0 and current main 3bc5677. Save as refs.py and run with PYTHONHASHSEED=1 python refs.py, then seeds 2–5:

from types import SimpleNamespace
import pycardano as pc

address = pc.Address(pc.VerificationKeyHash(b"p" * 28), network=pc.Network.TESTNET)
builder = pc.TransactionBuilder(SimpleNamespace())
builder.add_input(pc.UTxO(
    pc.TransactionInput(pc.TransactionId(b"z" * 32), 0),
    pc.TransactionOutput(address, 10_000_000),
))
builder.add_output(pc.TransactionOutput(address, 9_800_000))
builder.fee = 200_000
for i in range(7):
    builder.reference_inputs.add(
        pc.TransactionInput(pc.TransactionId(bytes([i]) * 32), i)
    )
body = builder._build_tx_body()
print([ref.index for ref in body.reference_inputs], str(body.id))

Seeds 1 and 2 produced [4, 3, 6, 2, 0, 1, 5] and [1, 0, 4, 2, 5, 3, 6]; five seeds yielded five body hashes. This isolates construction internals, not ledger validation; unsorted serialization is not claimed to be ledger-invalid.

Acceptance: identical bytes in opt-in mode across insertion/hash-seed permutations; unchanged default/imported bytes; consistent handling of mixed UTxO/TransactionInput references and duplicate out-refs; resolved redeemer indices must match the final order. No automatic callback discovery or broader builder redesign is requested.

Created by gpt-6-astra high under supervision of @Cerkoryn

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions