Skip to content

feat(AggLayer claim e2e #3): GlobalIndex wrapper#2407

Merged
mmagician merged 3 commits intoagglayer-newfrom
mmagician-global-index-wrapper
Feb 14, 2026
Merged

feat(AggLayer claim e2e #3): GlobalIndex wrapper#2407
mmagician merged 3 commits intoagglayer-newfrom
mmagician-global-index-wrapper

Conversation

@mmagician
Copy link
Collaborator

@mmagician mmagician commented Feb 5, 2026

  • change the underlying representation of global index from [u32; 8] to [u8; 32] so that it's easier to construct from raw bytes coming in from Ethereum tx's,
  • wrap in a GlobalIndex struct
  • and add simple validation rules (mostly for testing)
  • since the global index must be later hashed, it's put on stack in LE-byte order within each felt.
  • to make the extraction of mainnet_flag, leaf_index easier, we reverse to BE order before processing
    • for that, move the existing swap_u32_bytes to a shared util location

@mmagician mmagician added no changelog This PR does not require an entry in the `CHANGELOG.md` file agglayer PRs or issues related to AggLayer bridging integration labels Feb 5, 2026
@mmagician mmagician force-pushed the mmagician-global-index-wrapper branch from 049a4f6 to e80e7ea Compare February 5, 2026 20:17
@mmagician mmagician force-pushed the mmagician-get-leaf-test-vec branch from 18439d5 to be2e67a Compare February 8, 2026 21:13
@mmagician mmagician force-pushed the mmagician-global-index-wrapper branch from 19cb775 to 778b6e7 Compare February 8, 2026 21:33
@mmagician mmagician changed the title feat: GlobalIndex wrapper feat(AggLayer claim e2e #3): GlobalIndex wrapper Feb 8, 2026
@mmagician mmagician requested review from bobbinth and partylikeits1983 and removed request for partylikeits1983 February 8, 2026 22:02
@mmagician mmagician added the pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority label Feb 9, 2026
Copy link
Contributor

@partylikeits1983 partylikeits1983 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Makes sense to store GlobalIndex in Rust as [u8; 32] and in the VM [u32; 8].

Comment on lines +22 to +36
// ================================================================================================
// GLOBAL INDEX
// ================================================================================================

/// Represents an AggLayer global index as a 256-bit value (32 bytes).
///
/// The global index is a uint256 that encodes (from MSB to LSB):
/// - Top 160 bits (limbs 0-4): must be zero
/// - 32 bits (limb 5): mainnet flag (value = 1 for mainnet, 0 for rollup)
/// - 32 bits (limb 6): rollup index (must be 0 for mainnet deposits)
/// - 32 bits (limb 7): leaf index (deposit index in the local exit tree)
///
/// Bytes are stored in big-endian order, matching Solidity's uint256 representation.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct GlobalIndex([u8; 32]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can follow this same type of layout for implementing theu256 type for the u256 to Felt scaling PR: #2331

@mmagician mmagician force-pushed the mmagician-get-leaf-test-vec branch from b658ab6 to ea8d6d7 Compare February 14, 2026 17:21
Base automatically changed from mmagician-get-leaf-test-vec to agglayer-new February 14, 2026 17:37
@mmagician mmagician force-pushed the mmagician-global-index-wrapper branch from 12c5dda to df775f2 Compare February 14, 2026 17:44
@mmagician mmagician merged commit 8ad690b into agglayer-new Feb 14, 2026
15 checks passed
@mmagician mmagician deleted the mmagician-global-index-wrapper branch February 14, 2026 18:12
Comment on lines +48 to +59
/// Creates a new [`GlobalIndex`] from a 32-byte array (big-endian).
pub fn new(bytes: [u8; 32]) -> Self {
Self(bytes)
}

/// Validates that this is a valid mainnet deposit global index.
///
/// Checks that:
/// - The top 160 bits (limbs 0-4, bytes 0-19) are zero
/// - The mainnet flag (limb 5, bytes 20-23) is exactly 1
/// - The rollup index (limb 6, bytes 24-27) is 0
pub fn validate_mainnet(&self) -> Result<(), GlobalIndexError> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to change this into a constructor - e.g., something like:

pub fn new_mainnet(bytes: [u8; 32]) -> Result<Self, GlobalIndexError> {
    ...
}

Comment on lines +43 to +46
pub fn from_hex(hex_str: &str) -> Result<Self, HexParseError> {
let bytes: [u8; 32] = hex_to_bytes(hex_str)?;
Ok(Self(bytes))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do more validation here? We could return GlobalIndexError and hex parsing could be one reason to return an error. Other reasons would be if the global index is malformed.

The general idea is to enforce that if we have GlobalIndex struct, we know the underlying index is correctly formed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agglayer PRs or issues related to AggLayer bridging integration no changelog This PR does not require an entry in the `CHANGELOG.md` file pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants