diff --git a/src/gateway/resolution.rs b/src/gateway/resolution.rs index 25f87a5..f6218a9 100644 --- a/src/gateway/resolution.rs +++ b/src/gateway/resolution.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use ethers::{abi::Token, providers::namehash, utils::keccak256, types::H160}; +use ethers::{abi::Token, providers::namehash, types::H160, utils::keccak256}; use thiserror::Error; use tracing::info; @@ -18,25 +18,40 @@ pub struct UnresolvedQuery<'a> { pub enum ResolveError { #[error("Unknown error")] NotFound, + #[error("Record not found: {0}")] + NotFoundRecord(String), + #[error("Unparsable")] + Unparsable, + #[error("Sender unparsable")] + SenderUnparsable, + #[error("Payload unparsable")] + PayloadUnparsable, + #[error("Hash mismatch")] + HashMismatch, } impl UnresolvedQuery<'_> { pub async fn resolve(&self, state: Arc) -> Result { - info!("Resolving query: {:?}", self.data); - let payload: Vec = match &self.data { - ResolverFunctionCall::Text(_bf, record) => { - let v = hex::encode(_bf); - - info!("Resolving text record: {:?}, for {}", v, self.name); + ResolverFunctionCall::Text(alt_hash, record) => { + info!(name = self.name, record = record, "Resolution"); let hash = namehash(&self.name).to_fixed_bytes().to_vec(); - info!("Resolving text record: {:?}", hash); + if alt_hash != &hash { + return Err(ResolveError::HashMismatch); + } + + let hash = namehash(&self.name).to_fixed_bytes().to_vec(); let x = state.db.get_records(&hash, &[record]).await; - let value = x.get(record).to_owned().unwrap().clone().unwrap(); + let value = x + .get(record) + .to_owned() + .ok_or(ResolveError::NotFoundRecord(record.clone()))? + .clone() + .ok_or(ResolveError::NotFoundRecord(record.clone()))?; vec![Token::String(value)] } @@ -47,7 +62,12 @@ impl UnresolvedQuery<'_> { let x = state.db.get_addresses(&hash, &[&chain.to_string()]).await; - let value = x.get(&chain.to_string()).to_owned().unwrap().clone().unwrap(); + let value = x + .get(&chain.to_string()) + .to_owned() + .ok_or(ResolveError::NotFound)? + .clone() + .ok_or(ResolveError::NotFound)?; let bytes = value.as_bytes().to_vec(); @@ -61,19 +81,33 @@ impl UnresolvedQuery<'_> { let x = state.db.get_addresses(&hash, &[&chain.to_string()]).await; - let value = x.get(&chain.to_string()).to_owned().unwrap().clone().unwrap(); + let value = x + .get(&chain.to_string()) + .to_owned() + .ok_or(ResolveError::NotFound)? + .clone() + .ok_or(ResolveError::NotFound)?; - let address = value.parse().unwrap(); + let address = value.parse().map_err(|_| ResolveError::Unparsable)?; vec![Token::Address(address)] } - _ => Vec::new(), + _ => { + info!("Unimplemented Method"); + + Vec::new() + } }; let ttl = 3600; let expires = chrono::Utc::now().timestamp() as u64 + ttl; - let sender = self.calldata.sender.parse().unwrap(); - let request_payload = hex::decode(self.calldata.data.trim_start_matches("0x")).unwrap(); + let sender = self + .calldata + .sender + .parse() + .map_err(|_| ResolveError::SenderUnparsable)?; + let request_payload = hex::decode(self.calldata.data.trim_start_matches("0x")) + .map_err(|_| ResolveError::PayloadUnparsable)?; let data = ethers::abi::encode(&payload); let request_hash = keccak256(request_payload).to_vec(); let result_hash = keccak256(&data).to_vec();