ab_system_contract_address_allocator/
lib.rs#![no_std]
use ab_contracts_common::env::Env;
use ab_contracts_common::{Address, ContractError, ShardIndex};
use ab_contracts_io_type::trivial_type::TrivialType;
use ab_contracts_macros::contract;
#[derive(Copy, Clone, TrivialType)]
#[repr(C)]
pub struct AddressAllocator {
pub next_address: u64,
pub max_address: u64,
}
#[contract]
impl AddressAllocator {
#[init]
pub fn new(#[env] env: &Env) -> Self {
let shard_index = env.shard_index();
let expected_self_address = shard_index.to_u32() as u64 * ShardIndex::MAX_SHARDS as u64;
debug_assert_eq!(
env.own_address(),
Address::from(expected_self_address),
"Unexpected allocator address"
);
Self {
next_address: expected_self_address + 1,
max_address: (shard_index.to_u32() as u64 + 1) * ShardIndex::MAX_SHARDS as u64 - 1,
}
}
#[update]
pub fn allocate_address(&mut self, #[env] env: &mut Env) -> Result<Address, ContractError> {
if env.caller() != Address::SYSTEM_CODE {
return Err(ContractError::AccessDenied);
}
let next_address = self.next_address;
if next_address == self.max_address {
return Err(ContractError::InvalidState);
}
self.next_address += 1;
Ok(Address::from(next_address))
}
}