util

package
v0.0.0-...-800ad12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 19, 2025 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package util provides Ethereum-compatible cryptographic signing utilities. This file contains functions for handling Ethereum-style message signing and signature recovery, implementing EIP-191 and EIP-155 standards for message authentication.

Package util provides utility functions and types for the Hyperlane Morpheum project. This package contains core data structures and helper functions used across the application, including address handling, cryptographic operations, pagination, and routing mechanisms.

Package util provides utility functions for working with Hyperlane protocol messages. Hyperlane is a universal interoperability protocol that enables secure communication between different blockchain networks.

Package util provides utility functions for cryptographic operations and data structures. This file implements an incremental Merkle tree data structure optimized for blockchain applications.

Package util provides pagination utilities for Cosmos SDK collections. This file contains functions for implementing efficient pagination over collections.Map data structures, supporting both simple key-based pagination and prefix-based pagination for complex key structures like Pair[K1, K2].

Package util provides post-dispatch hook metadata structures for Hyperlane message processing. This file defines the metadata structure used by post-dispatch hooks to handle message processing, fee collection, and custom hook logic in the Cosmos ecosystem.

Package util provides a generic router system for managing and routing to different module types. This file implements a flexible routing mechanism that allows dynamic registration and retrieval of modules based on their type identifiers, with support for generating unique addresses and managing module sequences.

Index

Constants

View Source
const (
	// HEX_ADDRESS_LENGTH defines the total byte length of a HexAddress (32 bytes)
	HEX_ADDRESS_LENGTH = 32

	// ENCODED_HEX_ADDRESS_LENGTH defines the length of the hex-encoded string representation
	// (0x prefix + 32 bytes hex encoded = 66 bytes total)
	ENCODED_HEX_ADDRESS_LENGTH = 66
)

SPEC: HexAddress

The HexAddress mimics an evm-compatible address for a smart contract. Due to the nature of cosmos, addresses must be created differently.

Requirements: - HexAddresses must be unique across all cosmos modules interacting with Hyperlane

Structure - The HexAddress has 32 bytes and is used for external communication - For internal usage and storage an uint64 is totally sufficient

Encoding: - 0:20 bytes are the module identifier - 20:24 bytes is the module type. This is used to identify the correct module implementation for this type in the router. See `util./router.go` - 24:32 bytes is the internal id. Can be used for internal collection storage.

Constants defining the structure and layout of HexAddress

View Source
const (
	// VersionOffset is the byte position where the message version is stored (1 byte)
	VersionOffset = 0
	// NonceOffset is the byte position where the nonce starts (4 bytes, big-endian)
	NonceOffset = 1
	// OriginOffset is the byte position where the origin domain ID starts (4 bytes, big-endian)
	OriginOffset = 5
	// SenderOffset is the byte position where the sender address starts (32 bytes)
	SenderOffset = 9
	// DestinationOffset is the byte position where the destination domain ID starts (4 bytes, big-endian)
	DestinationOffset = 41
	// RecipientOffset is the byte position where the recipient address starts (32 bytes)
	RecipientOffset = 45
	// BodyOffset is the byte position where the message body/payload starts (variable length)
	BodyOffset = 77
)

Byte offset constants for parsing Hyperlane message structure. These offsets define the position of each field within the serialized message bytes. The message format follows a fixed-width layout for efficient parsing and validation.

View Source
const (
	// TreeDepth defines the maximum depth of the Merkle tree (32 levels)
	// This allows for up to 2^32 - 1 leaves in the tree
	TreeDepth = 32

	// MaxLeaves is the maximum number of leaves that can be inserted into the tree
	// Calculated as (2^TreeDepth) - 1 = (2^32) - 1 = 4,294,967,295
	MaxLeaves = (1 << TreeDepth) - 1
)

Constants defining the Merkle tree configuration

View Source
const (
	// MAX_QUERY_LIMIT defines the maximum number of items that can be returned in a single paginated query.
	// This prevents excessive memory usage and ensures reasonable response times.
	MAX_QUERY_LIMIT = 1000
)

Constants for pagination configuration

Variables

View Source
var ZeroHashes = [TreeDepth][32]byte{
	hexToBytes("0000000000000000000000000000000000000000000000000000000000000000"),
	hexToBytes("ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5"),
	hexToBytes("b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30"),
	hexToBytes("21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85"),
	hexToBytes("e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344"),
	hexToBytes("0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d"),
	hexToBytes("887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968"),
	hexToBytes("ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83"),
	hexToBytes("9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af"),
	hexToBytes("cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0"),
	hexToBytes("f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5"),
	hexToBytes("f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892"),
	hexToBytes("3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c"),
	hexToBytes("c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb"),
	hexToBytes("5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc"),
	hexToBytes("da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2"),
	hexToBytes("2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f"),
	hexToBytes("e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a"),
	hexToBytes("5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0"),
	hexToBytes("b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0"),
	hexToBytes("c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2"),
	hexToBytes("f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9"),
	hexToBytes("5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377"),
	hexToBytes("4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652"),
	hexToBytes("cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef"),
	hexToBytes("0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d"),
	hexToBytes("b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0"),
	hexToBytes("838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e"),
	hexToBytes("662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e"),
	hexToBytes("388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322"),
	hexToBytes("93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735"),
	hexToBytes("8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9"),
}

ZeroHashes represents a precomputed array of zero hashes for each level of the tree. These are the default hash values used when a branch doesn't exist at a particular level. This optimization allows for efficient root calculation without storing the entire tree.

The zero hashes are computed as: - Level 0: 32 zero bytes (0x0000...0000) - Level i: Keccak256(ZeroHashes[i-1], ZeroHashes[i-1]) for i > 0

These values are used in root calculation when a branch is missing at a given level.

Functions

func BranchRoot

func BranchRoot(item [32]byte, branch [TreeDepth][32]byte, index uint32) [32]byte

BranchRoot calculates and returns the Merkle root for a given leaf, branch, and index. This function is used for Merkle proof verification - it reconstructs the root hash from a leaf and its corresponding branch (proof path) to verify inclusion.

The algorithm works by: 1. Starting with the leaf hash 2. For each level, combining the current hash with the corresponding branch hash 3. The order of combination depends on the bit position in the index

Parameters:

  • item: The leaf hash to verify
  • branch: The Merkle proof path (branch hashes from leaf to root)
  • index: The position of the leaf in the tree (0-based)

Returns:

  • [32]byte: The computed root hash that should match the tree's root

Algorithm:

The function uses the binary representation of the index to determine the
order of hash combination at each level. If the i-th bit is 1, the branch
hash is the left child; if 0, it's the right child.

func DecodeEthHex

func DecodeEthHex(s string) ([]byte, error)

DecodeEthHex decodes a hex-encoded string to raw bytes, handling Ethereum-style hex format.

This function removes the optional "0x" prefix and decodes the remaining hex string to bytes. It's commonly used for processing Ethereum addresses, transaction hashes, and other hex-encoded data.

Parameters:

  • s: The hex-encoded string, optionally prefixed with "0x"

Returns:

  • []byte: The decoded raw bytes
  • error: Any error encountered during decoding

func EncodeEthHex

func EncodeEthHex(b []byte) string

EncodeEthHex encodes raw bytes to a hex string with Ethereum-style "0x" prefix.

This function converts raw bytes to a hex-encoded string and adds the "0x" prefix, which is the standard format used throughout the Ethereum ecosystem. It's commonly used for formatting addresses, hashes, and other binary data.

Parameters:

  • b: The raw bytes to encode

Returns:

  • string: The hex-encoded string with "0x" prefix

func ExampleRetryStrategy

func ExampleRetryStrategy()

ExampleRetryStrategy demonstrates various ways to use the retry strategy

func ExampleRetryStrategyAdvanced

func ExampleRetryStrategyAdvanced()

ExampleRetryStrategyAdvanced demonstrates advanced usage patterns

func ExampleRetryStrategyExponentialBackoff

func ExampleRetryStrategyExponentialBackoff()

ExampleRetryStrategyExponentialBackoff demonstrates the exponential backoff for high retry counts

func ExampleRetryStrategyRealWorld

func ExampleRetryStrategyRealWorld()

ExampleRetryStrategyRealWorld demonstrates a real-world usage scenario

func ExampleRetryStrategySchedule

func ExampleRetryStrategySchedule()

ExampleRetryStrategySchedule demonstrates viewing the retry schedule

func ExampleRetryStrategyWithCallback

func ExampleRetryStrategyWithCallback()

ExampleRetryStrategyWithCallback demonstrates using retry callbacks

func ExampleRetryStrategyWithConditionalRetry

func ExampleRetryStrategyWithConditionalRetry()

ExampleRetryStrategyWithConditionalRetry demonstrates conditional retry logic

func ExampleRetryStrategyWithContext

func ExampleRetryStrategyWithContext()

ExampleRetryStrategyWithContext demonstrates context cancellation

func GetEthSigningHash

func GetEthSigningHash(msg []byte) [32]byte

GetEthSigningHash hashes a message according to EIP-191 standard.

This function implements the Ethereum Signed Message format, which provides a standardized way to sign arbitrary data. The message is enveloped with a specific prefix to prevent signature reuse across different contexts.

The enveloping format follows EIP-191: `"\x19Ethereum Signed Message:\n" + message.length + message`

Parameters:

  • msg: The raw message bytes to be signed

Returns:

  • [32]byte: The Keccak256 hash of the enveloped message

func GetPaginatedFromMap

func GetPaginatedFromMap[T any, K any](ctx context.Context, collection collections.Map[K, T], pagination *query.PageRequest) ([]T, *query.PageResponse, error)

GetPaginatedFromMap retrieves paginated entries from a collections.Map where keys are of type K and values are of type T. Returns them according to pagination parameters.

This function provides a simpler pagination interface for collections with single-type keys. It's the basic pagination function that GetPaginatedPrefixFromMap builds upon for more complex composite key scenarios.

Parameters:

  • ctx: Context for the operation, used for cancellation and timeouts
  • collection: The collections.Map containing the data, with K keys and T values
  • pagination: Query pagination parameters including limit, key, and reverse ordering

Returns:

  • []T: Slice of paginated values
  • *query.PageResponse: Pagination metadata including the next key if more results exist
  • error: Any error encountered during the operation

Pagination behavior:

  1. If no pagination is provided, defaults to counting total with default limit
  2. Key-based pagination can be used, offset is not supported for performance reasons
  3. For key-based pagination, uses provided key as start/end boundary
  4. In reverse order, results are returned in descending order
  5. Returns nextKey in PageResponse if more results exist beyond the current page

Note: This is a simpler version of GetPaginatedPrefixFromMap that works with any key type K

func GetPaginatedPrefixFromMap

func GetPaginatedPrefixFromMap[T any, K1 any, K2 any](ctx context.Context, collection collections.Map[collections.Pair[K1, K2], T], pagination *query.PageRequest, prefix K1) ([]T, *query.PageResponse, error)

GetPaginatedPrefixFromMap retrieves paginated entries from a collections.Map where keys are pairs [K1, K2] and values are of type T. It filters entries by a prefix of type K1 and returns them according to pagination parameters.

This function is designed for collections that use composite keys where you want to filter by the first component of the key pair. It's particularly useful for relational data where you need to query all entries associated with a specific prefix.

Parameters:

  • ctx: Context for the operation, used for cancellation and timeouts
  • collection: The collections.Map containing the data, with Pair[K1, K2] keys and T values
  • pagination: Query pagination parameters including limit, key, and reverse ordering
  • prefix: The K1 type prefix to filter entries by

Returns:

  • []T: Slice of paginated values matching the prefix
  • *query.PageResponse: Pagination metadata including the next key if more results exist
  • error: Any error encountered during the operation

Pagination behavior:

  1. If no pagination is provided, defaults to counting total with default limit
  2. Key-based pagination can be used, offset is not supported for performance reasons
  3. For key-based pagination, decodes the provided key and uses it as start/end boundary
  4. In reverse order, results are returned in descending order
  5. Returns nextKey in PageResponse if more results exist beyond the current page

Note: This implementation assumes the collection's KeyCodec can properly handle Pair[K1, K2] keys

func PackAny

func PackAny(item proto.Message) (*codectypes.Any, error)

func PackAnys

func PackAnys(isms []proto.Message) ([]*codectypes.Any, error)

func RecoverEthSignature

func RecoverEthSignature(hash []byte, sig []byte) (*ecdsa.PublicKey, error)

RecoverEthSignature recovers the public key from a given signature and message hash.

This function implements EIP-155 signature recovery, which allows extracting the public key that was used to sign a message from the signature itself. The signature must follow the standard 65-byte format with recovery ID.

Signature format:

  • First 32 bytes: R component of the signature
  • Next 32 bytes: S component of the signature
  • Last byte: Recovery ID (27 or 28 for EIP-155)

Parameters:

  • hash: The 32-byte message hash that was signed
  • sig: The 65-byte signature (R + S + recovery_id)

Returns:

  • *ecdsa.PublicKey: The recovered public key, or nil if recovery fails
  • error: Any error encountered during recovery

func RunAllExamples

func RunAllExamples()

RunAllExamples runs all the retry strategy examples

Types

type HexAddress

type HexAddress [HEX_ADDRESS_LENGTH]byte

HexAddress represents a 32-byte address structure that mimics EVM-compatible addresses for smart contracts in the Cosmos ecosystem. It provides a standardized way to represent module addresses with embedded type and ID information.

func CreateMockHexAddress

func CreateMockHexAddress(identifier string, id int64) HexAddress

CreateMockHexAddress generates a deterministic HexAddress for testing purposes. It creates a SHA256 hash from the concatenation of the identifier string and the ID. This function is primarily used in testing scenarios where deterministic addresses are needed.

func DecodeHexAddress

func DecodeHexAddress(s string) (HexAddress, error)

DecodeHexAddress parses a hex-encoded string and converts it to a HexAddress. The input string can optionally include the "0x" prefix, which will be stripped. Returns an error if the string length is invalid or contains non-hex characters.

func GenerateHexAddress

func GenerateHexAddress(moduleSpecifier [module_length]byte, internalType uint32, internalId uint64) HexAddress

GenerateHexAddress creates a new HexAddress with the specified components. This is the primary constructor for creating properly structured HexAddresses with module specifier, type, and internal ID components.

Parameters:

  • moduleSpecifier: 20-byte module identifier
  • internalType: 4-byte module type identifier
  • internalId: 8-byte internal ID for collection storage

func NewZeroAddress

func NewZeroAddress() HexAddress

NewZeroAddress creates and returns a new HexAddress initialized with all zero bytes. This represents an uninitialized or null address state.

func (HexAddress) Bytes

func (h HexAddress) Bytes() []byte

Bytes returns the raw byte slice representation of the HexAddress. This is useful for internal operations that need direct byte access.

func (HexAddress) Compare

func (h HexAddress) Compare(other HexAddress) int

Compare compares two HexAddresses lexicographically. Returns -1 if h < other, 0 if h == other, or 1 if h > other. This method is useful for sorting and ordering operations.

func (HexAddress) Equal

func (h HexAddress) Equal(other HexAddress) bool

Equal checks if two HexAddresses are equal by comparing their byte representations. Returns true if both addresses have identical byte content.

func (HexAddress) GetInternalId

func (h HexAddress) GetInternalId() uint64

GetInternalId extracts the internal ID from the HexAddress. The internal ID is stored in bytes 24-31 and represents a unique identifier for internal collection storage and management.

func (HexAddress) GetType

func (h HexAddress) GetType() uint32

GetType extracts the module type from the HexAddress. The module type is stored in bytes 20-23 and is used to identify the correct module implementation in the router system.

func (HexAddress) IsZeroAddress

func (h HexAddress) IsZeroAddress() bool

IsZeroAddress checks if the HexAddress is the zero address (all bytes are 0). Returns true if the address is uninitialized or represents a null address.

func (HexAddress) Marshal

func (h HexAddress) Marshal() ([]byte, error)

Marshal implements the protobuf Marshaler interface. Returns the hex-encoded string representation as bytes.

func (HexAddress) MarshalJSON

func (h HexAddress) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface. Returns the hex-encoded string representation as JSON.

func (*HexAddress) MarshalTo

func (h *HexAddress) MarshalTo(data []byte) (n int, err error)

MarshalTo implements the protobuf MarshalerTo interface. Writes the hex-encoded string representation to the provided byte slice. Returns the number of bytes written and an error if the buffer is too small.

func (*HexAddress) Size

func (h *HexAddress) Size() int

Size implements the protobuf Sizer interface. Returns the fixed size of the hex-encoded string representation.

func (HexAddress) String

func (h HexAddress) String() string

String returns the hex-encoded string representation of the HexAddress with "0x" prefix. This format is compatible with EVM address representations and is used for external communication.

func (*HexAddress) Unmarshal

func (h *HexAddress) Unmarshal(data []byte) error

Unmarshal implements the protobuf Unmarshaler interface. Parses the hex-encoded string representation from the provided byte slice. Returns an error if the data length is invalid or contains invalid hex characters.

func (*HexAddress) UnmarshalJSON

func (h *HexAddress) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface. Parses the hex-encoded string representation from JSON data. Returns an error if the JSON data is invalid or contains invalid hex characters.

type HyperlaneApp

type HyperlaneApp interface {
	// Exists checks if an application with the given recipient address exists.
	Exists(ctx context.Context, recipient HexAddress) (bool, error)

	// Handle processes a received Hyperlane message.
	// This is where the actual application logic is executed.
	Handle(ctx context.Context, mailboxId HexAddress, message HyperlaneMessage) error

	// ReceiverIsmId returns the ISM ID that should be used for verifying messages
	// sent to the specified recipient address.
	ReceiverIsmId(ctx context.Context, recipient HexAddress) (*HexAddress, error)
}

HyperlaneApp defines the interface for Hyperlane application modules. These modules handle the actual processing of messages and implement the business logic for cross-chain communication.

type HyperlaneMessage

type HyperlaneMessage struct {
	// Version specifies the protocol version for message format compatibility
	Version uint8
	// Nonce is a unique identifier for message ordering and replay protection
	Nonce uint32
	// Origin is the domain ID of the blockchain where this message originated
	Origin uint32
	// Sender is the address of the account that initiated this cross-chain message
	Sender HexAddress
	// Destination is the domain ID of the target blockchain for this message
	Destination uint32
	// Recipient is the address on the destination chain that will receive this message
	Recipient HexAddress
	// Body contains the actual message payload/data to be delivered
	Body []byte
}

HyperlaneMessage implements the Hyperlane message specification for cross-chain communication. This struct represents a standardized message format that enables secure and verifiable communication between different blockchain domains in the Hyperlane network.

The message structure follows the official Hyperlane specification: https://docs.hyperlane.xyz/docs/reference/libraries/message

Message Layout (in bytes): [0:1] Version - Protocol version (1 byte) [1:5] Nonce - Message nonce for ordering (4 bytes, big-endian) [5:9] Origin - Source domain ID (4 bytes, big-endian) [9:41] Sender - Source address (32 bytes) [41:45] Destination - Target domain ID (4 bytes, big-endian) [45:77] Recipient - Target address (32 bytes) [77:] Body - Message payload (variable length)

func ParseHyperlaneMessage

func ParseHyperlaneMessage(raw []byte) (HyperlaneMessage, error)

ParseHyperlaneMessage deserializes a raw byte slice into a HyperlaneMessage struct. This function parses the binary message format according to the Hyperlane specification, extracting each field from its designated byte offset and converting multi-byte fields from big-endian format.

Parameters:

  • raw: The raw byte slice containing the serialized Hyperlane message

Returns:

  • HyperlaneMessage: The parsed message struct
  • error: Returns an error if the message is too short or malformed

The function validates that the input has at least the minimum required length (BodyOffset = 77 bytes) before attempting to parse the fixed-width fields.

func (HyperlaneMessage) Bytes

func (msg HyperlaneMessage) Bytes() []byte

Bytes serializes the HyperlaneMessage struct into its binary representation. This method converts the message fields back into the standardized byte format that matches the Hyperlane specification, with proper big-endian encoding for multi-byte integer fields.

The serialization process: 1. Converts uint32 fields (Nonce, Origin, Destination) to 4-byte big-endian format 2. Converts HexAddress fields (Sender, Recipient) to their 32-byte representation 3. Concatenates all fields in the correct order according to the message layout

Returns:

  • []byte: The complete serialized message as a byte slice

func (HyperlaneMessage) Id

func (msg HyperlaneMessage) Id() HexAddress

Id computes and returns the unique identifier for this Hyperlane message. The message ID is generated by taking the Keccak256 hash of the serialized message bytes, which provides a deterministic and collision-resistant identifier according to the Hyperlane specification.

This ID is used throughout the Hyperlane protocol for: - Message tracking and indexing - Merkle tree construction for batch verification - Cross-chain message routing and delivery confirmation - Dispute resolution and fraud proofs

Returns:

  • HexAddress: The 32-byte Keccak256 hash of the message as a HexAddress

func (HyperlaneMessage) String

func (msg HyperlaneMessage) String() string

String returns a human-readable hex representation of the serialized Hyperlane message. This method provides a convenient way to display the complete message in hexadecimal format with the standard "0x" prefix, making it suitable for logging, debugging, and API responses.

The output format is a single hex string containing all message fields serialized according to the Hyperlane specification, which can be used for: - Message verification and comparison - Cross-chain message transmission - Debugging and troubleshooting - API documentation and examples

Returns:

  • string: The hex-encoded message bytes with "0x" prefix

type InterchainSecurityModule

type InterchainSecurityModule interface {
	// Exists checks if an ISM with the given ID exists in the system.
	Exists(ctx context.Context, ismId HexAddress) (bool, error)

	// Verify validates a message against the ISM's security requirements.
	// Returns true if the message is valid according to the ISM's verification logic.
	Verify(ctx context.Context, ismId HexAddress, metadata []byte, message HyperlaneMessage) (bool, error)
}

InterchainSecurityModule defines the interface for interchain security modules. These modules are responsible for verifying the authenticity and validity of messages received from other chains in the Hyperlane network.

type MerkleTree

type MerkleTree struct {
	// Branch stores the current branch hashes at each level of the tree
	// Each element represents a hash at depth i in the tree
	Branch [TreeDepth][32]byte

	// Count tracks the number of leaves currently in the tree
	// This is used to determine the tree structure and calculate the root
	Count uint32
}

MerkleTree represents an incremental Merkle tree optimized for blockchain applications. This implementation uses a sparse tree approach where only the necessary branch nodes are stored, making it memory-efficient for large trees.

The tree maintains: - Branch: An array of 32-byte hashes representing the current branch from root to leaves - Count: The total number of leaves that have been inserted into the tree

func NewTree

func NewTree(branch [32][32]byte, count uint32) *MerkleTree

NewTree creates a new MerkleTree instance with the given branch and count. This constructor is typically used when reconstructing a tree from stored state.

Parameters:

  • branch: A 32-element array of 32-byte hashes representing the current branch
  • count: The number of leaves currently in the tree

Returns:

  • *MerkleTree: A new MerkleTree instance with the specified branch and count

func (*MerkleTree) GetCount

func (tree *MerkleTree) GetCount() uint32

GetCount returns the current number of leaves in the Merkle tree.

Returns:

  • uint32: The number of leaves currently inserted into the tree

func (*MerkleTree) GetLatestCheckpoint

func (tree *MerkleTree) GetLatestCheckpoint() ([32]byte, uint32, error)

GetLatestCheckpoint returns the root hash and index of the most recently inserted leaf. This is useful for creating checkpoints that can be used to verify tree state.

Returns:

  • [32]byte: The root hash at the time of the latest leaf insertion
  • uint32: The index of the latest leaf (count - 1)
  • error: An error if no leaves have been inserted yet

func (*MerkleTree) GetRoot

func (tree *MerkleTree) GetRoot() [32]byte

GetRoot calculates and returns the current root hash of the Merkle tree. The root represents the top-level hash that summarizes the entire tree state.

Returns:

  • [32]byte: The 32-byte root hash of the current tree state

func (*MerkleTree) Insert

func (tree *MerkleTree) Insert(node [32]byte) error

Insert adds a new leaf node to the Merkle tree and updates the branch accordingly. This implements an incremental insertion algorithm that efficiently maintains the tree structure without storing the entire tree.

The algorithm works by: 1. Finding the position of the new leaf based on the current count 2. Walking up the tree, combining hashes as needed 3. Updating the branch array to reflect the new tree state

Parameters:

  • node: A 32-byte hash representing the new leaf to insert

Returns:

  • error: An error if the tree is already full (has reached MaxLeaves)

Algorithm:

The insertion uses the binary representation of the count to determine
the path through the tree. For each bit position, if the bit is 1,
we store the current node at that level and return. If the bit is 0,
we combine the current node with the existing branch hash and continue.

type PostDispatchModule

type PostDispatchModule interface {
	// Exists checks if a post-dispatch hook with the given ID exists in the system.
	Exists(ctx context.Context, hookId HexAddress) (bool, error)

	// PostDispatch executes the post-dispatch logic and returns the coins charged.
	// This method is called after message dispatch to handle fees and custom processing.
	PostDispatch(ctx context.Context, mailboxId, hookId HexAddress, metadata StandardHookMetadata, message HyperlaneMessage, maxFee sdk.Coins) (sdk.Coins, error)

	// QuoteDispatch provides a fee quote for the post-dispatch operation without executing it.
	// This is used for fee estimation and validation before actual dispatch.
	QuoteDispatch(ctx context.Context, mailboxId, hookId HexAddress, metadata StandardHookMetadata, message HyperlaneMessage) (sdk.Coins, error)

	// HookType returns the type identifier for this hook module.
	HookType() uint8
}

PostDispatchModule defines the interface for post-dispatch hook modules. These modules are executed after a message has been dispatched and are used for fee collection, gas estimation, and custom processing logic.

type Ranger

type Ranger[K any] struct {
	// contains filtered or unexported fields
}

Ranger is a generic type that implements the collections.Ranger interface for pagination. It defines a range of keys to iterate over with a specific ordering.

Type parameters:

  • K: The type of keys in the collection

func (Ranger[K]) RangeValues

func (r Ranger[K]) RangeValues() (start, end *collections.RangeKey[K], order collections.Order, err error)

RangeValues implements the collections.Ranger interface. Returns the range boundaries and ordering for iteration.

type RetryConfig

type RetryConfig struct {
	// MaxRetries is the maximum number of retry attempts (0 means unlimited)
	MaxRetries int
	// Context for cancellation
	Context context.Context
	// OnRetry is called before each retry attempt
	OnRetry func(attempt int, err error, delay time.Duration)
	// ShouldRetry determines if an error should trigger a retry
	ShouldRetry func(error) bool
}

RetryConfig holds configuration for retry behavior

type RetryInfo

type RetryInfo struct {
	Attempt int
	Delay   time.Duration
	Total   time.Duration
}

RetryInfo provides information about retry timing

type RetryStrategy

type RetryStrategy struct {
	// contains filtered or unexported fields
}

RetryStrategy defines the retry timing strategy

func NewRetryStrategy

func NewRetryStrategy() *RetryStrategy

NewRetryStrategy creates a new retry strategy with the default configuration

func (*RetryStrategy) Execute

func (rs *RetryStrategy) Execute(fn func() error) error

Execute runs a function with retry logic

func (*RetryStrategy) GetDelayForAttempt

func (rs *RetryStrategy) GetDelayForAttempt(attempt int) time.Duration

GetDelayForAttempt returns the delay for a specific attempt number without executing retry logic

func (*RetryStrategy) GetRetrySchedule

func (rs *RetryStrategy) GetRetrySchedule(maxAttempts int) []RetryInfo

GetRetrySchedule returns a slice of RetryInfo for the first N attempts

func (*RetryStrategy) String

func (rs *RetryStrategy) String() string

String returns a human-readable description of the retry strategy

func (*RetryStrategy) WithContext

func (rs *RetryStrategy) WithContext(ctx context.Context) *RetryStrategy

WithContext sets the context for cancellation

func (*RetryStrategy) WithMaxRetries

func (rs *RetryStrategy) WithMaxRetries(maxRetries int) *RetryStrategy

WithMaxRetries sets the maximum number of retries

func (*RetryStrategy) WithOnRetry

func (rs *RetryStrategy) WithOnRetry(callback func(attempt int, err error, delay time.Duration)) *RetryStrategy

WithOnRetry sets the callback function called before each retry

func (*RetryStrategy) WithShouldRetry

func (rs *RetryStrategy) WithShouldRetry(shouldRetry func(error) bool) *RetryStrategy

WithShouldRetry sets the function that determines if an error should trigger a retry

type Router

type Router[T any] struct {
	// contains filtered or unexported fields
}

Router is a generic router that manages modules of type T and provides functionality for module registration, retrieval, and address generation. It uses a sequence counter to generate unique addresses for new modules.

Type parameters:

  • T: The type of modules managed by this router (must implement one of the module interfaces)

func NewRouter

func NewRouter[T any](keyPrefix []byte, name string, builder *collections.SchemaBuilder) *Router[T]

NewRouter creates a new router instance with the specified configuration. The router name is used as a prefix for generating unique module addresses.

Parameters:

  • keyPrefix: The key prefix for the sequence storage
  • name: The router name (must be at most 20 bytes)
  • builder: The collections schema builder for sequence initialization

Returns:

  • *Router[T]: A new router instance

Panics:

  • If the router name exceeds the maximum length of 20 bytes

func (*Router[T]) GetInternalSequence

func (r *Router[T]) GetInternalSequence(ctx context.Context) (uint64, error)

GetInternalSequence returns the current value of the internal sequence counter without incrementing it. This is useful for checking the current state.

Parameters:

  • ctx: Context for the operation

Returns:

  • uint64: The current sequence value
  • error: Any error encountered during the operation

func (*Router[T]) GetModule

func (r *Router[T]) GetModule(id HexAddress) (*T, error)

GetModule retrieves a module instance based on the module type embedded in the HexAddress. The module type is extracted from bytes 20-23 of the address using the GetType() method.

Parameters:

  • id: The HexAddress containing the module type information

Returns:

  • *T: A pointer to the module instance, or nil if not found
  • error: An error if the module type is not registered

func (*Router[T]) GetModuleIds

func (r *Router[T]) GetModuleIds() (moduleIds []uint32)

GetModuleIds returns a sorted list of all registered module IDs. This is useful for enumeration and debugging purposes.

Returns:

  • []uint32: A sorted slice of all registered module IDs

func (*Router[T]) GetNextSequence

func (r *Router[T]) GetNextSequence(ctx context.Context, moduleId uint8) (HexAddress, error)

GetNextSequence generates the next unique address for a module of the specified type. This method increments the internal sequence counter and creates a new HexAddress that combines the router name, module type, and sequence number.

Parameters:

  • ctx: Context for the operation
  • moduleId: The module type ID for which to generate an address

Returns:

  • HexAddress: A new unique address for the module
  • error: An error if the sequence cannot be incremented or the module type is not registered

func (*Router[T]) RegisterModule

func (r *Router[T]) RegisterModule(moduleId uint8, module T)

RegisterModule registers a new module with the specified ID in the router. Each module ID can only be registered once to prevent conflicts.

Parameters:

  • moduleId: The unique identifier for the module type (uint8)
  • module: The module instance to register

Panics:

  • If a module with the same ID has already been registered

func (*Router[T]) SetInternalSequence

func (r *Router[T]) SetInternalSequence(ctx context.Context, value uint64) error

SetInternalSequence sets the internal sequence counter to a specific value. This is primarily used for initialization and testing purposes.

Parameters:

  • ctx: Context for the operation
  • value: The new sequence value to set

Returns:

  • error: Any error encountered during the operation

type StandardHookMetadata

type StandardHookMetadata struct {
	// Address represents the Cosmos account address of the message sender.
	// This is used to determine the origin of the message and is particularly
	// important for fee collection mechanisms like Interchain Gas Payment (IGP).
	// The address is used to identify which account should be charged for
	// the message processing and gas costs.
	Address sdk.AccAddress

	// GasLimit specifies the maximum amount of gas that can be consumed
	// by the destination transaction. This is used for gas estimation and
	// fee calculation purposes. The hook can use this value to determine
	// appropriate fees and validate that sufficient gas is allocated.
	GasLimit math.Int

	// CustomHookMetadata contains application-specific data that can be passed
	// to a PostDispatch hook for custom processing logic. The hook implementation
	// is responsible for validating, decoding, and processing this custom metadata.
	// This field allows for extensibility and custom behavior in hook implementations.
	CustomHookMetadata []byte
}

StandardHookMetadata contains the metadata required for post-dispatch hook processing. This structure is application-specific and differs from the EVM implementation to accommodate Cosmos SDK patterns and requirements.

Post-dispatch hooks are executed after a message has been dispatched and are used for various purposes such as fee collection, gas estimation, and custom processing logic.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL