Skip to content

Optional explicit Unicity Service request deadline #82

Description

@ristik

Background

An application may specify an exclusive Unicity Service request deadline. It is optional, because transaction construction must not require access to a reliable system clock.

This is a greenfield protocol with no mainnet, so the deadline does not need a separate compatibility encoding. It occupies a fixed position in one wire shape and is written as the CBOR simple value null when the application does not supply one, which is how the other optional fields in these same arrays are already encoded. appendix-encoding.tex states this as the general rule for optional tuple elements.

This issue concerns request-deadline API and encoding only. Mandatory leaf reference-time commitment is specified separately.

Wire format

One version and one element count per structure:

MintTransaction      [2, networkId, recipient, salt, tokenType, justification, data, expiresAt]
TransferTransaction  [2, recipient, stateMask, data, expiresAt]
CertificationData    [2, lockScript, sourceStateHash, transactionHash, expiresAt, witness]

expiresAt : uint | null

expiresAt is part of the transaction hash preimage in both cases, so

txhash = SHA-256(CBOR([…, expiresAt]))

is total and needs no case split, and changing the value changes txhash and invalidates the witness. A service-assigned deadline is not inserted into the transaction or the certification data.

Naming

The field is named expiresAt (expires_at in Rust, ExpiresAt in Go). The value is an absolute exclusive instant in Unix seconds, not a duration, and these SDKs already use "timeout" for transport and polling deadlines.

Scope in this SDK

  • One accepted version and one element count per structure, both checked once.
  • Represent an omitted deadline as null and encode it in its fixed position.
  • Include expiresAt in transaction hashing and certification data unconditionally.
  • Enforce tau < expiresAt during verification only when a deadline is present. When it is absent, the service-assigned deadline is not recorded, not signed, and not re-checked by a verifier; that is inherent to not having a clock, not a regression.
  • Default mint, transfer and split flows must read no system clock.
  • Replace the positional-overload factories with the language's idiom for optional arguments.
  • Keep certified transaction and proof reference-time behavior aligned with the leaf reference-time issue; an omitted deadline must not change that separate protocol invariant.

Acceptance criteria

  • One version and one element count per structure; any other version is rejected.
  • An omitted deadline round-trips as CBOR null in its fixed position.
  • Default mint, transfer, and split flows do not read system time.
  • Changing expiresAt changes txhash and invalidates the existing witness.
  • Verification enforces the exclusive boundary when a deadline is present and skips request-expiry policy when it is absent.
  • Unit, functional, example, and cross-SDK fixtures cover both a present and an absent deadline.

Java specifics

  • The field is a nullable Long, never a long with 0 as a sentinel: zero is a legal instant in $\mathbb{T}$.
  • The accessor is Optional<Long> getExpiresAt(), matching Optional<byte[]> getData() on the same interface.
  • MintTransaction.create had grown to 18 overloads. Replace the set with MintTransaction.builder(networkId, recipient), naming the optional arguments.

Companion issues

Repository Reference time in the leaf value Request timeout
aggregator-go unicitynetwork/aggregator-go#176 unicitynetwork/aggregator-go#177
rugregator ristik/rugregator#3 ristik/rugregator#4
bft-core (branch l1) unicitynetwork/bft-core#23 (RSMT), unicitynetwork/bft-core#24 (ZK) out of scope
state-transition-sdk-js unicitynetwork/state-transition-sdk-js#144 unicitynetwork/state-transition-sdk-js#145
state-transition-sdk-java #81 #82
state-transition-sdk-rust unicitynetwork/state-transition-sdk-rust#16 unicitynetwork/state-transition-sdk-rust#17

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions