Commit graph

34 commits

Author SHA1 Message Date
Hossein Zoda
1ddab462aa ido minor fixes 2026-06-26 10:52:40 +03:00
Hossein Zoda
d363c2c930 ido followup update, offering contract updated & set ido create exe fee to 10m sats 2026-06-25 17:20:31 +03:00
Hossein Zoda
b88475a75b ido: record EntryDistributed per distribution tx with the entry's txid
The EntryDistributed update was pushed in the POSTLAUNCH->DISTRIBUTED
branch using the collection tx's own txid. That branch fires once at
final collection rather than per distribution tx, and tx.compute_txid()
never equals an entry's creation txid, so the dist_expr join
(d.entry_txid = e.txid) never matched and entries were never marked
distributed.

Push it in the DISTRIBUTING handler instead, once per distribution tx,
using input#1.previous_output.txid (the entry NFT being spent), which is
the entry's creation txid recorded by IdoUpdate::Entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:57:31 +00:00
Hossein Zoda
f9ee877392 format 2026-06-23 02:38:25 +03:00
Hossein Zoda
0831834d8f ido: replace txchain model with unified state-chain indexing
Replace index_block/index_mempool with a single index_txs that takes an
Option<blockhash> (Some for confirmed, None for mempool). Add
delete_entries(blockhash) for reorg undo and to drop stale mempool state
before applying confirmed blocks. Replace has_txchain_tx with
has_indexed_tx; chain-follow now keys on ido_state.next_output_index
instead of the removed tracker map.

Remove the debug-only txchain RPC endpoints and the debug config gating.
Keep txchain_head as a public RPC field.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 19:46:23 +00:00
Hossein Zoda
e2f72e608e format 2026-06-22 10:48:08 +00:00
Hossein Zoda
c7a9e9bea6 ido: replace num-bigint with malachite
Migrate the ido module's arbitrary-precision math from num-bigint to
malachite (already a workspace dependency). BigInt becomes
malachite::Integer throughout; the VM-number byte codec uses
PowerOf2Digits, sign handling uses Integer::sign(), and primitive
conversions use try_from.

Add an IntegerAsStr serde adapter for string-serialized fields, since
malachite's FromStr::Err is () and does not satisfy DisplayFromStr's
Display bound. JSON output is unchanged.

Drop the now-unused num-bigint and num-traits dependencies.

Also fix all clippy warnings in the module surfaced by the migration
(unwrap-after-is_none control flow, a const->static LazyLock bug,
an oversized enum variant boxed, and assorted mechanical lints).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 10:41:39 +00:00
Hossein Zoda
5f49ad75c0 format ido 2026-06-21 01:44:39 +03:00
Hossein Zoda
0aa4d1c530 add copyright to db/ido/mod.rs 2026-06-21 01:44:39 +03:00
Hossein Zoda
62b8fb6436 ido: only update block_height when tx is already in the txchain
on_add_ido_tx rebuilt the whole chain whenever the input tx was not the
txchain head. A mempool tx confirming after the chain advanced past it
would needlessly trigger a full rebuild.

Reconstruct the current chain (txchain_head .. txchain_entrypoint) and,
if the tx is already part of it, only update its block height. Extract
the shared chain-walking logic into reconstruct_txchain, reused by both
the membership check and the rebuild branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
9b0a54c926 ido: maintain entry aggregates in active state
Replace the per-request get_ido_entry_aggregates SQL scan with running
totals carried in IdoActiveState: totalDemandAmount, totalSupplyAmount,
and totalDiscount. Initialized to 0 at the preinit->active transition and
incremented on each entry added; the rebuild path recomputes them by
replaying the txchain, so they self-heal.

Drop the now-unused get_ido_entry_aggregates DB fn, the IdoEntryAggregatesRpc
type, the /<id>/aggregates RPC handler, and its route registration.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
b8468a1256 ido: record created_at and launched_at timestamps
Add two timestamp columns to the ido table, both sourced from Delphi NFT
commitments (48-bit LE unix seconds):

- created_at (NOT NULL, default 0): from the Delphi NFT in the preinit's
  first output, set at IDO creation. 0 if the commitment is too short.
- launched_at (NULL): from the Delphi NFT in output#3 of the launch
  transaction, set in lockstep with launch_txid. Null until launched.

Both are threaded through the parse/context/update paths and exposed on
IdoRpcRecord.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
d5bdf5a740 ido: filter list_ido_entries by owner_nfthash
Add an optional owner_nfthash query param to GET /<id>/entries. Accepts
up to 20 comma-delimited 32-byte hex hashes; an entry matches any listed
value via an owner_nfthash IN (...) clause. Rejects malformed hex,
wrong-length values, and >20 filters with a 400.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
aec0a6f0f8 ido: add /<id>/aggregates endpoint for entry totals
Sum demand/supply amounts and count entries for an IDO, used to show
"raised so far" for active offerings where on-chain state keeps no
running total.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
a410aee95f ido: migrate to bitcoincash 0.32 script API; fix mempool diff
Update ido/mod.rs for the bitcoincash 0.32 API: Script -> ScriptBuf,
push_slice via &PushBytes (new pb() helper), as_byte_array/as_bytes.
Fix update_mempool to diff against cauldron_txs instead of defi_txs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
856b374a6d ido improvements & fixes (WIP) 2026-06-21 01:44:39 +03:00
Hossein Zoda
b1df63c6c4 ido: garbage collect tracker entries of mempool txs that never confirm
Stamp mempool tracker entries with the negative of the highest known
block height instead of a fixed -1 sentinel, and trim on abs(height) so
entries whose tx is invalidated before confirming (e.g. by a double
spend) age out after TRACKER_MAX_BLOCK_DEPTH like confirmed ones. The
height is still replaced with the real one once the tx confirms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
7f46b1b4b7 ido: index unconfirmed txs from the mempool
- electrum mempool fetch gains an ido filter: state machine spends
  (IDO_SIGNATURE in scriptsig) union preinit announcements
  (IDO_PREINIT_ANNOUNCEMENT_SIGNATURE in scriptpubkey)
- split tx scanning out of index_block into index_txs and add
  index_mempool, which indexes with a -1 sentinel height;
  txchain_trim_tracker leaves negative heights alone and the real
  height replaces the sentinel once the tx confirms in a block
- block indexing now skips re-creating an ido already seen in the
  mempool, only updating its tracker height
- mempool txs are kahn-sorted so txchain parents index before children

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
e14fbd4f1e ido more fixes 2026-06-21 01:44:39 +03:00
Hossein Zoda
874e9f0231 set mock platform fee nfthash 2026-06-21 01:44:39 +03:00
Hossein Zoda
366823cf02 ido: validate delphi nft in preinit first output; announcement moves to last
The preinit tx layout changed: the first output is now the Delphi NFT and
the announcement OP_RETURN is the last output. Read the announcement from the
last output in both is_preinit_broadcast and parse_ido_preinit_tx_params.

Add validity checks on the first output's Delphi NFT: its category must match
the announcement's delphiCategory, and the 48-bit commitment timestamp (current
time) must place launchConditions.expiresAt within a 1-30 day window.

The two PREINIT_TEST_TX vectors use the old layout, so the three preinit parse
tests are marked #[ignore] pending new-format sample transactions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
b56ce5bc63 ido: key txchain tx lookup by txid; gate debug endpoints behind config
Change get_txchain_tx to take the public txid (a unique field) instead of
the non-public internal txchain item id, and promote it to a production
endpoint. Mount the two remaining debug endpoints (list_ido_txchain,
list_txchain_tracker_map) only when `debug = true` in the config.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
e86de7d5f5 ido: hide txchain_entrypoint, expose txchain_head as head txid
The IDO RPC record no longer leaks internal txchain row ids. Drop the
txchain_entrypoint field entirely, and change txchain_head from the
internal ido_txchain.id to the head record's txid (display hex).

list_idos and get_ido_by_offering_token_id resolve this in a single
query via LEFT JOIN ido_txchain ON head_tx.id = ido.txchain_head; a
NULL head yields null. Adds tests for both the resolved and null cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
6728753db0 ido: use preinit_txid hex as public id (rename internal id)
Rename ido.id -> ido.internal_id in the schema and IdoDBRecord, and
expose the preinit_txid hex as the public "id" in all RPC responses.

Public API shape:
  - IdoRpcRecord.id: i64 -> String (hex of preinit_txid). preinit_txid
    field is preserved unchanged.
  - IdoEntryRpcRecord.ido_id: i64 -> String (hex of parent preinit_txid).
  - IdoTxChainRpcRecord.ido_id: i64 -> String (hex of parent preinit_txid).
  - IdoTxChainRpcRecord gains ido_internal_id: i64 (debug endpoint only).
  - Routes /<id>/entries and /<id>/txchain accept the preinit_txid hex
    as the path id; returns 404 IDO_NOT_FOUND on miss.

Internals:
  - New lookup_internal_id_by_preinit_txid helper.
  - list_ido_entries / list_ido_txchain take preinit_txid_hex as input
    so the caller (which already parsed it from the path) avoids the
    extra "preinit_txid by internal_id" lookup.
  - Child table FK columns (ido_entry.ido_id, ido_txchain.ido_id) keep
    their names; only the parent PK and field accesses were renamed.

Notes:
  - Breaking API change for /ido/* endpoints. Clients reading "id" or
    "ido_id" as integers must switch to strings.
  - ido.db has no migration framework: drop the file and re-index on
    deploy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-21 01:44:39 +03:00
Hossein Zoda
210a51f274 ido bcmr ser/deser fixes 2026-06-21 01:44:39 +03:00
Hossein Zoda
c4eaad4cec ido more fixes +two unittests 2026-06-21 01:44:39 +03:00
Hossein Zoda
a944db4702 ido better error reporting 2026-06-21 01:44:39 +03:00
Hossein Zoda
f8ddac6ec3 followup update for ido -> adding ipfs bcmr placeholder 2026-06-21 01:44:39 +03:00
Hossein Zoda
335818460f followup changes to ido contracts 2026-06-21 01:44:39 +03:00
Hossein Zoda
3f8a9cd026 ido more fixes 2026-06-21 01:44:39 +03:00
Hossein Zoda
aa99f775da tiny fix 2026-06-21 01:44:39 +03:00
Hossein Zoda
988426e485 ido, compiles, with claude generated unittests 2026-06-21 01:44:39 +03:00
Hossein Zoda
0629e168c3 ido incomplete c02 2026-06-21 01:44:39 +03:00
Hossein Zoda
ce9dba23cf (WIP) ido 2026-06-21 01:44:39 +03:00