Skip to content

Commit

Permalink
feature: reverse resolving (#9)
Browse files Browse the repository at this point in the history
* feat: add set_address_to_domain to override reverse resolving

* feat: add reverse resolving
  • Loading branch information
Th0rgal authored Oct 10, 2023
1 parent 37b895f commit 269e490
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 13 deletions.
6 changes: 5 additions & 1 deletion src/interface/naming.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ trait INaming<TContractState> {

fn domain_to_address(self: @TContractState, domain: Span<felt252>) -> ContractAddress;

fn address_to_domain(self: @TContractState, address: ContractAddress) -> Array<felt252>;
fn address_to_domain(self: @TContractState, address: ContractAddress) -> Span<felt252>;

// external
fn buy(
Expand All @@ -39,6 +39,10 @@ trait INaming<TContractState> {

fn reset_subdomains(ref self: TContractState, domain: Span<felt252>);

fn set_address_to_domain(ref self: TContractState, domain: Span<felt252>);

fn reset_address_to_domain(ref self: TContractState);

// admin
fn set_admin(ref self: TContractState, new_admin: ContractAddress);

Expand Down
65 changes: 53 additions & 12 deletions src/naming/main.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ mod Naming {
enum Event {
DomainMint: DomainMint,
DomainRenewal: DomainRenewal,
DomainToResolver: DomainToResolver,
DomainResolverUpdate: DomainResolverUpdate,
AddressToDomainUpdate: AddressToDomainUpdate,
DomainTransfer: DomainTransfer,
SubdomainsReset: SubdomainsReset,
SaleMetadata: SaleMetadata,
Expand All @@ -51,12 +52,19 @@ mod Naming {
}

#[derive(Drop, starknet::Event)]
struct DomainToResolver {
struct DomainResolverUpdate {
#[key]
domain: Span<felt252>,
resolver: ContractAddress
}

#[derive(Drop, starknet::Event)]
struct AddressToDomainUpdate {
#[key]
address: ContractAddress,
domain: Span<felt252>,
}

#[derive(Drop, starknet::Event)]
struct DomainTransfer {
#[key]
Expand Down Expand Up @@ -207,11 +215,11 @@ mod Naming {
}

// This function allows to find which domain to use to display an account
fn address_to_domain(self: @ContractState, address: ContractAddress) -> Array<felt252> {
fn address_to_domain(self: @ContractState, address: ContractAddress) -> Span<felt252> {
let mut domain = ArrayTrait::new();
self._address_to_domain_util(address, ref domain);
if domain.len() != 0 && self.domain_to_address(domain.span()) == address {
domain
domain.span()
} else {
let identity = IIdentityDispatcher {
contract_address: self.starknetid_contract.read()
Expand All @@ -221,9 +229,7 @@ mod Naming {
let id_hashed_domain = identity
.get_verifier_data(id, 'name', get_contract_address(), 0);
let domain = self.unhash_domain(id_hashed_domain);
assert(
self.domain_to_address(domain.span()) == address, 'domain not pointing back'
);
assert(self.domain_to_address(domain) == address, 'domain not pointing back');
domain
}
}
Expand Down Expand Up @@ -360,6 +366,26 @@ mod Naming {
self.emit(Event::SubdomainsReset(SubdomainsReset { domain: domain, }));
}


// will override your main id
fn set_address_to_domain(ref self: ContractState, domain: Span<felt252>) {
let address = get_caller_address();
assert(self.domain_to_address(domain) == address, 'domain not pointing back');
self.emit(Event::AddressToDomainUpdate(AddressToDomainUpdate { address, domain }));
self.set_address_to_domain_util(address, domain);
}

fn reset_address_to_domain(ref self: ContractState) {
let address = get_caller_address();
self
.emit(
Event::AddressToDomainUpdate(
AddressToDomainUpdate { address, domain: array![].span() }
)
);
self.set_address_to_domain_util(address, array![0].span());
}

// ADMIN

fn set_admin(ref self: ContractState, new_admin: ContractAddress) {
Expand Down Expand Up @@ -412,7 +438,7 @@ mod Naming {
return hashed_domain;
}

fn unhash_domain(self: @ContractState, domain_hash: felt252) -> Array<felt252> {
fn unhash_domain(self: @ContractState, domain_hash: felt252) -> Span<felt252> {
let mut i = 0;
let mut domain = ArrayTrait::new();
loop {
Expand All @@ -421,8 +447,9 @@ mod Naming {
break;
}
domain.append(domain_part);
i += 1;
};
domain
domain.span()
}

fn assert_purchase_is_possible(
Expand Down Expand Up @@ -512,6 +539,20 @@ mod Naming {
}
}

fn set_address_to_domain_util(
ref self: ContractState, address: ContractAddress, mut domain: Span<felt252>
) {
match domain.pop_back() {
Option::Some(domain_part) => {
self._address_to_domain.write((address, domain.len()), *domain_part);
return self.set_address_to_domain_util(address, domain);
},
Option::None => {
return;
}
}
}

fn domain_to_resolver(
self: @ContractState, domain: Span<felt252>, parent_start_id: u32
) -> (ContractAddress, u32) {
Expand Down Expand Up @@ -588,7 +629,7 @@ mod Naming {
key: 1,
parent_key: 0,
};
self._hash_to_domain.write((hashed_domain, 0), hashed_domain);
self._hash_to_domain.write((hashed_domain, 0), domain);
self._domain_data.write(hashed_domain, data);
self.emit(Event::DomainMint(DomainMint { domain, owner: id, expiry }));

Expand All @@ -597,8 +638,8 @@ mod Naming {
if (resolver.into() != 0) {
self
.emit(
Event::DomainToResolver(
DomainToResolver { domain: array![domain].span(), resolver }
Event::DomainResolverUpdate(
DomainResolverUpdate { domain: array![domain].span(), resolver }
)
);
}
Expand Down
65 changes: 65 additions & 0 deletions src/tests/naming/test_usecases.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,68 @@ fn test_non_owner_can_renew_domain() {
eth.approve(naming.contract_address, price);
naming.renew(domain_name, 365, ContractAddressZeroable::zero(), 0, 0);
}


#[test]
#[available_gas(2000000000)]
fn test_set_address_to_domain() {
// setup
let (eth, pricing, identity, naming) = deploy();
let caller = contract_address_const::<0x123>();
set_contract_address(caller);
let id1: u128 = 1;
let id2: u128 = 2;
let first_domain_top: felt252 = 82939898252385817;
let second_domain_top: felt252 = 3151716132312299378;

//we mint the ids
identity.mint(id1);
identity.mint(id2);

// buy the domains
let (_, price1) = pricing.compute_buy_price(11, 365);
eth.approve(naming.contract_address, price1);
naming
.buy(
id1,
first_domain_top,
365,
ContractAddressZeroable::zero(),
ContractAddressZeroable::zero(),
0,
0
);

let (_, price2) = pricing.compute_buy_price(12, 365);
eth.approve(naming.contract_address, price2);
naming
.buy(
id2,
second_domain_top,
365,
ContractAddressZeroable::zero(),
ContractAddressZeroable::zero(),
0,
0
);

// let's try the resolving
let first_domain = array![first_domain_top].span();
assert(naming.domain_to_address(first_domain) == caller, 'wrong domain target');

// set reverse resolving
identity.set_main_id(id1);
let expect_domain1 = naming.address_to_domain(caller);
assert(expect_domain1 == first_domain, 'wrong rev resolving 1');

// override reverse resolving
let second_domain = array![second_domain_top].span();
naming.set_address_to_domain(second_domain);
let expect_domain2 = naming.address_to_domain(caller);
assert(expect_domain2 == second_domain, 'wrong rev resolving 2');

// remove override
naming.reset_address_to_domain();
let expect_domain1 = naming.address_to_domain(caller);
assert(expect_domain1 == first_domain, 'wrong rev resolving b');
}

0 comments on commit 269e490

Please sign in to comment.