Skip to content

Commit

Permalink
Merge pull request #4 from starknet-id/feat/custom_resolver_ccip
Browse files Browse the repository at this point in the history
ref: update uri management & include sliced domain in offchain_resolver error msg
  • Loading branch information
Th0rgal authored Apr 17, 2024
2 parents 83baad5 + 870ca20 commit 8a51512
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 26 deletions.
5 changes: 4 additions & 1 deletion src/interface/resolver.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ trait IResolver<TContractState> {
fn resolve(
self: @TContractState, domain: Span<felt252>, field: felt252, hint: Span<felt252>
) -> felt252;
fn update_uri(ref self: TContractState, new_uri: Span<felt252>);

fn get_uris(self: @TContractState) -> Array<felt252>;
fn add_uri(ref self: TContractState, new_uri: Span<felt252>);
fn remove_uri(ref self: TContractState, index: felt252);
}
120 changes: 99 additions & 21 deletions src/resolver.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod Resolver {
#[storage]
struct Storage {
public_key: felt252,
uri: LegacyMap<felt252, felt252>,
uri: LegacyMap<(felt252, felt252), felt252>,
#[substorage(v0)]
storage_read: storage_read_component::Storage,
#[substorage(v0)]
Expand All @@ -40,18 +40,15 @@ mod Resolver {

#[derive(Drop, starknet::Event)]
struct StarknetIDOffChainResolverUpdate {
uri: Span<felt252>,
uri_added: Span<felt252>,
uri_removed: Span<felt252>,
}


#[constructor]
fn constructor(
ref self: ContractState, owner: ContractAddress, _public_key: felt252, uri: Span<felt252>
) {
fn constructor(ref self: ContractState, owner: ContractAddress, _public_key: felt252) {
self.ownable.initializer(owner);
self.public_key.write(_public_key);
self.store_uri(uri);
self.emit(StarknetIDOffChainResolverUpdate { uri });
}

#[external(v0)]
Expand All @@ -60,7 +57,7 @@ mod Resolver {
self: @ContractState, domain: Span<felt252>, field: felt252, hint: Span<felt252>
) -> felt252 {
if hint.len() != 4 {
panic(self.get_uri(array!['offchain_resolving']));
panic(self.get_error_array(array!['offchain_resolving'], domain));
}

let max_validity = *hint.at(3);
Expand All @@ -86,37 +83,118 @@ mod Resolver {
return *hint.at(0);
}

fn update_uri(ref self: ContractState, new_uri: Span<felt252>) {
fn get_uris(self: @ContractState) -> Array<felt252> {
let mut res: Array<felt252> = array![];
let mut i: felt252 = 0;
loop {
if self.uri.read((i, 0)) == 0 {
break;
}
if self.uri.read((i, 0)) != 'this call was removed' {
// we get the next uri at index i
let mut new_uri = self.get_uri_at_index(i);
res.append(new_uri.len().into());
loop {
match new_uri.pop_front() {
Option::Some(value) => { res.append(value); },
Option::None => { break; }
}
};
}
i += 1;
};
res
}

fn add_uri(ref self: ContractState, new_uri: Span<felt252>) {
self.ownable.assert_only_owner();
self.store_uri(new_uri);
self.emit(StarknetIDOffChainResolverUpdate { uri: new_uri, });
let mut i: felt252 = 0;
loop {
if self.uri.read((i, 0)) == 0 {
self
.emit(
StarknetIDOffChainResolverUpdate {
uri_added: new_uri, uri_removed: array![].span()
}
);
self.store_uri(new_uri, i);

break;
}
i += 1;
};
}

fn remove_uri(ref self: ContractState, index: felt252) {
self.ownable.assert_only_owner();
let uri_removed = self.get_uri_at_index(index).span();
self.emit(StarknetIDOffChainResolverUpdate { uri_added: array![].span(), uri_removed });
self.uri.write((index, 0), 'this call was removed');
}
}

#[generate_trait]
impl InternalImpl of InternalTrait {
fn store_uri(ref self: ContractState, mut uri: Span<felt252>) {
let mut index = 0;
fn get_uri_at_index(self: @ContractState, index: felt252) -> Array<felt252> {
let mut res = array![];
let mut j: felt252 = 0;
loop {
let value = self.uri.read((index, j));
if value == 0 {
break;
}
res.append(value);
j += 1;
};
res
}

fn store_uri(ref self: ContractState, mut uri: Span<felt252>, index: felt252) {
let mut j = 0;
loop {
match uri.pop_front() {
Option::Some(value) => {
self.uri.write(index, *value);
index += 1;
self.uri.write((index, j), *value);
j += 1;
},
Option::None => { break; }
}
};
}

fn get_uri(self: @ContractState, mut res: Array<felt252>) -> Array<felt252> {
let mut index = 0;
fn get_error_array(
self: @ContractState, mut res: Array<felt252>, mut domain: Span<felt252>
) -> Array<felt252> {
// append domain to error array
res.append(domain.len().into());
loop {
let value = self.uri.read(index);
if value == 0 {
match domain.pop_front() {
Option::Some(value) => { res.append(*value); },
Option::None => { break; }
}
};
// append uris to error array
self.append_uris(res)
}

fn append_uris(self: @ContractState, mut res: Array<felt252>) -> Array<felt252> {
let mut i: felt252 = 0;
loop {
if self.uri.read((i, 0)) == 0 {
break;
}
res.append(value);
index += 1;
if self.uri.read((i, 0)) != 'this call was removed' {
// we get the next uri at index i
let mut new_uri = self.get_uri_at_index(i);
res.append(new_uri.len().into());
loop {
match new_uri.pop_front() {
Option::Some(value) => { res.append(value); },
Option::None => { break; }
}
};
}
i += 1;
};
res
}
Expand Down
63 changes: 59 additions & 4 deletions src/tests/resolver/test_resolver.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use array::ArrayTrait;
use debug::PrintTrait;
use core::option::OptionTrait;
use zeroable::Zeroable;
use traits::Into;

Expand Down Expand Up @@ -48,9 +49,7 @@ fn deploy(
Naming::TEST_CLASS_HASH, array![identity.into(), pricing.into(), 0, admin]
);

let resolver = utils::deploy(
Resolver::TEST_CLASS_HASH, array![admin, pub_key, 1, 'http://0.0.0.0:8090']
);
let resolver = utils::deploy(Resolver::TEST_CLASS_HASH, array![admin, pub_key]);
(
IERC20CamelDispatcher { contract_address: eth },
IPricingDispatcher { contract_address: pricing },
Expand All @@ -60,11 +59,59 @@ fn deploy(
)
}

#[test]
#[available_gas(20000000000)]
fn test_uri() {
let (eth, pricing, identity, naming, resolver) = deploy(
0x64018d8ea7829641419aff38ea79efd3eafedf3a5c1fe001d35339b889d48f4
);

let caller = contract_address_const::<0x123>();
set_contract_address(caller);

// add a some uris
resolver.add_uri(array!['http://0.0.0.0:8090/resolve?dom', 'ain='].span());
resolver.add_uri(array!['http://sepolia.starknet.id/reso', 'lve?domain='].span());
resolver.add_uri(array!['http://sepolia_2.starknet.id/re', 'solve?domain='].span());

let mut uris = resolver.get_uris();
assert(uris.len() == 9, 'wrong length');
assert(uris.at(0) == @2, 'wrong nb of arg');
assert(uris.at(1) == @'http://0.0.0.0:8090/resolve?dom', 'wrong uri');
assert(uris.at(2) == @'ain=', 'wrong uri');
assert(uris.at(3) == @2, 'wrong nb of arg');
assert(uris.at(4) == @'http://sepolia.starknet.id/reso', 'wrong 2nd uri');
assert(uris.at(5) == @'lve?domain=', 'wrong 2nd uri');
assert(uris.at(6) == @2, 'wrong nb of arg');
assert(uris.at(7) == @'http://sepolia_2.starknet.id/re', 'wrong 2nd uri');
assert(uris.at(8) == @'solve?domain=', 'wrong 2nd uri');

// remove the uri at index 1
resolver.remove_uri(1);
let mut uris = resolver.get_uris();
assert(uris.len() == 6, 'wrong length');
assert(uris.at(0) == @2, 'wrong nb of arg');
assert(uris.at(1) == @'http://0.0.0.0:8090/resolve?dom', 'wrong uri');
assert(uris.at(2) == @'ain=', 'wrong uri');
assert(uris.at(3) == @2, 'wrong nb of arg');
assert(uris.at(4) == @'http://sepolia_2.starknet.id/re', 'wrong 2nd uri');
assert(uris.at(5) == @'solve?domain=', 'wrong 2nd uri');
}

#[test]
#[available_gas(20000000000)]
#[should_panic(
expected: (
'offchain_resolving', 'http://0.0.0.0:8090', 'ENTRYPOINT_FAILED', 'ENTRYPOINT_FAILED'
'offchain_resolving',
1,
999902,
1,
'http://0.0.0.0:8090',
2,
'http://0.0.0.0:8090/resolve?dom',
'ain=',
'ENTRYPOINT_FAILED',
'ENTRYPOINT_FAILED'
)
)]
fn test_offchain_resolving_no_hint() {
Expand All @@ -78,6 +125,10 @@ fn test_offchain_resolving_no_hint() {
let iris: felt252 = 999902;
let notion: felt252 = 1059716045;

// add uri
resolver.add_uri(array!['http://0.0.0.0:8090'].span());
resolver.add_uri(array!['http://0.0.0.0:8090/resolve?dom', 'ain='].span());

//we mint an identity
identity.mint(id1);

Expand Down Expand Up @@ -109,6 +160,10 @@ fn test_offchain_resolving_with_hint() {
let notion: felt252 = 1059716045;
let iris: felt252 = 999902;

// add uri
resolver.add_uri(array!['http://0.0.0.0:8090'].span());
resolver.add_uri(array!['http://0.0.0.0:8090/resolve?dom', 'ain='].span());

let max_validity: felt252 = 1701167467;
let timestamp: u64 = 1701167467 - 1800; // max_validity - 30 minutes
set_block_timestamp(timestamp);
Expand Down

0 comments on commit 8a51512

Please sign in to comment.