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>
This commit is contained in:
Hossein Zoda 2026-06-23 12:57:31 +00:00
parent f9ee877392
commit b88475a75b

View file

@ -1908,7 +1908,7 @@ enum IdoUpdate {
OfferingTokenId(Vec<u8>),
Entry(IdoUpdateEntry),
EntryDistributed {
txid: Vec<u8>,
entry_txid: Vec<u8>,
},
}
@ -1989,8 +1989,8 @@ fn print_updates(updates: &[IdoUpdate]) {
let v = rev_blob(&value.txid);
debug!("IDO IdoUpdate::Entry(value): {}", hex::encode(v));
}
IdoUpdate::EntryDistributed { txid } => {
let v = rev_blob(txid);
IdoUpdate::EntryDistributed { entry_txid } => {
let v = rev_blob(entry_txid);
debug!("IDO IdoUpdate::EntryDistributed: {}", hex::encode(v));
}
}
@ -2282,6 +2282,11 @@ fn ido_add_tx(context: &IdoContext, tx: &Transaction) -> Result<IdoAddResult> {
}
_ => return Err(anyhow::anyhow!("expecting active parameters")),
}
// input#1
let second_input = tx
.input
.get(1)
.ok_or_else(|| anyhow::anyhow!("Should have the second input!"))?;
// output#0 should contain a token with offering_token_id
let first_output = tx
.output
@ -2356,6 +2361,9 @@ fn ido_add_tx(context: &IdoContext, tx: &Transaction) -> Result<IdoAddResult> {
} else {
return Err(anyhow::anyhow!("output#0 is not recognized!"));
}
updates.push(IdoUpdate::EntryDistributed {
entry_txid: second_input.previous_output.txid.to_blob(),
});
print_updates(&updates);
Ok(IdoAddResult {
updates,
@ -2406,9 +2414,6 @@ fn ido_add_tx(context: &IdoContext, tx: &Transaction) -> Result<IdoAddResult> {
platformEarnedAmount: prev_state.platformEarnedAmount.clone(),
},
)));
updates.push(IdoUpdate::EntryDistributed {
txid: tx.compute_txid().to_blob(),
});
print_updates(&updates);
Ok(IdoAddResult {
updates,
@ -2540,14 +2545,14 @@ async fn upsert_updates_to_ido_entries(
.execute(&mut **dbtx)
.await?;
}
IdoUpdate::EntryDistributed { txid } => {
IdoUpdate::EntryDistributed { entry_txid } => {
sqlx::query(
"INSERT INTO ido_distribution (ido_id, entry_txid, txid, blockhash)
VALUES (?, ?, ?, ?)
ON CONFLICT(ido_id, entry_txid) DO NOTHING",
)
.bind(internal_id)
.bind(txid)
.bind(entry_txid)
.bind(tx_txid)
.bind(&blockhash_blob)
.execute(&mut **dbtx)