axelar-cgp-sui

Module 0xa1::auth

use 0x2::bcs;
use 0x2::clock;
use 0x2::table;
use 0x2::tx_context;
use 0xa1::bytes32;
use 0xa1::events;
use 0xa1::proof;
use 0xa1::weighted_signers;

Struct AxelarSigners

struct AxelarSigners has store
Fields
epoch: u64
Epoch of the signers.
epoch_by_signers_hash: table::Table<bytes32::Bytes32, u64>
Epoch for the signers hash.
domain_separator: bytes32::Bytes32
Domain separator between chains.
minimum_rotation_delay: u64
Minimum rotation delay.
last_rotation_timestamp: u64
Timestamp of the last rotation.
previous_signers_retention: u64
Number of previous signers retained (latest signer isn't included in the count).

Struct MessageToSign

struct MessageToSign has copy, drop, store
Fields
domain_separator: bytes32::Bytes32
signers_hash: bytes32::Bytes32
data_hash: bytes32::Bytes32

Constants

const EInsufficientRotationDelay: vector<u8> = [105, 110, 115, 117, 102, 102, 105, 99, 105, 101, 110, 116, 32, 114, 111, 116, 97, 116, 105, 111, 110, 32, 100, 101, 108, 97, 121];

const EInvalidEpoch: vector<u8> = [116, 104, 101, 32, 100, 105, 102, 102, 101, 114, 101, 110, 99, 101, 32, 98, 101, 116, 119, 101, 101, 110, 32, 99, 117, 114, 114, 101, 110, 116, 95, 101, 112, 111, 99, 104, 32, 97, 110, 100, 32, 115, 105, 103, 110, 101, 114, 115, 95, 101, 112, 111, 99, 104, 32, 101, 120, 99, 101, 101, 100, 115, 32, 116, 104, 101, 32, 97, 108, 108, 111, 119, 101, 100, 32, 114, 101, 116, 101, 110, 116, 105, 111, 110, 32, 112, 101, 114, 105, 111, 100];

Function new

public(friend) fun new(ctx: &mut tx_context::TxContext): auth::AxelarSigners
Implementation
public(package) fun new(ctx: &mut TxContext): AxelarSigners {
    AxelarSigners {
        epoch: 0,
        epoch_by_signers_hash: table::new(ctx),
        domain_separator: bytes32::default(),
        minimum_rotation_delay: 0,
        last_rotation_timestamp: 0,
        previous_signers_retention: 0,
    }
}

Function setup

public(friend) fun setup(domain_separator: bytes32::Bytes32, minimum_rotation_delay: u64, previous_signers_retention: u64, initial_signers: weighted_signers::WeightedSigners, clock: &clock::Clock, ctx: &mut tx_context::TxContext): auth::AxelarSigners
Implementation
public(package) fun setup(
    domain_separator: Bytes32,
    minimum_rotation_delay: u64,
    previous_signers_retention: u64,
    initial_signers: WeightedSigners,
    clock: &Clock,
    ctx: &mut TxContext,
): AxelarSigners {
    let mut signers = AxelarSigners {
        epoch: 0,
        epoch_by_signers_hash: table::new(ctx),
        domain_separator,
        minimum_rotation_delay,
        last_rotation_timestamp: 0,
        previous_signers_retention,
    };

    signers.rotate_signers(clock, initial_signers, false);

    signers
}

Function validate_proof

public(friend) fun validate_proof(self: &auth::AxelarSigners, data_hash: bytes32::Bytes32, proof: proof::Proof): bool
Implementation
public(package) fun validate_proof(
    self: &AxelarSigners,
    data_hash: Bytes32,
    proof: Proof,
): bool {
    let signers = proof.signers();
    let signers_hash = signers.hash();
    let signers_epoch = self.epoch_by_signers_hash[signers_hash];
    let current_epoch = self.epoch;
    let is_latest_signers = current_epoch == signers_epoch;

    assert!(
        signers_epoch != 0 &&
        (current_epoch - signers_epoch) <= self.previous_signers_retention,
        EInvalidEpoch,
    );

    proof.validate(
        bcs::to_bytes(
            &MessageToSign {
                domain_separator: self.domain_separator,
                signers_hash,
                data_hash,
            },
        ),
    );

    is_latest_signers
}

Function rotate_signers

public(friend) fun rotate_signers(self: &mut auth::AxelarSigners, clock: &clock::Clock, new_signers: weighted_signers::WeightedSigners, enforce_rotation_delay: bool)
Implementation
public(package) fun rotate_signers(
    self: &mut AxelarSigners,
    clock: &Clock,
    new_signers: WeightedSigners,
    enforce_rotation_delay: bool,
) {
    new_signers.validate();

    self.update_rotation_timestamp(clock, enforce_rotation_delay);

    let new_signers_hash = new_signers.hash();
    let epoch = self.epoch + 1;

    // Aborts if the signers already exist
    self.epoch_by_signers_hash.add(new_signers_hash, epoch);
    self.epoch = epoch;

    events::signers_rotated(
        epoch,
        new_signers_hash,
        new_signers,
    );
}

Function update_rotation_timestamp

fun update_rotation_timestamp(self: &mut auth::AxelarSigners, clock: &clock::Clock, enforce_rotation_delay: bool)
Implementation
fun update_rotation_timestamp(
    self: &mut AxelarSigners,
    clock: &Clock,
    enforce_rotation_delay: bool,
) {
    let current_timestamp = clock.timestamp_ms();

    // If the rotation delay is enforced, the current timestamp should be
    // greater than the last rotation timestamp plus the minimum rotation delay.
    assert!(
        !enforce_rotation_delay ||
        current_timestamp >=
        self.last_rotation_timestamp + self.minimum_rotation_delay,
        EInsufficientRotationDelay,
    );

    self.last_rotation_timestamp = current_timestamp;
}