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
#[error]
const EInsufficientRotationDelay: vector<u8> = b"insufficient rotation delay";
#[error]
const EInvalidEpoch: vector<u8> = b"the difference between current_epoch and signers_epoch exceeds the allowed retention period";
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;
}