Skip to content

Commit 4f7cc96

Browse files
committed
[phantom]: fix _orders slot for post-#988 layout and emit PhantomBidWindowExhausted in on_finalize
- indexer: ordersStorageSlot now targets _orders at slot 9. PR #988 removed the _admin storage slot from IntentGatewayV2, shifting _orders down from 10 to 9. Injecting at the stale slot left the escrow override a no-op. - pallet: move the PhantomBidWindowExhausted emission from on_initialize to on_finalize so a bid placed in the window-closing block is already in storage when the indexer aggregates the snapshot. The on_finalize storage reads are reserved in the on_initialize weight.
1 parent 685dbc6 commit 4f7cc96

2 files changed

Lines changed: 32 additions & 24 deletions

File tree

modules/pallets/intents-coprocessor/src/lib.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,8 @@ pub mod pallet {
361361
// Only notify gateways with different addresses (same address automatically accepts)
362362
for (existing_state_machine, existing_gateway_info) in Gateways::<T>::iter() {
363363
// Skip if same state machine or same gateway address
364-
if existing_state_machine == state_machine ||
365-
existing_gateway_info.gateway == gateway
364+
if existing_state_machine == state_machine
365+
|| existing_gateway_info.gateway == gateway
366366
{
367367
continue;
368368
}
@@ -616,24 +616,10 @@ pub mod pallet {
616616
{
617617
fn on_initialize(n: BlockNumberFor<T>) -> Weight {
618618
let Some(config) = PhantomOrderConfig::<T>::get() else {
619-
return Weight::zero();
619+
// Reserve the read on_finalize performs on CurrentPhantomOrder.
620+
return T::DbWeight::get().reads(2);
620621
};
621622

622-
// Signal each active commitment on the block its bid window closes so the indexer can
623-
// aggregate that order's snapshot. Done before the generation gate so it still fires on
624-
// blocks where no new batch is produced.
625-
if let Some(active) = CurrentPhantomOrder::<T>::get() {
626-
let window: BlockNumberFor<T> = Self::phantom_bid_window().into();
627-
for (commitment, info) in active.iter() {
628-
if n == info.created_at_block.saturating_add(window) {
629-
Self::deposit_event(Event::PhantomBidWindowExhausted {
630-
commitment: *commitment,
631-
created_at: info.created_at_block,
632-
});
633-
}
634-
}
635-
}
636-
637623
let should_generate = match LastPhantomGeneration::<T>::get() {
638624
None => true,
639625
Some(last) => {
@@ -642,8 +628,9 @@ pub mod pallet {
642628
},
643629
};
644630

631+
// reads here (config + last_generation) plus the reads on_finalize performs.
645632
if !should_generate {
646-
return T::DbWeight::get().reads(3);
633+
return T::DbWeight::get().reads(4);
647634
}
648635

649636
// Phantom orders carry the latest confirmed height as their deadline so they read
@@ -656,7 +643,7 @@ pub mod pallet {
656643
"No confirmed state machine height for {:?}, skipping phantom order generation",
657644
config.chain,
658645
);
659-
return T::DbWeight::get().reads(4);
646+
return T::DbWeight::get().reads(5);
660647
};
661648

662649
let mut batch: BoundedVec<
@@ -681,7 +668,28 @@ pub mod pallet {
681668
CurrentPhantomOrder::<T>::put(batch);
682669
LastPhantomGeneration::<T>::put(n);
683670

684-
T::DbWeight::get().reads_writes(4, 2)
671+
// reads: config + last_generation + latest_height + the on_finalize reads.
672+
T::DbWeight::get().reads_writes(5, 2)
673+
}
674+
675+
fn on_finalize(n: BlockNumberFor<T>) {
676+
// Signal each active commitment on the block its bid window closes so the indexer can
677+
// aggregate that order's snapshot. Emitted in on_finalize (after all extrinsics) so any
678+
// bid placed in the window-closing block is already in storage when the snapshot is
679+
// taken. The bid window is expected to be shorter than the generation interval, so the
680+
// active batch is never replaced by on_initialize on the same block its window closes.
681+
let Some(active) = CurrentPhantomOrder::<T>::get() else {
682+
return;
683+
};
684+
let window: BlockNumberFor<T> = Self::phantom_bid_window().into();
685+
for (commitment, info) in active.iter() {
686+
if n == info.created_at_block.saturating_add(window) {
687+
Self::deposit_event(Event::PhantomBidWindowExhausted {
688+
commitment: *commitment,
689+
created_at: info.created_at_block,
690+
});
691+
}
692+
}
685693
}
686694
}
687695

sdk/packages/indexer/src/handlers/events/substrateChains/phantom-simulation.helpers.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ export function hasTokenSlotOverride(address: string): boolean {
3333
return address.toLowerCase() in TOKEN_SLOT_OVERRIDES
3434
}
3535

36-
// _orders is mapping(bytes32 => mapping(address => uint256)) at slot 10.
36+
// _orders is mapping(bytes32 => mapping(address => uint256)) at slot 9 in IntentGatewayV2.
37+
// (PR #988 removed the _admin slot, shifting _orders down from slot 10 to slot 9.)
3738
// inputTokenBytes32 must be the address left-padded to 32 bytes, matching abi.encode(address).
38-
// NOTE: If PR #988 (removes _admin from IntentGatewayV2) merges first, _orders shifts to slot 9.
3939
export function ordersStorageSlot(commitment: HexString, inputTokenBytes32: HexString): HexString {
40-
const innerSlot = keccak256(concat([commitment, toHex(10n, { size: 32 })]))
40+
const innerSlot = keccak256(concat([commitment, toHex(9n, { size: 32 })]))
4141
return keccak256(concat([inputTokenBytes32, innerSlot]))
4242
}
4343

0 commit comments

Comments
 (0)