[fortuna] support multiple random value encodings (#1129)
This commit is contained in:
parent
f36e868ef6
commit
46b597e653
|
@ -58,6 +58,21 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.4"
|
||||
|
@ -511,7 +526,11 @@ version = "0.4.31"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -750,6 +769,41 @@ dependencies = [
|
|||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.4.0"
|
||||
|
@ -771,6 +825,9 @@ name = "deranged"
|
|||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
|
@ -1407,6 +1464,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"serde_qs",
|
||||
"serde_with",
|
||||
"serde_yaml",
|
||||
"sha3",
|
||||
"tokio",
|
||||
|
@ -1787,6 +1845,35 @@ dependencies = [
|
|||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
|
@ -1855,6 +1942,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3270,6 +3358,35 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23"
|
||||
dependencies = [
|
||||
"base64 0.21.4",
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.0.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with_macros",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.25"
|
||||
|
@ -4263,6 +4380,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.51.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
|
|
@ -20,6 +20,7 @@ reqwest = { version = "0.11.22", features = ["json", "blocking"] }
|
|||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
serde_qs = { version = "0.12.0", features = ["axum"] }
|
||||
serde_json = "1.0.107"
|
||||
serde_with = { version = "3.4.0", features = ["hex", "base64"] }
|
||||
serde_yaml = "0.9.25"
|
||||
sha3 = "0.10.8"
|
||||
tokio = { version = "1.33.0", features = ["full"] }
|
||||
|
|
|
@ -8,18 +8,19 @@ use {
|
|||
axum::{
|
||||
extract::{
|
||||
Path,
|
||||
Query,
|
||||
State,
|
||||
},
|
||||
Json,
|
||||
},
|
||||
pythnet_sdk::wire::array,
|
||||
serde_with::serde_as,
|
||||
utoipa::{
|
||||
IntoParams,
|
||||
ToSchema,
|
||||
},
|
||||
};
|
||||
|
||||
// TODO: this should probably take path parameters /v1/revelation/<chain_id>/<sequence_number>
|
||||
/// Reveal the random value for a given sequence number and blockchain.
|
||||
///
|
||||
/// Given a sequence number, retrieve the corresponding random value that this provider has committed to.
|
||||
|
@ -34,11 +35,12 @@ responses(
|
|||
(status = 200, description = "Random value successfully retrieved", body = GetRandomValueResponse),
|
||||
(status = 403, description = "Random value cannot currently be retrieved", body = String)
|
||||
),
|
||||
params(GetRandomValueQueryParams)
|
||||
params(RevelationPathParams, RevelationQueryParams)
|
||||
)]
|
||||
pub async fn revelation(
|
||||
State(state): State<crate::api::ApiState>,
|
||||
Path(GetRandomValueQueryParams { chain_id, sequence }): Path<GetRandomValueQueryParams>,
|
||||
Path(RevelationPathParams { chain_id, sequence }): Path<RevelationPathParams>,
|
||||
Query(RevelationQueryParams { encoding }): Query<RevelationQueryParams>,
|
||||
) -> Result<Json<GetRandomValueResponse>, RestError> {
|
||||
state
|
||||
.metrics
|
||||
|
@ -70,8 +72,10 @@ pub async fn revelation(
|
|||
.state
|
||||
.reveal(sequence)
|
||||
.map_err(|_| RestError::Unknown)?;
|
||||
let encoded_value = Blob::new(encoding.unwrap_or(BinaryEncoding::Hex), value.clone());
|
||||
|
||||
Ok(Json(GetRandomValueResponse {
|
||||
value: (*value).clone(),
|
||||
value: encoded_value,
|
||||
}))
|
||||
} else {
|
||||
Err(RestError::NoPendingRequest)
|
||||
|
@ -80,15 +84,67 @@ pub async fn revelation(
|
|||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, IntoParams)]
|
||||
#[into_params(parameter_in=Path)]
|
||||
pub struct GetRandomValueQueryParams {
|
||||
pub struct RevelationPathParams {
|
||||
#[param(value_type = String)]
|
||||
pub chain_id: ChainId,
|
||||
pub sequence: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, IntoParams)]
|
||||
#[into_params(parameter_in=Query)]
|
||||
pub struct RevelationQueryParams {
|
||||
pub encoding: Option<BinaryEncoding>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum BinaryEncoding {
|
||||
#[serde(rename = "hex")]
|
||||
Hex,
|
||||
#[serde(rename = "base64")]
|
||||
Base64,
|
||||
#[serde(rename = "array")]
|
||||
Array,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||
pub struct GetRandomValueResponse {
|
||||
// TODO: choose serialization format
|
||||
#[serde(with = "array")]
|
||||
pub value: [u8; 32],
|
||||
pub value: Blob,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||
#[serde(tag = "encoding", rename_all = "kebab-case")]
|
||||
pub enum Blob {
|
||||
Hex {
|
||||
#[serde_as(as = "serde_with::hex::Hex")]
|
||||
data: [u8; 32],
|
||||
},
|
||||
Base64 {
|
||||
#[serde_as(as = "serde_with::base64::Base64")]
|
||||
data: [u8; 32],
|
||||
},
|
||||
Array {
|
||||
#[serde(with = "array")]
|
||||
data: [u8; 32],
|
||||
},
|
||||
}
|
||||
|
||||
impl Blob {
|
||||
pub fn new(encoding: BinaryEncoding, data: [u8; 32]) -> Blob {
|
||||
match encoding {
|
||||
BinaryEncoding::Hex => Blob::Hex { data },
|
||||
BinaryEncoding::Base64 => Blob::Base64 { data },
|
||||
BinaryEncoding::Array => Blob::Array { data },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn data(&self) -> &[u8; 32] {
|
||||
match self {
|
||||
Blob::Hex { data } => data,
|
||||
Blob::Base64 { data } => data,
|
||||
Blob::Array { data } => data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,10 +45,10 @@ pub async fn generate(opts: &GenerateOptions) -> Result<()> {
|
|||
.await?;
|
||||
|
||||
tracing::info!(
|
||||
response = base64_standard_engine.encode(resp.value),
|
||||
response = base64_standard_engine.encode(resp.value.data()),
|
||||
"Retrieved the provider's random value.",
|
||||
);
|
||||
let provider_randomness = resp.value;
|
||||
let provider_randomness = resp.value.data();
|
||||
|
||||
// Submit the provider's and our values to the contract to reveal the random number.
|
||||
let random_value = contract
|
||||
|
|
|
@ -38,6 +38,8 @@ pub async fn run(opts: &RunOptions) -> Result<()> {
|
|||
components(
|
||||
schemas(
|
||||
crate::api::GetRandomValueResponse,
|
||||
crate::api::Blob,
|
||||
crate::api::BinaryEncoding,
|
||||
)
|
||||
),
|
||||
tags(
|
||||
|
|
Loading…
Reference in New Issue