diff --git a/scripts/testnet.sh b/scripts/testnet.sh index db6f5df..04ea29b 100755 --- a/scripts/testnet.sh +++ b/scripts/testnet.sh @@ -13,7 +13,7 @@ docker build -t hacker-challenge:latest . docker ps -a | grep 'hacker-challenge' | awk '{ print $NF }' | xargs docker rm -f || true -for i in {0..10} +for i in {0..50} do docker run -d --name "hacker-challenge_$i" \ --env INIT_NODES="172.17.0.2 172.17.0.3 172.17.0.4" \ diff --git a/src/datastore.rs b/src/datastore.rs index 9a5f9dc..d236c34 100644 --- a/src/datastore.rs +++ b/src/datastore.rs @@ -45,6 +45,12 @@ impl From for SigningError { } } +impl From for SigningError { + fn from(_: std::io::Error) -> Self { + Self::CorruptedKey + } +} + type IP = String; impl std::fmt::Display for SigningError { @@ -107,7 +113,7 @@ impl Store { } pub async fn tabled_disk_list(&self, page: u64) -> String { - let mut offset = page.wrapping_mul(10); + let mut offset = page.wrapping_mul(20); #[derive(Tabled)] struct OutputRow { id: u64, @@ -147,6 +153,20 @@ impl Store { Table::new(output).to_string() } + pub async fn disk_sign_message_with_key( + &self, + message: &str, + key_id: u64, + ) -> Result { + let crate::persistence::Node{keypair, ..} = + self.persistence.get_node_by_id(key_id).await?; + + // let signature = format!("{:?}", signing_key.sign(message.as_bytes())); + let signature = hex::encode(keypair.sign(message.as_bytes()).to_bytes()); + + Ok(signature) + } + pub async fn sign_message_with_key( &self, message: &str, diff --git a/src/http_server.rs b/src/http_server.rs index b00c18c..9dbfe5e 100644 --- a/src/http_server.rs +++ b/src/http_server.rs @@ -23,7 +23,7 @@ To access keys that are saved on disk, navigate to /disk. Disk entries are pagin You can navigate to a specific page by using get params. Example: https://{ip}/disk?page={number}. To sign a random message using a key from disk, use /disk/sign and send the key id as a get param: curl -G \ - --data-urlencode "pubkey_id=1337" \ + --data-urlencode "key=1337" \ --data-urlencode "something=YOUR_MESSAGE_HERE" \ 'IP_OF_THE_NODE:31372/disk/sign' @@ -34,6 +34,7 @@ Good luck! "#; enum HTTPError { + NoKeyID, NoPubkey, NoMessage, Store(SigningError), @@ -44,6 +45,7 @@ impl Writer for HTTPError { async fn write(self, _req: &mut Request, _depot: &mut Depot, res: &mut Response) { res.status_code(StatusCode::BAD_REQUEST); match self { + HTTPError::NoKeyID => res.render("key ID must be specified as a get param"), HTTPError::NoPubkey => res.render("pubkey must be specified as GET param"), HTTPError::NoMessage => res.render("something must be specified as GET param"), HTTPError::Store(e) => res.render(format!("{e}")), @@ -92,6 +94,25 @@ async fn disk_list(req: &mut Request, depot: &mut Depot) -> Result Result { + let ds = depot.obtain::>().unwrap(); + let key = match req.query::("key") { + Some(k) => k, + None => return Err(HTTPError::NoKeyID), + }; + + let something = match req.query::("something") { + Some(k) => k, + None => return Err(HTTPError::NoMessage), + }; + + match ds.disk_sign_message_with_key(&something, key).await { + Ok(s) => Ok(s), + Err(e) => Err(HTTPError::Store(e)), + } +} + pub async fn init(ds: Arc) { let acceptor = TcpListener::new("0.0.0.0:31372").bind().await; let router = Router::new() @@ -102,7 +123,11 @@ pub async fn init(ds: Arc) { .get(memory_list) .push(Router::with_path("sign").get(memory_sign)), ) - .push(Router::with_path("disk").get(disk_list)); + .push( + Router::with_path("disk") + .get(disk_list) + .push(Router::with_path("sign").get(disk_sign)), + ); println!("{:?}", router); Server::new(acceptor).serve(router).await; }