Commit graph

299 commits

Author SHA1 Message Date
Hossein Zoda
bb4e489904 Merge branch 'ido-preinit-zero-remainder' into 'master'
ido: rebake preinit for the zero-remainder oToken genesis

See merge request riftenlabs/riftenlabs-indexer!106
2026-08-27 11:34:52 +00:00
Hossein Zoda
5861c412c8 ido: rebake preinit for the zero-remainder oToken genesis
libriften 00ff654 relaxed ido/preinit.cash's
`offeredTokenTotalSupply > fundingOTokenAmount` to `>=`, so a token can
be minted with its whole supply committed to the IDO. At a zero
remainder the oToken authbase cannot hold a zero-amount token output, so
it carries an immutable NFT with the OTOKEN_AUTHBASE_NFT_COMMITMENT
("BCMR") marker instead; preinit grows 1419 -> 1433 bytes.

- Swap the baked IDO_PREINIT_CONTRACT hex to the new bytecode from
  templates/ido.json (contracts.IDOPreInit). The only bytecode changes
  are a069 -> a269 and the output#0 commitment check becoming a branch
  on the remainder; without the swap no new preinit's rebuilt p2sh32
  would match and no IDO would be admitted.
- Relax the announcement-validation mirror of that require from `<=` to
  `<`, so a whole-supply genesis is no longer marked invalid.

The state machine never reads output#0's commitment or amount, and
build_preinit_bytecode bakes no contract length (the size feeds only the
unlock bytecode, which the indexer does not build), so nothing else
moves. The other 14 baked contracts still match the current templates,
and the schema and announcement format are unchanged, so IDO_DB_VERSION
stays at 5.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 09:39:57 +00:00
jakobsn
cc0ab0b16f Merge branch 'feeHistory' into 'master'
# Store the LP fee per history entry; bound and cache

See merge request riftenlabs/riftenlabs-indexer!105
2026-08-25 12:55:22 +00:00
jakobsn
b5e8c45487 # Store the LP fee per history entry; bound and cache 2026-08-25 12:55:21 +00:00
Hossein Zoda
7f424c79d0 Merge branch 'update-ido-contracts' into 'master'
ido: rebake contract bytecode from the cashscript-only rebuild

See merge request riftenlabs/riftenlabs-indexer!104
2026-08-24 20:48:19 +00:00
Hossein Zoda
bafaad5965 ido: rebake contract bytecode from the cashscript-only rebuild
libriften migrated the cauldron contracts to pure CashScript sources
(a6a8d86) and rebuilt them on 0.14 next.4, recompiling all nine
ido/offering contracts. Swap the baked hex constants to the new
bytecode (preinit 1419B, postlaunch 2190B, ido initiator 230B,
offering initiator 637B, offering 441B, entry 50B, launcher 618B,
distdeploy 620B, distrefund 288B); the common contracts, layouts,
slots, and the announcement format are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 19:42:06 +00:00
Dagur Valberg Johannsson
bbcbe0354c Merge branch 'moria-v11-test18' into 'master'
moria v1-1: TEST18 categories and riftenlabs-defi 0.5.1

See merge request riftenlabs/riftenlabs-indexer!103
2026-08-21 12:02:41 +00:00
Dagur Valberg Johannsson
499275eaef moria v1-1: TEST18 categories and riftenlabs-defi 0.5.1
Switch the indexer off the local path dep onto crates.io 0.5.1 (75-byte
loan, 3-byte principal). Point chipnet deploy constants at TEST18 and
keep continuation UTXOs on partial redeem/repay.
2026-08-21 13:36:30 +02:00
Dagur Valberg Johannsson
90ad5def9a Merge branch 'v11' into 'master'
Cut over to Moria v1-1; drop v1 indexing

See merge request riftenlabs/riftenlabs-indexer!102
2026-08-18 07:21:46 +00:00
Dagur Valberg Johannsson
a5e91afea8 Cut over to Moria v1-1; drop v1 indexing
Replace the v1 moria indexer with v1-1 tables and RPC. Chipnet tracks the
live deployment only; mainnet stays idle until a v1-1 deployment exists.

v1-1 rows carry delegate hash, borrow-time allowance deposits, crank fee
takes, and allowance-close recoveries. Policy lives on the parked
allowance (verified nSequence hint or first spend), not on the loan NFT.
Bar/pool history and realized NAV APR are confirmed-blocks only.

Bind the API before IBD so Rocket is up during sync. Empty electrum
header batches shrink the chain instead of panicking.

Depend on published riftenlabs-defi 0.4.6.
2026-08-18 09:15:19 +02:00
Hossein Zoda
0efac510fb Merge branch 'orb+ido+pool' into 'master'
orb+ido+pool

See merge request riftenlabs/riftenlabs-indexer!98
2026-08-12 07:49:06 +00:00
Hossein Zoda
c0aafdb77f fmt 2026-08-12 10:06:16 +03:00
Hossein Zoda
eaa977f98a ido: widen the announcement minOffer field to 8 bytes
Tracks the libriften change growing the preinit announcement main data
push from 185 to 189 bytes: minOffer now reads at [122..130) and every
later field shifts by 4. The announcement signature's OP_PUSHDATA1
length byte moves to 0xbd, so only new-format announcements are
detected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:06:16 +03:00
Hossein Zoda
c2b1b5be09 ido: stamp purchase entries with a first_seen timestamp
ido_entry gains a first_seen column: the unix time the purchase was
first indexed — the block's median-time-past when first seen in a
confirmed block, wall-clock time when first seen in the mempool. The
entry insert is ON CONFLICT DO NOTHING, so a mempool-seen purchase
keeps its (earlier) mempool stamp when the tx later confirms. This
matches the first_seen_timestamp convention already used by the
cauldron pool-history tables.

index_txs takes a new mtp: Option<i64> parameter: the block path in
index.rs passes the block MTP it already has in scope, the mempool
path passes None and the ido module falls back to timeutil::time_now().
The stamp is threaded through on_add_ido_tx into
upsert_updates_to_ido_entries — the only real entry write path.

The entries RPC exposes it as IdoEntryRpcRecord.first_seen; 0 means
unknown (rows written before the column existed). This lets the
frontend show purchase recency: an activity feed with time-ago, a
"last purchase X ago" signal, and raise-over-time series derived
client-side from the entries.

IDO_DB_VERSION bumps 4 -> 5. As with previous versions there is no
migration: delete ido.db and re-index from scratch — historical
entries then pick up their block MTP as first_seen.

Adds a querytest covering the round-trip and the pre-upgrade
default-0 shape (list_ido_entries_carries_first_seen).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:06:16 +03:00
Hossein Zoda
f3818fd7a2 ido: resync to the PoolParams-free spec; native BCH xToken; conf NFT run()-only
Port libriften feb2167 + 05d3454 + a582108 (through HEAD a582108):

- The ORB PoolParams NFT is gone from the spec. The IdoParams commitment
  field orbPoolParamsCategory (32, VM-order category) is replaced by
  permanentPoolPlatformNfth (32, verbatim hash) — the delegation-pool
  platform nfth the postlaunch bakes; run() reconstructs the permanent
  pool's thin main from it on-chain, so the indexer's only duties are to
  source it from the params NFT commitment and prove the output #7
  postlaunch rebuild was baked with it (unchanged mechanism). Stored on
  the PreInit/Active parameters as permanentPoolPlatformNfth.
- postlaunch io realignment: run() drops the PoolParams io#4 — the
  offering confirmation NFT is consumed exactly ONCE, at run() input#4,
  and is forbidden in init()/collect() (a582108). Collects no longer
  copy the NFT through io#4, so they are invisible to the tracked chain
  (they only move proceeds into the covenant storages); the POSTLAUNCH
  status now advances solely on the final run tx. The platform payout
  moved to output#4 and the altPPOut pool-deploy-failure fallback is
  gone (altPPOutPayout dropped from the Distributed state, matching
  libriften indexer-types).
- Native BCH xToken: offer.xTokenCategory is now nullable (all-zero
  on-chain = native sentinel -> JSON null). Native IDOs take payment via
  the offering's XWNT path (entry flag required-iff-native, payment in
  the entry's value, fresh owner nft at #2) and their permanent pool is
  a single-UTXO tokenbch-delegation pool at run() output#0 (BCH reserve
  in the value; sibling slot -> OP_RETURN). The offering/postlaunch
  builders bake an empty push for a native category.
- IDO_POSTLAUNCH_CONTRACT re-synced (1627 -> 2193 bytes, byte-matching
  ido.json; embeds the new delegation contracts + both native branches);
  initiator/preinit/offering-layer contracts verified byte-identical.
- Per-network ORB constants centralized in src/db/orbconstants.rs: the
  IdoParams NFT category moved there next to the delegation-pool
  platform nfth (chipnet pins the deployed ORB v0 records, mainnet stays
  all-zero fail-closed).
- ido.db schema version 4: no backward compatibility, delete ido.db and
  re-index.

Verified: cargo build, test (233 passing), clippy (no new warnings)
and fmt all clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:06:16 +03:00
Hossein Zoda
dcebaf2648 tokentoken/tokenbch: index delegation pools, replace the pre-delegation AMM
Replace the old P2SH32/CONJURE TokenToken AMM indexer (never in
production; its tables are dropped by an always-run migration) with the
delegation-model indexers from riftenlabs-defi 0.4.5:

- tokentoken: two co-created bare-P2S UTXOs (thin main + storage
  sibling). tokenbch (new): single-UTXO token<->BCH pool with the
  runtime feePaidInToken fee side. Both admitted purely by the constant
  locking derived from the per-network delegation-pool platform NFTH.
- src/db/orbconstants.rs: ONE platform NFTH serves both contracts —
  chipnet pins the deployed ORB v0 value (libriften orb/v0/chipnet.ts),
  mainnet is the all-zero placeholder: while unconfigured NOTHING
  delegation-related is parsed, fetched or indexed (fail-closed).
- Schema: immutable config (nftOwner, tokens, poolFeeRate, minFee,
  virtualX/Y, tokenbch feePaidInToken) on the pool row; per-state
  history carries raw reserves, owed, platformFeeRate (both mutable by
  platform sweeps) and deltas. History rows now FK tx(txid) ON DELETE
  CASCADE, so evicted mempool txs clean up after themselves (the old
  tokentoken indexer leaked those).
- LP teardowns carry no pool output: ingestion probes every
  blob-presenting tx's spent outpoints against the recorded pool set
  and flags a known pool UTXO spent without successor as withdrawn
  (withdrawn_in_txid FK ON DELETE SET NULL reverts an evicted teardown;
  reorg undo reverts a confirmed one).
- electrum mempool filters: the combined logic blob (scriptsig; every
  spend incl. teardowns) + the constant thin-main locking (scriptpubkey;
  creations), per contract, skipped while unconfigured.
- RPC: /tokentoken responses gain owed_a, platform/pool fee rates,
  minFee and virtual offsets; new /tokenbch (pool/active?token, pools,
  tokens) mirrors it for BCH pairs.
- deps: bitcoincash 0.32.4 (token.amount -> .to_int() in the ido
  indexer), riftenlabs-defi 0.4.5. NOTE: 0.4.5 (rust-riftenlabs-defi
  7c65f66) is not on crates.io yet — until it is published, build with
  a local [patch.crates-io] pointing at the sibling checkout (the
  committed Cargo.lock carries the path-patched entry). Also fixes a
  latent test bug (ido_params_nft_commitment_roundtrip never wrote
  createExecutionFee after the 127-byte layout shift).

Verified: cargo build, test (232 passing), clippy (no new warnings)
and fmt all clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:06:13 +03:00
Hossein Zoda
f39ce11bf2 ido: keep offeredTokenTotalSupply in Active parameters
IdoActiveParameters dropped offeredTokenTotalSupply, so clients couldn't compute the offered-vs-total-supply share for live (non-PREINIT) IDOs. Carry it forward from the preinit parameters at the PreInit->Active transition and add it to the struct. A serde default of -1 (the pre-existing-token "unknown supply" sentinel) lets ido_state rows written before this field existed still deserialize.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 10:02:22 +03:00
Hossein Zoda
8b99314322 update offering initial output 2026-08-12 10:02:22 +03:00
Hossein Zoda
54f8e931be update ipfs rebuild contract 2026-08-12 10:02:22 +03:00
Hossein Zoda
4b5acefc3c ido: categories in display/UI byte order, drop hardcoded PLP limits
libriften moved encodeVmTokenCategory/decodeVmTokenCategory (which reverse
the 32 category bytes, display<->VM) into the ido announcement and ORB
IdoParams serialize/deserialize layer. Net wire effects the indexer sees:
- preinit announcement delphiCategory[44..76] and xTokenCategory[126..158]
  are now VM/little-endian (were display order);
- the IdoParams commitment stays VM on-wire, but the derived on-chain
  postlaunch orbPoolParamsCategory push flips display->VM (decode now
  returns display, the unchanged bake re-wraps it in encodeVmTokenCategory).

Keep the three categories (delphiCategory, xTokenCategory,
orbPoolParamsCategory) in display/UI byte order in-memory and over RPC:
reverse at every parse site (announcement + IdoParams NFT commitment) and
restore the .rev() on the output#0 delphi-NFT to_blob() compare. The
build_*_bytecode helpers keep reversing display->VM when baking, so the
output#7 P2SH32 rebuild matches the new on-chain layout.

Also drop the now-unused hardcoded MAX_PLP_SHARE / MAX_PLP_ANNUAL_DISCOUNT
/ MIN_PLP_ANNUAL_DISCOUNT statics and dead checks; the min-PLP limits are
NFT-pinned (minPlpShare / minPlpAfterDiscount) and the discount/max-discount
checks now just guard against negatives.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 10:02:22 +03:00
Hossein Zoda
3130462118 ido: port "CldIdo00" signature + announcement permanentLiquidityMinFee
Sync the IDO indexer to libriften 48aa1f7 (+ follow-ups):

- IDO_SIGNATURE 20->10 bytes: [0x08 "CldIdo00" 0x75] (was OP_PUSH18
  "CauldronIdo-2026Q2"). The separate "CauldronIdo0" announcement
  signature is folded into the same 8 raw bytes, so
  IDO_PREINIT_ANNOUNCEMENT_SIGNATURE = 6a 4c b9 + "CldIdo00";
  is_preinit_broadcast is now length-agnostic. Electrum mempool
  filters track automatically (they reference the constants).
- Recompile the 3 affected contracts from templates: IDO initiator
  233->231, IDO preinit 1469->1465, offering launcher 630->628.
  IDO_POSTLAUNCH_CONTRACT and the other offering contracts are
  byte-identical and left as-is.
- Announcement OP_RETURN carries permanentLiquidityMinFee as a 2-byte
  field at data[166..168]; mainData is now 185 bytes. Read minFee from
  the announcement rather than the (unreadable) postlaunch copy.

Fix the source of the two "free" postlaunch params:

- Output #7 (ido initiator bytecode storage) is P2SH32, so the partial
  bytecode cannot be read back from it. Drop the impossible extraction
  (extract_params_from_partial_ido_initiator_bytecode +
  PartialPostlaunchExtractedParams). extract_data_from_storage_script_
  with_data_and_size is kept for its valid callers (revealed redeem
  scripts, bare bcmr storages).
- orbPoolParamsCategory now comes from the ORB IdoParams NFT commitment
  (output #10). The commitment parse is moved above the params
  construction so the value is available; the now-tautological
  orbPoolParamsCategory vs NFT check is removed.
- Verification is the existing output #7 rebuild: build the expected
  bytecode from the announcement values plus the NFT-sourced
  orbPoolParamsCategory, hash to P2SH32, and compare. Since minFee is a
  2-byte announcement field it always fits the postlaunch's 2-byte push,
  so build_partial_postlaunch_bytecode stays infallible.

- Tests: preinit_detect -> legacy_preinit_announcement_not_detected
  (legacy fixture must no longer be detected under the new signature);
  replace the extraction round-trip test with a structural check of the
  partial postlaunch bytecode layout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 10:02:22 +03:00
Hossein Zoda
4b5fd93db4 ido: sync IdoParams commitment to 127-byte layout, enforce NFT-pinned min PLP
libriften 0941c88 grew the ORB IdoParams NFT commitment 121->127 bytes,
inserting minPlpAfterDiscount/minPlpShare (4-byte pIntLE numerators over
PERMANENT_LIQUIDITY_SHARE_DENOMINATOR) between maxExpireDuration and
entryExecutionFee, and shrinking paramsUseFee 4->2 bytes.

- Parse the two new fields; shift entryExecutionFee/createExecutionFee offsets.
- Drop the hardcoded MIN_PLP_SHARE / MIN_PLP_AFTER_DISCOUNT statics; enforce
  both minimums from the NFT commitment inside the version-verified block
  (permanentLiquidityShareNumerator >= minPlpShare, and
  maxDiscountRateNumerator + minPlpAfterDiscount <= permanentLiquidityShareNumerator).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 10:02:22 +03:00
Hossein Zoda
8967e115e9 ido: resync postlaunch contract & enforce IdoParams NFT version
- update IDO_POSTLAUNCH_CONTRACT to the recompiled 1627-byte script
  (libriften cd58dd1): postlaunch.cash reordered the permanent-pool
  sibling config, moving the all-zero nftOwner to the end. The indexer
  byte-compares this body against on-chain output#7, so the stale
  1669-byte constant would have marked every new IDO invalid.
- set CHIPNET_IDO_PARAMS_NFT_CATEGORY (was an all-zero placeholder).
- validate the ORB IdoParams NFT commitment version byte: only index
  when it equals IDO_PARAMS_VERSION (0x00), else push an
  "incompatible with the indexer" reason and mark the IDO invalid.
  The other commitment fields are read at v0 offsets, so the parameter
  comparisons are skipped on a version mismatch to avoid spurious errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 10:02:22 +03:00
Hossein Zoda
ef98772140 bcmr: index new registrations from mempool, no confirmation needed
Add an OP_RETURN "BCMR" prefix filter to the rostrum mempool.get pass and
index matching txs in update_mempool with the all-zeros sentinel blockhash
(same pattern as oracle). A newly registered BCMR becomes the auth head and
is downloaded immediately; the confirming block re-stamps the entry with
its real blockhash in place.

- insert_authheader: INSERT OR REPLACE -> upsert. REPLACE deletes the row,
  cascading away downloaded bcmr_data on every mempool->confirmed upgrade.
- update_mempool drops sentinel entries whose tx left the mempool (evicted
  or replaced), so stale auth heads never linger.
- clear bcmr mempool state at startup; always-run migration adds txid and
  blockhash indexes on auth_chain_entry for the per-pass lookups.

Auth chain transfers without a BCMR output still index at confirmation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:02:22 +03:00
Hossein Zoda
783f581ea6 ido: postlaunch collect/run lifecycle + bare-p2s locks, no backward compatibility
Sync with libriften ido+ttd head (37a5c01):

- postlaunch rework: collect copies the offering confirmation NFT through
  io#4 (the chain continues from the verified copy at output#4, state
  unchanged); run consumes it at input#5. The called method is dispatched
  from the carrier's unlocking bytecode (<args..> <functionIndex> <redeem>);
  run's altPPOut argument is decoded as a VM number — when true the pool
  legs were paid back to the collector (pool-deploy-failure fallback,
  recorded as altPPOutPayout) instead of deploying the permanent pool. The
  accumulated BCH pot paid to the platform p2nfth at output#5 is recorded
  as platformBchPayout. Chain-follow probe list extended to [0,1,3,4,5].
- postlaunch constructor gains a 4-byte executionFee push (partial
  postlaunch bytecode is now 8 pushes + body).
- p2nfth and plain storages lock as bare-p2s (blob storages stay p2sh32);
  nfthash preimage flipped to hash256(commitment + category);
  P2NFTH contract is 78cf7bce7eaa87.
- all changed contract constants regenerated from the libriften templates
  (initiator 233 B, postlaunch 1669 B, preinit 1469 B).
- fix IdoActiveParameters construction missing orbPoolParamsCategory and
  permanentLiquidityMinFee; box IdoUpdate::State to keep the enum small.
- ido db version 3; no migration — delete ido.db and re-index.
- legacy-generation fixture tests marked #[ignore].

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:02:22 +03:00
Hossein Zoda
2d1a462a47 ido: port to ORB IdoParams generation, no backward compatibility
Preinit txs must now spend an ORB IdoParams NFT (use() at input #1,
preserved at output #10) whose per-network category is pinned and whose
121-byte commitment is cross-checked field-by-field against the
announced parameters; xToken must be a non-native token. ido.db is
version-gated (PRAGMA user_version = 2); legacy IDOs do not parse.

Also refresh the embedded IDOPostLaunch contract to the current
tokentoken-delegation build (1616 bytes, libriften ido+ttd a9fcfa0);
the previous copy predated the recompile and would have failed the
preinit output #7 byte-compare. All other embedded contracts verified
byte-identical to the libriften templates.

Per-network IdoParams NFT categories are still all-zero placeholders;
until set, every preinit indexes as is_valid=false.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:02:22 +03:00
Hossein Zoda
2909059dfa ido minor fixes 2026-08-12 10:02:22 +03:00
Hossein Zoda
1164cb96d0 ido followup update, offering contract updated & set ido create exe fee to 10m sats 2026-08-12 10:02:22 +03:00
jakobsn
0600e5a360 Merge branch 'correctCandles' into 'master'
Nice spot

See merge request riftenlabs/riftenlabs-indexer!101
2026-08-11 13:26:48 +00:00
jakobsn
bff99822a3 Nice spot 2026-08-11 15:03:50 +02:00
jakobsn
0a969b296b Merge branch 'dontPanich' into 'master'
A malformed token id must come back as a 400, not take the process down.

See merge request riftenlabs/riftenlabs-indexer!100
2026-08-11 09:31:04 +00:00
jakobsn
6262e5accf A malformed token id must come back as a 400, not take the process down. 2026-08-11 11:25:33 +02:00
jakobsn
feeb37081c Merge branch 'priceChange' into 'master'
More flexible pricechange calc for less than 24h, 7d, of trading since creation

See merge request riftenlabs/riftenlabs-indexer!99
2026-08-10 11:11:42 +00:00
jakobsn
d3f8929068 More flexible pricechange calc for less than 24h, 7d, of trading since creation 2026-08-10 12:53:18 +02:00
jakobsn
c78c8e06fa Merge branch 'candlestick-gross-volume-pricing' into 'master'
Price candlesticks by gross volume instead of net deltas

See merge request riftenlabs/riftenlabs-indexer!96
2026-07-30 12:24:30 +00:00
jakobsn
7387ae792b Price candlesticks by gross volume instead of net deltas 2026-07-30 12:24:29 +00:00
jakobsn
4a23ce70d4 Merge branch 'authChain' into 'master'
Expose authchain head + optional local IPFS gateway for BCMR downloads

See merge request riftenlabs/riftenlabs-indexer!91
2026-06-24 11:07:31 +00:00
jakobsn
3c5af42b4b Expose authchain head + optional local IPFS gateway for BCMR downloads 2026-06-24 11:07:31 +00:00
jakobsn
69d443d13f Merge branch 'graph-price-inconsistency' into 'master'
Use last trade as the basis for the price outside chart instead of the last token/sats amount

See merge request riftenlabs/riftenlabs-indexer!86
2026-06-23 14:16:20 +00:00
jakobsn
b36c0b71a6 Use last trade as the basis for the price outside chart instead of the last token/sats amount 2026-06-23 14:16:19 +00:00
Dagur Valberg Johannsson
d5fa393870 Merge branch 'ido' into 'master'
ido

See merge request riftenlabs/riftenlabs-indexer!81
2026-06-23 13:08:55 +00: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