Skip to content

nLockTime hardcoded to 0 in call-tx builder blocks deadline-based contracts #40

@E-Jacko

Description

@E-Jacko

Summary

The Rust SDK's call-tx builder writes nLockTime = 0 unconditionally. There is no way for callers to override this via CallOptions. Contracts that assert against extractLocktime(txPreimage) therefore cannot work as designed:

  • An auction close() method that requires extractLocktime(txPreimage) >= deadline always fails for any non-zero deadline, because the signed transaction's nLockTime is 0.
  • The same applies to any time-locked contract (escrow refund after timeout, vesting release, etc.).

The TypeScript SDK has the same gap in packages/runar-sdk/src/contract.ts.

Reproduction

The reference test test_auction_close in integration/rust/tests/auction.rs works around this by hardcoding deadline = 0:

SdkValue::Int(0), // deadline=0 so extractLocktime(txPreimage) >= deadline passes with nLocktime=0

The workaround proves the limitation is known. With any realistic non-zero deadline (e.g. currentBlock + 8), close() fails ARC validation because the script's deadline assertion returns false.

Affected files

  • packages/runar-rs/src/sdk/types.rsCallOptions struct has no locktime field.
  • packages/runar-rs/src/sdk/contract.rs and packages/runar-rs/src/sdk/calling.rs — call-tx build sites write to_little_endian_32(0) for the locktime bytes.

Proposed fix

Add an optional locktime: Option<u32> field to CallOptions. Default None → SDK still writes 0 → existing callers see identical behavior. Callers can pass Some(n) for time-locked methods.

This is purely additive and back-compatible.

Evidence

A patched SDK has been validated against BSV mainnet: transactions with a caller-supplied non-zero nLockTime mine successfully through ARC; the same transactions with hardcoded nLockTime = 0 are rejected with Script evaluated without error but finished with a false/empty top stack element (the deadline assertion failing).

PR with fix + regression tests is opened alongside this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions