keyforkd: add required 2 path segments
This commit is contained in:
parent
72666011a4
commit
f60b77254a
|
@ -103,7 +103,7 @@ mod tests {
|
||||||
impl Test {
|
impl Test {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
field: "hello world!".to_string()
|
field: "hello world!".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,8 +135,7 @@ mod tests {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn can_serde_responses() {
|
async fn can_serde_responses() {
|
||||||
let content = serialize(&Test::new())
|
let content = serialize(&Test::new()).unwrap();
|
||||||
.unwrap();
|
|
||||||
let mut service = ServiceBuilder::new()
|
let mut service = ServiceBuilder::new()
|
||||||
.layer(BincodeLayer::<Test>::new())
|
.layer(BincodeLayer::<Test>::new())
|
||||||
.service(App);
|
.service(App);
|
||||||
|
|
|
@ -7,6 +7,15 @@ use tower::Service;
|
||||||
// NOTE: All values implemented in Keyforkd must implement Clone with low overhead, either by
|
// NOTE: All values implemented in Keyforkd must implement Clone with low overhead, either by
|
||||||
// using an Arc or by having a small signature. This is because Service<T> takes &mut self.
|
// using an Arc or by having a small signature. This is because Service<T> takes &mut self.
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum KeyforkdRequestError {
|
||||||
|
#[error("Invalid derivation length: Expected: 2, actual: {0}")]
|
||||||
|
InvalidDerivationLength(usize),
|
||||||
|
|
||||||
|
#[error("Derivation error: {0}")]
|
||||||
|
Derivation(#[from] DerivationError),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Keyforkd {
|
pub struct Keyforkd {
|
||||||
mnemonic: Arc<Mnemonic>,
|
mnemonic: Arc<Mnemonic>,
|
||||||
|
@ -23,7 +32,7 @@ impl Keyforkd {
|
||||||
impl Service<DerivationRequest> for Keyforkd {
|
impl Service<DerivationRequest> for Keyforkd {
|
||||||
type Response = DerivationResponse;
|
type Response = DerivationResponse;
|
||||||
|
|
||||||
type Error = DerivationError;
|
type Error = KeyforkdRequestError;
|
||||||
|
|
||||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
|
||||||
|
|
||||||
|
@ -37,7 +46,14 @@ impl Service<DerivationRequest> for Keyforkd {
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(skip(self)))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(skip(self)))]
|
||||||
fn call(&mut self, req: DerivationRequest) -> Self::Future {
|
fn call(&mut self, req: DerivationRequest) -> Self::Future {
|
||||||
let mnemonic = self.mnemonic.clone();
|
let mnemonic = self.mnemonic.clone();
|
||||||
Box::pin(async { req.derive_with_mnemonic(&mnemonic) })
|
Box::pin(async {
|
||||||
|
let len = req.path().len();
|
||||||
|
if len < 2 {
|
||||||
|
return Err(KeyforkdRequestError::InvalidDerivationLength(len));
|
||||||
|
}
|
||||||
|
req.derive_with_mnemonic(&mnemonic)
|
||||||
|
.map_err(KeyforkdRequestError::from)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +70,9 @@ mod tests {
|
||||||
async fn properly_derives_data() {
|
async fn properly_derives_data() {
|
||||||
// Pulled from keyfork-derive-util's tests, which is more extensively tested.
|
// Pulled from keyfork-derive-util's tests, which is more extensively tested.
|
||||||
let tests = [
|
let tests = [
|
||||||
|
/*
|
||||||
|
* Note: Tests excluded because the derivation path is not deep enough
|
||||||
|
* for the API's preferences.
|
||||||
(
|
(
|
||||||
&hex!("000102030405060708090a0b0c0d0e0f")[..],
|
&hex!("000102030405060708090a0b0c0d0e0f")[..],
|
||||||
DerivationPath::from_str("m").unwrap(),
|
DerivationPath::from_str("m").unwrap(),
|
||||||
|
@ -68,6 +87,7 @@ mod tests {
|
||||||
hex!("68e0fe46dfb67e368c75379acec591dad19df3cde26e63b93a8e704f1dade7a3"),
|
hex!("68e0fe46dfb67e368c75379acec591dad19df3cde26e63b93a8e704f1dade7a3"),
|
||||||
hex!("008c8a13df77a28f3445213a0f432fde644acaa215fc72dcdf300d5efaa85d350c"),
|
hex!("008c8a13df77a28f3445213a0f432fde644acaa215fc72dcdf300d5efaa85d350c"),
|
||||||
),
|
),
|
||||||
|
*/
|
||||||
(
|
(
|
||||||
&hex!("000102030405060708090a0b0c0d0e0f")[..],
|
&hex!("000102030405060708090a0b0c0d0e0f")[..],
|
||||||
DerivationPath::from_str("m/0'/1'/2'/2'/1000000000'").unwrap(),
|
DerivationPath::from_str("m/0'/1'/2'/2'/1000000000'").unwrap(),
|
||||||
|
@ -86,4 +106,46 @@ mod tests {
|
||||||
assert_eq!(response.data, private_key)
|
assert_eq!(response.data, private_key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[should_panic]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn errors_on_no_path() {
|
||||||
|
let tests = [(
|
||||||
|
&hex!("000102030405060708090a0b0c0d0e0f")[..],
|
||||||
|
DerivationPath::from_str("m").unwrap(),
|
||||||
|
hex!("90046a93de5380a72b5e45010748567d5ea02bbf6522f979e05c0d8d8ca9fffb"),
|
||||||
|
hex!("2b4be7f19ee27bbf30c667b642d5f4aa69fd169872f8fc3059c08ebae2eb19e7"),
|
||||||
|
hex!("00a4b2856bfec510abab89753fac1ac0e1112364e7d250545963f135f2a33188ed"),
|
||||||
|
)];
|
||||||
|
let wordlist = Wordlist::default().arc();
|
||||||
|
for (seed, path, _, private_key, _) in tests {
|
||||||
|
let mnemonic = Mnemonic::from_entropy(&seed[..], wordlist.clone()).unwrap();
|
||||||
|
assert_eq!(mnemonic.seed(), seed);
|
||||||
|
let req = DerivationRequest::new(DerivationAlgorithm::Ed25519, path);
|
||||||
|
let mut keyforkd = Keyforkd::new(mnemonic);
|
||||||
|
let response = keyforkd.ready().await.unwrap().call(req).await.unwrap();
|
||||||
|
assert_eq!(response.data, private_key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[should_panic]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn errors_on_short_path() {
|
||||||
|
let tests = [(
|
||||||
|
&hex!("000102030405060708090a0b0c0d0e0f")[..],
|
||||||
|
DerivationPath::from_str("m/0'").unwrap(),
|
||||||
|
hex!("8b59aa11380b624e81507a27fedda59fea6d0b779a778918a2fd3590e16e9c69"),
|
||||||
|
hex!("68e0fe46dfb67e368c75379acec591dad19df3cde26e63b93a8e704f1dade7a3"),
|
||||||
|
hex!("008c8a13df77a28f3445213a0f432fde644acaa215fc72dcdf300d5efaa85d350c"),
|
||||||
|
)];
|
||||||
|
let wordlist = Wordlist::default().arc();
|
||||||
|
for (seed, path, _, private_key, _) in tests {
|
||||||
|
let mnemonic = Mnemonic::from_entropy(&seed[..], wordlist.clone()).unwrap();
|
||||||
|
assert_eq!(mnemonic.seed(), seed);
|
||||||
|
let req = DerivationRequest::new(DerivationAlgorithm::Ed25519, path);
|
||||||
|
let mut keyforkd = Keyforkd::new(mnemonic);
|
||||||
|
let response = keyforkd.ready().await.unwrap().call(req).await.unwrap();
|
||||||
|
assert_eq!(response.data, private_key)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue