diff --git a/CHANGELOG.md b/CHANGELOG.md index 64ec179f7..fe1e9c77f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,11 +26,14 @@ multiple oracle inputs, this means any programs that were compiled and used need runtime - In [#1179](https://github.com/entropyxyz/entropy-core/pull/1179) the format of TDX Quote input data has been changed. +- In [#1184](https://github.com/entropyxyz/entropy-core/pull/1184/) The ```OracleData``` mapping now holds a +struct ```OracleInfo``` which includes the ```oracle_data``` and the ```oracle_type``` ### Added - Protocol message versioning ([#1140](https://github.com/entropyxyz/entropy-core/pull/1140)) - CLI command to get oracle headings ([#1170](https://github.com/entropyxyz/entropy-core/pull/1170)) - Add TSS endpoint to get TDX quote ([#1173](https://github.com/entropyxyz/entropy-core/pull/1173)) +- Add type info to oracle data ([#1184](https://github.com/entropyxyz/entropy-core/pull/1184)) ### Changed - Use correct key rotation endpoint in OCW ([#1104](https://github.com/entropyxyz/entropy-core/pull/1104)) diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index 4ee7c5dae..9d55c8bcd 100644 Binary files a/crates/client/entropy_metadata.scale and b/crates/client/entropy_metadata.scale differ diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index 062de590a..c3f7e4842 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -50,6 +50,7 @@ use base64::prelude::{Engine, BASE64_STANDARD}; use entropy_protocol::RecoverableSignature; use entropy_shared::HashingAlgorithm; use futures::stream::StreamExt; +use serde::{Deserialize, Serialize}; use sp_core::{ sr25519::{self, Signature}, Pair, @@ -446,20 +447,33 @@ pub async fn request_attestation( Ok(user::request_attestation(api, rpc, attestee).await?) } +/// Return type for getting oracle headings. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct OracleDataReturn { + pub oracle_heading: String, + pub oracle_type: String, +} /// Get oracle data headings /// This is useful for program developers to know what oracle data is available pub async fn get_oracle_headings( api: &OnlineClient, - _rpc: &LegacyRpcMethods, -) -> Result, ClientError> { + rpc: &LegacyRpcMethods, +) -> Result, ClientError> { let storage_address = entropy::storage().oracle().oracle_data_iter(); - let mut iter = api.storage().at_latest().await?.iter(storage_address).await?; + let block_hash = rpc + .chain_get_block_hash(None) + .await? + .ok_or(ClientError::ChainFetch("Failed to get block hash"))?; + let mut iter = api.storage().at(block_hash).iter(storage_address).await?; let mut headings = Vec::new(); while let Some(Ok(kv)) = iter.next().await { // Key is: storage_address || 128 bit hash || key let mut input = &kv.key_bytes[32 + 16 + 1..]; - let heading = String::decode(&mut input)?; - headings.push(heading); + let oracle_heading = String::decode(&mut input)?; + headings.push(OracleDataReturn { + oracle_heading, + oracle_type: std::str::from_utf8(&kv.value.oracle_type)?.to_string(), + }); } Ok(headings) } diff --git a/crates/client/src/errors.rs b/crates/client/src/errors.rs index c2f4ab241..42f6e5d52 100644 --- a/crates/client/src/errors.rs +++ b/crates/client/src/errors.rs @@ -123,4 +123,6 @@ pub enum ClientError { Codec(#[from] parity_scale_codec::Error), #[error("Attestation request: {0}")] AttestationRequest(#[from] AttestationRequestError), + #[error("Chain Fetch: {0}")] + ChainFetch(&'static str), } diff --git a/crates/client/src/tests.rs b/crates/client/src/tests.rs index 1663dbedb..e062475b7 100644 --- a/crates/client/src/tests.rs +++ b/crates/client/src/tests.rs @@ -14,7 +14,7 @@ use crate::{ change_endpoint, change_threshold_accounts, get_oracle_headings, register, remove_program, request_attestation, store_program, substrate::query_chain, - update_programs, + update_programs, OracleDataReturn, }; use entropy_shared::{QuoteContext, QuoteInputData}; @@ -284,7 +284,10 @@ async fn test_get_oracle_headings() { current_block = rpc.chain_get_header(Some(finalized_head)).await.unwrap().unwrap().number; } - let headings = get_oracle_headings(&api, &rpc).await.unwrap(); - - assert_eq!(headings, vec!["block_number_entropy".to_string()]); + let oracle_headings = get_oracle_headings(&api, &rpc).await.unwrap(); + let mock_data = OracleDataReturn { + oracle_heading: "block_number_entropy".to_string(), + oracle_type: "u32".to_string(), + }; + assert_eq!(oracle_headings, vec![mock_data]); } diff --git a/crates/test-cli/src/lib.rs b/crates/test-cli/src/lib.rs index 8b76fe5f8..4d82ab622 100644 --- a/crates/test-cli/src/lib.rs +++ b/crates/test-cli/src/lib.rs @@ -573,8 +573,12 @@ pub async fn run_command( } }, CliCommand::GetOracleHeadings => { - let headings = get_oracle_headings(&api, &rpc).await?; - Ok(serde_json::to_string_pretty(&headings)?) + let oracles_data = get_oracle_headings(&api, &rpc).await?; + if cli.json { + Ok(serde_json::to_string_pretty(&oracles_data)?) + } else { + Ok(format!("{:?}", oracles_data)) + } }, CliCommand::GetTdxQuote { tss_endpoint, output_filename } => { let quote_bytes = diff --git a/crates/threshold-signature-server/src/helpers/substrate.rs b/crates/threshold-signature-server/src/helpers/substrate.rs index ee8a27df5..0ec2099c8 100644 --- a/crates/threshold-signature-server/src/helpers/substrate.rs +++ b/crates/threshold-signature-server/src/helpers/substrate.rs @@ -19,7 +19,8 @@ use crate::{ entropy::{ self, runtime_types::{ - bounded_collections::bounded_vec::BoundedVec, pallet_programs::pallet::ProgramInfo, + bounded_collections::bounded_vec::BoundedVec, pallet_oracle::module::OracleInfo, + pallet_programs::pallet::ProgramInfo, }, }, EntropyConfig, @@ -70,9 +71,10 @@ pub async fn get_oracle_data( for program_oracle_data in program_oracle_datas { let oracle_data_call = entropy::storage().oracle().oracle_data(BoundedVec(program_oracle_data)); - let oracle_info = - query_chain(api, rpc, oracle_data_call, None).await?.unwrap_or(BoundedVec(vec![])); - oracle_infos.push(oracle_info.0); + let oracle_info = query_chain(api, rpc, oracle_data_call, None) + .await? + .unwrap_or(OracleInfo { oracle_data: BoundedVec(vec![]), oracle_type: vec![] }); + oracle_infos.push(oracle_info.oracle_data.0); } Ok(oracle_infos) } diff --git a/pallets/oracle/src/benchmarking.rs b/pallets/oracle/src/benchmarking.rs index 3f3713c6b..74991ce59 100644 --- a/pallets/oracle/src/benchmarking.rs +++ b/pallets/oracle/src/benchmarking.rs @@ -26,7 +26,7 @@ benchmarks! { }: { Oracle::::on_initialize(50u32.into()); } verify { - assert_eq!(OracleData::::get(BoundedVec::try_from("block_number_entropy".encode()).unwrap()).unwrap()[0], 50); + assert_eq!(OracleData::::get(BoundedVec::try_from("block_number_entropy".encode()).unwrap()).unwrap().oracle_data[0], 50); } impl_benchmark_test_suite!(Oracle, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/pallets/oracle/src/lib.rs b/pallets/oracle/src/lib.rs index ec1898f03..c9eba75b1 100644 --- a/pallets/oracle/src/lib.rs +++ b/pallets/oracle/src/lib.rs @@ -26,6 +26,7 @@ use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; +use sp_std::vec::Vec; #[cfg(test)] mod mock; @@ -55,13 +56,22 @@ pub mod module { type WeightInfo: WeightInfo; } + /// Oracle Info for oracle data + #[derive(Clone, Encode, Decode, Eq, PartialEqNoBound, RuntimeDebug, TypeInfo)] + #[scale_info(skip_type_params(T))] + pub struct OracleInfo { + pub oracle_data: BoundedVec, + pub oracle_type: Vec, + } + + /// Storage for oracle info to be passed to programs. #[pallet::storage] #[pallet::getter(fn oracle_data)] pub type OracleData = StorageMap< _, Blake2_128Concat, BoundedVec, - BoundedVec, + OracleInfo, OptionQuery, >; @@ -92,8 +102,11 @@ pub mod module { OracleData::::insert( BoundedVec::try_from("block_number_entropy".encode()) .expect("Key fits in bounded vec; qed"), - BoundedVec::try_from(block_number.encode()) - .expect("Block number fits in bounded vec; qed"), + OracleInfo { + oracle_data: BoundedVec::try_from(block_number.encode()) + .expect("Block number fits in bounded vec; qed"), + oracle_type: "u32".as_bytes().to_vec(), + }, ); T::WeightInfo::on_initialize() } diff --git a/pallets/oracle/src/tests.rs b/pallets/oracle/src/tests.rs index b823ed013..71a2d42cf 100644 --- a/pallets/oracle/src/tests.rs +++ b/pallets/oracle/src/tests.rs @@ -31,10 +31,11 @@ fn test_set_block_number() { >::on_initialize(50); - assert_eq!( + let oracle_info = Oracle::oracle_data(BoundedVec::try_from("block_number_entropy".encode()).unwrap()) - .unwrap()[0], - 50 - ); + .unwrap(); + + assert_eq!(u32::decode(&mut oracle_info.oracle_data.as_ref()).unwrap(), 50u32); + assert_eq!(std::str::from_utf8(&oracle_info.oracle_type).unwrap().to_string(), "u32"); }); }