Merge pull request #90 from uqbar-dao/jf/qns-v2

Jf/qns v2
This commit is contained in:
dr-frmr 2023-12-19 17:08:00 -05:00 committed by GitHub
commit f06652d359
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 124 additions and 96 deletions

View File

@ -6,7 +6,8 @@ use serde_json::json;
use std::collections::HashMap; use std::collections::HashMap;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use uqbar_process_lib::{ use uqbar_process_lib::{
await_message, get_typed_state, http, set_state, Address, Message, Payload, Request, Response, await_message, get_typed_state, http, println, receive, set_state, Address, Message, Payload,
Request, Response,
}; };
wit_bindgen::generate!({ wit_bindgen::generate!({
@ -55,7 +56,7 @@ pub enum NetActions {
QnsBatchUpdate(Vec<QnsUpdate>), QnsBatchUpdate(Vec<QnsUpdate>),
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize, Default)]
pub struct QnsUpdate { pub struct QnsUpdate {
pub name: String, // actual username / domain name pub name: String, // actual username / domain name
pub owner: String, pub owner: String,
@ -75,16 +76,18 @@ impl TryInto<Vec<u8>> for NetActions {
} }
sol! { sol! {
event WsChanged( // Logged whenever a QNS node is created
uint256 indexed node, event NodeRegistered(bytes32 indexed node, bytes name);
uint96 indexed protocols,
bytes32 publicKey,
uint32 ip,
uint16 port,
bytes32[] routers
);
event NodeRegistered(uint256 indexed node, bytes name); event KeyUpdate(bytes32 indexed node, bytes32 key);
event IpUpdate(bytes32 indexed node, uint128 ip);
event WsUpdate(bytes32 indexed node, uint16 port);
event WtUpdate(bytes32 indexed node, uint16 port);
event TcpUpdate(bytes32 indexed node, uint16 port);
event UdpUpdate(bytes32 indexed node, uint16 port);
event RoutingUpdate(bytes32 indexed node, bytes32[] routers);
} }
fn subscribe_to_qns(from_block: u64) -> Vec<u8> { fn subscribe_to_qns(from_block: u64) -> Vec<u8> {
@ -92,13 +95,19 @@ fn subscribe_to_qns(from_block: u64) -> Vec<u8> {
"SubscribeEvents": { "SubscribeEvents": {
"addresses": [ "addresses": [
// QNSRegistry on sepolia // QNSRegistry on sepolia
"0x9e5ed0e7873E0d7f10eEb6dE72E87fE087A12776", "0x1C5595336Fd763a81887472D30D6CbD736Acf0E3",
], ],
"from_block": from_block, "from_block": from_block,
"to_block": null, "to_block": null,
"events": [ "events": [
"NodeRegistered(uint256,bytes)", "NodeRegistered(bytes32,bytes)",
"WsChanged(uint256,uint96,bytes32,uint32,uint16,bytes32[])", "KeyUpdate(bytes32,bytes32)",
"IpUpdate(bytes32,uint128)",
"WsUpdate(bytes32,uint16)",
"WtUpdate(bytes32,uint16)",
"TcpUpdate(bytes32,uint16)",
"UdpUpdate(bytes32,uint16)",
"RoutingUpdate(bytes32,bytes32[])",
], ],
"topic1": null, "topic1": null,
"topic2": null, "topic2": null,
@ -128,12 +137,10 @@ impl Guest for Component {
None => {} None => {}
} }
println!("qns_indexer: starting at block {}", state.block);
match main(our, state) { match main(our, state) {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
println!("qns_indexer: ended with error: {:?}", e); println!("qns_indexer: error: {:?}", e);
} }
} }
} }
@ -180,13 +187,11 @@ fn main(our: Address, mut state: State) -> anyhow::Result<()> {
"Content-Type".to_string(), "Content-Type".to_string(),
"application/json".to_string(), "application/json".to_string(),
)]), )]),
}) })?,
.unwrap(),
) )
.payload(Payload { .payload(Payload {
mime: Some("application/json".to_string()), mime: Some("application/json".to_string()),
bytes: serde_json::to_string(&node) bytes: serde_json::to_string(&node)?
.unwrap()
.as_bytes() .as_bytes()
.to_vec(), .to_vec(),
}) })
@ -204,8 +209,7 @@ fn main(our: Address, mut state: State) -> anyhow::Result<()> {
"Content-Type".to_string(), "Content-Type".to_string(),
"application/json".to_string(), "application/json".to_string(),
)]), )]),
}) })?,
.unwrap(),
) )
.send()?; .send()?;
continue; continue;
@ -217,80 +221,110 @@ fn main(our: Address, mut state: State) -> anyhow::Result<()> {
}; };
match msg { match msg {
// Probably more message types later...maybe not...
AllActions::EventSubscription(e) => { AllActions::EventSubscription(e) => {
state.block = hex_to_u64(&e.block_number).unwrap(); state.block = hex_to_u64(&e.block_number)?;
match decode_hex(&e.topics[0].clone()) { let nodeId = &e.topics[1];
NodeRegistered::SIGNATURE_HASH => {
// print_to_terminal(0, format!("qns_indexer: got NodeRegistered event: {:?}", e).as_str());
let node = &e.topics[1]; let name = if decode_hex(&e.topics[0]) == NodeRegistered::SIGNATURE_HASH {
let decoded = let decoded =
NodeRegistered::decode_data(&decode_hex_to_vec(&e.data), true).unwrap(); NodeRegistered::decode_data(&decode_hex_to_vec(&e.data), true).unwrap();
let Ok(name) = dnswire_decode(decoded.0.clone()) else { match dnswire_decode(decoded.0.clone()) {
// print_to_terminal( Ok(name) => {
// 1, state.names.insert(nodeId.to_string(), name.clone());
// &format!("qns_indexer: failed to decode name: {:?}", decoded.0), }
// ); Err(_) => {
continue; println!("qns_indexer: failed to decode name: {:?}", decoded.0);
}; }
state.names.insert(node.to_string(), name);
} }
WsChanged::SIGNATURE_HASH => { continue;
let node = &e.topics[1]; } else if let Some(name) = state.names.get(nodeId) {
name
} else {
println!("qns_indexer: failed to find name: {:?}", nodeId);
continue;
};
let node = state
.nodes
.entry(name.to_string())
.or_insert_with(QnsUpdate::default);
if node.name == "" {
node.name = name.clone();
}
if node.node == "" {
node.node = nodeId.clone();
}
let mut send = false;
match decode_hex(&e.topics[0].clone()) {
NodeRegistered::SIGNATURE_HASH => {} // will never hit this
KeyUpdate::SIGNATURE_HASH => {
let decoded = let decoded =
WsChanged::decode_data(&decode_hex_to_vec(&e.data), true).unwrap(); KeyUpdate::decode_data(&decode_hex_to_vec(&e.data), true).unwrap();
let public_key = hex::encode(decoded.0); node.public_key = format!("0x{}", hex::encode(decoded.0));
let ip = decoded.1; send = true;
let port = decoded.2; }
let routers_raw = decoded.3; IpUpdate::SIGNATURE_HASH => {
let routers: Vec<String> = routers_raw let decoded =
IpUpdate::decode_data(&decode_hex_to_vec(&e.data), true).unwrap();
let ip = decoded.0;
node.ip = format!(
"{}.{}.{}.{}",
(ip >> 24) & 0xFF,
(ip >> 16) & 0xFF,
(ip >> 8) & 0xFF,
ip & 0xFF
);
send = true;
}
WsUpdate::SIGNATURE_HASH => {
let decoded =
WsUpdate::decode_data(&decode_hex_to_vec(&e.data), true).unwrap();
node.port = decoded.0;
send = true;
}
WtUpdate::SIGNATURE_HASH => {
let decoded =
WtUpdate::decode_data(&decode_hex_to_vec(&e.data), true).unwrap();
}
TcpUpdate::SIGNATURE_HASH => {
let decoded =
TcpUpdate::decode_data(&decode_hex_to_vec(&e.data), true).unwrap();
}
UdpUpdate::SIGNATURE_HASH => {
let decoded =
UdpUpdate::decode_data(&decode_hex_to_vec(&e.data), true).unwrap();
}
RoutingUpdate::SIGNATURE_HASH => {
let decoded =
RoutingUpdate::decode_data(&decode_hex_to_vec(&e.data), true).unwrap();
let routers_raw = decoded.0;
node.routers = routers_raw
.iter() .iter()
.map(|r| { .map(|r| {
let key = hex::encode(r); let key = format!("0x{}", hex::encode(r));
match state.names.get(&key) { match state.names.get(&key) {
Some(name) => name.clone(), Some(name) => name.clone(),
None => format!("0x{}", key), // TODO it should actually just panic here None => format!("proposed router did not exist: 0x{}", key),
} }
}) })
.collect::<Vec<String>>(); .collect::<Vec<String>>();
send = true;
let Some(name) = state.names.get(node) else {
println!(
"qns_indexer: failed to find name for node during WsChanged: {:?}",
node
);
continue;
};
let update = QnsUpdate {
name: name.clone(),
owner: "0x".to_string(), // TODO or get rid of
node: node.clone(),
public_key: format!("0x{}", public_key),
ip: format!(
"{}.{}.{}.{}",
(ip >> 24) & 0xFF,
(ip >> 16) & 0xFF,
(ip >> 8) & 0xFF,
ip & 0xFF
),
port,
routers,
};
state.nodes.insert(name.clone(), update.clone());
Request::new()
.target((&our.node, "net", "sys", "uqbar"))
.try_ipc(NetActions::QnsUpdate(update))?
.send()?;
} }
event => { event => {
println!("qns_indexer: got unknown event: {:?}", event); println!("qns_indexer: got unknown event: {:?}", event);
} }
} }
if send {
Request::new()
.target((&our.node, "net", "sys", "uqbar"))
.try_ipc(NetActions::QnsUpdate(node.clone()))?
.send()?;
}
} }
} }
set_state(&bincode::serialize(&state)?); set_state(&bincode::serialize(&state)?);

View File

@ -1,13 +1,13 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.e62f8e3a.css", "main.css": "/static/css/main.e62f8e3a.css",
"main.js": "/static/js/main.ad67a3c7.js", "main.js": "/static/js/main.547b1c20.js",
"index.html": "/index.html", "index.html": "/index.html",
"main.e62f8e3a.css.map": "/static/css/main.e62f8e3a.css.map", "main.e62f8e3a.css.map": "/static/css/main.e62f8e3a.css.map",
"main.ad67a3c7.js.map": "/static/js/main.ad67a3c7.js.map" "main.547b1c20.js.map": "/static/js/main.547b1c20.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.e62f8e3a.css", "static/css/main.e62f8e3a.css",
"static/js/main.ad67a3c7.js" "static/js/main.547b1c20.js"
] ]
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -30,7 +30,7 @@ abigen!(
type RegistrationSender = mpsc::Sender<(Identity, Keyfile, Vec<u8>)>; type RegistrationSender = mpsc::Sender<(Identity, Keyfile, Vec<u8>)>;
pub const _QNS_SEPOLIA_ADDRESS: &str = "0x9e5ed0e7873E0d7f10eEb6dE72E87fE087A12776"; pub const _QNS_SEPOLIA_ADDRESS: &str = "0x1C5595336Fd763a81887472D30D6CbD736Acf0E3";
pub fn _ip_to_number(ip: &str) -> Result<u32, &'static str> { pub fn _ip_to_number(ip: &str) -> Result<u32, &'static str> {
let octets: Vec<&str> = ip.split('.').collect(); let octets: Vec<&str> = ip.split('.').collect();
@ -535,18 +535,15 @@ async fn _networking_info_valid(rpc_url: String, ip: String, ws_port: u16, our:
// check if Identity for this username has correct networking keys, // check if Identity for this username has correct networking keys,
// if not, prompt user to reset them. // if not, prompt user to reset them.
let Ok(ws_rpc) = Provider::<Ws>::connect(rpc_url.clone()).await else { let Ok(ws_rpc) = Provider::<Ws>::connect(rpc_url.clone()).await else {
println!("1");
return false; return false;
}; };
let Ok(qns_address): Result<EthAddress, _> = _QNS_SEPOLIA_ADDRESS.parse() else { let Ok(qns_address): Result<EthAddress, _> = _QNS_SEPOLIA_ADDRESS.parse() else {
println!("2");
return false; return false;
}; };
let contract = QNSRegistry::new(qns_address, ws_rpc.into()); let contract = QNSRegistry::new(qns_address, ws_rpc.into());
let node_id: U256 = namehash(&our.name).as_bytes().into(); let node_id: U256 = namehash(&our.name).as_bytes().into();
let Ok((chain_pubkey, chain_ip, chain_port, chain_routers)) = contract.ws(node_id).call().await let Ok((chain_pubkey, chain_ip, chain_port, chain_routers)) = contract.ws(node_id).call().await
else { else {
println!("3");
return false; return false;
}; };
@ -566,13 +563,11 @@ async fn _networking_info_valid(rpc_url: String, ip: String, ws_port: u16, our:
let current_ip = match _ip_to_number(&ip) { let current_ip = match _ip_to_number(&ip) {
Ok(ip_num) => ip_num, Ok(ip_num) => ip_num,
Err(_) => { Err(_) => {
println!("5");
return false; return false;
} }
}; };
let Ok(networking_key_bytes) = _hex_string_to_u8_array(&our.networking_key) else { let Ok(networking_key_bytes) = _hex_string_to_u8_array(&our.networking_key) else {
println!("6");
return false; return false;
}; };
@ -588,7 +583,6 @@ async fn _networking_info_valid(rpc_url: String, ip: String, ws_port: u16, our:
// double check that keys match on-chain information // double check that keys match on-chain information
if !routing_match || !pubkey_match { if !routing_match || !pubkey_match {
println!("7");
return false; return false;
} }