mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-02 16:21:42 +00:00
Archive remote_signer code (#2559)
## Proposed Changes
This PR deletes all `remote_signer` code from Lighthouse, for the following reasons:
* The `remote_signer` code is unused, and we have no plans to use it now that we're moving to supporting the Web3Signer APIs: #2522
* It represents a significant maintenance burden. The HTTP API tests have been prone to platform-specific failures, and breakages due to dependency upgrades, e.g. #2400.
Although the code is deleted it remains in the Git history should we ever want to recover it. For ease of reference:
- The last commit containing remote signer code: 5a3bcd2904
- The last Lighthouse version: v1.5.1
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
[package]
|
||||
name = "remote_signer_test"
|
||||
version = "0.2.0"
|
||||
authors = ["Herman Junge <herman@sigmaprime.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
environment = { path = "../../lighthouse/environment" }
|
||||
hex = "0.4.2"
|
||||
httpmock = "0.5.8"
|
||||
remote_signer_client = { path = "../../remote_signer/client" }
|
||||
remote_signer_consumer = { path = "../../common/remote_signer_consumer" }
|
||||
reqwest = { version = "0.11.0", features = ["blocking", "json"] }
|
||||
serde = { version = "1.0.116", features = ["derive"] }
|
||||
serde_json = "1.0.58"
|
||||
tempfile = "3.1.0"
|
||||
tokio = { version = "1.10.0", features = ["time"] }
|
||||
types = { path = "../../consensus/types" }
|
||||
sensitive_url = { path = "../../common/sensitive_url" }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = "~0.3.5"
|
||||
windows-acl = "~0.3.0"
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
use crate::*;
|
||||
use clap::{App, Arg, ArgMatches};
|
||||
use environment::{Environment, EnvironmentBuilder};
|
||||
pub use local_signer_test_data::*;
|
||||
use remote_signer_client::Client;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use tempfile::{Builder as TempBuilder, TempDir};
|
||||
use types::EthSpec;
|
||||
|
||||
pub struct ApiTestSigner<E: EthSpec> {
|
||||
pub address: String,
|
||||
environment: Environment<E>,
|
||||
}
|
||||
|
||||
pub struct ApiTestResponse {
|
||||
pub status: u16,
|
||||
pub json: Value,
|
||||
}
|
||||
|
||||
impl ApiTestSigner<E> {
|
||||
pub fn new(arg_vec: Vec<&str>) -> Self {
|
||||
let matches = set_matches(arg_vec);
|
||||
let mut environment = get_environment(false);
|
||||
let runtime_context = environment.core_context();
|
||||
|
||||
let client = environment
|
||||
.runtime()
|
||||
.block_on(Client::new(runtime_context, &matches))
|
||||
.map_err(|e| format!("Failed to init Rest API: {}", e))
|
||||
.unwrap();
|
||||
|
||||
let address = get_address(&client);
|
||||
|
||||
Self {
|
||||
address,
|
||||
environment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown(mut self) {
|
||||
self.environment.fire_signal()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_matches(arg_vec: Vec<&str>) -> ArgMatches<'static> {
|
||||
let matches = App::new("BLS_Remote_Signer")
|
||||
.arg(
|
||||
Arg::with_name("storage-raw-dir")
|
||||
.long("storage-raw-dir")
|
||||
.value_name("DIR"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("port")
|
||||
.long("port")
|
||||
.value_name("PORT")
|
||||
.default_value("9000")
|
||||
.takes_value(true),
|
||||
);
|
||||
|
||||
matches.get_matches_from(arg_vec)
|
||||
}
|
||||
|
||||
pub fn get_environment(is_log_active: bool) -> Environment<E> {
|
||||
let environment_builder = EnvironmentBuilder::mainnet();
|
||||
|
||||
let builder = if is_log_active {
|
||||
environment_builder.async_logger("info", None).unwrap()
|
||||
} else {
|
||||
environment_builder.null_logger().unwrap()
|
||||
};
|
||||
|
||||
builder
|
||||
.multi_threaded_tokio_runtime()
|
||||
.unwrap()
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn set_up_api_test_signer_raw_dir() -> (ApiTestSigner<E>, TempDir) {
|
||||
let tmp_dir = TempBuilder::new()
|
||||
.prefix("bls-remote-signer-test")
|
||||
.tempdir()
|
||||
.unwrap();
|
||||
let arg_vec = vec![
|
||||
"this_test",
|
||||
"--port",
|
||||
"0",
|
||||
"--storage-raw-dir",
|
||||
tmp_dir.path().to_str().unwrap(),
|
||||
];
|
||||
let test_signer = ApiTestSigner::new(arg_vec);
|
||||
|
||||
(test_signer, tmp_dir)
|
||||
}
|
||||
|
||||
pub fn set_up_api_test_signer_to_sign_message() -> (ApiTestSigner<E>, TempDir) {
|
||||
let (test_signer, tmp_dir) = set_up_api_test_signer_raw_dir();
|
||||
add_sub_dirs(&tmp_dir);
|
||||
add_key_files(&tmp_dir);
|
||||
add_non_key_files(&tmp_dir);
|
||||
add_mismatched_key_file(&tmp_dir);
|
||||
add_invalid_secret_key_file(&tmp_dir);
|
||||
|
||||
(test_signer, tmp_dir)
|
||||
}
|
||||
|
||||
pub fn http_get(url: &str) -> ApiTestResponse {
|
||||
let response = reqwest::blocking::get(url).unwrap();
|
||||
|
||||
ApiTestResponse {
|
||||
status: response.status().as_u16(),
|
||||
json: serde_json::from_str(&response.text().unwrap()).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn http_post(url: &str, hashmap: HashMap<&str, &str>) -> ApiTestResponse {
|
||||
let response = reqwest::blocking::Client::new()
|
||||
.post(url)
|
||||
.json(&hashmap)
|
||||
.send()
|
||||
.unwrap();
|
||||
|
||||
ApiTestResponse {
|
||||
status: response.status().as_u16(),
|
||||
json: serde_json::from_str(&response.text().unwrap()).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn http_post_custom_body(url: &str, body: &str) -> ApiTestResponse {
|
||||
let response = reqwest::blocking::Client::new()
|
||||
.post(url)
|
||||
.body(body.to_string())
|
||||
.send()
|
||||
.unwrap();
|
||||
|
||||
ApiTestResponse {
|
||||
status: response.status().as_u16(),
|
||||
json: serde_json::from_str(&response.text().unwrap()).unwrap(),
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
// Legit BLS pairs.
|
||||
pub const PUBLIC_KEY_1: &str = "b7354252aa5bce27ab9537fd0158515935f3c3861419e1b4b6c8219b5dbd15fcf907bddf275442f3e32f904f79807a2a";
|
||||
pub const SECRET_KEY_1: &str = "68081afeb7ad3e8d469f87010804c3e8d53ef77d393059a55132637206cc59ec";
|
||||
|
||||
pub const PUBLIC_KEY_1_BYTES: [u8; 48] = [
|
||||
183, 53, 66, 82, 170, 91, 206, 39, 171, 149, 55, 253, 1, 88, 81, 89, 53, 243, 195, 134, 20, 25,
|
||||
225, 180, 182, 200, 33, 155, 93, 189, 21, 252, 249, 7, 189, 223, 39, 84, 66, 243, 227, 47, 144,
|
||||
79, 121, 128, 122, 42,
|
||||
];
|
||||
|
||||
pub const SECRET_KEY_1_BYTES: [u8; 32] = [
|
||||
104, 8, 26, 254, 183, 173, 62, 141, 70, 159, 135, 1, 8, 4, 195, 232, 213, 62, 247, 125, 57, 48,
|
||||
89, 165, 81, 50, 99, 114, 6, 204, 89, 236,
|
||||
];
|
||||
|
||||
pub const PUBLIC_KEY_2: &str = "9324739760579527b4f8c34c5df42f9fd89f59fdbe8a01d58675769f60fec5da9b9c8d7a3203cf2217692e49e7b98d97";
|
||||
pub const SECRET_KEY_2: &str = "45b5e876e5e57b23af3e86c37d708626cf1dcca6a650091bba2ddb3e0b7304ae";
|
||||
|
||||
pub const PUBLIC_KEY_3: &str = "8244ac66a8bffa0ce0af04d69ed7ed009951061259173a7c7ae1f25c049f0fcbbf2fad67b6d2b276a697315be755dac5";
|
||||
pub const SECRET_KEY_3: &str = "1e52a4e54e89ccba813d5f902545749c356f6187341b4e765bf43ece401762f6";
|
||||
|
||||
// It is valid (from 0731e07e99a0b1c69f0de13ad65e5c374e72d0a997d43387ad70448485879ca1),
|
||||
// But we are not uploading it.
|
||||
pub const ABSENT_PUBLIC_KEY: &str = "827803e94e4b8d306735df9002465b310fabb39802341dc5c616a204e4e8dc7dbb6caa4733b5da54f8cdeec7788e7500";
|
||||
|
||||
// This is the public key of 0e5faaa97a63929cecb8597949ae148c0607f1b30bd057a7487efeb4c701fbf8.
|
||||
pub const MISMATCHED_PUBLIC_KEY: &str = "83d40dfb1cbcf2a55c139faa3feec14bdae92dd485009ac8c5670d241f71c2ce064afa48dbaf091e16d0e4356038b948";
|
||||
|
||||
// The valid secret key is 3d703bd0dfdf2abb925b2d6bf1adf045ce8d93b8baff07e3313c5e150b043e89
|
||||
pub const PUBLIC_KEY_FOR_INVALID_SECRET_KEY: &str = "aac313c0bc04880c4e9f4b0b69a9f310b09b9325027666cc7f255f88c7f35b82a82b2aa004c9be655b5696fea67f7300";
|
||||
pub const INVALID_SECRET_KEY: &str = "WubbaLubbaDubDub";
|
||||
|
||||
// This is the public key of 34e62afe7c4402009a46bf8af574f9d6701c2cf72b3868eeeb59dfa6e7ff6bcf.
|
||||
pub const SUB_DIR_NAME: &str = "aadbe2d5c0316dd3c9a522029f332cde578730e61d759685d7ad3bf1166c5f0bf094c3abc105384506f052e2b7a1bae0";
|
||||
|
||||
// Silly files with long names (96 chars) to fill your BLS raw file directory.
|
||||
pub const SILLY_FILE_NAME_1: &str =
|
||||
"IAmAdamPrinceofEterniaDefenderofthesecretsoftheCastleGrayskullThisisCringermyfearlessfriendFabul";
|
||||
pub const SILLY_CONTENT_1: &str = "HemanandtheMastersoftheUniverse";
|
||||
|
||||
pub const SILLY_FILE_NAME_2: &str =
|
||||
"InthenearfutureDocTerrorandhiscyborgcompanionHackerunleashtheirforcestoconquerEarthOnlyoneforcec";
|
||||
pub const SILLY_CONTENT_2: &str = "Centurions";
|
||||
|
||||
pub const SILLY_FILE_NAME_3: &str =
|
||||
"OurworldisinperilGaiathespiritoftheearthcannolongerstandtheterribledestructionplaguingourplanetS";
|
||||
pub const SILLY_CONTENT_3: &str = "CaptainPlanet";
|
||||
|
||||
// Taken from some random string.
|
||||
pub const SIGNING_ROOT: &str = "b6bb8f3765f93f4f1e7c7348479289c9261399a3c6906685e320071a1a13955c";
|
||||
|
||||
pub const SIGNING_ROOT_BYTES: [u8; 32] = [
|
||||
182, 187, 143, 55, 101, 249, 63, 79, 30, 124, 115, 72, 71, 146, 137, 201, 38, 19, 153, 163,
|
||||
198, 144, 102, 133, 227, 32, 7, 26, 26, 19, 149, 92,
|
||||
];
|
||||
|
||||
// Expected signature for the message 0xb6bb8f3765f93f4f1e7c7348479289c9261399a3c6906685e320071a1a13955c
|
||||
// using 68081afeb7ad3e8d469f87010804c3e8d53ef77d393059a55132637206cc59ec as secret key
|
||||
pub const EXPECTED_SIGNATURE_1: &str = "0xb5d0c01cef3b028e2c5f357c2d4b886f8e374d09dd660cd7dd14680d4f956778808b4d3b2ab743e890fc1a77ae62c3c90d613561b23c6adaeb5b0e288832304fddc08c7415080be73e556e8862a1b4d0f6aa8084e34a901544d5bb6aeed3a612";
|
||||
|
||||
pub const EXPECTED_SIGNATURE_1_BYTES: [u8; 96] = [
|
||||
181, 208, 192, 28, 239, 59, 2, 142, 44, 95, 53, 124, 45, 75, 136, 111, 142, 55, 77, 9, 221,
|
||||
102, 12, 215, 221, 20, 104, 13, 79, 149, 103, 120, 128, 139, 77, 59, 42, 183, 67, 232, 144,
|
||||
252, 26, 119, 174, 98, 195, 201, 13, 97, 53, 97, 178, 60, 106, 218, 235, 91, 14, 40, 136, 50,
|
||||
48, 79, 221, 192, 140, 116, 21, 8, 11, 231, 62, 85, 110, 136, 98, 161, 180, 208, 246, 170, 128,
|
||||
132, 227, 74, 144, 21, 68, 213, 187, 106, 238, 211, 166, 18,
|
||||
];
|
||||
|
||||
// Expected signature for the message 0xb6bb8f3765f93f4f1e7c7348479289c9261399a3c6906685e320071a1a13955c
|
||||
// using 45b5e876e5e57b23af3e86c37d708626cf1dcca6a650091bba2ddb3e0b7304ae as secret key
|
||||
pub const EXPECTED_SIGNATURE_2: &str = "0xb6b63e3cecd0967d9f9b90e3ee113dfb21ecd3901dbc654ca69649ac5a0746758661306627f18bb6d7a6ea03ace069500ee79a28154c172dd71ffe4b711875e48b60466a90f3a4dcacdbc9b5f5434ad68c91e603fe1703324d83617f5270aead";
|
||||
|
||||
pub const EXPECTED_SIGNATURE_2_BYTES: [u8; 96] = [
|
||||
182, 182, 62, 60, 236, 208, 150, 125, 159, 155, 144, 227, 238, 17, 61, 251, 33, 236, 211, 144,
|
||||
29, 188, 101, 76, 166, 150, 73, 172, 90, 7, 70, 117, 134, 97, 48, 102, 39, 241, 139, 182, 215,
|
||||
166, 234, 3, 172, 224, 105, 80, 14, 231, 154, 40, 21, 76, 23, 45, 215, 31, 254, 75, 113, 24,
|
||||
117, 228, 139, 96, 70, 106, 144, 243, 164, 220, 172, 219, 201, 181, 245, 67, 74, 214, 140, 145,
|
||||
230, 3, 254, 23, 3, 50, 77, 131, 97, 127, 82, 112, 174, 173,
|
||||
];
|
||||
|
||||
// Expected signature for the message 0xb6bb8f3765f93f4f1e7c7348479289c9261399a3c6906685e320071a1a13955c
|
||||
// using 1e52a4e54e89ccba813d5f902545749c356f6187341b4e765bf43ece401762f6 as secret key
|
||||
pub const EXPECTED_SIGNATURE_3: &str = "0x874f7d6d4174df1088ab40bd9a3c808554c55d6de1dffcacc7ef56c3ca22e20b52a23dd5bb6568a123b59df0bacef3de14d4c197a2fb2a5868a18c4b11f6d7957673d9a302bf6812b1d5df9b264504f682b43dfbcf4f9130cb5ebb9b8e3737de";
|
||||
|
||||
pub const EXPECTED_SIGNATURE_3_BYTES: [u8; 96] = [
|
||||
135, 79, 125, 109, 65, 116, 223, 16, 136, 171, 64, 189, 154, 60, 128, 133, 84, 197, 93, 109,
|
||||
225, 223, 252, 172, 199, 239, 86, 195, 202, 34, 226, 11, 82, 162, 61, 213, 187, 101, 104, 161,
|
||||
35, 181, 157, 240, 186, 206, 243, 222, 20, 212, 193, 151, 162, 251, 42, 88, 104, 161, 140, 75,
|
||||
17, 246, 215, 149, 118, 115, 217, 163, 2, 191, 104, 18, 177, 213, 223, 155, 38, 69, 4, 246,
|
||||
130, 180, 61, 251, 207, 79, 145, 48, 203, 94, 187, 155, 142, 55, 55, 222,
|
||||
];
|
||||
|
||||
// These HAPPY_PATH constants were obtained running "sanity check" tests. i.e. Usign the non-remote way for producing the signature.
|
||||
pub const HAPPY_PATH_BLOCK_SIGNATURE_C137: &str = "0x87c2a5bbd71d6277802e8bf5319b84c9fbb7441c4ce56dc39e721ba4371e7521a04a36c166c5cba37e8c645e91cc31fc02884bf44fdeb51c52173e642934fd3f3e8f72f53c2ec7da284630dc86e49da75cb2578761403ed24c3a8e4bccf33e4c";
|
||||
|
||||
pub const HAPPY_PATH_ATT_SIGNATURE_C137: &str = "0xada13507d81feb5a5057565f45abed9248be56a463efa944598090bdcdd61c3fa51bb5ef34f845100efe0c14dc0c0fa20d068a7ea4f14c3e9b43aa1c44f14cb73371e48338a90622b0bee4c3a988b726d3ad87ea8a111115a0d6e1e908c421d8";
|
||||
|
||||
pub const HAPPY_PATH_RANDAO_SIGNATURE_C137: &str = "0x8c5c88491486d0c4572e4043fd42b3f774778c6f9c44464b61272c9667d18f3ca894ae08344fcd7f6dd8b6954572b90a10ce7457367cecaa9f6ef7bf105aa2e79ae7e9568317d933ac2a8e45fb06f3edfc3f6f5881ca96c8eed0c2a83fa9bc2d";
|
||||
@@ -1,152 +0,0 @@
|
||||
use crate::*;
|
||||
use remote_signer_client::api_response::SignatureApiResponse;
|
||||
use remote_signer_consumer::{Error, RemoteSignerHttpConsumer, RemoteSignerObject};
|
||||
use reqwest::ClientBuilder;
|
||||
use sensitive_url::SensitiveUrl;
|
||||
use serde::Serialize;
|
||||
use tokio::runtime::Builder;
|
||||
use tokio::time::Duration;
|
||||
use types::{AttestationData, BeaconBlock, Epoch, EthSpec, Fork, Hash256};
|
||||
|
||||
pub fn set_up_test_consumer(test_signer_address: &str) -> RemoteSignerHttpConsumer {
|
||||
set_up_test_consumer_with_timeout(test_signer_address, 12)
|
||||
}
|
||||
|
||||
pub fn set_up_test_consumer_with_timeout(
|
||||
test_signer_address: &str,
|
||||
timeout: u64,
|
||||
) -> RemoteSignerHttpConsumer {
|
||||
let url = SensitiveUrl::parse(test_signer_address).unwrap();
|
||||
let reqwest_client = ClientBuilder::new()
|
||||
.timeout(Duration::from_secs(timeout))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
RemoteSignerHttpConsumer::from_components(url, reqwest_client)
|
||||
}
|
||||
|
||||
pub fn do_sign_request<E: EthSpec, T: RemoteSignerObject>(
|
||||
test_client: &RemoteSignerHttpConsumer,
|
||||
test_input: RemoteSignerTestData<E, T>,
|
||||
) -> Result<String, Error> {
|
||||
let runtime = Builder::new_multi_thread().enable_all().build().unwrap();
|
||||
|
||||
runtime.block_on(test_client.sign(
|
||||
&test_input.public_key,
|
||||
test_input.bls_domain,
|
||||
test_input.data,
|
||||
test_input.fork,
|
||||
test_input.genesis_validators_root,
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct BlockRequestBody<E: EthSpec> {
|
||||
bls_domain: String,
|
||||
data: BeaconBlock<E>,
|
||||
fork: Fork,
|
||||
genesis_validators_root: Hash256,
|
||||
}
|
||||
|
||||
pub fn get_test_block_body(seed: u64) -> String {
|
||||
let block: BeaconBlock<E> = get_block(seed);
|
||||
let epoch = block.epoch();
|
||||
|
||||
let fork = Fork {
|
||||
previous_version: [1; 4],
|
||||
current_version: [2; 4],
|
||||
epoch,
|
||||
};
|
||||
|
||||
let genesis_validators_root = Hash256::from_low_u64_be(seed);
|
||||
|
||||
let block_request_body = BlockRequestBody {
|
||||
bls_domain: "beacon_proposer".to_string(),
|
||||
data: block,
|
||||
fork,
|
||||
genesis_validators_root,
|
||||
};
|
||||
|
||||
serde_json::to_string(&block_request_body).unwrap()
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct AttestationRequestBody {
|
||||
bls_domain: String,
|
||||
data: AttestationData,
|
||||
fork: Fork,
|
||||
genesis_validators_root: Hash256,
|
||||
}
|
||||
|
||||
pub fn get_test_attestation_body(seed: u64) -> String {
|
||||
let attestation = get_attestation::<E>(seed);
|
||||
let epoch = attestation.target.epoch;
|
||||
|
||||
let fork = Fork {
|
||||
previous_version: [1; 4],
|
||||
current_version: [2; 4],
|
||||
epoch,
|
||||
};
|
||||
|
||||
let genesis_validators_root = Hash256::from_low_u64_be(seed);
|
||||
|
||||
let attestation_request_body = AttestationRequestBody {
|
||||
bls_domain: "beacon_attester".to_string(),
|
||||
data: attestation,
|
||||
fork,
|
||||
genesis_validators_root,
|
||||
};
|
||||
|
||||
serde_json::to_string(&attestation_request_body).unwrap()
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct RandaoRequestBody {
|
||||
bls_domain: String,
|
||||
data: Epoch,
|
||||
fork: Fork,
|
||||
genesis_validators_root: Hash256,
|
||||
}
|
||||
|
||||
pub fn get_test_randao_body(seed: u64) -> String {
|
||||
let epoch = Epoch::new(seed);
|
||||
|
||||
let fork = Fork {
|
||||
previous_version: [1; 4],
|
||||
current_version: [2; 4],
|
||||
epoch,
|
||||
};
|
||||
|
||||
let genesis_validators_root = Hash256::from_low_u64_be(seed);
|
||||
|
||||
let randao_request_body = RandaoRequestBody {
|
||||
bls_domain: "randao".to_string(),
|
||||
data: epoch,
|
||||
fork,
|
||||
genesis_validators_root,
|
||||
};
|
||||
|
||||
serde_json::to_string(&randao_request_body).unwrap()
|
||||
}
|
||||
|
||||
pub fn assert_sign_ok(resp: ApiTestResponse, expected_signature: &str) {
|
||||
assert_eq!(resp.status, 200);
|
||||
assert_eq!(
|
||||
serde_json::from_value::<SignatureApiResponse>(resp.json)
|
||||
.unwrap()
|
||||
.signature,
|
||||
expected_signature
|
||||
);
|
||||
}
|
||||
|
||||
pub fn assert_sign_error(resp: ApiTestResponse, http_status: u16, error_msg: &str) {
|
||||
assert_eq!(resp.status, http_status);
|
||||
assert_eq!(
|
||||
resp.json["error"]
|
||||
.as_str()
|
||||
.unwrap()
|
||||
// cross-platform compatiblity
|
||||
.replace("\\", ""),
|
||||
error_msg
|
||||
);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
mod api_test_signer;
|
||||
mod constants;
|
||||
mod consumer;
|
||||
mod local_signer_test_data;
|
||||
mod mock;
|
||||
mod remote_signer_test_data;
|
||||
mod utils;
|
||||
|
||||
pub use api_test_signer::*;
|
||||
pub use constants::*;
|
||||
pub use consumer::*;
|
||||
pub use local_signer_test_data::*;
|
||||
pub use mock::*;
|
||||
pub use remote_signer_test_data::*;
|
||||
use types::MainnetEthSpec;
|
||||
pub use utils::*;
|
||||
|
||||
pub type E = MainnetEthSpec;
|
||||
@@ -1,103 +0,0 @@
|
||||
use crate::*;
|
||||
use hex::decode;
|
||||
use remote_signer_consumer::RemoteSignerObject;
|
||||
use std::mem;
|
||||
use types::{
|
||||
AttestationData, BeaconBlock, ChainSpec, Domain, Epoch, EthSpec, Fork, Hash256, SecretKey,
|
||||
SignedRoot,
|
||||
};
|
||||
|
||||
pub struct LocalSignerTestData<T: RemoteSignerObject> {
|
||||
secret_key: SecretKey,
|
||||
spec: ChainSpec,
|
||||
fork: Fork,
|
||||
genesis_validators_root: Hash256,
|
||||
obj: T,
|
||||
}
|
||||
|
||||
impl<T: RemoteSignerObject> LocalSignerTestData<T> {
|
||||
pub fn new(obj: T) -> Self {
|
||||
let epoch = obj.get_epoch();
|
||||
|
||||
Self {
|
||||
secret_key: SecretKey::deserialize(&decode(SECRET_KEY_1).unwrap()).unwrap(),
|
||||
spec: E::default_spec(),
|
||||
fork: Fork {
|
||||
previous_version: [1; 4],
|
||||
current_version: [2; 4],
|
||||
epoch,
|
||||
},
|
||||
genesis_validators_root: Hash256::from_low_u64_be(0xc137),
|
||||
obj,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalSignerTestData<BeaconBlock<E>> {
|
||||
pub fn sign(&self) -> String {
|
||||
let signed_block = self.obj.clone().sign(
|
||||
&self.secret_key,
|
||||
&self.fork,
|
||||
self.genesis_validators_root,
|
||||
&self.spec,
|
||||
);
|
||||
|
||||
signed_block.signature().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalSignerTestData<AttestationData> {
|
||||
pub fn sign(&self) -> String {
|
||||
let domain = self.spec.get_domain(
|
||||
self.obj.target.epoch,
|
||||
Domain::BeaconAttester,
|
||||
&self.fork,
|
||||
self.genesis_validators_root,
|
||||
);
|
||||
|
||||
let message = self.obj.signing_root(domain);
|
||||
let signature = &self.secret_key.sign(message);
|
||||
|
||||
signature.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalSignerTestData<Epoch> {
|
||||
pub fn sign(&self) -> String {
|
||||
let domain = self.spec.get_domain(
|
||||
self.obj,
|
||||
Domain::Randao,
|
||||
&self.fork,
|
||||
self.genesis_validators_root,
|
||||
);
|
||||
|
||||
let message = self.obj.signing_root(domain);
|
||||
let signature = &self.secret_key.sign(message);
|
||||
|
||||
signature.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_input_local_signer_block(seed: u64) -> LocalSignerTestData<BeaconBlock<E>> {
|
||||
let block: BeaconBlock<E>;
|
||||
|
||||
unsafe {
|
||||
block = mem::transmute(get_block::<E>(seed));
|
||||
}
|
||||
|
||||
LocalSignerTestData::new(block)
|
||||
}
|
||||
|
||||
pub fn get_input_local_signer_attestation(seed: u64) -> LocalSignerTestData<AttestationData> {
|
||||
let attestation: AttestationData;
|
||||
|
||||
unsafe {
|
||||
attestation = mem::transmute(get_attestation::<E>(seed));
|
||||
}
|
||||
|
||||
LocalSignerTestData::new(attestation)
|
||||
}
|
||||
|
||||
pub fn get_input_local_signer_randao(seed: u64) -> LocalSignerTestData<Epoch> {
|
||||
LocalSignerTestData::new(Epoch::new(seed))
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
use crate::*;
|
||||
use httpmock::{Method::POST, MockServer};
|
||||
use tokio::time::Duration;
|
||||
|
||||
pub fn set_up_mock_server(status: u16, body: &str) -> MockServer {
|
||||
set_up_mock_server_with_timeout(status, body, 0)
|
||||
}
|
||||
|
||||
pub fn set_up_mock_server_with_timeout(status: u16, body: &str, delay: u64) -> MockServer {
|
||||
let server = MockServer::start();
|
||||
|
||||
server.mock(|when, then| {
|
||||
when.method(POST).path(format!("/sign/{}", PUBLIC_KEY_1));
|
||||
then.status(status)
|
||||
.delay(Duration::from_secs(delay))
|
||||
.body(body);
|
||||
});
|
||||
|
||||
server
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
use crate::*;
|
||||
use remote_signer_consumer::RemoteSignerObject;
|
||||
use std::marker::PhantomData;
|
||||
use types::{AttestationData, BeaconBlock, Domain, Epoch, EthSpec, Fork, Hash256};
|
||||
|
||||
pub struct RemoteSignerTestData<E: EthSpec, T: RemoteSignerObject> {
|
||||
pub public_key: String,
|
||||
pub bls_domain: Domain,
|
||||
pub data: T,
|
||||
pub fork: Fork,
|
||||
pub genesis_validators_root: Hash256,
|
||||
|
||||
_phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec, T: RemoteSignerObject> RemoteSignerTestData<E, T> {
|
||||
pub fn new(public_key: &str, data: T, bls_domain: Domain) -> Self {
|
||||
let epoch = data.get_epoch();
|
||||
|
||||
Self {
|
||||
public_key: public_key.to_string(),
|
||||
bls_domain,
|
||||
data,
|
||||
fork: Fork {
|
||||
previous_version: [1; 4],
|
||||
current_version: [2; 4],
|
||||
epoch,
|
||||
},
|
||||
genesis_validators_root: Hash256::from_low_u64_be(0xc137),
|
||||
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_input_data_block(seed: u64) -> RemoteSignerTestData<E, BeaconBlock<E>> {
|
||||
let block = get_block::<E>(seed);
|
||||
RemoteSignerTestData::new(PUBLIC_KEY_1, block, Domain::BeaconProposer)
|
||||
}
|
||||
|
||||
pub fn get_input_data_attestation(seed: u64) -> RemoteSignerTestData<E, AttestationData> {
|
||||
let attestation = get_attestation::<E>(seed);
|
||||
RemoteSignerTestData::new(PUBLIC_KEY_1, attestation, Domain::BeaconAttester)
|
||||
}
|
||||
|
||||
pub fn get_input_data_randao(seed: u64) -> RemoteSignerTestData<E, Epoch> {
|
||||
let epoch = Epoch::new(seed);
|
||||
RemoteSignerTestData::new(PUBLIC_KEY_1, epoch, Domain::Randao)
|
||||
}
|
||||
|
||||
pub fn get_input_data_and_set_domain<E: EthSpec, T: RemoteSignerObject>(
|
||||
f: fn(u64) -> RemoteSignerTestData<E, T>,
|
||||
bls_domain: Domain,
|
||||
) -> RemoteSignerTestData<E, T> {
|
||||
let mut test_input = f(0xc137);
|
||||
test_input.bls_domain = bls_domain;
|
||||
|
||||
test_input
|
||||
}
|
||||
|
||||
pub fn get_input_data_and_set_public_key<E: EthSpec, T: RemoteSignerObject>(
|
||||
f: fn(u64) -> RemoteSignerTestData<E, T>,
|
||||
p: &str,
|
||||
) -> RemoteSignerTestData<E, T> {
|
||||
let mut test_input = f(0xc137);
|
||||
test_input.public_key = p.to_string();
|
||||
|
||||
test_input
|
||||
}
|
||||
@@ -1,302 +0,0 @@
|
||||
use crate::*;
|
||||
pub use constants::*;
|
||||
pub use consumer::*;
|
||||
pub use local_signer_test_data::*;
|
||||
pub use mock::*;
|
||||
use remote_signer_client::Client;
|
||||
pub use remote_signer_test_data::*;
|
||||
use std::fs::{create_dir, File};
|
||||
use std::io::Write;
|
||||
use std::net::IpAddr::{V4, V6};
|
||||
use std::path::Path;
|
||||
use tempfile::TempDir;
|
||||
use types::{
|
||||
AggregateSignature, Attestation, AttestationData, AttesterSlashing, BeaconBlock,
|
||||
BeaconBlockHeader, BitList, Checkpoint, Deposit, DepositData, Epoch, EthSpec, FixedVector,
|
||||
Hash256, IndexedAttestation, ProposerSlashing, PublicKeyBytes, Signature, SignatureBytes,
|
||||
SignedBeaconBlockHeader, SignedVoluntaryExit, Slot, Unsigned, VariableList, VoluntaryExit,
|
||||
};
|
||||
#[cfg(windows)]
|
||||
use winapi::um::winnt::{
|
||||
FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_READ_ATTRIBUTES, FILE_READ_EA, READ_CONTROL,
|
||||
STANDARD_RIGHTS_ALL, SYNCHRONIZE, WRITE_DAC,
|
||||
};
|
||||
|
||||
/// This is the security identifier in Windows for the owner of a file. See:
|
||||
/// - https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows#well-known-sids-all-versions-of-windows
|
||||
#[cfg(windows)]
|
||||
const OWNER_SID_STR: &str = "S-1-3-4";
|
||||
/// We don't need any of the `AceFlags` listed here:
|
||||
/// - https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
|
||||
#[cfg(windows)]
|
||||
const OWNER_ACL_ENTRY_FLAGS: u8 = 0;
|
||||
/// See here for explanation:
|
||||
/// - https://docs.microsoft.com/en-us/windows/win32/wmisdk/file-and-directory-access-rights-constants
|
||||
#[cfg(windows)]
|
||||
const OWNER_ACL_ENTRY_RESTRICT_MASK: u32 =
|
||||
FILE_READ_ATTRIBUTES | FILE_READ_EA | READ_CONTROL | WRITE_DAC | SYNCHRONIZE;
|
||||
/// Generic Rights:
|
||||
/// - https://docs.microsoft.com/en-us/windows/win32/fileio/file-security-and-access-rights
|
||||
/// STANDARD_RIGHTS_ALL
|
||||
/// - https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask
|
||||
#[cfg(windows)]
|
||||
const OWNER_ACL_ENTRY_UNRESTRICT_MASK: u32 =
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE | STANDARD_RIGHTS_ALL;
|
||||
|
||||
pub fn get_address(client: &Client) -> String {
|
||||
let listening_address = client.get_listening_address();
|
||||
let ip = match listening_address.ip() {
|
||||
V4(ip) => ip.to_string(),
|
||||
V6(ip) => ip.to_string(),
|
||||
};
|
||||
|
||||
format!("http://{}:{}", ip, listening_address.port())
|
||||
}
|
||||
|
||||
pub fn restrict_permissions(path: &Path) {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::fs;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
let metadata = fs::metadata(path).unwrap();
|
||||
let mut permissions = metadata.permissions();
|
||||
permissions.set_mode(0o0311); // set to '*-wx--x--x'
|
||||
fs::set_permissions(path, permissions).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use winapi::um::winnt::PSID;
|
||||
use windows_acl::acl::{AceType, ACL};
|
||||
|
||||
let path_str = path.to_str().unwrap();
|
||||
let mut acl = ACL::from_file_path(&path_str, false).unwrap();
|
||||
|
||||
let owner_sid = windows_acl::helper::string_to_sid(OWNER_SID_STR).unwrap();
|
||||
let entries = acl.all().unwrap();
|
||||
// remove all AccessAllow entries
|
||||
for entry in &entries {
|
||||
if let Some(ref entry_sid) = entry.sid {
|
||||
acl.remove(entry_sid.as_ptr() as PSID, Some(AceType::AccessAllow), None)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
// add single entry for minimal access to file owner
|
||||
// allowing them only to read attributes of the file
|
||||
// and read/modify permissions
|
||||
acl.add_entry(
|
||||
owner_sid.as_ptr() as PSID,
|
||||
AceType::AccessAllow,
|
||||
OWNER_ACL_ENTRY_FLAGS,
|
||||
OWNER_ACL_ENTRY_RESTRICT_MASK,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unrestrict_permissions(path: &Path) {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::fs;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
let metadata = fs::metadata(path).unwrap();
|
||||
let mut permissions = metadata.permissions();
|
||||
permissions.set_mode(0o0755); // set to '*rwxr-xr-x'
|
||||
fs::set_permissions(path, permissions).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use winapi::um::winnt::PSID;
|
||||
use windows_acl::acl::{AceType, ACL};
|
||||
|
||||
let path_str = path.to_str().unwrap();
|
||||
let mut acl = ACL::from_file_path(&path_str, false).unwrap();
|
||||
|
||||
let owner_sid = windows_acl::helper::string_to_sid(OWNER_SID_STR).unwrap();
|
||||
// add single entry for file owner
|
||||
acl.add_entry(
|
||||
owner_sid.as_ptr() as PSID,
|
||||
AceType::AccessAllow,
|
||||
OWNER_ACL_ENTRY_FLAGS,
|
||||
OWNER_ACL_ENTRY_UNRESTRICT_MASK,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_key_files(tmp_dir: &TempDir) {
|
||||
let pairs = vec![
|
||||
(PUBLIC_KEY_1, SECRET_KEY_1),
|
||||
(PUBLIC_KEY_2, SECRET_KEY_2),
|
||||
(PUBLIC_KEY_3, SECRET_KEY_3),
|
||||
];
|
||||
|
||||
add_files(tmp_dir, pairs);
|
||||
}
|
||||
|
||||
pub fn add_mismatched_key_file(tmp_dir: &TempDir) {
|
||||
let pairs = vec![(MISMATCHED_PUBLIC_KEY, SECRET_KEY_1)];
|
||||
|
||||
add_files(tmp_dir, pairs);
|
||||
}
|
||||
|
||||
pub fn add_invalid_secret_key_file(tmp_dir: &TempDir) {
|
||||
let pairs = vec![(PUBLIC_KEY_FOR_INVALID_SECRET_KEY, INVALID_SECRET_KEY)];
|
||||
|
||||
add_files(tmp_dir, pairs);
|
||||
}
|
||||
|
||||
pub fn add_non_key_files(tmp_dir: &TempDir) {
|
||||
let pairs = vec![
|
||||
(SILLY_FILE_NAME_1, SILLY_CONTENT_1),
|
||||
(SILLY_FILE_NAME_2, SILLY_CONTENT_2),
|
||||
(SILLY_FILE_NAME_3, SILLY_CONTENT_3),
|
||||
];
|
||||
|
||||
add_files(tmp_dir, pairs);
|
||||
}
|
||||
|
||||
fn add_files(tmp_dir: &TempDir, pairs: Vec<(&str, &str)>) {
|
||||
for pair in pairs {
|
||||
let file_path = tmp_dir.path().join(pair.0);
|
||||
let mut tmp_file = File::create(file_path).unwrap();
|
||||
writeln!(tmp_file, "{}", pair.1).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_sub_dirs(tmp_dir: &TempDir) {
|
||||
let random_sub_dir_path = tmp_dir.path().join("random_sub_dir_name");
|
||||
create_dir(random_sub_dir_path).unwrap();
|
||||
|
||||
let another_sub_dir_path = tmp_dir.path().join(SUB_DIR_NAME);
|
||||
create_dir(another_sub_dir_path).unwrap();
|
||||
}
|
||||
|
||||
/// We spice up some of the values, based on a given `seed` parameter.
|
||||
pub fn get_block<E: EthSpec>(seed: u64) -> BeaconBlock<E> {
|
||||
let spec = &mut E::default_spec();
|
||||
spec.genesis_slot = Slot::new(seed);
|
||||
|
||||
let header = BeaconBlockHeader {
|
||||
slot: Slot::new(seed),
|
||||
proposer_index: 0,
|
||||
parent_root: Hash256::from_low_u64_be(222 * seed),
|
||||
state_root: Hash256::from_low_u64_be(333 * seed),
|
||||
body_root: Hash256::from_low_u64_be(444 * seed),
|
||||
};
|
||||
|
||||
let signed_header = SignedBeaconBlockHeader {
|
||||
message: header,
|
||||
signature: Signature::empty(),
|
||||
};
|
||||
let indexed_attestation: IndexedAttestation<E> = IndexedAttestation {
|
||||
attesting_indices: VariableList::new(vec![0_u64; E::MaxValidatorsPerCommittee::to_usize()])
|
||||
.unwrap(),
|
||||
data: AttestationData::default(),
|
||||
signature: AggregateSignature::empty(),
|
||||
};
|
||||
|
||||
let deposit_data = DepositData {
|
||||
pubkey: PublicKeyBytes::empty(),
|
||||
withdrawal_credentials: Hash256::from_low_u64_be(555 * seed),
|
||||
amount: 0,
|
||||
signature: SignatureBytes::empty(),
|
||||
};
|
||||
let proposer_slashing = ProposerSlashing {
|
||||
signed_header_1: signed_header.clone(),
|
||||
signed_header_2: signed_header,
|
||||
};
|
||||
|
||||
let attester_slashing = AttesterSlashing {
|
||||
attestation_1: indexed_attestation.clone(),
|
||||
attestation_2: indexed_attestation,
|
||||
};
|
||||
|
||||
let attestation: Attestation<E> = Attestation {
|
||||
aggregation_bits: BitList::with_capacity(E::MaxValidatorsPerCommittee::to_usize()).unwrap(),
|
||||
data: AttestationData::default(),
|
||||
signature: AggregateSignature::empty(),
|
||||
};
|
||||
|
||||
let deposit = Deposit {
|
||||
proof: FixedVector::from_elem(Hash256::from_low_u64_be(666 * seed)),
|
||||
data: deposit_data,
|
||||
};
|
||||
|
||||
let voluntary_exit = VoluntaryExit {
|
||||
epoch: Epoch::new(1),
|
||||
validator_index: 1,
|
||||
};
|
||||
|
||||
let signed_voluntary_exit = SignedVoluntaryExit {
|
||||
message: voluntary_exit,
|
||||
signature: Signature::empty(),
|
||||
};
|
||||
|
||||
let mut block: BeaconBlock<E> = BeaconBlock::empty(spec);
|
||||
for _ in 0..E::MaxProposerSlashings::to_usize() {
|
||||
block
|
||||
.body_mut()
|
||||
.proposer_slashings_mut()
|
||||
.push(proposer_slashing.clone())
|
||||
.unwrap();
|
||||
}
|
||||
for _ in 0..E::MaxDeposits::to_usize() {
|
||||
block
|
||||
.body_mut()
|
||||
.deposits_mut()
|
||||
.push(deposit.clone())
|
||||
.unwrap();
|
||||
}
|
||||
for _ in 0..E::MaxVoluntaryExits::to_usize() {
|
||||
block
|
||||
.body_mut()
|
||||
.voluntary_exits_mut()
|
||||
.push(signed_voluntary_exit.clone())
|
||||
.unwrap();
|
||||
}
|
||||
for _ in 0..E::MaxAttesterSlashings::to_usize() {
|
||||
block
|
||||
.body_mut()
|
||||
.attester_slashings_mut()
|
||||
.push(attester_slashing.clone())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
for _ in 0..E::MaxAttestations::to_usize() {
|
||||
block
|
||||
.body_mut()
|
||||
.attestations_mut()
|
||||
.push(attestation.clone())
|
||||
.unwrap();
|
||||
}
|
||||
block
|
||||
}
|
||||
|
||||
pub fn get_attestation<E: EthSpec>(seed: u64) -> AttestationData {
|
||||
let slot = Slot::from(seed);
|
||||
let epoch = slot.epoch(E::slots_per_epoch());
|
||||
|
||||
let build_checkpoint = |epoch_u64: u64| -> Checkpoint {
|
||||
Checkpoint {
|
||||
epoch: Epoch::new(epoch_u64),
|
||||
root: Hash256::from_low_u64_be(333 * seed),
|
||||
}
|
||||
};
|
||||
|
||||
let source = build_checkpoint(epoch.as_u64().saturating_sub(2));
|
||||
let target = build_checkpoint(epoch.as_u64());
|
||||
|
||||
let index = 0xc137u64;
|
||||
|
||||
AttestationData {
|
||||
slot,
|
||||
index,
|
||||
beacon_block_root: Hash256::from_low_u64_be(666 * seed),
|
||||
source,
|
||||
target,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user