f9d60f5436
## Issue Addressed Closes #2274 ## Proposed Changes * Modify the `YamlConfig` to collect unknown fields into an `extra_fields` map, instead of failing hard. * Log a debug message if there are extra fields returned to the VC from one of its BNs. This restores Lighthouse's compatibility with Teku beacon nodes (and therefore Infura)
229 lines
8.5 KiB
Rust
229 lines
8.5 KiB
Rust
mod post {
|
|
use remote_signer_consumer::{Error, RemoteSignerHttpConsumer};
|
|
use remote_signer_test::*;
|
|
use reqwest::{ClientBuilder, Url};
|
|
use tokio::time::Duration;
|
|
|
|
#[test]
|
|
fn server_unavailable() {
|
|
let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message();
|
|
let test_client = set_up_test_consumer(&test_signer.address);
|
|
|
|
test_signer.shutdown();
|
|
|
|
let test_input = get_input_data_block(0xc137);
|
|
let signature = do_sign_request(&test_client, test_input);
|
|
|
|
match signature.unwrap_err() {
|
|
Error::Reqwest(e) => {
|
|
let error_msg = e.to_string();
|
|
assert!(error_msg.contains("error sending request for url"));
|
|
assert!(error_msg.contains(PUBLIC_KEY_1));
|
|
assert!(error_msg.contains("error trying to connect"));
|
|
assert!(error_msg.contains("tcp connect error"));
|
|
assert!(error_msg.contains("Connection refused"));
|
|
}
|
|
e => panic!("{:?}", e),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn server_error() {
|
|
let (test_signer, tmp_dir) = set_up_api_test_signer_to_sign_message();
|
|
set_permissions(tmp_dir.path(), 0o40311);
|
|
set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40311);
|
|
|
|
let test_client = set_up_test_consumer(&test_signer.address);
|
|
let test_input = get_input_data_block(0xc137);
|
|
let signature = do_sign_request(&test_client, test_input);
|
|
|
|
set_permissions(tmp_dir.path(), 0o40755);
|
|
set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40755);
|
|
|
|
match signature.unwrap_err() {
|
|
Error::ServerMessage(message) => assert_eq!(message, "Storage error: PermissionDenied"),
|
|
e => panic!("{:?}", e),
|
|
}
|
|
|
|
test_signer.shutdown();
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_url() {
|
|
let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message();
|
|
|
|
let run_testcase = |u: &str| -> Result<String, String> {
|
|
let url: Url = u.parse().map_err(|e| format!("[ParseError] {:?}", e))?;
|
|
|
|
let reqwest_client = ClientBuilder::new()
|
|
.timeout(Duration::from_secs(12))
|
|
.build()
|
|
.unwrap();
|
|
|
|
let test_client = RemoteSignerHttpConsumer::from_components(url, reqwest_client);
|
|
|
|
let test_input = get_input_data_block(0xc137);
|
|
let signature = do_sign_request(&test_client, test_input);
|
|
|
|
signature.map_err(|e| match e {
|
|
Error::InvalidUrl(message) => format!("[InvalidUrl] {:?}", message),
|
|
Error::Reqwest(re) => {
|
|
if re.is_builder() {
|
|
format!("[Reqwest - Builder] {:?}", re.url().unwrap())
|
|
} else if re.is_request() {
|
|
format!("[Reqwest - Request] {:?}", re.url().unwrap())
|
|
} else {
|
|
format!("[Reqwest] {:?}", re)
|
|
}
|
|
}
|
|
_ => format!("{:?}", e),
|
|
})
|
|
};
|
|
|
|
let testcase = |u: &str, msg: &str| assert_eq!(run_testcase(u).unwrap_err(), msg);
|
|
|
|
// url::parser::ParseError.
|
|
// These cases don't even make it to the step of building a RemoteSignerHttpConsumer.
|
|
testcase("", "[ParseError] RelativeUrlWithoutBase");
|
|
testcase("/4/8/15/16/23/42", "[ParseError] RelativeUrlWithoutBase");
|
|
testcase("localhost", "[ParseError] RelativeUrlWithoutBase");
|
|
testcase(":", "[ParseError] RelativeUrlWithoutBase");
|
|
testcase("0.0:0", "[ParseError] RelativeUrlWithoutBase");
|
|
testcase(":aa", "[ParseError] RelativeUrlWithoutBase");
|
|
testcase("0:", "[ParseError] RelativeUrlWithoutBase");
|
|
testcase("ftp://", "[ParseError] EmptyHost");
|
|
testcase("http://", "[ParseError] EmptyHost");
|
|
testcase("http://127.0.0.1:abcd", "[ParseError] InvalidPort");
|
|
testcase("http://280.0.0.1", "[ParseError] InvalidIpv4Address");
|
|
|
|
// `Error::InvalidUrl`.
|
|
// The RemoteSignerHttpConsumer is created, but fails at `path_segments_mut()`.
|
|
testcase(
|
|
"localhost:abcd",
|
|
"[InvalidUrl] Url { scheme: \"localhost\", username: \"\", password: None, host: None, port: None, path: \"abcd\", query: None, fragment: None }",
|
|
);
|
|
testcase("localhost:", "[InvalidUrl] Url { scheme: \"localhost\", username: \"\", password: None, host: None, port: None, path: \"\", query: None, fragment: None }");
|
|
|
|
// `Reqwest::Error` of the `Builder` kind.
|
|
// POST is not made.
|
|
testcase(
|
|
"unix:/run/foo.socket",
|
|
&format!(
|
|
"[Reqwest - Builder] Url {{ scheme: \"unix\", username: \"\", password: None, host: None, port: None, path: \"/run/foo.socket/sign/{}\", query: None, fragment: None }}",
|
|
PUBLIC_KEY_1
|
|
),
|
|
);
|
|
// `Reqwest::Error` of the `Request` kind.
|
|
testcase(
|
|
"http://127.0.0.1:0",
|
|
&format!(
|
|
"[Reqwest - Request] Url {{ scheme: \"http\", username: \"\", password: None, host: Some(Ipv4(127.0.0.1)), port: Some(0), path: \"/sign/{}\", query: None, fragment: None }}",
|
|
PUBLIC_KEY_1
|
|
),
|
|
);
|
|
|
|
test_signer.shutdown();
|
|
}
|
|
|
|
#[test]
|
|
fn wrong_url() {
|
|
let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message();
|
|
|
|
let run_testcase = |u: &str| -> Result<String, String> {
|
|
let url: Url = u.parse().unwrap();
|
|
|
|
let reqwest_client = ClientBuilder::new()
|
|
.timeout(Duration::from_secs(12))
|
|
.build()
|
|
.unwrap();
|
|
|
|
let test_client = RemoteSignerHttpConsumer::from_components(url, reqwest_client);
|
|
|
|
let test_input = get_input_data_block(0xc137);
|
|
let signature = do_sign_request(&test_client, test_input);
|
|
|
|
signature.map_err(|e| format!("{:?}", e))
|
|
};
|
|
|
|
let testcase = |u: &str, msgs: Vec<&str>| {
|
|
let r = run_testcase(u).unwrap_err();
|
|
|
|
for msg in msgs.iter() {
|
|
assert!(r.contains(msg), "{:?} should contain {:?}", r, msg);
|
|
}
|
|
};
|
|
|
|
testcase(
|
|
"http://error-dns",
|
|
vec![
|
|
"reqwest::Error",
|
|
"kind: Request",
|
|
&format!("/sign/{}", PUBLIC_KEY_1),
|
|
"hyper::Error(Connect, ConnectError",
|
|
"dns error",
|
|
"failed to lookup address information",
|
|
],
|
|
);
|
|
|
|
test_signer.shutdown();
|
|
}
|
|
|
|
#[test]
|
|
fn wrong_public_key() {
|
|
let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message();
|
|
let test_client = set_up_test_consumer(&test_signer.address);
|
|
|
|
let mut test_input = get_input_data_block(0xc137);
|
|
test_input.public_key = ABSENT_PUBLIC_KEY.to_string();
|
|
|
|
let signature = do_sign_request(&test_client, test_input);
|
|
|
|
match signature.unwrap_err() {
|
|
Error::ServerMessage(msg) => {
|
|
assert_eq!(msg, format!("Key not found: {}", ABSENT_PUBLIC_KEY))
|
|
}
|
|
e => panic!("{:?}", e),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_secret_key() {
|
|
let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message();
|
|
let test_client = set_up_test_consumer(&test_signer.address);
|
|
|
|
let mut test_input = get_input_data_block(0xc137);
|
|
test_input.public_key = PUBLIC_KEY_FOR_INVALID_SECRET_KEY.to_string();
|
|
|
|
let signature = do_sign_request(&test_client, test_input);
|
|
|
|
match signature.unwrap_err() {
|
|
Error::ServerMessage(msg) => assert_eq!(
|
|
msg,
|
|
format!(
|
|
"Invalid secret key: public_key: {}; Invalid hex character: W at index 0",
|
|
PUBLIC_KEY_FOR_INVALID_SECRET_KEY
|
|
)
|
|
),
|
|
e => panic!("{:?}", e),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn key_mismatch() {
|
|
let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message();
|
|
let test_client = set_up_test_consumer(&test_signer.address);
|
|
|
|
let mut test_input = get_input_data_block(0xc137);
|
|
test_input.public_key = MISMATCHED_PUBLIC_KEY.to_string();
|
|
|
|
let signature = do_sign_request(&test_client, test_input);
|
|
|
|
match signature.unwrap_err() {
|
|
Error::ServerMessage(msg) => {
|
|
assert_eq!(msg, format!("Key mismatch: {}", MISMATCHED_PUBLIC_KEY))
|
|
}
|
|
e => panic!("{:?}", e),
|
|
}
|
|
}
|
|
}
|